Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡

文章目录

  • Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡
    • 在Nacos上注册服务提供者集群
    • 服务消费者集成Feign+Ribbon
      • 介绍
      • 在Spring Cloud Alibaba中使用Feign+Ribbon
        • 使用 RestTemplate 和 FeignClient
          • 使用RestTmplate+Ribbon
          • 使用FeignTemplate
          • Feign的Fallback机制
    • Github仓库地址

Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡

  • 运行示例代码时需要先安装Lombok插件,或去除使用Lombok的相关代码再运行

在Nacos上注册服务提供者集群

在服务提供者的示例代码中将bootstrap.yml另外复制两份,分别命名为bootstrap-cluster1.ymlbootstrap-cluster2.yml。如下图所示:
Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡_第1张图片
分别对应的端口为808080818082,其他参数如Nacos等可参考代码。可在idea配置启动如下
Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡_第2张图片
分别启动服务提供者,启动成功后可以在Nacos管理页面上看到服务提供者已经注册到Nacos上。
Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡_第3张图片
Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡_第4张图片

服务消费者集成Feign+Ribbon

介绍

  • Feign介绍:

Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。
通俗一点讲:可以像调用本地方法一样的调用远程服务的方法。

  • Ribbon介绍

在Spring Cloud Alibaba中使用Feign+Ribbon

为了便于使用,NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入。如果您有定制化的需求,可以自己实现自己的 ServerList。

Nacos Discovery Starter 默认集成了 Ribbon ,所以对于使用了 Ribbon 做负载均衡的组件,可以直接使用 Nacos 的服务发现。

使用 RestTemplate 和 FeignClient

这部分将分别使用RestTemplate结合Ribbon实现客户端侧的负载均衡,以及使用FeignClient(默认集成了Ribbon)实现负载均衡。

使用RestTmplate+Ribbon
  • 添加 @LoadBlanced 注解,使得 RestTemplate 接入 Ribbon
	@Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
	
  • 编写Controller
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

实现了基于随机策略的负载均衡

使用FeignTemplate
  • 编写EchoService接口,代码如下
@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的客户端侧的负载均衡。因为使用的负载均衡策略与上一步相同,所以结果也呈现出随机算法的负载均衡策略。

Feign的Fallback机制

在网络请求时,可能会出现异常请求,如果还想再异常情况下使系统可用,那么就需要容错处理,比如:网络请求超时时给用户提示“稍后重试”或使用本地快照数据等等。
在服务提供者一方增加一个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,所得结果如下:
Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡_第5张图片
如果不使用fallback机制,则会直接报错:
Nacos+Feign+Ribbon声明式Rest调用及客户端侧负载均衡_第6张图片

Github仓库地址

仓库链接

你可能感兴趣的:(Spring,Cloud,Alibaba,微服务,Nacos,Ribbon,Feign,Spring,Cloud,Alibaba)