<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
@MapperScan("com.itmuch.contentcenter.dao") @SpringBootApplication @EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class) @EnableBinding({Source.class}) public class ContentCenterApplication {
@FeignClient(name = "user-center") public interface UserCenterFeignClient { /** * http://user-center/users/{id} * * @param id * @return */ @GetMapping("/users/{id}") UserDTO findById(@PathVariable Integer id); }
private final UserCenterFeignClient userCenterFeignClient; // 1. 代碼不可讀 // 2. 複雜的url難以維護:https://user-center/s?ie={ie}&f={f}&rsv_bp=1&rsv_idx=1&tn=baidu&wd=a&rsv_pq=c86459bd002cfbaa&rsv_t=edb19hb%2BvO%2BTySu8dtmbl%2F9dCK%2FIgdyUX%2BxuFYuE0G08aHH5FkeP3n3BXxw&rqlang=cn&rsv_enter=1&rsv_sug3=1&rsv_sug2=0&inputT=611&rsv_sug4=611 // 3. 難以相應需求的變化,變化很沒有幸福感 // 4. 編程體驗不統一 UserDTO userDTO = this.userCenterFeignClient.findById(userId);
@FeignClient(name = "user-center", configuration = GlobalFeignConfiguration.class) public interface UserCenterFeignClient { /** * http://user-center/users/{id} * * @param id * @return */ @GetMapping("/users/{id}") UserDTO findById(@PathVariable Integer id); }
/** * feign的配置類 * 這個類別加@Configuration註解了,不然必須挪到@ComponentScan能掃描的包之外 */ public class GlobalFeignConfiguration { @Bean public Logger.Level level(){ // 讓feign打印全部請求的細節 return Logger.Level.FULL; } }
logging: level: com.itmuch.contentcenter.feignclient.UserCenterFeignClient: debug
EnableFeignClientsjava
// 掃描mybatis哪些包裏面的接口 @MapperScan("com.itmuch.contentcenter.dao") @SpringBootApplication @EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class) @EnableBinding({Source.class}) public class ContentCenterApplication {
/** * feign的配置類 * 這個類別加@Configuration註解了,不然必須挪到@ComponentScan能掃描的包之外 */ public class GlobalFeignConfiguration { @Bean public Logger.Level level(){ // 讓feign打印全部請求的細節 return Logger.Level.FULL; } }
// 掃描mybatis哪些包裏面的接口 @MapperScan("com.itmuch.contentcenter.dao") @SpringBootApplication @EnableFeignClients// (defaultConfiguration = GlobalFeignConfiguration.class) @EnableBinding({Source.class}) public class ContentCenterApplication {
@GetMapping("test-get") public UserDTO query(UserDTO userDTO) { return testUserCenterFeignClient.query(userDTO); }
import com.itmuch.contentcenter.domain.dto.user.UserDTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "user-center") public interface TestUserCenterFeignClient { @GetMapping("/q") UserDTO query(@SpringQueryMap UserDTO userDTO); }
@FeignClient(name = "user-center") public interface UserFeignClient { @RequestMapping(value = "/q", method = RequestMethod.GET) public UserDTO query(@RequestParam("id") Long id, @RequestParam("username") String username); }
下面來討論如何使用Feign構造包含多個參數的POST請求。假設服務提供者的Controller是這樣編寫的:git
@RestController public class UserController { @PostMapping("/post") public User post(@RequestBody User user) { ... } }
@FeignClient(name = "microservice-provider-user") public interface UserFeignClient { @RequestMapping(value = "/post", method = RequestMethod.POST) public User post(@RequestBody User user); }
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; // 脫離ribbon的使用 @FeignClient(name = "baidu", url = "http://www.baidu.com") public interface TestBaiduFeignClient { @GetMapping("") String index(); }
feign: sentinel: # 爲feign整合sentinel enabled: true client: config: # 全局配置 default: loggerLevel: full requestInterceptors: - com.itmuch.contentcenter.feignclient.interceptor.TokenRelayRequestIntecepor httpclient: # 讓feign使用apache httpclient作請求;而不是默認的urlconnection enabled: true # feign的最大鏈接數 max-connections: 200 # feign單個路徑的最大鏈接數 max-connections-per-route: 50
從實踐上看,採用feign的方式更優雅(feign內部也使用了ribbon作負載均衡)。github