一、引入
上面那个使用者一直都是访问的第一个goods-serivce服务,那如果我有很多个service服务,后面岂不是都是没用的,所以我们要解决这一问题。现版本的Eureka Server已经自动集成了Ribbon无需引入。
二、开启多个goods服务
现来模拟有3个goods-server服务
更改goods配置文件中的端口号
再打印一下信息,这样让我们知道是那个服务收到的信息
@RestController
@RequestMapping(value = "/goods" ,produces ="application/json;charset=UTF-8")
public class GoodsController {
@Autowired
GoodsService goodsService;
@GetMapping("/{id}")
public JSONObject get(@PathVariable("id") int id){
System.out.println("1号收到请求");
return goodsService.findGoodsByID(id);
}
}
因为是直接用的同一个项目开启服务,所以一定要修改之后再选择对应的启动器
开启3个之后我们再Eureka中查看一下
三、开启负载均衡
在order的restTemplate
上添加`` @LoadBalanced```
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
修改实现类
@Autowired
RestTemplate restTemplate;
@Override
public JSONObject queryOrderByUserIDII(int id) {
List<Order> orders = orderMapper.queryOrderByUserIDII(id);
JSONArray goods = new JSONArray();
for (Order order:orders){
/**
* 有多台服务器用ribbon做负载均衡
*/
String service = "goods-service";
String url = "http://" + service + "/goods/" + order.getGoods_id();
Goods good =restTemplate.getForObject(url,Goods.class);
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(good);
goods.add(jsonObject);
}
JSONObject returnJsono = new JSONObject();
returnJsono.put("code",200);
returnJsono.put("msg","success");
returnJsono.put("data",goods);
return returnJsono;
}
四、查看是否实现
在提供的数据中2017用户的订单有两个,那么就会查询两次物品信息
再次访问http://localhost:8888/order/query/2017
在打印台中我们能看知道
多刷新几次就会发现2条信息,总会有一个服务不用做事,这就是轮询的方式实现负载均衡,当使用者发来请求,注册中心会将调用多个同名服务中的下一个。
五、总结
我们关掉三个中的一个服务,刷新三次其中两次出现这样的问题:
另外一次就会成功查询。
因为我们模拟了一个服务宕机,但是他没有从Eureka服务中立即删除。Eureka自我保护机制,当其注册表里服务因为网络或其他原因出现故障而关停时,Eureka不会剔除服务注册,而是等待其修复,90s发送一次心跳检测。轮询到关掉的服务之后就会报连接错误。
测试觉得麻烦可以关闭自我保护机制,线上使用一定要开启。
因为虽然汇报一两次错,若返回错误次数多了就不会轮询这个服务。开启保护机制之后服务注册不会被删除,过一会再访问他还是会先去尝试使用掉线的服务,报错了之后不再使用。等待他重新接入。
没有保护机制就直接删除服务。最简单的就是断网了的情况,后面如果回复通信了,可是服务已经被删除了,需要重新启动服务服务才行。