SpringCloud是目前微服務(wù)轉(zhuǎn)型的首選,主要得益于其活躍的社區(qū)支持度以及全量的配套組件,本章筆者將會(huì)把SpringCloud Netfix的幾個(gè)核心組件組合起來(lái),和老鐵們一起逐步完成全套的應(yīng)用框架搭建,這樣有需要的老鐵們?cè)陧?xiàng)目中就可以直接使用啦。
在SpringCloud Netfix中,核心的組件包括:注冊(cè)中心(Eureka)、負(fù)載均衡(Ribbon)、服務(wù)調(diào)用(Feign)、熔斷及降級(jí)(Hystrix)、網(wǎng)關(guān)(Gateway)、配置中心(Config)、鏈路追蹤(Sleuth)等幾大組件。我們都知道SpringCloud是基于SpringBoot整出來(lái)的微服務(wù)框架,換言之在開(kāi)發(fā)SpringCloud微服務(wù)的時(shí)候,咱就少不了要使用SpringBoot,所以這里的整合SpringCloud也就遵循了SpringBoot的某種整合的規(guī)范,比如對(duì)于依賴(lài)的引用就遵守:spring-cloud-starter-xxx這種規(guī)范,這里的xxx值得就是咱們使用的組件,比如如果咱們需要整合Ribbon,那它的依賴(lài)名稱(chēng)就是spring-cloud-starter-netflix-ribbon。
首先筆者將應(yīng)用的整體情況做如下介紹:
1.應(yīng)用的整體架構(gòu)圖:

2.使用的SpringCloud的版本是Hoxton.SR9,老鐵們可以根據(jù)自己需要選擇版本。
3.微服務(wù)的代碼層級(jí)關(guān)系

其中parent為所有模塊的父依賴(lài),主要管理公共依賴(lài);common是各個(gè)模塊都需要用到的一些通用類(lèi);springcloud-demo-eureka-service則是eureka注冊(cè)中心以及配置中心;global-gateway是網(wǎng)關(guān);order-demo和product-demo是具體的服務(wù)。
4.JDK版本筆者用的是JDK1.8。
5.需要提前下載zipkin服務(wù),下載地址大家到網(wǎng)上搜,下載后執(zhí)行:java -jar zipkin.jar啟動(dòng)即可,然后訪問(wèn):http://localhost:9411/zipkin/看看能否正常訪問(wèn),正常情況下訪問(wèn)顯示如下:

6.登錄到github上,創(chuàng)建一個(gè)服務(wù),比如筆者這里創(chuàng)建了springcloud-demo-config的服務(wù),用于存放配置文件。
7.啟動(dòng)順序:注冊(cè)中心和配置中心->服務(wù)提供者->消費(fèi)者->網(wǎng)關(guān)。
接下來(lái)就看每個(gè)模塊的代碼了:
1.parent
parent的主要作用是管理公共的依賴(lài),核心就是一個(gè)pom.xml文件,需要注意的是,它的parent是spring-boot-starter-parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.6.RELEASE</version>
</parent>
<groupId>my.springcloud.demo</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<modules>
<module>product-demo</module>
<module>springcloud-demo-eureka-service</module>
<module>order-demo</module>
<module>springcloud-demo-eureka-service2</module>
<module>common</module>
<module>global-gateway</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>my.springcloud.demo</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.eureka+config
該模塊主要是注冊(cè)中心和配置中心。
2.1.依賴(lài)
<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-server</artifactId>
</dependency>
<!--config server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
它主要的兩個(gè)依賴(lài)是spring-cloud-config-server和spring-cloud-starter-netflix-eureka-server。
2.2.配置文件
它的配置文件application.properties如下:
server.port=8761
spring.application.name=springcloud-demo-eureka-service
#最好取個(gè)名字,方便區(qū)分
eureka.instance.instance-id=springclouddemo1.com
#false不注冊(cè)自己,當(dāng)然也可以設(shè)置為true,注冊(cè)自己
eureka.client.register-with-eureka=false
#config服務(wù)使用git存儲(chǔ)數(shù)據(jù),這里配置git倉(cāng)庫(kù)的地址
spring.cloud.config.server.git.uri=https://github.com/xxxx/springcloud-demo-config.git
spring.cloud.config.server.git.username=xxxxxx@126.com
spring.cloud.config.server.git.password=xxxxxxxx
#指定倉(cāng)庫(kù)分支
spring.cloud.config.server.git.default-label=master
eureka.instance.prefer-ip-address=true
2.3.啟動(dòng)類(lèi)注解
在啟動(dòng)類(lèi)上增加三個(gè)注解:@EnableEurekaServer @SpringBootApplication @EnableConfigServer。
3.gateway
網(wǎng)關(guān)作為作為應(yīng)用的入口,它的主要作用就是請(qǐng)求轉(zhuǎn)發(fā)、統(tǒng)一驗(yàn)證、路由、限流等,這里我們通過(guò)網(wǎng)關(guān)向后臺(tái)應(yīng)用轉(zhuǎn)發(fā)。作為訪問(wèn)的入口,網(wǎng)關(guān)同時(shí)也應(yīng)該是調(diào)用鏈路的發(fā)起者。
3.1.依賴(lài)
<!--服務(wù)發(fā)現(xiàn)eureka client依賴(lài)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--網(wǎng)關(guān)依賴(lài)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--調(diào)用鏈路依賴(lài)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--config client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
3.2.在配置文件bootstrap.yml中指定配置服務(wù)
spring:
application:
name: global-gateway
cloud:
config:
uri: http://localhost:8761
label: master
3.3.遠(yuǎn)程倉(cāng)庫(kù)配置文件
這里我們使用的是配置中心的遠(yuǎn)程配置,所以在git倉(cāng)庫(kù)的springcloud-demo-config.git應(yīng)用下,添加gateway的配置文件:global-gateway-${active}.properties,指定注冊(cè)中心、zipkin的地址,同時(shí)配置網(wǎng)關(guān)自動(dòng)發(fā)現(xiàn),內(nèi)容如下:
spring.application.name=global-gateway
server.port=9006
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
#配置網(wǎng)關(guān)自動(dòng)發(fā)現(xiàn)
spring.cloud.gateway.discovery.locator.enabled=true
spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1
3.4.啟動(dòng)類(lèi)注解
然后在啟動(dòng)類(lèi)上添加如下注解:
@SpringBootApplication
@EnableDiscoveryClient
通過(guò)網(wǎng)關(guān)訪問(wèn)時(shí)通過(guò)指定服務(wù)名和服務(wù)URL,如:
??http://localhost:9006/ORDER-DEMO/order/getOrder?id=1??
4.商品服務(wù)
作為具體的服務(wù)提供者,它需要往注冊(cè)中心注冊(cè)服務(wù);
同時(shí)需要從配置中心讀取配置文件,也就是作為配置服務(wù)的客戶(hù)端;
上報(bào)調(diào)用鏈路數(shù)據(jù);
4.1.依賴(lài)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--熔斷-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--調(diào)用鏈路依賴(lài)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--config client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
4.2.在配置文件bootstrap.yml中指定配置服務(wù)
spring:
application:
name: product-demo
cloud:
config:
uri: http://localhost:8761
label: master
4.3.遠(yuǎn)程倉(cāng)庫(kù)配置文件
這里我們使用的是配置中心的遠(yuǎn)程配置,所以在git倉(cāng)庫(kù)的springcloud-demo-config.git應(yīng)用下,添加商品服務(wù)的配置文件:product-demo-${active}.properties
spring.application.name=product-demo
eureka.instance.instance-id=productdemo
eureka.instance.hostname=localhost
server.port=8080
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
management.endpoint.info.enabled=true
management.endpoints.web.exposure.include=*
management.endpoint.health.enabled=true
management.endpoint.health.show-details=always
management.endpoint.shutdown.enabled = true
info.app.name=productDemo
info.company.name=test
info.test.tt=this is product
spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1
4.4.啟動(dòng)類(lèi)注解
如果需要開(kāi)啟熔斷,則需要在啟動(dòng)類(lèi)上增加注解:SpringBootApplication和EnableCircuitBreaker
5.訂單服務(wù)
同商品服務(wù)類(lèi)似,但是它需要消費(fèi)商品服務(wù),作為服務(wù)的消費(fèi)者,它需要往注冊(cè)中心注冊(cè)服務(wù),同時(shí)需要從注冊(cè)中心同步服務(wù)信息;
同時(shí)需要從配置中心讀取配置文件,也就是作為配置服務(wù)的客戶(hù)端;
上報(bào)調(diào)用鏈路數(shù)據(jù);
5.1.依賴(lài)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--熔斷依賴(lài)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--調(diào)用鏈路依賴(lài)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--config client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
5.2.在配置文件bootstrap.yml中指定配置服務(wù)
spring:
application:
name: order-demo
cloud:
config:
uri: http://localhost:8761
label: master
5.3.遠(yuǎn)程倉(cāng)庫(kù)配置文件
這里我們使用的是配置中心的遠(yuǎn)程配置,所以在git倉(cāng)庫(kù)的springcloud-demo-config.git應(yīng)用下,添加商品服務(wù)的配置文件:product-demo-${active}.properties
spring.application.name=order-demo
server.port=8081
eureka.instance.hostname=localhost
eureka.instance.instance-id=orderdemo
management.endpoint.info.enabled=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
#zipkin
spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1
5.4.啟動(dòng)類(lèi)注解
如果需要開(kāi)啟熔斷,則需要在啟動(dòng)類(lèi)上增加注解:
@SpringBootApplication
@EnableHystrix
如果微服務(wù)調(diào)用使用Feign,則還需要增加@EnableFeignClients注解,并且添加接口,同時(shí)在接口上添加FeignClient注解,如筆者這里將調(diào)用PRODUCT-DEMO服務(wù):
@FeignClient("PRODUCT-DEMO")
public interface ProductFeignService {
@RequestMapping("/product/getProduct")
public Product getProduct(@RequestParam(value="id") Integer id);
}
當(dāng)然如果是想使用Ribbon調(diào)用,則需要在配置類(lèi)中增加如下代碼:
@Bean
@LoadBalanced
public RestTemplate createRestTemplate(){
return new RestTemplate();
}
使用時(shí),直接通過(guò)如下注解方式直接注入即可使用:
@Autowired
private RestTemplate restTemplate;
然后編寫(xiě)其他代碼,完成服務(wù)之間的調(diào)用,這里筆者想對(duì)熔斷的使用啰嗦兩句,發(fā)送熔斷的地方有兩個(gè)地方:一個(gè)是服務(wù)提供方,當(dāng)服務(wù)出現(xiàn)異常情況時(shí),服務(wù)本身可以觸發(fā)熔斷,直接返回統(tǒng)一的錯(cuò)誤;另外一個(gè)是消費(fèi)方,這種情況下熔斷有了另外一個(gè)名詞,也叫降級(jí),一般是服務(wù)方不能正常提供服務(wù),比如訪問(wèn)超時(shí),或者主動(dòng)斷開(kāi)服務(wù)的情況下,消費(fèi)方做出的反應(yīng),這種壓根就不會(huì)向服務(wù)提供方發(fā)起請(qǐng)求。
所有代碼完成后,以此啟動(dòng),然后通過(guò)網(wǎng)關(guān)訪問(wèn),然后登錄http://localhost:9411/,可以查看整體的調(diào)用依賴(lài)和調(diào)用鏈路信息,至此整體搭建完成。