0 环境
系统环境:win10
编辑器:IDEA
1 提供者提供消费接口
首先提供者提供访问接口 然后创建消费者 消费这个访问接口
// 提供接口 @RestController public class HelloController { @GetMapping("/hello") public String hello(){ return "hello provider"; } }
2 创建消费者&基本使用
创建消费者需要获取provider(提供者)的接口地址 需要到eureka server中查找 先写死访问地址 慢慢解耦 这个东东到底好在哪里
1 依赖
添加web client依赖 一会要用到 还是创建springboot项目的方式
2 yml配置
spring: application: name: consumer server: port: 1301 eureka: client: service-url: defaultZone: http://localhost:1234/eureka
3 消费接口
// 下面的消费接口都需要这个 // 以前需要添加启动注解 现在不需要添加 即可使用 @Autowired DiscoveryClient discoveryClient;
/** * @Description: 消费者和提供者直接连接 强耦合 未通过server * @Param: * @return: 正确 -> 返回提供者定死的hello里的返回值 失败 -> error * @Author: 水面行走 * @Date: 2020/2/27 */ @GetMapping("/useHello") public String useHello(){ // HttpURLConnection发起请求 写死provider地址 HttpURLConnection connection = null; try { // 新建url openConnxxx打开连接 -> HttpURLConnection URL url = new URL("http://localhost:1300/hello"); connection = (HttpURLConnection) url.openConnection(); // 若是200 读取 if (200 == connection.getResponseCode()) { BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); // 就一行的字符串 不需要遍历了 String s = reader.readLine(); return s; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return "use error"; }
4 启动项目
5 消费接口改造
/** * @Description: 改造1 通过server查询需要获取提供者的信息(在上面的基础连接上进行升级改造) * @Param: * @return: * @Author: xxxxx * @Date: 2020/2/xx */ @GetMapping("/useHello1") public String userHello1(){
// 由于查询到的服务列表是一个集合 可能是集合化部署 集合中每一项就是一个实例 List<ServiceInstance> provider = discoveryClient.getInstances("provider"); for (ServiceInstance serviceInstance : provider) { // 获取host port stringbuffer->append追加 String host = serviceInstance.getHost(); int port = serviceInstance.getPort(); // 类似格式 http://localhost:1300/hello // 上面的写死这个格式 现在是动态获取 拼接 最后在转换 其他一样的 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("http://") .append(host) .append(":") .append(port) .append("/hello"); System.out.println("格式转换:"+stringBuffer.toString()); HttpURLConnection connection = null; try { // 在通过tostring转化为需要的url // 新建url openConnxxx打开连接 -> HttpURLConnection URL url = new URL(stringBuffer.toString()); connection = (HttpURLConnection) url.openConnection(); // 若是200 读取 if (200 == connection.getResponseCode()) { BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); // 就一行的字符串 不需要遍历了 String s = reader.readLine(); return s; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return "error"; }
6 重启项目
7 集群化部署&简单的负载均衡
// 为了体验负载均衡的效果 添加了一个port数值 @RestController public class HelloController { @Value("${server.port}") Integer port; @GetMapping("/hello") public String hello(){ return "hello provider" + port; } }
首先修改提供者接口 打包提供者 打包成功后 定位到提供者target目录 右键打开命令行 输入java -jar xxx.jar --server.port=xxxx(启动提供者)
为了实现简单负载均衡(取余) 最好全部重启一下 开启server provider consumer(启动前 添加下面的代码)
/** * @Description: 改造2 集群式+负载均衡(取余) * @Param: * @return: * @Author: * @Date: 2020/2/xx */ @GetMapping("/useHello2") public String userHello2(){ // 由于查询到的服务列表是一个集合 可能是集合化部署 集合中每一项就是一个实例 List<ServiceInstance> provider = discoveryClient.getInstances("provider"); // for (ServiceInstance serviceInstance : provider) { int count = 0; // System.out.println((count) % provider.size()); ServiceInstance serviceInstance = provider.get((count++) % provider.size()); // 获取host port stringbuffer->append追加 String host = serviceInstance.getHost(); int port = serviceInstance.getPort(); // 类似格式 http://localhost:1300/hello // 上面的写死这个格式 现在是动态获取 拼接 最后在转换 其他一样的 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("http://") .append(host) .append(":") .append(port) .append("/hello"); // System.out.println("格式转换:"+stringBuffer.toString()); HttpURLConnection connection = null; try { // 在通过tostring转化为需要的url // 新建url openConnxxx打开连接 -> HttpURLConnection URL url = new URL(stringBuffer.toString()); connection = (HttpURLConnection) url.openConnection(); // 若是200 读取 if (200 == connection.getResponseCode()) { BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); // 就一行的字符串 不需要遍历了 String s = reader.readLine(); return s; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // } return "error"; }
3 升级改造
2方面动手: http调用 --> spring提供RestTemplate 负载均衡 --> Ribbon
1 http调用
http调用 将HttpURLConnection以及下面的那一段 用RestTemplate替换
application中添加 ---------------------------- @Bean RestTemplate restTemplate(){ return new RestTemplate(); } ----------------------------------- @Autowired DiscoveryClient discoveryClient; @GetMapping("/useHello3") public String userHello3() { // 由于查询到的服务列表是一个集合 可能是集合化部署 集合中每一项就是一个实例 List<ServiceInstance> provider = discoveryClient.getInstances("provider"); // for (ServiceInstance serviceInstance : provider) { int count = 0; // System.out.println((count) % provider.size()); ServiceInstance serviceInstance = provider.get((count++) % provider.size()); // 获取host port stringbuffer->append追加 String host = serviceInstance.getHost(); int port = serviceInstance.getPort(); // 类似格式 http://localhost:1300/hello // 上面的写死这个格式 现在是动态获取 拼接 最后在转换 其他一样的 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("http://") .append(host) .append(":") .append(port) .append("/hello"); // System.out.println("格式转换:"+stringBuffer.toString()); String s = restTemplate.getForObject(stringBuffer.toString(), String.class); return s; }
2 开启负载均衡
application中添加bean ---------------------------------- @Bean // 负载均衡注解 @LoadBalanced RestTemplate restTemplateOne(){ return new RestTemplate(); } ------------------------------------------------- controller层添加 ====================== @Autowired DiscoveryClient discoveryClient; @Autowired @Qualifier("restTemplateOne") RestTemplate restTemplateOne; @GetMapping("/useHello4") public String userHello4() { String address = "http://provider/hello"; String retStr = restTemplateOne.getForObject(address, String.class); return retStr; }
3 效果
4 小结
给RestTemplate添加负载均衡的注解 开启它 具备了负载均衡 可以理解为RestTemplate = http调用 + 负载均衡