zl程序教程

您现在的位置是:首页 >  其他

当前栏目

(三)SpringCloud OpenFegin使用指北

2023-04-18 14:04:55 时间

前言-微服务架构设计风格

微服务设于基于RESTful架构,使用RESTful可以将愈发复杂单体应用通过HTTP请求、JSON传输数据拆分为不同的业务模块,达到服务独立部署、快速启动、模块协同开发、低耦合、代码复用、职责单一的目的,使团队间相对隔离的敏捷式开发。微服务的盛行首要解决的便是不同服务间调用的问题。

现有解决方案

  • Ribbon+RestTemplate
  • Feign
  • OpenFeign

Ribbon+RestTemplate是基于HTTP+TCP实现服务间通信,其原理是通过RestTemplate构造HTTP请求来完成,相当于单体应用通过HTTP调用第三方接口,是一种远程调用的实现方式。

Feign基于Ribbon+RestTemplate,其内部是通过JDK动态代理的方式,将对外调用的接口抽象成接口,使用远程API的Method方法实例,进行MethodHandler方法处理器分发,根据参数构造Request实例,一般是Controller实现自定义的接口,供外部调用。Feign内部实现了负载均衡,根据负载量、请求量分发至不同的服务,但目前Feign已不再维护。

OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

OpenFeign是目前使用最为广泛的远程服务调用方式。

下文使用的demo开源地址: https://github.com/FirstMrRight/org_eureka_demo.git

OpenFeign使用方式

0.0 创建一个Maven项目,在新创建的Maven项目中创建SpringBoot项目,共需要eureka中心、provider、openfeign、commons四个SpringBoot项目,这四个项目的父pom是最初创建的Maven项目。

父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>org.example</groupId>
    <artifactId>org_eureka_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

1.1 Eureka项目

pom.xml

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    
    <groupId>org.javaboy</groupId>
    <artifactId>eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka</name>
    <description>Demo project for Spring Boot</description>
    
    
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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>

1.2 在Eureka启动类中增加@EnableEurekaServer注解,声明为服务的注册中心

在配置文件中必须要配置服务名称、端口以及是否为客户端

spring.application.name=eureka
server.port=1111
eureka.client.fetch-registry=false
eureka.client.register-with-eureka=false

2.1配置生产者

在生产者中定义可对外调用的接口

public interface IUserService {
    @GetMapping("/hello")
    //这里的方法名无所谓,随意取
    String hello();
}

Controller实现该接口

@RestController
public class HelloController implements IUserService {
    @Value("${server.port}")
    Integer port;
    @Override

    public String hello() {
        String s = "hello javaboy:" + port;
        System.out.println(new Date());
        return s;
    }
}

在配置文件中将客户端注册到eureka上,配置服务名称,作为外部调用的唯一标识

spring.application.name=provider
server.port=1113
eureka.client.service-url.defaultZone=http://localhost:1111/eureka

3.1配置消费者

消费者即服务调用者,我们使用openFeign来实现外部服务的调用。

pom中需要引入以下依赖:

<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>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在消费者的启动类中使用@EnableFeignClients注解声明服务为一个客户端。

创建一个接口,继承自生产者接口,使用@FeignClient(value = “provider”)来确定调用哪个服务,value值是服务名称。

@FeignClient(value = "provider")
public interface HelloService extends IUserService {
}

该接口的实现便是生产者Controller中对应的方法。

注入该生产者的Service

User实体类在commons包

@RestController
public class HelloController {
    @Autowired
    HelloService helloService;

    @GetMapping("/hello")
    public String hello() throws UnsupportedEncodingException {
        String s = helloService.hello();
        System.out.println(s);
        User user = new User();
        user.setId(1);
        user.setUsername("javaboy");
        user.setPassword("123");
        return helloService.hello();
    }
}

启动顺序:

注册中心>生产者>消费者

4.1接口调用测试