Spring Cloud学习:02服务消费者(Ribbon&Feign)

在微服务架构中,业务会拆分成一个独立的服务,服务与服务之间基于http restful进行通信。Spring Cloud有两种服务调用方式,一种是Ribbon+restTemplate,另一种是Feign。

1 Ribbon+restTemplate

1.1 Ribbon介绍

Spring Cloud Ribbon是基于HTTP和TCP的客户端负载均衡工具,基于Netflix Ribbon实现。通过Spring Cloud封装,可以方便地将面向服务的REST模板请求自动转换成客户端负载均衡的服务调用。包括下面的Feign调用,也是基于Ribbon实现的。

基于Spring Cloud Ribbon的封装,使用客户端负载均衡调用服务非常简单,只需实现两步:
       ①服务提供者只需启动多个服务实例并注册到一个注册中心或多个相关联的服务注册中心。
       ②服务消费者直接通过调用被@LoadBalanced注解(开启客户端负载均衡)的RestTemplate实现面向服务的接口调用。

1.2 测试Ribbon+restTemplate方式调用

1.2.1创建服务提供方(Eureka Client)

基于之前工程,创建新模块ribbon-service,选择Spring Initializr->Cloud Discovery->Eureka Discovery,并添加以下依赖:

<dependencies>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-ribbon</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
</dependencies>

1.2.2 添加服务提供方配置文件

server:
    port: 8764

eureka:
    client:
      serviceUrl:
        defaultZone: http://localhost:8761/eureka/

spring:
    application:
      name: ribbon-service #指明应用名称(服务与服务相互调用根据name属性)

1.2.3 启动类中添加初始化RestTemplate,用于发起REST请求,使用@LoadBalanced注解开启负载均衡。

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonServiceApplication {

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

    public static void main(String[] args) {
        SpringApplication.run(RibbonServiceApplication.class, args);
    }
}

1.2.4 创建一个接口消费Eureka Client提供的接口:

@RestController
public class DemoController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/one")
    public String one(){
        return restTemplate.getForObject("http://ONE-SERVICE/one",String.class);
    }
    
}

1.2.5 启动工程

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①启动服务注册中心eureka-server工程;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②启动one-service工程,当前端口为8762,修改端口为8763,再次启动一个实例(如使用IDEA,在Edit Configurations中指定应用中去除勾选Single instance only,否则请求时会出现以下错误),启动完成后,one-service拥有2个服务实例;

&nbsp; &nbsp; &nbsp; &nbsp;③启动ribbon-service工程,端口为8764。

1.2.6 浏览器多次访问http://localhost:8764/one,交替出现以下内容,说明负载均衡访问不同端口的服务实例。

one-service test port:8762

one-service test port:8763

2 Feign

2.1 Feign介绍

Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。

分布式应用早在十几年前就开始出现,各自的应用运行在各自的tomcat,jboss一类的容器中,他们之间的相互调用变成了一种远程调用,而实现远程调用的方式很多。按照协议划分,可以有RPC,Webservice,http。不同的框架也对他们有了各自的实现,如dubbo(x),motan就都是RPC框架,本文所要讲解的Feign便可以理解为一种http框架,用于分布式服务之间通过Http进行接口交互。说他是框架,有点过了,可以理解为一个http工具,只不过在spring cloud全家桶的体系中,它比httpclient,okhttp,retrofit这些http工具都要强大的多。

2.2 测试Feign方式调用

2.2.1 创建Feign方式的服务提供方

基于先前工程创建新模块feign-service,选择Spring Initializr->Cloud Discovery->Eureka Discovery,并添加以下依赖:

<dependencies>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-feign</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
</dependencies>

2.2.2 添加服务提供方配置信息

server:
    port: 8765

eureka:
    client:
      serviceUrl:
        defaultZone: http://localhost:8761/eureka/

spring:
    application:
      name: feign-service #指明应用名称(服务与服务相互调用根据name属性)

2.2.3 启动类添加@EnableFeignClients注解开启Feign功能

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignServiceApplication {

   public static void main(String[] args) {
      SpringApplication.run(FeignServiceApplication.class, args);
   }
}

2.2.4 定义一个Feign接口,使用@FeignClient ("服务名称")调用指定服务,调用one-service服务的”/one”接口:

@FeignClient("one-service")
public interface FeignDemoService {

    @RequestMapping(value = "/one", method = RequestMethod.GET)
    String invocateOneService();
}

2.2.5 添加测试接口

@RestController
public class FeignDemoController {

    @Autowired
    FeignDemoService feignDemoService;

    @RequestMapping("/one")
    public String one() {
        return feignDemoService.invocateOneService();
    }
}

2.2.6 启动工程

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①启动服务注册中心eureka-server工程;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②启动one-service 2个服务实例,端口分别为8762和 8763;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;③启动feign-service工程,端口为8765。

2.2.7 浏览器多次访问http://localhost:8765/one,交替出现以下内容:

one-service test port:8762

one-service test port:8763

本文源码下载地址:

https://github.com/laravelshao/spring-cloud-learning/tree/master/setion02-ribbon-feign

3 参考资料

Spring RestTemplate as a Load Balancer Client

How to Include Feign

方志朋->史上最简单的SpringCloud教程

翟永超->Spring Cloud基础教程 &amp; Spring Cloud微服务实战

文章来源:

Author:LaravelShao
link:https://my.oschina.net/LaravelShao/blog/1554386