Ribbon&OpenFeign配置使用
Ribbon
是什么
客户端的负载均衡,和进行轮训、随机、权重、自定义等规则配置访问;
通过指定注册到注册中心的服务名,根据设置的规则自动进行调用
工作流程
- 先选择 EurekaServer,它优先选择在同一个区域内负载较少的server
- 再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址其中Ribbon提供多种策略:比如轮询、随机、根据响应时间加权等规则
怎么用
见 此处
负载算法
官方提供算法
参考尚硅谷杨哥教程
| 类型 | 方法 | 
|---|---|
| 轮训 | RoundRobinRule | 
| 随机 | RandomRule | 
| 先按照轮训策略获取服务,如果获取服务失败则再指定时间内重试,获取可用服务 | RetryRule | 
| 对轮询策略的扩展,响应速度越快的实例选择权重越大 | WeightResponseTimeRule | 
| 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 | BestAvailableRule | 
| 先过滤掉故障实例,再选择并发较小的实例 | AvailabilityFilterRule | 
| 默认规则,复合判断server所在区域的性能和server的可用性选择服务器 | ZoneAvoidanceRule | 
使用方法
- 
在被标注@SpringBootApplication注解的XXXApplication上级包外新建负载均衡配置文件,如果配置文件在XXXApplication包同级或下级,此配置失效 ![image-20201026165516598]() 
- 
RbRule.java文件内容 package rule; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RbRule { @Bean public IRule rule() { return new RandomRule(); //定义新的策略为随机 } }
- 
修改ClientApplication.java文件 package com.project.client; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import rule.RbRule; @SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @RibbonClient(name = "SERVICE-PROJECT",configuration = RbRule.class) // 客户端名称 上一步定义的规则 public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } }
- 
测试 执行访问192.168.1.2/getInstance,正常三台服务提供应随机输出 
自定义负载算法
查看 RandomRule类源码(其他的几个类也一样),得知几个关键类及方法:
- 
ILoadBalancer//获得注册服务数量的方法
- 
getAllServers()//获得所有注册到Eureka的服务
- 
getReachableServers()//获得所有在线的服务
- 
isAlive()//判断服务是否存活 true存活
在rule包下新建MyRule
简单实现一个倒序轮训的规则,仅仅实现,不考虑健壮性
public class MyRule extends AbstractLoadBalancerRule {
    AtomicInteger atomicInteger=new AtomicInteger();
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
    @Override
    public Server choose(Object key) {
        ILoadBalancer loadBalancer = getLoadBalancer();//获得注册服务数量的方法
        List<Server> allServers = loadBalancer.getAllServers();//获得所有注册到Eureka的服务
        List<Server> reachableServers = loadBalancer.getReachableServers();//获得所有在线的服务
        if(atomicInteger.get()<1){
            atomicInteger.set(reachableServers.size());
        }
        int index = atomicInteger.decrementAndGet();
        Server server = reachableServers.get(index);
        //server.isAlive();//服务是否存活 true存活
        return server;
    }
}
修改自定义策略类RbRule
@Configuration
public class RbRule {
    @Bean
    public IRule rule() {
        return new MyRule(); //定义策略为自定义
        //return new RandomRule(); //定义新的策略为随机
    }
}
测试
此时会发现,轮询会按照getReachableServers()读出的list顺序倒序依次调用
OpenFeign
是什么
OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等。
OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
怎么用
基本使用
- 
导入pom <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.5.RELEASE</version> </dependency>
- 
XXXApplication.java开启 @SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableFeignClients //开启openfeign public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } }
- 
新增调用服务接口 @Service @FeignClient(value = "SERVICE-PROJECT") //调用的服务名 public interface FeignDemoService { @GetMapping(value = "/getInstanceId") //服务端的请求地址,如果有入参可通过@PathVariable传入 public String getInstance(); }
- 
调用测试 @Autowired private FeignDemoService feignDemoService; //引入刚刚创建的接口 @GetMapping("feignGetInstance") public String feignGetInstance(){ return feignDemoService.getInstance();//调用,即可返回对应服务提供接口的信息 }
指定负载均衡策略
添加此注解即可,使用细节同上
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@RibbonClient(name = "SERVICE-PROJECT",configuration = RbRule.class) //添加后OpenFeign也使用RbRule策略
@EnableFeignClients
public class ClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}
接口超时控制
- 
修改服务提供方,添加方法,此方法可定义执行时间 @GetMapping("getInstanceIdByTimeOut") public String getInstanceIdByTimeOut(int time) throws InterruptedException { if(time>0) { TimeUnit.SECONDS.sleep(time); } return instanceId+"_time_"+time; }
- 
修改FeignDemoService接口,新增方法 @GetMapping(value = "/getInstanceIdByTimeOut/{time}") public String getInstanceIdByTimeOut(@PathVariable("time") int time);
- 
修改调用超时时间 #设置feign客户端超时时间(OpenFeign默认支持ribbon) ribbon: #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的实际时间,单位毫秒 ReadTimeout: 5000 #不配置默认为1秒 #指的是建立连接后从服务器读取到可用资源所用的时间,单位毫秒 ConnectTimeout: 5000 #不配置默认为1秒
- 
调用getInstanceIdByTimeOut/{time}接口测试 time高于5秒就不再等待报错 
日志输出
对Feign接口调用情况进行监控和输出
日志级别
NONE: 默认的,不显示任何日志
BASIC: 仅记录请求方法、URL、响应状态码以及执行时间
HEADERS:除了BASIC 中自定义的信息外,还有请求和响应的信息头
FULL: 除了HEADERS中定义的信息外, 还有请求和响应的正文以及元数据。
新增配置类
@Configuration
public class FeignLogConfig {
    @Bean
    Logger.Level feignLoggerLevel() {
        return  Logger.Level.FULL;
    }
}
修改yml文件,设置日志
logging:
  level:
    com.project.client.service.*: debug #收集哪些包下的调用日志
测试,控制台会显示如下信息

Ribbon&Feign&OpenFeign区别
Ribbon
Ribbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件
Ribbon 可以用来做客户端负载均衡,调用注册中心的服务
Ribbon的使用需要代码里手动调用目标服务,请参考官方示例:https://github.com/Netflix/ribbon
Feign(不推荐,停止维护)
Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端
Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
Feign支持的注解和用法请参考官方文档:https://github.com/OpenFeign/feign
Feign本身不支持Spring MVC的注解,它有一套自己的注解
OpenFeign
OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等。
OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,
并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
 
                    
                     
                    
                 
                    
                
 

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号