LoadBalancer
Spring Cloud LoadBalancer是Spring Cloud中负责客户端负载均衡的模块,其主要原理是从nacos中获取服务列表通过选择合适的服务实例来实现负载均衡。
源码跟踪
可以看到这里的intercept()方法,拦截了用户的HttpRequest请求,然后做了几件事:
1、
request.getURI()
:获取请求uri,本例中就是 http://spzx-cloud-user/api/user/findUserByUserId/12、
originalUri.getHost()
:获取uri中的服务id,spzx-cloud-user
3、
this.loadBalancer.execute()
:处理服务id和用户请求。这里的
this.loadBalancer
是BlockingLoadBalancerClient
类型,我们继续跟入。
choose(String serviceId)方法做了两件事:
1、获取一个loadBalancer负载均衡器对象,默认类型为:RoundRobinLoadBalancer轮询
2、根据服务的id从Nacos注册中心中获取服务地址列表,从服务列表中选择一个服务实例对象loadBalancerResponse,包括实例的ip和port
更改负载均衡算法
LoadBalancer默认的负载均衡算法是RoundRobinLoadBalancer,如果想更改默认的负载均衡算法,那么此时需要向Spring容器中注册一个Bean,并且配置负载均衡的使用者。
代码如下所示:
1、在Spring容器中注册一个Bean(订单服务创建配置类)
public class CustomLoadBalancerConfiguration {//创建一个bean,类型为:RandomLoadBalancer,随机@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}
}
2、配置负载均衡算法的使用者
@Configuration
@LoadBalancerClients(value = {@LoadBalancerClient(name = "spzx-cloud-user" , configuration = CustomLoadBalancerConfiguration.class) // 将负载均衡算法应用到指定的服务提供方中
})
public class RestTemplateConfiguration {@Bean@LoadBalanced // 让RestTemplate具有负载均衡的能力public RestTemplate restTemplate() {return new RestTemplate() ;}}
重启服务 重启服务后可以看出 负载均衡算法已经被修改。
OpenFeign
OpenFeign 是一个Web声明式的Http客户端远程远程调用工具,底层是封装HttpClient技术,提供接口和注解形式调用。 亦在解决 restTemplate 进行远程调用的弊端。 由于通过restTemplate 进行服务调用时参数传递不够灵活所以我们这里采用了 openFeign来替代 redisTemplate
OpenFeign的配置
1. 在我们自己的微服务中引入openFeign的依赖
<!-- 加入OpenFeign的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、在启动类上添加 @EnableFeignClients 注解开启OpenFeign的功能支持
3.编写OpenFeign的客户端
package com.atguigu.spzx.cloud.order.feign;
@FeignClient(value = "spzx-cloud-user") // 声明当前接口是一个访问user-service的feign的客户端
public interface UserFeignClient {@GetMapping("/api/user/findUserByUserId/{userId}")
public abstract User queryById(@PathVariable("userId") Long userId) ; // 根据userId查询用户信息的接口方法}
这个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:
① 请求方式:GET
② 请求路径:/api/user/findUserByUserId/{userId}
③ 请求参数:Long userId
④ 返回值类型:User
这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。
4、修改微服务中的远程调用代码,使用Feign客户端代替RestTemplate:
@Service
public class OrderServiceImpl implements OrderService {@Autowired
private OrderMapper orderMapper ;@Autowired
private UserFeignClient userFeignClient ;@Override
public Order findOrderByOrderId(Long orderId) {
Order order = orderMapper.findOrderByOrderId(orderId);// 远程调用
User user = userFeignClient.queryById(order.getUserId());
order.setUser(user);
return order ;
}
}
OpenFeign自定义配置
日志配置
Feign提供了日志打印功能,我们在项目中可以通过配置来调整日志级别,从而了解Feign中http请求的细节 ,也就是说feign提供的日志功能可以对接口的调用情况进行监控和输出。
feign的日志的级别分为四种:
① NONE:不记录任何日志信息,这是默认值。
② BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
③ HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
④ FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
1.明配置类
public class DefaultFeignConfiguration {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.FULL; // 日志级别为FULL
}
}
2、如果要全局生效,将其放到微服务的启动类的@EnableFeignClients这个注解中
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
3、如果是局部生效,则把它放到对应的@FeignClient这个注解中: @FeignClient 是自定义的配置类用于进行配置openFeign的远程调用的。
@FeignClient(value = "spzx-cloud-user", configuration = DefaultFeignConfiguration .class)
4、在配置文件中配置 debug级别打印
logging:
level:
com.atguigu.spzx.cloud.order.feign: debug