SpringCloud系列十:使用Feign實現聲明式REST調用

1. 回顧web

  前文的示例中是使用RestTemplate實現REST API調用的,代碼大體以下:
spring

@GetMapping("/user/{id}") public User findById(@PathVariable Long id) { return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class); }

  由代碼剋制,咱們是使用拼接字符串的方式構造URL的,該URL只有一個參數。sql

  然而在現實中,URL每每有多個參數。若是這時還使用這種方式構造URL,那麼就會變得很低效,而且難以維護。服務器

2. Feign簡介架構

  Feign是Netflix開發的聲明式、模板化的HTTP客戶端,其靈感來自Retrofit、JAXRS-2.0以及WebSocket。Feign可幫助咱們更加便捷、優雅地調用HTTP API。app

  在Spring Cloud中,使用Feign很是簡單——建立一個接口,並在接口上添加一些註解,代碼就完成了。Feign支持多種註解,例如Feign自帶的註解或者負載均衡

  JAX-RS註解等。ide

  Spring Cloud對Feign進行了加強,使Feign支持了Spring MVC註解,並整合了Ribbon和Eureka,從而讓Feign的使用更加方便。微服務

3. 爲服務消費者整合Feignpost

  > 複製項目 microservice-consumer-movie,將ArtifactId修改成 microservice-consumer-movie-feign

  > 添加Feign的依賴

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

  > 建立一個Feign接口,並添加@FeignClient註解

package com.itmuch.cloud.microserviceconsumermoviefeign.feign; import com.itmuch.cloud.microserviceconsumermoviefeign.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "microservice-provider-user") public interface UserFeignClient { @GetMapping(value = "/{id}") User findById(@PathVariable("id") Long id); }

  @FeignClient註解中的microservice-provider-user是一個任意的客戶端名稱,用於建立Ribbon負載均衡器。在本例中,因爲使用了Eureka,

  因此Ribbon會把microservice-provider-user解析成Eureka Server服務註冊表中的服務。

  若是不想使用Eureka,也可以使用service.ribbon.listOfServers屬性配置服務器列表

  也可以使用url屬性指定請求的URL(URL能夠是完整的URL或主機名),例如

  @FeignClient(name = "microservice-provider-user", url = "http://localhost:8000/")

  > 修改Controller代碼,讓其調用Feign接口

package com.itmuch.cloud.microserviceconsumermoviefeign.controller; import com.itmuch.cloud.microserviceconsumermoviefeign.feign.UserFeignClient; import com.itmuch.cloud.microserviceconsumermoviefeign.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class MovieController { @Autowired private UserFeignClient userFeignClient; @GetMapping("/user/{id}") public User findById(@PathVariable Long id) { return this.userFeignClient.findById(id); } }

  > 修改啓動類,添加@EnableFeignClients註解

package com.itmuch.cloud.microserviceconsumermoviefeign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class MicroserviceConsumerMovieFeignApplication { public static void main(String[] args) { SpringApplication.run(MicroserviceConsumerMovieFeignApplication.class, args); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }

  > 啓動 microservice-discovery-eureka

  > 啓動兩個以上的 microservice-provider-user 實例

  > 啓動 microservice-consumer-movie-feign

  > 屢次訪問 http://localhost:8010/user/1,在各個實例的控制檯下均可看見相似日誌

Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.balance as balance3_0_0_, user0_.name as name4_0_0_, user0_.username as username5_0_0_ from user user0_ where user0_.id=?
2018-03-27 17:48:19.468 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [1] 2018-03-27 17:48:19.480 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([age2_0_0_] : [INTEGER]) - [20] 2018-03-27 17:48:19.481 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([balance3_0_0_] : [NUMERIC]) - [100.00] 2018-03-27 17:48:19.481 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([name4_0_0_] : [VARCHAR]) - [張三] 2018-03-27 17:48:19.481 TRACE 14160 --- [nio-8001-exec-2] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([username5_0_0_] : [VARCHAR]) - [account1]

4. 總結

  以上結果說明,本文實現了聲明式的REST API調用,同時還實現了客戶端側的負載均衡。

  下文將講解自定義Feign配置,敬請期待~~~

5. 參考

  周立 --- 《Spring Cloud與Docker微服務架構與實戰》

相關文章
相關標籤/搜索