基于Eureka搭建Springcloud微服务-6.使用OpenFeign实现客户端负载均衡

lingwh原创2020年5月19日大约 6 分钟约 1944 字

6.使用OpenFeign实现客户端负载均衡

6.1.章节内容概述

本章节涉及主要内容有:
 6.1.章节内容概述
 6.2.章节内容大纲
 6.3.OpenFeign简介
 6.4.通过配置Ribbon实现对OpenFeign的配置来实现负载均衡
 6.5.通过直接配置OpenFeign实现对OpenFeign的配置来实现负载均衡
具体每个小节中包含的内容可使通过下面的章节内容大纲进行查看。

6.2.章节内容大纲

6.3.OpenFeign简介

Feign是SpringCloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是: 使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。核心作用是为HTTP形式的Rest API提供了非常简洁高效的RPC调用方式,可以让编写远程调用代码就像编写本地Service一样简单。

官方网址(SPRING.IO)

https://docs.spring.io/spring-cloud-openfeign/docs/2.2.10.BUILD-SNAPSHOT/reference/html/

6.4.通过配置Ribbon实现对OpenFeign的配置来实现负载均衡

6.4.1.模块简介

通过配置Ribbon实现对OpenFeign的配置来实现的服务消费者,在YML中编写相关配置,之所以可以这样,是因为OpenFeign的底层实现就是Ribbon,启动端口: 80

6.4.2.模块目录结构

springcloud-consumer-loadbalance-openfeign-configuration-ribbon-order80
|-- src
|   •-- main
|       |-- java
|       |   •-- org
|       |       •-- openatom
|       |           •-- springcloud
|       |               |-- config
|       |               |   •-- OpenFeignConfig.java
|       |               |-- controller
|       |               |   •-- OrderConsumerController.java
|       |               |-- service
|       |               |   •-- PaymentServiceOpenFeign.java
|       |               •-- OrderServiceConsumerLoadBalanceOpenFeignConfigurationRibbon80.java
|       •-- resources
|           •-- application.yml
•-- pom.xml

6.4.3.创建模块

在父工程(springcloud-eureka)中创建一个名为springcloud-consumer-loadbalance-openfeign-configuration-ribbon-order80的maven模块,注意:当前模块创建成功后,在父工程pom.xml中<modules></modules>中会自动生成有关当前模块的信息

6.4.4.编写模块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">
    <parent>
        <artifactId>springcloud-eureka</artifactId>
        <groupId>org.openatom</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consumer-loadbalance-openfeign-configuration-ribbon-order80</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--引入公共的工程-->
        <dependency>
            <groupId>org.openatom</groupId>
            <artifactId>springcloud-api-commons</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>
    </dependencies>
    <!--热部署需要加这个-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>

        <resources>
            <resource>
                <directory>src/main/resources/</directory>
                <includes>
                    <!--不区分环境:直接加载application.yml配置文件-->
                    <include>application.yml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

6.4.5.编写模块application.yml

server:
  port: 80

spring:
  application:
    name: SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-HARDCORE-ORDER80 #注意:服务名不要出现_
  devtools:
    restart:
      enabled: true
  logging:
    level: info

eureka:
  client:
    register-with-eureka: true  #表示是否将自己注册进EurekaServer默认为true。
    fetchRegistry: true  #是否从EurekaServer抓取已有的注册信息,默认为true。服务提供端是单节点无所谓,是集群必须设置为true才能配合ribbon使用负载均衡,否则报异常No instances available for SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER
    service-url:
      #单机版
      defaultZone: http://localhost:7001/eureka
      #集群版
      #defaultZone: http://eureka7002:7002/eureka,http://eureka7003:7003/eureka,http://eureka7004:7004/eureka
  instance:
    instance-id: ${spring.application.name} #Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容
    prefer-ip-address: false #访问路径可以显示IP地址,点击Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容地址栏是否显示IP地址

#通过对Ribbon的配置实现对OpenFeign的配置
SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER: #服务提供端名称
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  #Ribbon负载均衡规则类所在的路径,自带七种规则,也可以是自定位规则的类所在的路径
    ConnectTimeout: 5000  #建立连接所用的时间,适用于网络正常的情况下,两端建立连接所用的时间,不配置如果连接超时会报异常
    ReadTimeout: 5000   #建立连接后,从服务器读取到可用资源的所用的时间,不配置如果读取资源超时会报异常(java.net.SocketTimeoutException: Read timed out)
logging: #OpenFeign增强日志配置
  level:
    org.openatom.springcloud.services.PaymentServiceOpenFeign: debug  #OpenFeign日志以什么级别监控哪个接口

6.4.6.编写模块config

package org.openatom.springcloud.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class OpenFeignConfig {

    /**
     * NONE:默认的,不显示任何日志;
     * BASIC:仅记录请求方法、URL、响应状态码及执行时间;
     * HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
     * FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

6.4.7.编写模块service

package org.openatom.springcloud.service;

import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * OpenFeign硬编码实现远程调用
 */
@Component
@FeignClient(name="SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER")
public interface PaymentServiceOpenFeign {
    @PostMapping(value = "/provider/payment/create")
    CommonResult create(@RequestBody Payment payment);

    @GetMapping(value = "/provider/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

    @GetMapping(value = "/provider/payment/openfeign/timeout")
    String getPaymentByIdTimeout();
}

6.4.8.编写模块controller

package org.openatom.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;
import org.openatom.springcloud.service.PaymentServiceOpenFeign;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderConsumerController {

    //单机版
//    public static final String PAYMENT_URL = "http://localhost:8001";
//    public static final String PAYMENT_URL = "http://localhost:8002";

    @Resource
    private PaymentServiceOpenFeign paymentServiceOpenFeign;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment) {
        return paymentServiceOpenFeign.create(payment);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        return paymentServiceOpenFeign.getPaymentById(id);
    }

    @GetMapping("/consumer/payment/openfeign/timeout")
    public String getPaymentByIdTimeout() {
        return paymentServiceOpenFeign.getPaymentByIdTimeout();
    }
}

6.4.9.编写模块主启动类

package org.openatom.springcloud;

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

/**
 * 1.使用OpenFeign完成远程调用,如果要配置负载均衡策略,和Ribbon配置负载均衡策略方式相同
 *      本微服务主要测试OpenFeign的功能,所以采用YML文件配置Ribbon的负载均衡策略
 * 2.OpenFeign是对Ribbon和RestTemplate的封装,所以配置负载均衡方式同Ribbon配置负载均衡方式,而且不需要在容器中手动注入ResTemplate对象
 * 3.OpenFeign硬编码实现远程调用
 * 4.对所有微服务统一进行配置,如连接超时时间配置、读取超时时间配置,YML中将OpenFegin的配置和对Ribbon的配置写在了一起
 * 5.开启OpenFeign增强日志后可以看到Http调用的详细信息
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] <--- HTTP/1.1 200 (59ms)
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] connection: keep-alive
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] content-type: application/json
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] date: Tue, 31 May 2022 19:51:37 GMT
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] keep-alive: timeout=60
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] transfer-encoding: chunked
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById]
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] {"code":200,"message":"查询成功,serverPort:  8006","data":{"id":1,"serial":"15646546546"}}
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] <--- END HTTP (94-byte body)
 */
@EnableEurekaClient //添加@EnableEurekaClient好像没什么用,但是还是加上
@SpringBootApplication
@EnableFeignClients
public class OrderServiceConsumerLoadBalanceOpenFeignConfigurationRibbon80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceConsumerLoadBalanceOpenFeignConfigurationRibbon80.class, args);
    }
}

6.4.10.测试模块

启动相关服务
测试通过配置Ribbon实现对OpenFeign的配置来实现负载均衡
在浏览器中访问
http://localhost/consumer/payment/get/1
第一次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8001","data":{"id":1,"serial":"15646546546"}}
第二次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8002","data":{"id":1,"serial":"15646546546"}}
第三次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8002","data":{"id":1,"serial":"15646546546"}}
第四次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8001","data":{"id":1,"serial":"15646546546"}}
可以看到四次访问返回的结果中,四次返回结果是没有规律的,因为采用的MyRoundRobinRule(自定义策略,这个策略的效果也是随机调用),实际返回结果可能不是上面的情况,但是一定是随机进行服务调用的

6.4.11.注意事项

OpenFeign和RestTemplate
使用OpenFeign实现远程调用时,容器中注入不用注入RestTemplate,OpenFeign已经在底层对RestTemplate做了封装

在application.yml中配置开启OpenFeign增强日志
logging: #OpenFeign增强日志配置
    level:
    org.openatom.springcloud.services.PaymentServiceOpenFeign: debug  #OpenFeign日志以什么级别监控哪个接口

6.5.通过直接配置OpenFeign实现对OpenFeign的配置来实现负载均衡

6.5.1.模块简介

通过直接配置OpenFeign实现对OpenFeign的配置来实现的服务消费者,在YML中编写相关配置,之前在YML配置的Ribbon的相关配置现在直接配置在了YML中OpenFeign部分,启动端口: 80

6.5.2.模块目录结构

springcloud-consumer-loadbalance-openfeign-configuration-openfeign-order80
|-- src
|   •-- main
|       |-- java
|       |   •-- org
|       |       •-- openatom
|       |           •-- springcloud
|       |               |-- config
|       |               |   •-- OpenFeignConfig.java
|       |               |-- controller
|       |               |   •-- OrderConsumerController.java
|       |               |-- service
|       |               |   •-- PaymentServiceOpenFeign.java
|       |               •-- OrderServiceConsumerLoadBalanceOpenFeignConfigurationOpenfeign80.java
|       •-- resources
|           •-- application.yml
•-- pom.xml

6.5.3.创建模块

在父工程(springcloud-eureka)中创建一个名为springcloud-consumer-loadbalance-openfeign-configuration-openfeign-order80的maven模块,注意:当前模块创建成功后,在父工程pom.xml中<modules></modules>中会自动生成有关当前模块的信息

6.5.4.编写模块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">
    <parent>
        <artifactId>springcloud-eureka</artifactId>
        <groupId>org.openatom</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consumer-loadbalance-openfeign-configuration-openfeign-order80</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--引入公共的工程-->
        <dependency>
            <groupId>org.openatom</groupId>
            <artifactId>springcloud-api-commons</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>
    </dependencies>
    <!--热部署需要加这个-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
        <!--打包多环境-->
        <resources>
            <resource>
                <directory>src/main/resources/</directory>
                <includes>
                    <!--不区分环境:直接加载application.yml配置文件-->
                    <include>application.yml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

6.5.5.编写模块application.yml

server:
  port: 80

spring:
  application:
    name: SPRINGCLOUD-CONSUMER-LOADBALANCE-OPENFEIGN-CONFIGURATION-ORDER80 #注意:服务名不要出现_
  devtools:
    restart:
      enabled: true
  logging: #Spring运行日志配置
    level: info

eureka:
  client:
    register-with-eureka: true  #表示是否将自己注册进EurekaServer默认为true。
    fetchRegistry: true  #是否从EurekaServer抓取已有的注册信息,默认为true。服务提供端是单节点无所谓,是集群必须设置为true才能配合ribbon使用负载均衡,否则报异常No instances available for SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER
    service-url:
      #单机版
      defaultZone: http://localhost:7001/eureka
      #集群版
      #defaultZone: http://eureka7002:7002/eureka,http://eureka7003:7003/eureka,http://eureka7004:7004/eureka
  instance:
    instance-id: ${spring.application.name} #Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容
    prefer-ip-address: false #访问路径可以显示IP地址,点击Eureka仪表盘中Instances currently registered with Eureka.Status显示的内容地址栏是否显示IP地址

#某个/某些服务的Ribbon配置
SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER: #服务提供端名称
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  #Ribbon负载均衡规则类所在的路径,自带七种规则,也可以是自定位规则的类所在的路径
#对OpenFeign进行单独配置
feign:
  client:
    config:
      #这里填具体的服务名称(也可以填default,表示对所有服务生效)
      SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER:  #服务提供端名称
        #connectTimeout和readTimeout这两个得一起配置才会生效
        connectTimeout: 5000  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
        readTimeout: 5000   #指的是建立连接后从服务器读取到可用资源所用的时间
logging: #OpenFeign增强日志配置
  level:
    org.openatom.springcloud.services.PaymentServiceOpenFeign: debug  #OpenFeign日志以什么级别监控哪个接口

6.5.6.编写模块config

package org.openatom.springcloud.config;

import feign.Logger;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;

@Configuration
public class OpenFeignConfig {

    /**
     * NONE:默认的,不显示任何日志;
     * BASIC:仅记录请求方法、URL、响应状态码及执行时间;
     * HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
     * FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

6.5.7.编写模块service

package org.openatom.springcloud.service;

import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * OpenFeign硬编码实现远程调用
 */
@Component
@FeignClient(name="SPRINGCLOUD-PROVIDER-PAYMENT-SERVICE-CLUSTER")
public interface PaymentServiceOpenFeign {
    @PostMapping(value = "/provider/payment/create")
    CommonResult create(@RequestBody Payment payment);

    @GetMapping(value = "/provider/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

    @GetMapping(value = "/provider/payment/openfeign/timeout")
    String getPaymentByIdTimeout();
}

6.5.8.编写模块controller

package org.openatom.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.openatom.springcloud.service.PaymentServiceOpenFeign;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderConsumerController {

    //单机版
//    public static final String PAYMENT_URL = "http://localhost:8001";
//    public static final String PAYMENT_URL = "http://localhost:8002";

    @Resource
    private PaymentServiceOpenFeign paymentServiceOpenFeign;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment) {
        return paymentServiceOpenFeign.create(payment);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
        return paymentServiceOpenFeign.getPaymentById(id);
    }

    @GetMapping("/consumer/payment/openfeign/timeout")
    public String getPaymentByIdTimeout() {
        return paymentServiceOpenFeign.getPaymentByIdTimeout();
    }
}

6.5.9.编写模块主启动类

package org.openatom.springcloud;

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

/**
 * 1.使用OpenFeign完成远程调用,如果要配置负载均衡策略,和Ribbon配置负载均衡策略方式相同
 *      本微服务主要测试OpenFeign的功能,所以采用YML文件配置Ribbon的负载均衡策略
 * 2.OpenFeign是对Ribbon和RestTemplate的封装,所以配置负载均衡方式同Ribbon配置负载均衡方式,而且不需要在容器中手动注入ResTemplate对象
 * 3.OpenFeign YML文件配置实现远程调用,但不是完全将服务信息配置在YML中,只是在YML中写一些增强的配置,相关的服务中仍然要写服务名,@FeignClient(name="SPRING-CLOUD-PROVIDER-CONSUL-PAYMENT-SERVICE")
 * 4.对每个微服务单独进行配置,如连接超时时间配置、读取超时时间配置,YML没有把OpenFegin的配置和对Ribbon的配置写在一起
 * 5.开启OpenFeign增强日志后可以看到Http调用的详细信息
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] <--- HTTP/1.1 200 (59ms)
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] connection: keep-alive
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] content-type: application/json
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] date: Tue, 31 May 2022 19:51:37 GMT
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] keep-alive: timeout=60
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] transfer-encoding: chunked
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById]
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] {"code":200,"message":"查询成功,serverPort:  8006","data":{"id":1,"serial":"15646546546"}}
 *      2022-06-01 03:51:37.176 DEBUG 16792 --- [p-nio-80-exec-1] o.o.s.services.PaymentServiceOpenFeign   : [PaymentServiceOpenFeign#getPaymentById] <--- END HTTP (94-byte body)
 */
@EnableEurekaClient  //添加@EnableEurekaClient好像没什么用,但是还是加上
@SpringBootApplication
@EnableFeignClients
public class OrderServiceConsumerLoadBalanceOpenFeignConfigurationOpenfeign80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceConsumerLoadBalanceOpenFeignConfigurationOpenfeign80.class, args);
    }
}

6.5.10.测试模块

启动相关服务
测试通过直接配置OpenFeign实现对OpenFeign的配置来实现负载均衡
在浏览器中访问
http://localhost/consumer/payment/get/1
第一次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8001","data":{"id":1,"serial":"15646546546"}}
第二次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8002","data":{"id":1,"serial":"15646546546"}}
第三次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8002","data":{"id":1,"serial":"15646546546"}}
第四次访问返回结果
{"code":200,"message":"查询成功,serverPort:  8001","data":{"id":1,"serial":"15646546546"}}
可以看到四次访问返回的结果中,四次返回结果是没有规律的,因为采用的MyRoundRobinRule(自定义策略,这个策略的效果也是随机调用),实际返回结果可能不是上面的情况,但是一定是随机进行服务调用的

6.5.11.注意事项

OpenFeign和RestTemplate
容器中注入不用注入RestTemplate,OpenFeign已经在底层对RestTemplate做了封装

在application.yml中配置开启OpenFeign增强日志
logging: #OpenFeign增强日志配置
    level:
    org.openatom.springcloud.services.PaymentServiceOpenFeign: debug  #OpenFeign日志以什么级别监控哪个接口
上次编辑于: 2022/9/6 00:07:50
贡献者: lingwh
评论