在上一篇《Spring Cloud構建微服務架構(一)服務註冊與發現》中,我們已經成功創建了“服務註冊中心”,實現並註冊了一個“服務提供者:COMPUTE-SERVICE”。那麼我們要如何去消費服務提供者的接口內容呢?
Ribbon
Ribbon是一個基於HTTP和TCP客戶端的負載均衡器。Feign中也使用Ribbon,後續會介紹Feign的使用。
Ribbon可以在通過客戶端中配置的ribbonServerList服務端列表去輪詢訪問以達到均衡負載的作用。
當Ribbon與Eureka聯合使用時,ribbonServerList會被DiscoveryEnabledNIWSServerList重寫,擴展成從Eureka註冊中心中獲取服務端列表。同時它也會用NIWSDiscoveryPing來取代IPing,它將職責委託給Eureka來確定服務端是否已經啓動。
下面我們通過實例看看如何使用Ribbon來調用服務,並實現客戶端的均衡負載。
準備工作
- 啓動Chapter-9-1-1中的服務註冊中心:eureka-server
- 啓動Chapter-9-1-1中的服務提供方:compute-service
- 修改compute-service中的server-port爲2223,再啓動一個服務提供方:compute-service
可以看到COMPUTE-SERVICE服務有兩個單元正在運行:
- 192.168.21.101:compute-service:2222
- 192.168.21.101:compute-service:2223
使用Ribbon實現客戶端負載均衡的消費者
構建一個基本Spring Boot項目,並在pom.xml中加入如下內容:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> |
在應用主類中,通過@EnableDiscoveryClient
註解來添加發現服務能力。創建RestTemplate實例,並通過@LoadBalanced
註解開啓均衡負載能力。
public class RibbonApplication { RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonApplication.class, args); } } |
創建ConsumerController
來消費COMPUTE-SERVICE
的add服務。通過直接RestTemplate來調用服務,計算10 + 20的值。
public class ConsumerController { RestTemplate restTemplate; "/add", method = RequestMethod.GET) (value = public String add() { return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody(); } } |
application.properties
中配置eureka服務註冊中心
spring.application.name=ribbon-consumer server.port=3333 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ |
啓動該應用,並訪問兩次:http://localhost:3333/add
然後,打開compute-service的兩個服務提供方,分別輸出了類似下面的日誌內容:
- 端口爲
2222
服務提供端的日誌:
2016-06-02 11:16:26.787 INFO 90014 --- [io-2222-exec-10] com.didispace.web.ComputeController : /add, host:192.168.21.101, service_id:compute-service, result:30
|
- 端口爲
2223
服務提供端的日誌:
2016-06-02 11:19:41.241 INFO 90122 --- [nio-2223-exec-1] com.didispace.web.ComputeController : /add, host:192.168.21.101, service_id:compute-service, result:30
|
可以看到,之前啓動的兩個compute-service服務端分別被調用了一次。到這裏,我們已經通過Ribbon在客戶端已經實現了對服務調用的均衡負載。
完整示例可參考:Chapter9-1-2/eureka-ribbon
Feign
Feign是一個聲明式的Web Service客戶端,它使得編寫Web Serivce客戶端變得更加簡單。我們只需要使用Feign來創建一個接口並用註解來配置它既可完成。它具備可插拔的註解支持,包括Feign註解和JAX-RS註解。Feign也支持可插拔的編碼器和解碼器。Spring Cloud爲Feign增加了對Spring MVC註解的支持,還整合了Ribbon和Eureka來提供均衡負載的HTTP客戶端實現。
下面,通過一個例子來展現Feign如何方便的聲明對上述computer-service服務的定義和調用。
創建一個Spring Boot工程,配置pom.xml
,將上述的配置中的ribbon依賴替換成feign的依賴即可,具體如下:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> |
在應用主類中通過@EnableFeignClients
註解開啓Feign功能,具體如下:
public class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class, args); } } |
定義compute-servic
e服務的接口,具體如下:
"compute-service") (public interface ComputeClient { "/add") (method = RequestMethod.GET, value = Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b); } |
- 使用
@FeignClient("compute-service")
註解來綁定該接口對應compute-service服務 - 通過Spring MVC的註解來配置compute-service服務下的具體實現。
在web層中調用上面定義的ComputeClient
,具體如下:
public class ConsumerController { ComputeClient computeClient; "/add", method = RequestMethod.GET) (value = public Integer add() { return computeClient.add(10, 20); } } |
application.properties
中不用變,指定eureka服務註冊中心即可,如:
spring.application.name=feign-consumer server.port=3333 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ |
啓動該應用,訪問幾次:http://localhost:3333/add
再觀察日誌,可以得到之前使用Ribbon時一樣的結果,對服務提供方實現了均衡負載。
這一節我們通過Feign以接口和註解配置的方式,輕鬆實現了對compute-service服務的綁定,這樣我們就可以在本地應用中像本地服務一下的調用它,並且做到了客戶端均衡負載。
完整示例可參考:Chapter9-1-2/eureka-feign