Client remote call
Feign
What is Feign?
Feign is declarative open source Netflix, HTTP client
GitHub: Feign Source
Why Feign?
- Original code readability is not high
- Complex URL difficult to maintain (
https://user-center/s?wd={userId}&rsv_spt=1&rsv_iqid=0x93bff3cd000cf3da&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=4&rsv_sug1=4&rsv_sug7=100&rsv_t=10c2risCimsUZC0RBruMerdnQRN1gRxFI%2BywuD0L3LwGGNd2dR8XE6x%2FyFOjHnR0oEi0&rsv_sug2=0&inputT=1535&rsv_sug4=1535&rsv_sug=2
) - Difficult to cope with rapid changes in demand
- JAVA coding experience and we write quite different
Reconstruction of Example Code
//替换前
ResponseEntity<UserDTO> userEntity = restTemplate.getForEntity(
"http://user-center/users/{userId}",
UserDTO.class, userId
);
UserDTO userDTO = new UserDTO();
if (null != userEntity) {
userDTO = userEntity.getBody();
log.info("ShareService#findById userDTO: {}", userDTO);
}
- Add dependent
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- Add comment startup class
@EnableFeignClients
Add Configuration- Implement the corresponding micro-client services
/**
* IUserCenterFeignClient for 定义 user-center feign client
*
* @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
* @since 2019/7/15
*/
@FeignClient(name = "user-center")
public interface IUserCenterFeignClient {
/**
* Feign client 会将请求转换为
* http://user-center/users/{userId}
*
* @param userId 用户id
* @return 返回用户对象
*/
@GetMapping(path = "/users/{userId}")
public UserDTO findById(@PathVariable Long userId);
}
- After replacing the code
//使用 FeignClient 来替换掉RestTemplate调用
UserDTO userDTO = this.userCenterFeignClient.findById(userId);
Feign composition
Feign's configuration
Java Code
Supported configuration items
Custom Feign log level
- Level content
Demo
Tip : it is possible to overlap the context of parent-child problems
- Add client configuration
/**
* IUserCenterFeignClient for 定义 user-center feign client
*
* @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
* @since 2019/7/15
*/
@FeignClient(name = "user-center",configuration = UserCenterFeignConfiguration.class)
public interface IUserCenterFeignClient {
...
}
- Write java profiles
/**
* UserCenterFeignConfiguration for 自定义user-center服务请求中,feign的配置信息
* {@link @Configuration} 不能添加该注解,否则会和ribbon一样,出现上下文重叠问题,造成配置全局共享
* 如要添加该注解,需要将该类放在主程序启动扫描不到的包下
*
* @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
* @since 2019/7/15
*/
public class UserCenterFeignConfiguration {
@Bean
public Logger.Level level() {
// 配置feign 日志级别,记录请求和响应的header、body以及元数据
return Logger.Level.FULL;
}
}
Be sure to add the client the full path in the configuration file
logging: level: #com.sxzhongf: debug com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
Print information
2019-07-15 15:06:11.650 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] <--- HTTP/1.1 200 (402ms)
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] content-type: application/json;charset=UTF-8
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] date: Mon, 15 Jul 2019 07:06:11 GMT
2019-07-15 15:06:11.651 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] transfer-encoding: chunked
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById]
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] {"id":1,"wxId":"","wxNickname":"IsaacZhang","roles":"","avatarUrl":"aaa","createTime":"2019-07-11T06:08:18.000+0000","updateTime":"2019-07-11T06:08:18.000+0000","bonus":100}
2019-07-15 15:06:11.652 DEBUG 20286 --- [nio-8010-exec-1] c.s.s.f.IUserCenterFeignClient : [IUserCenterFeignClient#findById] <--- END HTTP (173-byte body)
Configuration
Supported configuration items
demo
Use the configuration file to define log level
#logging:
#level:
#com.sxzhongf: debug
#com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
feign:
client:
config:
user-center: #单服务配置
loggerLevel: full
---
feign:
client:
config:
default: #全局配置日志级别
loggerLevel: full
Feign of inheritance
- The official is not recommended
- Most companies use?
Architects need to decide according to their own business situation, the need for different coupling micro-business services, or use of redundant code to liberate business coupling.
Feign multi-parameter request
Get
- use
@SpringQueryMap
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@GetMapping("/users/q")
public UserDTO query(@SpringQueryMap UserDTO userDTO);
}
- use
@RequestParam
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@RequestMapping(value = "/users/q",method = RequestMethod.GET)
public UserDTO query(@RequestParam("id") Long id,@RequestParam("name") String name);
}
- Use
Map
building, (not recommended)
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@RequestMapping(value = "/users/q",method = RequestMethod.GET)
public UserDTO query(@RequestParam Map<String,Object> conditions);
}
Note : This method is not recommended. Mainly because of poor readability, and if the parameter is empty when there will be some problems, for example,
map.put("username", null);
will leaduser-center
the service received username is""
, not null.
Post
Service provider method
@PostMapping("/create")
public User createUser(@RequestBody User user){
return null;
}
The caller service
@FeignClient(name = "user-center")
public interface ITestUserCenterFeignClient {
@RequestMapping(value = "/users/q",method = RequestMethod.POST)
public UserDTO query(@RequestBody UserDTO user);
}
Feign out of service registration / Ribbon call
@FeignClient(name = "xxxxx",url = "http://www.baidu.com")
public interface ITestBaiduFeignClient {
@GetMapping("")
public String getBaidu();
}
Feign Performance Optimization
Use connection pooling
httpClient
- Plus dependence
<!--Feign 性能优化,需要使用连接池,引入依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
- Add comment (not required)
- Change configuration
httpclient:
# 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
enabled: true
# feign 最大连接数
max-connections: 200
# feign 单个路径请求的最大连接数
max-connections-per-route: 50
okHttp
- Plus dependence
<!--Feign 性能优化,需要使用连接池,引入依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
- Add comment (not required)
- Change configuration
httpclient:
# 为feign启用 apache httpclient 做请求,而不使用默认的urlconection
#enabled: true
# feign 最大连接数
max-connections: 200
# feign 单个路径请求的最大连接数
max-connections-per-route: 50
okhttp:
enabled: true
Rational use Feign log
Production environments
Logger.Level.BASIC