- 运行示例代码时需要先安装Lombok插件,或去除使用Lombok的相关代码再运行
在服务提供者的示例代码中将bootstrap.yml
另外复制两份,分别命名为bootstrap-cluster1.yml
和bootstrap-cluster2.yml
。如下图所示:
分别对应的端口为8080
、8081
、8082
,其他参数如Nacos等可参考代码。可在idea配置启动如下
分别启动服务提供者,启动成功后可以在Nacos管理页面上看到服务提供者已经注册到Nacos上。
Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。
通俗一点讲:可以像调用本地方法一样的调用远程服务的方法。
为了便于使用,NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入。如果您有定制化的需求,可以自己实现自己的 ServerList。
Nacos Discovery Starter 默认集成了 Ribbon ,所以对于使用了 Ribbon 做负载均衡的组件,可以直接使用 Nacos 的服务发现。
这部分将分别使用
RestTemplate
结合Ribbon实现客户端侧的负载均衡,以及使用FeignClient(默认集成了Ribbon)实现负载均衡。
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
RestController
@Slf4j
public class SayHiConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/hello-rest/{user}")
public String rest(@PathVariable("user") String user) {
return restTemplate.getForObject("http://nacos-provider-demo-xuda/sayHi/" + user,
String.class);
}
}
使用Postman发送多次请求 http://10.0.90.30:8900/hello-rest/xuda
,每次的响应分别如下:
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
实现了RestTemplate的负载均衡功能。从响应结果来看,默认使用的是基于轮询算法
的负载均衡方式。其他配置方式可参考Ribbon 负载均衡策略配置. 下面演示基于随机算法
的负载均衡策略
随机策略
### 针对单个服务的 Ribbon 配置
nacos-provider-demo-xuda:
ribbon:
# 基于配置文件形式的 针对单个服务的 Ribbon 负载均衡策略
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置规则 随机
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置规则 重试
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置规则 随机
ConnectTimeout: 500 #请求连接超时时间
ReadTimeout: 1000 #请求处理的超时时间
OkToRetryOnAllOperations: true #对所有请求都进行重试
MaxAutoRetriesNextServer: 2 #切换实例的重试次数
MaxAutoRetries: 1 #对当前实例的重试次数
重新启动消费者服务,使用postman发送请求,多次请求的结果如下:
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
实现了基于随机策略的负载均衡
@FeignClient(name = "nacos-provider-demo-xuda")
public interface EchoService {
@GetMapping("/sayHi/{user}")
String sayHi(@PathVariable("user") String user);
}
其中@FeignClient
注解的name
属性是在Nacos上注册的服务提供者的名称。Controller如下
@RestController
@Slf4j
public class SayHiConsumerController {
@Autowired
private EchoService echoService;
@GetMapping("/hello/{user}")
public String sayHi(@PathVariable("user") String user) {
return echoService.sayHi(user);
}
}
启动项目,使用postman发送请求http://10.0.90.30:8900/hello/xuda
,结果如下:
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8080
Hello 【 xuda 】, My Service Port is: 8081
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8082
Hello 【 xuda 】, My Service Port is: 8081
实现了使用FeignClient的客户端侧的负载均衡。因为使用的负载均衡策略与上一步相同,所以结果也呈现出随机算法的负载均衡策略。
在网络请求时,可能会出现异常请求,如果还想再异常情况下使系统可用,那么就需要容错处理,比如:网络请求超时时给用户提示“稍后重试”或使用本地快照数据等等。
在服务提供者一方增加一个Contrller,抛出异常,模拟服务端不可用的情况
@GetMapping("/sayHiError/{user}")
public String sayHiError(@PathVariable("user") String user) {
throw new RuntimeException("模拟服务调用失败");
}
在服务调用者一方的EchoService.java
中修改如下:
@FeignClient(name = "nacos-provider-demo-xuda", fallback = EchoServiceFallback.class,
configuration = FeignConfiguration.class)
public interface EchoService {
@GetMapping("/sayHi/{user}")
String sayHi(@PathVariable("user") String user);
@GetMapping("/sayHiError/{user}")
String sayHiError(@PathVariable("user") String user);
}
新增一个fallback实现类
public class EchoServiceFallback implements EchoService {
@Override
public String sayHi(@PathVariable("user") String user) {
return "fallback";
}
@Override
public String sayHiError(@PathVariable("user")String user) {
return "服务器发生异常";
}
}
要使用Feign的fallback机制,需要开启Feign的Hystrix的功能,新增配置如下:
feign:
hystrix:
enabled: true
使用postman发送请求http://10.0.90.30:8900/helloError/xuda
,所得结果如下:
如果不使用fallback机制,则会直接报错:
仓库链接