Spring Cloud浅谈个人尝鲜------Feign 远程调用(三)

Spring Cloud浅谈个人尝鲜------Feign 远程调用(三)

在前后端分离架构中,服务层被拆分成了很多的微服务,服务与服务之间难免发生交互 。
Spring Cloud浅谈个人尝鲜------Feign  远程调用(三)
工作流程如下:

1、client1服务将自己注册到注册中心。

2、client2从注册中心获取client1服务的地址。

3、client2远程调用client1服务

1 Ribbon

1.1 Ribbon介绍

​ Ribbon是Netflix公司开源的一个负载均衡的项目(https://github.com/Netflix/ribbon),它是一个基于HTTP、TCP的客户端负载均衡器。

1、什么是负载均衡?

负载均衡是微服务架构中必须使用的技术,通过负载均衡来实现系统的高可用、集群扩容等功能。负载均衡可通过硬件设备及软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx等。

如下图是负载均衡的架构图:
Spring Cloud浅谈个人尝鲜------Feign  远程调用(三)
用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。

2、什么是客户端负载均衡?

上图是服务端负载均衡,客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均衡服务。

如下图是Ribbon负载均衡的流程图:
Spring Cloud浅谈个人尝鲜------Feign  远程调用(三)
1、在消费微服务中使用Ribbon实现负载均衡,Ribbon先从EurekaServer中获取服务列表。

2、Ribbon根据负载均衡的算法去调用微服务。

1.2 Ribbon测试

​ Spring Cloud引入Ribbon配合 restTemplate 实现客户端负载均衡。Java中远程调用的技术有很多,如:webservice、socket、rmi、Apache HttpClient、OkHttp等,互联网项目使用基于http的客户端较多,本项目使用OkHttp。

1、在客户端添加Ribbon依赖:
这里在client2配置ribbon依赖

 
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
     <version>1.1.5.RELEASE</version>
</dependency>
 <dependency>
     <groupId>com.squareup.okhttp3</groupId>
     <artifactId>okhttp</artifactId>
     <version>3.9.1</version>
  </dependency>

2、配置Ribbon参数

这里在client2的application.propertyis中配置ribbon参数

ribbon:
  MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试
  MaxAutoRetriesNextServer: 3 #切换实例的重试次数
  OkToRetryOnAllOperations: false  #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false
  ConnectTimeout: 5000  #请求连接的超时时间
  ReadTimeout: 6000 #请求处理的超时时间

3、负载均衡测试

1)启动两个client服务,注意端口要不一致

启动完成观察Eureka Server的服务列表

2)定义RestTemplate,使用@LoadBalanced注解

在client2的启动类中定义RestTemplate

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}

3)测试代码

在client2工程创建单元测试代码,远程调用test-producer的查询页面接口:

  
     @Autowired
    RestTemplate restTemplate;
   //负载均衡调用
        String serviceId ="TEST-PRODUCER1";
        for(int i=0;i<10;i++){
            //通过服务id调用
            String forObject = restTemplate.getForObject("http://" + serviceId + "/test/getString", String.class);

            System.out.println(forObject);
        }	

4)负载均衡测试

添加@LoadBalanced注解后,restTemplate会走LoadBalancerInterceptor拦截器,此拦截器中会通过RibbonLoadBalancerClient查询服务地址,可以在此类打断点观察每次调用的服务地址和端口,两个client服务会轮流被调用。
Spring Cloud浅谈个人尝鲜------Feign  远程调用(三)
可以看见,我们通过轮询策略分别调用了两台client1服务。

2 Feign

2.1 Feign介绍

​ Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。

2.2 Feign测试

1、在客户端添加依赖

在client2添加下边的依赖:

 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>

2、定义FeignClient接口

在client2中创建client包,定义查询client1的客户端该用接口,

@FeignClient(value = "TEST-PRODUCER1")
public interface ClientInterface {
    //远程调用client服务中的test01接口
    @GetMapping("/test/getString")//标识远程调用的http的方法类型是什么
    public  String test01();
}

3、启动类添加@EnableFeignClients注解
4、测试

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class TestFeignClient {
    @Autowired
    private ClientInterface clientInterface;

    @Test
    public void test01(){
        String s = clientInterface.test01();
        System.out.println(s);
    }
}

Feign工作原理如下:

1、 启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理对象

2、@FeignClient(value = “TEST-CLIENT1”)即指定了cms的服务名称,Feign会从注册中心获取cms服务列表,并通过负载均衡算法进行服务调用。

3、在接口方法 中使用注解 @GetMapping("/test/getString"),指定调用的url,Feign将根据url进行远程调用。

2.3 Feign注意点

SpringCloud对Feign进行了增强兼容了SpringMVC的注解 ,我们在使用SpringMVC的注解时需要注意:

1、feignClient接口 有参数在参数必须加@PathVariable(“XXX”)和@RequestParam(“XXX”)

2、feignClient返回值为复杂对象时其类型必须有无参构造函数。

上一篇:Springcloud的几大神兽,你会了吗?


下一篇:SpringCloud之Ribbon负载均衡及Feign消费者调用服务