分为两步:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
<version>2.2.1.RELEASEversion>
dependency>
server:
port: 8081
spring:
application:
name: feign-nacos-provider-modules # 服务名
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos discovery地址

在日志文件中出现如下信息,表示已经将服务注册到nacos中

我们通过nacos客户端验证一下


// 注意,接口名与方法名可以随意
// 参数指定了要访问的提供者微服务名称
//@FeignClient(url ="http://127.0.0.1:8081", value="abcmsc-provider-depart", path = "/provider/depart")
//@FeignClient(url ="${feign.client.url}", value="abcmsc-provider-depart", path = "/provider/depart")
@FeignClient( value="feign-nacos-provider-modules", path = "/provider/depart")
public interface DepartService {
@PostMapping("/save")
boolean saveDepart(@RequestBody DepartVO depart);
@DeleteMapping("/del/{id}")
boolean removeDepartById(@PathVariable("id") int id);
@PutMapping("/update")
boolean modifyDepart(@RequestBody DepartVO depart);
@GetMapping("/get/{id}")
DepartVO getDepartById(@PathVariable("id") int id);
@GetMapping("/list")
List<DepartVO> listAllDeparts();
}
分为两步:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
<version>2.2.1.RELEASEversion>
dependency>
server:
port: 8080
spring:
application:
name: feign-nacos-consumer # 微服务名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos discovery地址


访问消费者接口通过断点可以发现feign接口已经注入进来,url如下。

成功进入服务端接口

上述案例通过 Feign 接口来消费微服务的,但没体现出其负载均衡的功能。下面将进行 Feign 负载均衡功能展示。
实际生产中,提供者会在多个不同的服务器中运行且会注册到同一个注册中心。消费者是拉取服务列表之后,根据配置的负载均衡策略由ribbon选着一个具体服务消费。
在开发中我们将同一个提供者项目启动多次,模拟一下。
模拟创建3个提供者

3个提供者在启动时注册到了nacos服务列表

Feign 本身已经集成了Ribbon依赖和⾃动配置,因此我们不需要额外引⼊依赖,以通过 ribbon.xx 来进⾏全局配置,也可以通过服务名.ribbon.xx 来对指定服务进细节配置配
RoundRobinRule
轮询策略。Ribbon 默认采用的策略。若经过一轮轮询没有找到可用的 provider,其最多轮询 10 轮(代码中写死的,不能修改)。若还未找到,则返回 null。
RandomRule
随机策略,从所有可用的 provider 中随机选择一个。。
RetryRule
重试策略。先按照 RoundRobinRule 策略获取 server,若获取失败,则在指定的时限内重试。默认的时限为 500 毫秒。
BestAvailableRule
最可用策略。选择并发量最小的 provider,即连接的消费者数量最少的 provider。其会遍历服务列表中的每一个 server,选择当前连接数量 minimalConcurrentConnections 最小的 server。
AvailabilityFilteringRule
可用过滤算法。该算法规则是:过滤掉处于熔断状态的 server 与已经超过连接极限的server,对剩余 server 采用轮询策略。
在消费者端添加指定负载均衡算法的方式配置文件的方式有两种:
# 配置提供者负载均衡策略
feign-nacos-provider-modules: #提供者服务名称
ribbon: # 指定要使用的负载均衡策略
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #采用随机策略
@Configuration
public class feignConfig {
/**
* 随机策略
*/
@Bean
public IRule loadBalanceRule() {
return new RandomRule();
}
}
RoundRobinRule 轮询策略Ribbon 默认采用的策略
启动消费者发送15次请求,观察提供者日志如下。
RandomRule 随机策略修改feignConfig配置文件
@Configuration
public class feignConfig {
/**
* 随机策略
*/
@Bean
public IRule loadBalanceRule() {
return new RandomRule();
}
}
启动消费者发送15次请求,观察提供者日志如下。

Feign默认的请求处理超时时⻓1s,有时候我们的业务确实执⾏的需要⼀定时间,那么这个时候,我们就需要调整请求处理超时时⻓,Feign⾃⼰有超时设置,如果配置Ribbon的超时,则会以Ribbon的为准;
#针对的被调⽤⽅微服务名称,不加就是全局⽣效
feign-nacos-provider-modules: #提供者服务名称
ribbon: # 指定要使用的负载均衡策略
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #采用轮询策略
ConnectTimeout: 2000 #请求连接超时时间
ReadTimeout: 5000 #请求处理超时时间
OkToRetryOnAllOperations: true #对所有操作都进⾏重
MaxAutoRetries: 2 #对当前选中实例重试次数,不包括第⼀次调⽤
MaxAutoRetriesNextServer: 2 #切换实例的重试次数
根据如上配置,当访问到故障请求的时候,它会再尝试访问⼀次当前实例(次数由MaxAutoRetries配置)
如果不⾏,就换⼀个实例进⾏访问,如果还不⾏,再换⼀次实例访问(更换次数由MaxAutoRetriesNextServer配置),如果依然不⾏,返回失败信息
服务提供者一
服务提供者二:拷贝出来一份,其中getHandler接口睡眠一会,模拟超时。

启动服务,访问接口
1、consumer服务中访问接口时,会进行判断feign接口连接时间(ConnectTimeout: 2000)和请求处理( ReadTimeout: 5000)有没有达到设定的阈值。如果没有达到阈值,不会重试。
2、如果达到阈值,它会再尝试访问⼀次当前实例,发现还是不行,就再次尝试一次(次数达到MaxAutoRetries=2
3、上面发现还是不⾏,就换⼀个8085端口实例进⾏访问,程序正常连接请求也没有超过设置的5000毫秒,返回结果。如果还不⾏,再换⼀次实例访问(更换次数由MaxAutoRetriesNextServer配置)

1、只有IO 异常时,才会解析为可重试异常,进行重试操作。
2、Feign 自带重试机制,默认不开启,原理是捕获异常,发现超时异常,会进行重试,直到达到最大重试次数,退出循环请求3、Ribbon 也实现了自己的重试机制,基于RxJava,异步处理超时异常,默认也是不开启,需要添加重试次数设
4、推荐使用Ribbon 重试机制,需要注意关闭OkToRetryOnAllOperations,不然很容易出现接口幂等性问题,而且下游服务的GET请求,是要求只做查询功能