1. 程式人生 > >springcloud (二)服務消費者

springcloud (二)服務消費者

http://blog.didispace.com/springcloud2/

 

在上一篇《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

此時訪問:http://localhost:1111/

altalt

可以看到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註解開啟均衡負載能力。

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication {

	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}

	public static void main(String[] args) {
		SpringApplication.run(RibbonApplication.class, args);
	}

}

建立ConsumerController來消費COMPUTE-SERVICE的add服務。通過直接RestTemplate來呼叫服務,計算10 + 20的值。

@RestController
public class ConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    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功能,具體如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {

	public static void main(String[] args) {
		SpringApplication.run(FeignApplication.class, args);
	}

}

定義compute-service服務的介面,具體如下:

@FeignClient("compute-service")
public interface ComputeClient {

    @RequestMapping(method = RequestMethod.GET, value = "/add")
    Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);

}
  • 使用@FeignClient("compute-service")註解來繫結該介面對應compute-service服務
  • 通過Spring MVC的註解來配置compute-service服務下的具體實現。

在web層中呼叫上面定義的ComputeClient,具體如下:

@RestController
public class ConsumerController {

    @Autowired
    ComputeClient computeClient;

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    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