往期回顾

Nacos的安装与配置

Spring Cloud集成Nacos作为注册中心

LoadBalacer集成Nacos实现负载均衡

常见的负载均衡策略分析

Spring Cloud集成Dubbo实现RPC调用

SpringCloud集成Nacos作为配置中心

前面我们已经介绍了Nacos 的安装与配置,Spring Cloud 集成Nacos 作为服务的注册中心和配置中心,集成Nacos 实现服务的负载均衡和一些常见的负载均衡策略以及使用Dubbo进行RPC调用

接下来,将介绍如何使用OpenFeign 进行RPC调用

关于RPC的一些相关概念前面的文章已经介绍过,这里不再赘述。如果还有疑问的同学可以参见

Spring Cloud集成Dubbo实现RPC调用

OpenFeign介绍

Spring Cloud OpenFeign 是声明式的服务调用工具,它整合了Ribbon 和Hystrix ,拥有负载均衡和服务容错功能

Feign 是声明式的服务调用工具,我们只需创建一个接口并用注解的方式来配置它,就可以实现对某个服务接口的调用,简化了直接使用RestTemplate 来调用服务接口的开发量。Feign 具备可插拔的注解支持,同时支持Feign 注解、JAX-RS注解及SpringMvc注解。当使用Feign时,Spring Cloud集成了Ribbon 和Eureka 以提供负载均衡的服务调用及基于Hystrix 的服务容错保护功能。

大家经常听到有人说OpenFeign,有人说Feign,给人一种好像是两个东西的错觉。其实是因为Feign本身也是Netflix的开源项目,后面独立出来单独做了开源项目,改名为OpenFeign。这种情况其实很常见,比如鸿蒙-HarmonyOS就有Open HarmonyOS。

快速开始

引入依赖

我们先在原有的项目工程上创建一个新的消费者模块

引入对应依赖

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

org.springframework.cloud

spring-cloud-starter-netflix-ribbon

org.springframework.cloud

spring-cloud-starter-loadbalancer

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-config

org.springframework.cloud

spring-cloud-starter-bootstrap

org.springframework.cloud

spring-cloud-starter-openfeign

添加相关配置

Nacos配置

详见SpringCloud集成Nacos作为配置中心

新建bootstrap.yml

spring:

application:

name: user-openfeign-consumer

cloud:

nacos:

discovery:

server-addr: 192.168.199.128:8848 #Nacos地址

config:

server-addr: 192.168.199.128:8848 #Nacos地址

file-extension: yaml #这里我们获取的yaml格式的配置

添加application.yml

server:

port: 7002

spring:

profiles:

active: dev

配置OpenFeign 日志级别

日志的级别分为四种:

NONE :不记录任何日志信息,这是默认值。BASIC :仅记录请求的方法,URL以及响应状态码和执行时间HEADERS :在BASIC的基础上,额外记录了请求和响应的头信息FULL :记录所有请求和响应的明细,包括头信息、请求体、元数据

日志的级别如果没有特殊要求,一般使用 NONE、BASIC 两个就好了,默认是NONE

注意:因为feign调试日志是debug级别输出,springboot默认的日志级别是info,所以feign的debug日志级别就不会输出,所以需要对Feign接口单独配置日志输出级别

# 因为feign调试日志是debug级别输出,springboot默认的日志级别是info,所以feign的debug日志级别就不会输出

# logging.level=debug这样配置是对所有的日志级别进行配置

# 该场景只需要对feign接口进行debug配置,所以是这样配置logging.level.com.example.order.feign=debug

logging:

level:

cuit.epoch.pymjl.service.UserFeignClient: debug

Java代码的方式

可以基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level 的对象

先创建一个配置类

package cuit.epoch.pymjl.config;

import feign.Logger;

import org.springframework.context.annotation.Bean;

/**

* 在启动类的注解@EnableFeignClients上指定

* 局部生效就在@FeignClient中指定,不能加@Configuration注解

*

* @author Pymjl

* @version 1.0

* @date 2022/9/1 13:17

**/

public class OpenFeignConfig {

@Bean

public Logger.Level feignLogLevel() {

// 日志级别为BASIC

return Logger.Level.FULL;

}

}

如果要全局生效,将其放到 启动类的@EnableFeignClients 这个注解中

@SpringBootApplication

@EnableFeignClients(defaultConfiguration = OpenFeignConfig.class)

public class OpenFeignApplication {

public static void main(String[] args) {

SpringApplication.run(OpenFeignApplication.class, args);

}

}

如果是局部生效,则把它放到对应的@FeignClient 这个注解中

@FeignClient(value = "user-service",configuration = OpenFeignConfig.class)

配置文件的方式

# 针对某个微服务的配置 userservice:微服务名称 FULL:日志级别

feign.client.config.userservice.logger-level=FULL

# 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置

#feign.client.config.default.logger-level=FULL

配置LoadBalancer

详见LoadBalacer集成Nacos实现负载均衡

配置负载均衡策略

/**

* 注意不要加@Configuration

*

* @author Pymjl

* @version 1.0

* @date 2022/8/26 13:05

**/

public class MyLoadBalancerConfig {

@Resource

NacosDiscoveryProperties nacosDiscoveryProperties;

@Bean

ReactorLoadBalancer randomLoadBalancer(Environment environment,

LoadBalancerClientFactory loadBalancerClientFactory) {

String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);

// Nacos权重轮询

return new NacosLoadBalancer(loadBalancerClientFactory

.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);

}

}

配置RestTemplate

/**

* 在这里配置我们自定义的LoadBalancer策略 如果想自己扩展算法 需要实现ReactorServiceInstanceLoadBalancer接口

* @LoadBalancerClients(defaultConfiguration = {name = "CLOUD-PAYMENT-SERVICE", configuration = MyLoadBalancerConfig.class})

* 注意这里的name属性 需要和Nacos页面中的服务提供者名字一致

*

* @author Pymjl

* @version 1.0

* @date 2022/8/26 12:20

**/

@Configuration

@LoadBalancerClient(name = "user-service", configuration = MyLoadBalancerConfig.class)

public class RestTemplateConfig {

@Bean

@LoadBalanced

public RestTemplate restTemplate() {

return new RestTemplate();

}

}

超时配置

我们在通过 Feign 去调用接口,难免会遇到超时的问题,我们可以在 yml 文件设置超时属性,防止系统抛出超时异常

feign:

client:

config:

# 全局配置(default 默认就是适用于全部微服务)

default:

connectTimeout: 100000

readTimeout: 100000

# 单独配置

user-service:

connectTimeout: 300000

readTimeout: 300000

OpenFeign的其他配置

类型作用说明feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULLfeign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送feign. Contract支持的注解格式默认是SpringMVC的注解feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的@Bean覆盖默认Bean即可

常用的配置如下:

feign:

hystrix:

enabled: true #在Feign中开启Hystrix

compression:

request:

enabled: false #是否对请求进行GZIP压缩

mime-types: text/xml,application/xml,application/json #指定压缩的请求数据类型

min-request-size: 2048 #超过该大小的请求会被压缩

response:

enabled: false #是否对响应进行GZIP压缩

logging:

level: #修改日志级别

com.macro.cloud.service.UserService: debug

OpenFeign的优化

默认情况下,Feign 使用的是 UrlConnetcion 去请求,这种原生的请求方式一旦遇到高并发的情况下,响应会变得很慢,所以我们可以考虑加入连接池技术来优化性能, 比如常用的Ok Http 、Apache Http Client

在HTTP 通信的过程中,建立连接是一个很复杂的过程,涉及到多个数据包的交换,很耗时间,而且HTTP连接需要3次握手和4次挥手开销都很大。

这时可以采用HTTP连接池,节约大量的3次握手4次挥手时间,提升吞吐量。

默认的HttpURLConnection是JDK自带的,并不支持连接池,如果要实现连接池的机制,还需要自己来管理连接对象。

HttpClient 相比传统JDK自带的HttpURLConnection,它封装了访问HTTP的请求头,参数,内容体,响应等等。它不仅使客户端发送HTTP请求变得容易,而且也方便了开发人员测试接口(基于HTTP协议的),既提高了开发的效率,又提高了代码的健壮性。另外高并发大量的请求网络的时候,也是用"连接池"提升吞吐量。

OkHttp作为后期之秀,功能和性能上,可能稍优于HttpClient ,但是几乎没多大区别,实际使用时,都是可以的,不过HttpClient集成起来更方便

下面介绍下如何集成 Apache 下的 HttpClient 的连接池

先引入依赖

io.github.openfeign

feign-httpclient

编写对应的yml文件

feign:

httpclient:

enabled: true

max-connections: 200

max-connections-per-route: 50

编写对应的接口

先在服务提供者正常的编写service 代码,然后将service 注入进controller 完成controller 的编写

/**

* @author Pymjl

* @version 1.0

* @date 2022/8/25 12:48

**/

@RestController

@RequestMapping("/user")

public class UserController {

@Resource

UserService userService;

@GetMapping("/register")

public CommonResult register() {

userService.register();

return ResultUtils.success();

}

@GetMapping("/get/{id}")

public CommonResult get(@PathVariable("id") Long id) {

return ResultUtils.success(userService.get(id));

}

}

在消费者端编写对应的FeignClient ,和我们平常的service接口没太大的区别,只是在上面加上对应的SpringMVC注解

/**

* @author Pymjl

* @version 1.0

* @date 2022/9/1 0:03

**/

@FeignClient(value = "user-service")

public interface UserFeignClient {

/**

* 注册

*

* @return {@code CommonResult}

*/

@GetMapping("/user/register")

CommonResult register();

/**

* 得到

*

* @param id id

* @return {@code CommonResult}

*/

@GetMapping("/user/get/{id}")

CommonResult get(@PathVariable("id") Long id);

}

注意value 的值要和nacos 中的服务提供者的名字相同

然后编写对应的消费者controller

/**

* @author Pymjl

* @version 1.0

* @date 2022/9/1 0:09

**/

@RestController

@RequestMapping("/consumer")

public class TestController {

@Resource

UserFeignClient userFeignClient;

@GetMapping("/register")

public CommonResult register() {

return userFeignClient.register();

}

@GetMapping("/get/{id}")

public CommonResult get(@PathVariable Long id) {

return userFeignClient.get(id);

}

}

测试

先启动服务提供者user-service,再启动消费者

访问对应接口

查看消费者后台日志输出

从上面可以看见,因为我们对OpenFegin 配置了日志的输出级别,控制台在访问对应的请求时打印了对应的HTTP接口的详情

查看提供者的日志输出

至此,整合Nacos 和 OpenFegin 就完成了,至于OpenFegin 整合Hystrix 进行服务的降级与熔断这里不做赘述,后面考虑整合Sentinel

Spring Cloud 之前使用的断路器是 Netfilx 开源的 Hystrix 。被很多开发人员作为默认的断路器来使用。2018 年 11 月,当 Netflix 宣布将这个项目置于维护模式时(不再开发新特性,只进行例行维护),Spring Cloud 官方也不得不跟进了 Netfix ,在 SpringOne 2019中,Spring 宣布将从 Spring Cloud 3.1 版本中删除 Hystrix 仪表板。要不了多长时间 Spring Cloud Netfix 将结束生命周期。

应的请求时打印了对应的HTTP接口的详情

查看提供者的日志输出

[外链图片转存中…(img-J4Qu3Fig-1662298670269)]

至此,整合Nacos 和 OpenFegin 就完成了,至于OpenFegin 整合Hystrix 进行服务的降级与熔断这里不做赘述,后面考虑整合Sentinel

Spring Cloud 之前使用的断路器是 Netfilx 开源的 Hystrix 。被很多开发人员作为默认的断路器来使用。2018 年 11 月,当 Netflix 宣布将这个项目置于维护模式时(不再开发新特性,只进行例行维护),Spring Cloud 官方也不得不跟进了 Netfix ,在 SpringOne 2019中,Spring 宣布将从 Spring Cloud 3.1 版本中删除 Hystrix 仪表板。要不了多长时间 Spring Cloud Netfix 将结束生命周期。

项目源码:gitee github

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: