SpringCloud基础OpenFeign:远程通信
Posted 烟锁迷城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud基础OpenFeign:远程通信相关的知识,希望对你有一定的参考价值。
目录
1、基本介绍
1.1、简介
Feign是一个声明式的伪RPC的REST客户端,它用了基于接口的注解方式,可以以Java接口注解的方式调用Http请求,从而将请求模板化。
Feign被广泛应用在SpringCloud的解决方案中,是学习基于SpringCloud微服务架构不可或缺的重要组件。
1.2、代码示例
在前一个项目的基础上,不再使用RestTemplate,而是改用OpenFeign
在SpringCloudProvideConsumerApplication启动类上添加注解@EnableFeignClients
@EnableFeignClients
@SpringBootApplication
public class SpringCloudProvideConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudProvideConsumerApplication.class, args);
}
}
添加后,增加接口IHelloController,在上面加上@FeignClient,在注解内填写需要连接的服务名称:spring-cloud-provider-service
@FeignClient("spring-cloud-provider-service")
public interface IHelloControllerFeign {
@GetMapping("/hello")
String sayHello();
}
调用时,就将IHelloController作为一个服务进行调用,得到的结果与使用RestTemplate是相同的。
@RestController
public class MyHelloController {
@Autowired
IHelloControllerFeign helloControllerFeign;
@GetMapping("my")
public String sayHello() {
return helloControllerFeign.sayHello();
}
}
2、组件特性
2.1、开启Gzip压缩
OpenFeign支持压缩传输数据,减少数据传输压力,主流浏览器同样支持Gzip压缩协议,可以直接使用。
配置项如下:
#开启Gzip压缩
feign.compression.request.enabled=true
#接受压缩的最小数据大小
feign.compression.request.min-request-size=2048
#回传数据接受Gzip压缩
feign.compression.response.enabled=true
#Gzip压缩格式
feign.compression.request.mime-types=text/xml
- feign.compression.request.enabled:开启Gzip压缩功能
- feign.compression.request.min-request-size:接受压缩的最小数据量,避免太小的数据压缩之后反而变大,增加传输压力
- feign.compression.response.enabled:是否对返回结果进行压缩
- feign.compression.request.mime-types:压缩格式,支持的格式有"text/xml", "application/xml", "application/json"
2.2、日志追踪
OpenFeign可以开启日志追踪,追踪固定的接口
需要在配置文件中增加:
logging.level.[com.my.p5.springcloudprovideconsumer.IHelloControllerFeign]=debug
基本格式是logging.leve.[OpenFeign接口全路径名],数值是日志级别
增加FeignConfig类作为日志等级:
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLogger() {
return Logger.Level.FULL;
}
}
其中返回的常量值共有四个,分别是:
- FULL:所有日志信息
- HEADERS:包含BASIC级别的日志信息,额外包含请求头,响应头
- BASIC:仅记录请求方法,URL,响应状态码,执行时间
- NONE:不记录任何日志
在OpenFeign的接口中增加日志输出级别的类FeignConfig:
@FeignClient(name = "spring-cloud-provider-service", configuration = FeignConfig.class)
public interface IHelloControllerFeign {
@GetMapping("/hello")
String sayHello();
}
name为服务名,configuration为日志输出级别。
最终执行后的日志输出:
可以看到,日志输出的全部信息。
2.3、底层通信
feign采用的是代理模式,因此被称之为伪RPC。实际上,feign的底层是JDK提供的URLConnection,本身的性能不够好,如果想要替换,可以换成feign同样支持的okHttp。
想要替换为okHttp需要在pom文件中增加jar包:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
在配置文件中增加:
#关闭默认底层通信
feign.httpclient.enabled=false
#开启okHttp
feign.okhttp.enabled=true
3、多模块构建
在实际开发过程中,服务端和消费端会共用一些代码,比如参数类,在这时,就需要进行多模块构建。
可以将代码模块分为服务模块,消费模块,API模块
创建一个新的项目,spring-cloud-user-provide作为父模块
在pom文件中添加父依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
</parent>
在dependencyManagement标签内添加spring-boot-parent的依赖,代表它的子项目都会依赖父项目的pom
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot-starter-parent.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
增加新的子项目,user-provide,user-api,provide-consumer,将父依赖替换为:
<parent>
<groupId>com.my.example</groupId>
<artifactId>spring-cloud-user-provider</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
给user-provide,provide-consumer添加user-api依赖:
<dependency>
<groupId>com.my.example</groupId>
<artifactId>user-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
共有两种方式进行多模块构建。
3.1、第一种构建方式
在use-api增加两个类,User和UserClient
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@FeignClient("spring-cloud-user-provide")
public interface UserClient {
@GetMapping("/user")
public User queryUser();
}
在服务端增加UserController,在引入user-api的情况下,可以直接使用User类。
@RestController
public class UserController {
@GetMapping("/user")
public User queryUser() {
User user = new User();
user.setName("Lily");
user.setAge(18);
return user;
}
}
在消费端增加HelloController,在引入user-api的情况下,可以直接使用User类,可以将UserClient作为类似于Service层的类进行调用。
@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
private UserClient userClient;
@GetMapping("/user")
public String user() {
User user = userClient.queryUser();
return "hello " + user.getName();
}
}
构建完成后,访问:http://localhost:8082/hello/user
3.2、第二种构建方式
在data-api增加三个类,Data,DataFeign和IDataService
public class Data {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
feign是可以继承接口的,这样就可以不用实现方法
@FeignClient("spring-cloud-data-provide")
public interface DataFeign extends IDataService{
}
将接口内的方法增加GetMapping访问路径
public interface IDataService {
@GetMapping("/data")
Data sayHello();
}
在data-provider中添加一个类,对接口进行实现:
@RestController
public class DataServiceImpl implements IDataService {
@Override
public Data sayHello() {
Data data = new Data();
data.setName("Lily");
data.setAge(18);
return data;
}
}
在provider-consumer中添加一个类:
@RestController
@RequestMapping("/show")
public class ShowController {
@Autowired
private DataFeign dataFeign;
@GetMapping("/data")
public String data() {
Data data = dataFeign.sayHello();
return "hello " + data.getName();
}
}
构建完成后,访问:http://localhost:8082/show/data
我的公开码云代码地址:springclouduserprovider: springcloud测试
以上是关于SpringCloud基础OpenFeign:远程通信的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud系列——openfeign远程服务调用实战
SpringCloud04_OpenFeign的概述(远程调用)基本使用超时控制日志打印功能