Ribbon
使用RestTemplate时,如果不加@LoadBalance,调用不通,需要使用@LoadBalance作为负载均衡
手写一个客户端的负载均衡器
@GetMapping("order/create2")
public String createOrder2(){
List<ServiceInstance> instances = discoveryClient.getInstances("stock-service");
String uri = instances.get(0).getUri().toString(); // 获取第一个url,也可以自己进行负载均衡(随机、轮询)
System.out.println("uri:"+uri);
return restTemplate.getForObject(uri+ "/stock/reduce", String.class);
}
ribbon是netflix开源的一个客户端负载均衡器,不过现在已经不再更新了(闭源)
nacos中使用ribbon来做负载均衡
nacos-discovery中已经包含了ribbon
负载均衡规则
默认是轮询
修改负载均衡规则
使用java配置的方式(在调用方进行)
添加配置,使用random的方式进行负载均衡
public class RibbonConfig {
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
配置对应的服务的负载均衡策略
@Configuration
@RibbonClient(name = "stock-service", configuration = RibbonConfig.class)
public class StockRibbonConfig {
}
使用配置文件配置
stock-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
java配置高于配置文件配置
全局配置
一般不使用全局配置
直接在配置类上加@Configuration
@Configuration
public class RibbonConfig {
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
懒加载
ribbon默认是懒加载,第一次调用会很慢,可以改成饿加载
ribbon:
eager-load:
enabled: true
clients: stock-service
LoadBalance
LoadBalance是spring cloud提供的客户端的负载均衡器,用来替代ribbon
ribbon与LoadBalance对比
RestTemplate的扩展点是LoadBalancerClient
LoadBalance的使用
nacos-discovery中集成了ribbon,需要剔除掉
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
添加loadBalance依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
这样也可以使用RestTemplate进行服务调用
自定义负载均衡策略
LoadBalance自定义负载均衡策略需要实现ReactorServiceInstanceLoadBalancer接口
public class CustomerLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSuppliers;
public CustomerLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSuppliers){
this.serviceInstanceListSuppliers = serviceInstanceListSuppliers;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSuppliers.getIfAvailable();
return supplier.get().next().map(this::getInstanceResponse);
}
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances){
return new DefaultResponse(instances.get(0)); // 可以自己实现负载均衡
}
}
OpenFeign
常见的http客户端
HttpClient
apache下的,提供丰富、高效、最新的http请求
Okhttp
轻量级,一般用于安卓
HttpURLConnection
feign底层默认的就是HttpURLConnection,jdk中标准的http客户端;单线程
RestTemplate
介绍
openFeign是Netflix开源的声明式HTTP客户端
优点:
可以做到使用http请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方,更感知不到这是个http请求
openFeign实现远程http调用
整合openFeign
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
添加注解@EnableFeignClients
openFeign不用添加配置
client写法
@FeignClient("stock-service")
public interface StockClient {
@GetMapping("/stock/reduce")
String reduce();
}
调用
@Autowired
private StockClient stockClient;
@GetMapping("order/create3")
public String createOrder3(){
return stockClient.reduce();
}
openFeign中也集成了ribbon
openFeign通过ribbon做负载均衡,ribbon从nacos client获取服务列表
日志级别
生产环境中一般使用BASIC、NONE
配置日志级别
(需要提前配置好springboot的日志级别)
代码配置
添加配置类
public class StockFeignConfig {
@Bean
public Logger.Level level(){
return Logger.Level.FULL;
}
}
@FeignClient(name = "stock-service", configuration = StockFeignConfig.class)
配置文件
feign:
client:
config:
stock-service:
loggerLevel: full
全局配置
不推荐
@Configuration
public class StockFeignConfig {
@Bean
public Logger.Level level(){
return Logger.Level.FULL;
}
}
推荐
@EnableFeignClients(defaultConfiguration = StockFeignConfig.class)
推荐
feign:
client:
config:
default:
loggerLevel: full
配置项
Contract
@Bean
public Contract feignContract(){
return new SpringMvcContract();
}
Decoder
默认就是SpringDecoder,一般不修改
拦截器
需要实现RequestInterceptor接口
Client设置
添加依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
修改配置
feign:
httpclient:
enabled: true
max-connections: 200
也是可以使用其他Client
超时配置
@Bean
public Request.Options timeout(){
return new Request.Options(200,500);
}