本系列介紹的配置均基于 Spring Boot 2.0.1.RELEASE 版本和 Spring Cloud Finchley.SR1
eureka注冊續(xù)約流程
啟動注冊中心
服務(wù)提供者生產(chǎn)服務(wù)并注冊到服務(wù)中心中
消費者從服務(wù)中心中獲取服務(wù)并執(zhí)行
服務(wù)提供
1.在spring-cloud-manage下創(chuàng)建一個子項目producer-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>producer-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>
? ? ? ? <finalName>producer-service</finalName>
? ? ? ? <plugins>
? ? ? ? ? ? <plugin>
? ? ? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? ? ? <artifactId>spring-boot-maven-plugin</artifactId>
? ? ? ? ? ? </plugin>
? ? ? ? </plugins>
? ? </build>
</project>
2.創(chuàng)建啟動類
Finchley版本已經(jīng)不需要添加@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服務(wù)提供者的名字
server.por服務(wù)端口號
eureka.client.serviceUrl.defaultZoneeureka的服務(wù)注冊地址,如果eureka是多節(jié)點,多個地址逗號分隔,具體可以看上一篇博客:服務(wù)注冊與發(fā)現(xiàn)。
多節(jié)點eureka服務(wù)注冊如下:
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.啟動服務(wù)
服務(wù)啟動后,訪問eureka主頁http://localhost:8001/,即可看到如下頁面,說明服務(wù)已經(jīng)注冊到eureka上了?
6.調(diào)用下試試
訪問http://localhost:9001/test?param=test,看到返回結(jié)果如下
param is test
服務(wù)消費 ribbon
Ribbon 了,它是一個基于 HTTP 和 TCP 的客戶端負(fù)載均衡器。它可以通過在客戶端中配置ribbonServerList 來設(shè)置服務(wù)端列表去輪詢訪問以達(dá)到均衡負(fù)載的作用。
當(dāng) Ribbon 與 Eureka聯(lián)合使用時,ribbonServerList會被DiscoveryEnabledNIWSServerList 重寫,擴(kuò)展成從 Eureka 注冊中心中獲取服務(wù)實例列表。同時它也會用 NIWSDiscoveryPing 來取代 IPing,它將職責(zé)委托給 Eureka 來確定服務(wù)端是否已經(jīng)啟動。
1.在spring-cloud-manage下創(chuàng)建一個子項目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中已經(jīng)引用了ribbon先關(guān)的jar,所需不需要再引入了
2.創(chuàng)建啟動類
@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 自己有攔截器會對 服務(wù)名producer-service做解析,自動的去選取服務(wù)實例負(fù)載均衡調(diào)用,并將服務(wù)名替換成實際要請求的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.啟動服務(wù)
消費端服務(wù)啟動成功后,可以看到erueka時已經(jīng)顯示注冊成功了
5.調(diào)用消費端服務(wù)
訪問http://localhost:9002/ribbon/test?param=ribbon-test?,可以看到如下結(jié)果,說明消費端服務(wù)接收到參數(shù)后,通過ribbon負(fù)載均衡,調(diào)用到producer-service的接口。
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.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@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服務(wù)測試下實際的負(fù)載均衡效果。
服務(wù)消費 feign
Feign是一個聲明式的Web Service客戶端,它使得編寫Web Serivce客戶端變得更加簡單。我們只需要使用Feign來創(chuàng)建一個接口并用注解來配置它既可完成。它具備可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的編碼和解碼。Spring Cloud為Feign增加了對Spring MVC注解的支持,還整合了Ribbon和Eureka來提供均衡負(fù)載的HTTP客戶端實現(xiàn)。
在實際工作中,我們基本上都是使用Feign來完成調(diào)用的。我們通過一個例子來展現(xiàn) Feign 如何方便的聲明對 eureka-producer 服務(wù)的定義和調(diào)用。
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的超時時間,不然不會觸發(fā)重試,缺省為1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
4.feign 調(diào)用
創(chuàng)建feign客戶端調(diào)用類,其中name為所需調(diào)用的服務(wù)名,fallback使用Hystrix,當(dāng)producer-service不可用時,對服務(wù)做降級,并返回友好提示
@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服務(wù)中的參數(shù)名一致==
@Component
public class ProducerServiceFeignClientHystrix implements ProducerServiceFeignClient {
? ? @Override
? ? public String test(String param) {
? ? ? ? return "服務(wù)[producer-service]無法訪問";
? ? }
}
訪問http://localhost:9002/feign/test?param=feign-test,可以看到如下結(jié)果
param is feign-test
停止producer-service,再次訪問http://localhost:9002/feign/test?param=feign-test,可以看到如下結(jié)果,說明fallback已經(jīng)生效了
服務(wù)[producer-service]無法訪問
歡迎工作一到五年的Java工程師朋友們加入Java程序員開發(fā): 721575865
群內(nèi)提供免費的Java架構(gòu)學(xué)習(xí)資料(里面有高可用、高并發(fā)、高性能及分布式、Jvm性能調(diào)優(yōu)、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構(gòu)資料)合理利用自己每一分每一秒的時間來學(xué)習(xí)提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!