Feign是 Netflix 公司開源的聲明式HTTP客戶端java
Github : Feign 源碼git
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
)//替換前 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); }
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
@EnableFeignClients
/** * IUserCenterFeignClient for 定義 user-center feign client * * @author <a href="mailto:magicianisaac@gmail.com">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); }
//使用 FeignClient 來替換掉RestTemplate調用 UserDTO userDTO = this.userCenterFeignClient.findById(userId);
**Tip **: 有可能出現父子上下文重疊問題github
/** * IUserCenterFeignClient for 定義 user-center feign client * * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a> * @since 2019/7/15 */ @FeignClient(name = "user-center",configuration = UserCenterFeignConfiguration.class) public interface IUserCenterFeignClient { ... }
/** * UserCenterFeignConfiguration for 自定義user-center服務請求中,feign的配置信息 * {@link @Configuration} 不能添加該註解,不然會和ribbon同樣,出現上下文重疊問題,形成配置全局共享 * 如要添加該註解,須要將該類放在主程序啓動掃描不到的包下 * * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a> * @since 2019/7/15 */ public class UserCenterFeignConfiguration { @Bean public Logger.Level level() { // 配置feign 日誌級別,記錄請求和響應的header、body以及元數據 return Logger.Level.FULL; } }
必定要在配置文件中添加該client 全路徑spring
logging: level: #com.sxzhongf: debug com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug
打印信息apache
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)
使用配置文件來定義log leveljson
#logging: #level: #com.sxzhongf: debug #com.sxzhongf.sharedcenter.feignclients.IUserCenterFeignClient: debug feign: client: config: user-center: #單服務配置 loggerLevel: full --- feign: client: config: default: #全局配置日誌級別 loggerLevel: full
架構師須要根據自身業務狀況來決定,是否須要將不一樣的微服務進行業務耦合,仍是使用冗餘代碼的方式來解放業務耦合性。性能優化
@SpringQueryMap
@FeignClient(name = "user-center") public interface ITestUserCenterFeignClient { @GetMapping("/users/q") public UserDTO query(@SpringQueryMap UserDTO userDTO); }
@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); }
Map
構建,(不推薦)@FeignClient(name = "user-center") public interface ITestUserCenterFeignClient { @RequestMapping(value = "/users/q",method = RequestMethod.GET) public UserDTO query(@RequestParam Map<String,Object> conditions); }
注意:這種方式不建議使用。主要是由於可讀性很差,並且若是參數爲空的時候會有一些問題,例如
map.put("username", null);
會致使user-center
服務接收到的username是""
,而不是null。架構
服務提供者方法app
@PostMapping("/create") public User createUser(@RequestBody User user){ return null; }
服務調用者微服務
@FeignClient(name = "user-center") public interface ITestUserCenterFeignClient { @RequestMapping(value = "/users/q",method = RequestMethod.POST) public UserDTO query(@RequestBody UserDTO user); }
@FeignClient(name = "xxxxx",url = "http://www.baidu.com") public interface ITestBaiduFeignClient { @GetMapping("") public String getBaidu(); }
<!--Feign 性能優化,須要使用鏈接池,引入依賴--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
httpclient: # 爲feign啓用 apache httpclient 作請求,而不使用默認的urlconection enabled: true # feign 最大鏈接數 max-connections: 200 # feign 單個路徑請求的最大鏈接數 max-connections-per-route: 50
<!--Feign 性能優化,須要使用鏈接池,引入依賴--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
httpclient: # 爲feign啓用 apache httpclient 作請求,而不使用默認的urlconection #enabled: true # feign 最大鏈接數 max-connections: 200 # feign 單個路徑請求的最大鏈接數 max-connections-per-route: 50 okhttp: enabled: true
生產環境使用
Logger.Level.BASIC