SpringCloud之服務提供與呼叫(Ribbon,Feign)
本系列介紹的配置均基於 Spring Boot 2.0.1.RELEASE 版本和 Spring Cloud Finchley.SR1
eureka註冊續約流程
- 啟動註冊中心
- 服務提供者生產服務並註冊到服務中心中
- 消費者從服務中心中獲取服務並執行
</properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <finalName>producer-service</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.建立啟動類
Finchley版本已經不需要新增@EnableDiscoveryClient註解,Spring Cloud會自動識別。
@SpringBootApplication
public class ProducerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerServiceApplication.class, args);
}
}
3.配置檔案
spring.application.name=producer-service server.port=9001 #eureka eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
- spring.application.name 服務提供者的名字
- server.por 服務埠號
- eureka.client.serviceUrl.defaultZone eureka的服務註冊地址,如果eureka是多節點,多個地址逗號分隔,具體可以看上一篇部落格:服務註冊與發現。
多節點eureka服務註冊如下:
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/,http://localhost:8002/eureka/
4.Action or Controller類
@RestController @RequestMapping(value = "/test") public class ProducerAction { @RequestMapping(value = "", method = RequestMethod.GET) public String test(String param) { return "param is " + param; } }
5.啟動服務
6.呼叫下試試
param is test
服務消費 ribbon
Ribbon 了,它是一個基於 HTTP 和 TCP 的客戶端負載均衡器。它可以通過在客戶端中配置ribbonServerList 來設定服務端列表去輪詢訪問以達到均衡負載的作用。
當 Ribbon 與 Eureka聯合使用時,ribbonServerList會被DiscoveryEnabledNIWSServerList 重寫,擴充套件成從 Eureka 註冊中心中獲取服務例項列表。同時它也會用 NIWSDiscoveryPing 來取代 IPing,它將職責委託給 Eureka 來確定服務端是否已經啟動。
1.在spring-cloud-manage下建立一個子專案consumer-service
pom.xml檔案如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-manage</artifactId>
<groupId>org.springcloudmanage</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring-cloud-starter-netflix-eureka-client中已經引用了ribbon先關的jar,所需不需要再引入了
2.建立啟動類
@SpringBootApplication
public class ConsumerServiceApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
3.配置檔案
spring.application.name=consumer-service
server.port=9002
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
4.Action or Controller類
這裡注入restTemplate,Spring Cloud Ribbon 自己有攔截器會對 服務名producer-service做解析,自動的去選取服務例項負載均衡呼叫,並將服務名替換成實際要請求的IP地址和埠
@RestController
@RequestMapping(value = "/ribbon/test")
public class ConsumerAction {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "", method = RequestMethod.GET)
public String test(String param) {
String url = "http://producer-service/test/?param=" + param;
return restTemplate.getForObject(url, String.class);
}
}
5.啟動服務
消費端服務啟動成功後,可以看到erueka時已經顯示註冊成功了
5.呼叫消費端服務
param is ribbon-test
控制檯日誌
2018-08-28 16:25:23.397 INFO 3791 --- [nio-9002-exec-1] c.netflix.config.ChainedDynamicProperty : Flipping property: producer-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2018-08-28 16:25:23.414 INFO 3791 --- [nio-9002-exec-1] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-producer-service
2018-08-28 16:25:23.433 INFO 3791 --- [nio-9002-exec-1] c.netflix.loadbalancer.BaseLoadBalancer : Client: producer-service instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=producer-service,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2018-08-28 16:25:23.440 INFO 3791 --- [nio-9002-exec-1] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2018-08-28 16:25:23.462 INFO 3791 --- [nio-9002-exec-1] c.netflix.config.ChainedDynamicProperty : Flipping property: producer-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2018-08-28 16:25:23.463 INFO 3791 --- [nio-9002-exec-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client producer-service initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=producer-service,current list of Servers=[192.168.101.238:9001],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:1; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:192.168.101.238:9001; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springf[email protected]12e48993
2018-08-28 16:25:24.447 INFO 3791 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: producer-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
可以啟動多個producer-service服務測試下實際的負載均衡效果。
服務消費 feign
Feign是一個宣告式的Web Service客戶端,它使得編寫Web Serivce客戶端變得更加簡單。我們只需要使用Feign來建立一個介面並用註解來配置它既可完成。它具備可插拔的註解支援,包括Feign註解和JAX-RS註解。Feign也支援可插拔的編碼和解碼。Spring Cloud為Feign增加了對Spring MVC註解的支援,還整合了Ribbon和Eureka來提供均衡負載的HTTP客戶端實現。
在實際工作中,我們基本上都是使用Feign來完成呼叫的。我們通過一個例子來展現 Feign 如何方便的宣告對 eureka-producer 服務的定義和呼叫。
1.consumer-service新增對feign的依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-manage</artifactId>
<groupId>org.springcloudmanage</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consumer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.啟動類上加上feign所需註解
@EnableFeignClients
@SpringBootApplication
public class ConsumerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerServiceApplication.class, args);
}
}
3.配置檔案
spring.application.name=consumer-service
server.port=9002
#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
#開啟Hystrix斷路器
feign.hystrix.enabled=true
#斷路器的超時時間需要大於ribbon的超時時間,不然不會觸發重試,預設為1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
4.feign 呼叫
建立feign客戶端呼叫類,其中name為所需呼叫的服務名,fallback使用Hystrix,當producer-service不可用時,對服務做降級,並返回友好提示
@FeignClient(name = "producer-service", fallback = ProducerServiceFeignClientHystrix.class)
public interface ProducerServiceFeignClient {
@RequestMapping(value = "/test", method = RequestMethod.GET)
String test(@RequestParam("param") String param);
}
==注意@RequestParam("param")中name必須要和producer-service服務中的引數名一致==
@Component
public class ProducerServiceFeignClientHystrix implements ProducerServiceFeignClient {
@Override
public String test(String param) {
return "服務[producer-service]無法訪問";
}
}
param is feign-test
給大家推薦一個程式設計師學習交流群:863621962。群裡有分享的視訊,還有思維導圖 群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊
服務[producer-service]無法訪問