SpringCloud03_Ribbon客户端负载均衡和Feign组件
Ribbon
-
基于HTTP和TCP的客户端负载均衡工具(默认轮询策略,默认超时时间1秒)
-
服务端负载均衡
- 负载均衡算法在服务端
- 由负载均衡器维护服务地址列表
-
客户端负载均衡
- 负载均衡算法在客户端
- 客户端维护服务地址列表
-
简化RestTemplate远程调用
-
在RestTemplateConfig类加上@LoadBalanced注解
@Configuration public class RestTemplateConfig { @LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
-
@RestController @RequestMapping("/order") public class OrderController { @Autowired private RestTemplate restTemplate; /* *使用 Ribbon简化RestTemplate调用 *在声明restTemplate的Bean时候,添加一个注解:@LoadBalanced *在使用restTemplate发起请求时,需要定义url时,host:prot可替换为提供方的应用名称 */ @LoadBalanced @GetMapping("/goods/{id}") public Goods findGoodsById(@PathVariable("id") int id){ String url = "http://EUREKA-PROVIDER/goods/findOne/"+id; // 调用方法 Goods goods = restTemplate.getForObject(url, Goods.class); return goods; } }
-
Ribbon负责均衡策略:
- 随机:RandomRule
- 轮询:RoundRobinRule
- 最小并发:BestAvailableRule
- 过滤:AvailabilityFilteringRule
- 响应时间:WeightedResponseTimeRule
- 轮询重试:RetryRule
- 性能可用性:ZoneAvoidanceRule
-
设置负载均衡策略(在消费方设置)
-
配置
EUREKA-PROVIDER: #服务提供方名称 ribbon: NfloadBalancerRuleClassName: XxxRule #负载均衡策略类
-
编码
-
注入Irule的Bean
@Configuration public class MyRule { @Bean public IRule rule(){ return new RandomRule();//IRule实现类 } }
-
在启动类上添加注解
@RibbonClient(name="服务提供方的应用名称",configuration=MyRule.class)
-
-
Feign声明式服务调用
-
是一个声明式的REST客户端,使用基于接口的注解方式
-
Feign自动集成Ribbon,且默认开启相关功能(底层使用Ribbon实现负载均衡和远程调用)
Feign自动集成Hystrix,但默认关闭,需要手动开启
-
使用:
-
导包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
配置
ribbon: ConnectTimeout: 1000 # 连接超时时间 默认1s ReadTimeout: 3000 # 逻辑处理的超时时间 默认1s
-
编码
-
在启动类开启Feign功能
@EnableFeignClients
-
编写Feign接口
/** * * feign声明式接口。发起远程调用 * 指定当前类的方法都从Eureka中对应的服务去调用 * String url = "http://FEIGN-PROVIDER/goods/findOne/"+id; Goods goods = restTemplate.getForObject(url, Goods.class); * * 1. 定义接口 * 2. 接口上添加注解 @FeignClient,设置value属性为 服务提供者的 应用名称 * 3. 编写调用接口,接口的声明规则 和 提供方接口保持一致。 * 4. 注入该接口对象,调用接口方法完成远程调用 * */ @FeignClient(value = "FEIGN-PROVIDER") public interface ProviderService { // 通过Controller的地址映射注解告诉Feign该类findOne2方法从服务提供者的/findOne/{id}地址获取信息 // 通过Controller的参数获取注解告诉Feign的参数信息 // 通过返回值告诉Feign应该返回的参数应该封装的格式 @GetMapping("/goods/findOne/{id}") public Goods findOne(@PathVariable("id") int id); }
-
contrller层简化后
@RestController @RequestMapping("/order") public class OrderController { //@Autowired //private RestTemplate restTemplate; @Autowired private GoodsFeignClient goodsFeignClient; @GetMapping("/goods/{id}") public Goods findGoodsById(@PathVariable("id") int id){ /* 简化 String url = "http://FEIGN-PROVIDER/goods/findOne/"+id; // 3. 调用方法 Goods goods = restTemplate.getForObject(url, Goods.class); return goods; */ Goods goods = goodsFeignClient.findGoodsById(id); return goods; } }
-
-
-
Feign的日志记录
-
Feign只能记录debug级别的日志信息
logging: level: com.it:debug
-
定义Feign日志级别Bean
@Configuration public class FeignLogConfig { /* NONE,不记录 BASIC,记录基本的请求行,响应状态码数据 HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息 FULL;记录完成的请求 响应数据 */ @Bean public Logger.Level level(){ return Logger.Level.FULL; } }
-
启用Bean
@FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)
-