LoadBalancer 客户端的负载均衡器+openFeign 请求转发

时间:2024-03-17 14:22:41

LoadBalancer 

Spring Cloud LoadBalancer是Spring Cloud中负责客户端负载均衡的模块,其主要原理是从nacos中获取服务列表通过选择合适的服务实例来实现负载均衡。

源码跟踪

可以看到这里的intercept()方法,拦截了用户的HttpRequest请求,然后做了几件事:

1、request.getURI():获取请求uri,本例中就是 http://spzx-cloud-user/api/user/findUserByUserId/1

2、originalUri.getHost():获取uri中的服务id,spzx-cloud-user

3、this.loadBalancer.execute():处理服务id和用户请求。

这里的this.loadBalancerBlockingLoadBalancerClient类型,我们继续跟入。

choose(String serviceId)方法做了两件事:
1、获取一个loadBalancer负载均衡器对象,默认类型为:RoundRobinLoadBalancer轮询
2、根据服务的id从Nacos注册中心中获取服务地址列表,从服务列表中选择一个服务实例对象loadBalancerResponse,包括实例的ip和port

更改负载均衡算法

LoadBalancer默认的负载均衡算法是RoundRobinLoadBalancer,如果想更改默认的负载均衡算法,那么此时需要向Spring容器中注册一个Bean,并且配置负载均衡的使用者。

代码如下所示:

1、在Spring容器中注册一个Bean(订单服务创建配置类)

public class CustomLoadBalancerConfiguration {

    //创建一个bean,类型为:RandomLoadBalancer,随机
    @Bean
    ReactorLoadBalancer<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