SpringCloud进击 | 三浅出:服务消费者(Feign)【Finchley版本】

版权声明:本文为博主[魏风物语]原创文章,欢迎转载,转载请注明作者,原文超链接 https://blog.csdn.net/itanping/article/details/82868542

1.前言

上一节:SpringCloud进击 | 二浅出:服务消费者(Ribbon+REST)【Finchley版本】

上一节讲述了如何通过 Ribbon + RestTemplate 的方式去消费服务,而在实际工作中,我们基本上都是使用 Feign 来完成调用。这篇就来说说如何通过 Feign 实现服务消费者去消费服务。

Feign 默认集成了 Ribbon,并和 Eureka 结合,默认实现了负载均衡的效果。其特点有:

  • 可插拔的注解支持
  • 支持可插拔的 HTTP 编码器和解码器
  • 支持 Hystrix 和它的 Fallback
  • 支持 Ribbon 的负载均衡
  • 支持 HTTP 请求和响应的压缩

 

2.准备

三个角色,依旧使用上面章节已经创建好的工程:

  • 服务注册中心:wei-eureka-server,启动一个
  • 服务提供者:wei-service-provider,分别以 8010、8011 端口启动一次,获得两个实例的集群
  • 服务消费者:Feign,创建一个 wei-consumer-feign 模块

 

3.实践

3.1 创建服务消费者(Feign)

在项目上新建一个模块:wei-consumer-feign,创建方法与第一节创建模块过程类似。但在Dependencies选择依赖时需要注意以下:
a) 选择左侧的 Web 后,这里需要钩上 Web 项
b) 选择左侧的 Cloud Discovery 后,这里需要钩上 Eureka Discovery 项
c) 选择左侧的 Cloud Routing后,这里需要钩上 Feign 项 

最后点Finish后,一个模块就自动生成了,其 pom.xml 全内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wei</groupId>
    <artifactId>wei-consumer-feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>wei-consumer-feign</name>
    <description>服务消费者(Feign)(Finchley版本)</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--Feign实现声明式HTTP客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2 配置服务消费者

■ 编写配置 application.yml

server:
  port: 8030
spring:
  application:
    name: wei-cloud-feign    # 指定进行服务注册时该服务的名称,服务与服务之间相互调用一般都是根据这个name
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8090/eureka/    # 指定进行服务注册的地址

这里,指定的服务注册中心地址为 http://localhost:8090/eureka/,服务名称为:wei-consumer-feign,程序端口为:8030,spring.application.name:指定进行服务注册时该服务的名称,服务与服务之间相互调用一般都是根据这个name。

■ 编写配置Service

package com.wei.service.demo;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 通过@FeignClient("Eureka服务名称"),来指定调用消费哪个服务
 */
@FeignClient(value = "wei-service-provider")
public interface IDemoFeignService {

    /**
     * 注解@RequestMapping,映射服务提供者中的URL
     * @param name 入参
     * @return
     */
    @RequestMapping(value = "/demo/info", method = RequestMethod.GET)
    String getDemoFeignServiceName(@RequestParam(value = "name") String name);

    // Feign客户端和Ribbon类似,同样实现了客户端的负载均衡
    // 与Ribbon不同的是,Feign的调用与本地接口的调用更加类似,并且更加便捷、更加优雅,传入参数较多时得以体现
}

注意,这个 Service 是一个接口类。通过@FeignClient("Eureka服务提供者名称"),来指定调用和消费哪个服务提供者。当前配置是消费服务提供者 wei-service-provider 的 “/demo/info” 接口。

■ 编写配置Controller

package com.wei.controller.demo;

import com.wei.service.demo.IDemoFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoFeignController {

    /**
     * 编译器报错,无视。因为这个Bean是在程序启动的时候注入的,编译器感知不到,所以报错
     */
    @Autowired
    private IDemoFeignService iDemoFeignService;

    @RequestMapping(value = {"/feign/demo/info", "/demo/info"}, method = RequestMethod.GET)
    public String getDemoFeignName(@RequestParam(value = "name") String name) {
        String result = iDemoFeignService.getDemoFeignServiceName(name);
        result += "[Feign]";
        System.out.println(result);
        return result;
    }
}

具体使用时,通过 Service层,调用服务提供者的方法就像调用本地方法一样进行调用即可。

■ 配置main启动类

package com.wei;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * 注解@EnableFeignClients,开启Feign客户端功能
 */
@SpringBootApplication
@EnableFeignClients
public class WeiConsumerFeignApplication {

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

以前使用注解@EnableDiscoveryClient向服务中心注册,因为Eureka2.0已经不需要,所以这里可以不用该注解。

通过 Spring Cloud Feign 来实现服务调用的方式非常简单,注解 @EnableFeignClients 即可开启 Feign 客户端功能。

最后,Run一下这个启动类。我们再去 Spring Eureka 的服务注册信息面板,看一看这个服务消费者有没有被Eureka所发现并注册进去。

看来,一切正常。

3.3 验证服务消费者

好了,一切准备就绪。我们就来验证一下吧:

浏览器反复请求URL:http://localhost:8030/demo/info?name=tester 或者 http://localhost:8030/feign/demo/info?name=tester

Hi,tester,我是服务,我被调用了,服务名为:wei-service-provider,端口为:8010[Feign]

Hi,tester,我是服务,我被调用了,服务名为:wei-service-provider,端口为:8011[Feign]

我们可以看到浏览器也在8010和8011端口之间,也就是这个小的Service服务提供者集群之间交替打印输出内容。

到此,Feign 的负载均衡功能验证成功。论点2成立。

4.总结

Feign 客户端和 Ribbon 类似,同样实现了客户端的负载均衡,但与 Ribbon 不同的是,Feign 的调用与本地接口的调用更加类似,并且更加便捷、更加优雅,传入参数较多时得以体现。

4.1 案例中有三个角色:

     服务注册中心、服务提供者、服务消费者

4.2 它们的工作流:

  1. 启动服务注册中心
  2. 服务提供者 生产服务并注册到服务中心 
  3. 服务消费者 从服务中心中获取服务并使用

4.3 此时的架构图:


源码:https://github.com/itanping/wei-springcloud/tree/master/chapter03-feign

下一节,请关注:SpringCloud进击 | 四浅出:断路器(Hystrix)【Finchley版本】


猜你喜欢

转载自blog.csdn.net/itanping/article/details/82868542
今日推荐