整體架構
服務規划
完整Host配置
192.168.0.12 ek1.com
192.168.0.12 ek2.com
192.168.0.12 scServer1
192.168.0.12 scServer2
192.168.0.12 scclient1
192.168.0.12 scclient2
192.168.0.12 scgateway
192.168.0.12 sczipkin
192.168.0.12 scadmin
192.168.0.12 scconfig
配置Eureka Server注冊中心(集群模式)
Host配置
192.168.0.12 ek1.com
192.168.0.12 ek2.com
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
ek1 application.properties
#服務器端口
server.port=9001
#應用名稱,高可用的兩個eureka節點必須保持一致
spring.application.name=eurekaServer
#eureka多節點配置
#是否注冊
eureka.client.enabled=true
#是否將自己注冊到其他Eureka Server,默認為true需要
eureka.client.register-with-eureka=true
#是否從eureka server獲取注冊信息, 需要
eureka.client.fetch-registry=true
#設置服務注冊中心的URL,用於client和server端交流
#此節點應向其他節點發起請求
eureka.client.serviceUrl.defaultZone=http://ek2.com:9002/eureka/
#主機名,必填
eureka.instance.hostname=ek1.com
#分組名稱
#eureka.instance.app-group-name=eurekaServerGroup
#是否開啟自我保護
eureka.server.enable-self-preservation=true
#觸發自我保護閥值
eureka.server.renewal-percent-threshold=0.85
#失效服務間隔
eureka.server.eviction-interval-timer-in-ms=6000
ek2 application.properties
#服務器端口
server.port=9002
#應用名稱,兩個eureka節點必須保持一致
spring.application.name=eurekaServer
#eureka多節點配置
#是否將自己注冊到其他Eureka Server,默認為true需要
eureka.client.register-with-eureka=true
#是否從eureka server獲取注冊信息, 需要
eureka.client.fetch-registry=true
#設置服務注冊中心的URL,用於client和server端交流
#此節點應向其他節點發起請求
eureka.client.serviceUrl.defaultZone=http://ek1.com:9001/eureka/
#主機名,必填
eureka.instance.hostname=ek2.com
#分組名稱
#eureka.instance.app-group-name=eurekaServerGroup
management.endpoint.shutdown.enabled=true
應用開啟EurekaServer
@EnableEurekaServer // 啟用Eureka服務端
EurekaServer配置優化
TODO
EurekaServer地址
配置Eureka Clients
Host配置
192.168.0.12 scServer1
192.168.0.12 scServer2
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
scServer1 application.properties
server.port=8001
spring.application.name=scServer
#eureka client config
#是否注冊
eureka.client.enabled=true
#是否將自己注冊到其他Eureka Server,默認為true需要
eureka.client.register-with-eureka=true
#是否從eureka server獲取注冊信息, 需要
eureka.client.fetch-registry=true
#設置服務注冊中心的URL,用於client和server端交流
#重要說明:client默認向配置的第1個server地址注冊,第1個注冊不成功后再依次向第2個,第3個注冊(最多重試3次)
eureka.client.serviceUrl.defaultZone=http://ek1.com:9002/eureka/,http://ek2.com:9002/eureka/
#主機名,必填
eureka.instance.hostname=scServer1
#續約發送間隔默認30秒,心跳間隔
eureka.instance.lease-renewal-interval-in-seconds=5
#表示client間隔多久去拉取服務注冊信息,默認為30秒,如果要迅速獲取服務注冊狀態,可以縮小該值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
#續約到期時間(默認90秒)
eureka.instance.lease-expiration-duration-in-seconds=90
#將實例IP注冊到Eureka Server上(多網卡適用,其他服務可通過IP訪問)
#eureka.instance.prefer-ip-address=true
#eureka.instance.ip-address=192.168.0.12
#是否開啟健康檢測,對應EurekaServer控制台的Status狀態
eureka.client.healthcheck.enabled=true
scServer2 application.properties
server.port=8002
spring.application.name=scServer
#eureka client config
#是否注冊
eureka.client.enabled=true
#是否將自己注冊到其他Eureka Server,默認為true需要
eureka.client.register-with-eureka=true
#是否從eureka server獲取注冊信息, 需要
eureka.client.fetch-registry=true
#設置服務注冊中心的URL,用於client和server端交流
#重要說明:client默認向配置的第1個server地址注冊,第1個注冊不成功后再依次向第2個,第3個注冊(最多重試3次)
eureka.client.serviceUrl.defaultZone=http://ek1.com:9002/eureka/,http://ek2.com:9002/eureka/
#主機名,必填
eureka.instance.hostname=scServer2
#續約發送間隔默認30秒,心跳間隔
eureka.instance.lease-renewal-interval-in-seconds=5
#表示client間隔多久去拉取服務注冊信息,默認為30秒,如果要迅速獲取服務注冊狀態,可以縮小該值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
#續約到期時間(默認90秒)
eureka.instance.lease-expiration-duration-in-seconds=90
#將實例IP注冊到Eureka Server上(多網卡適用,其他服務可通過IP訪問)
#eureka.instance.prefer-ip-address=true
#eureka.instance.ip-address=192.168.0.12
#是否開啟健康檢測,對應EurekaServer控制台的Status狀態
eureka.client.healthcheck.enabled=true
測試地址
- http://scserver1:8001/user/getName
- http://scserver2:8002/user/getName
- 手工下線:http://scserver1:8001/health/adjust?status=down
配置客戶端服務調用(基於RestTemplate)及負載均衡(Ribbon)
說明:
- 請參考sc-client1應用代碼實現;
- spring-cloud-starter-netflix-eureka-client依賴中已存在Ribbon依賴信息(不需要重復導包)。
RestTemplate客戶端配置
/**
* Web配置
*
* @author binglang
* @date 2021/11/24 10:44
**/
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 開啟負載均衡
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
客戶端調用
/**
* 測試RestTemplate服務調用
*/
@GetMapping(value = "/getUserNameByRestTemplate")
// 整合Hystrix配置服務降級
// @HystrixCommand(fallbackMethod = "fallback")
public String getUserNameByRestTemplate() {
String serviceUrl = "http://SCSERVER/user/getName";
String username = restTemplate.getForObject(serviceUrl, String.class);
return username;
}
測試地址
配置客戶端服務調用(基於Feign)及負載均衡(Ribbon)
說明:請參考sc-client1應用代碼實現。
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
應用開啟Feign客戶端
@EnableFeignClients
實現流程
// 二方庫sc-common定義服務公共接口
com.binglangaimo.sccommon.service.feign.ICommonUserService
// 服務提供方sc-server1,sc-server2必須實現此接口
com.binglangaimo.scserver1.controller.UserController
// 服務調用方sc-client1定義帶@FeignClient注解接口
com.binglangaimo.scclient1.service.TestFeignService
// 服務調用
com.binglangaimo.scclient1.controller.TestController#getUserNameByFeign()
測試地址
配置服務容錯Hystrix
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
應用開啟Hystrix斷路器
@EnableCircuitBreaker // 開啟Hystrix斷路器
應用配置
說明:參考sc-client1/src/main/resources/application.properties
#feign配置
#feign調用開啟支持hystrix斷路器
feign.hystrix.enabled=true
三種實現方式:
參考代碼實現:com.binglangaimo.scclient1.service.TestFeignService
- 請求方法上加@HystrixCommand注解
- @FeignClient(value = "SCSERVER", fallback = TestFeignServiceFallBack.class)
- @FeignClient(qualifier = "testFeignServiceClient", value = "SCSERVER", fallbackFactory = TestFeignServiceFallBackFactory.class)
配置Hystrix Dashboard
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
應用開啟Hystrix Dashboard
@EnableHystrixDashboard // 開啟Hystrix Dashboard
應用配置
#hystrix配置,不配置會報錯,參考:https://www.cnblogs.com/itsharehome/p/15628220.html
hystrix.dashboard.proxy-stream-allow-list=scclient1
#actuator監控參數
#開啟所有端點(不推薦),生產環境僅開啟需要的即可
management.endpoints.web.exposure.include=*
監控地址
配置服務跟蹤Sleuth+Zipkin
說明:需要被跟蹤的服務都需要做以下配置。可參考sc-client1實現。
原理說明
- sleuth負責收集跟蹤信息並通過http請求發送給zipkin server;
- zipkin server將跟蹤信息進行存儲(默認內存,可以配置使用mysql,ES等),以及提供RESTful API;
- zipkin ui通過調用api進行數據展示。
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
應用配置
#zipkin配置
#zipkin server地址
spring.zipkin.base-url=http://sczipkin:9411/
#采樣頻率
spring.sleuth.sampler.rate=10
下載並啟動Zipkin
// 下載命令
curl -sSL https://zipkin.io/quickstart.sh | bash -s
// 啟動zipkin
java -jar zipkin.jar
測試地址
配置服務網關Zuul
說明:請參考sc-gateway應用實現。
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
應用配置
sc-gateway/src/main/resources/application.properties
應用開啟zuul網關
@EnableZuulProxy // 開啟Zuul網關
測試地址
- http://scgateway:8888/scclient1/test/getUserNameByFeign
- http://scgateway:8888/scserver/user/getName
- 開啟前綴訪問:http://scgateway:8888/api/v1/scserver/user/getName
- 開啟監控:http://scgateway:8888/actuator/routes
配置服務配置中心Spring Cloud Config
說明:sc-config為配置中心(Config Server);sc-client2支持從配置中心獲取配置(Config client)。
config服務端
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
應用配置
重要說明:
- Config Server支持配置從本地或遠端(git or svn)獲取配置信息;
- 項目config目錄用於存儲配置信息(支持eureke client、actuator等公共配置通過include方式引入);
- Config Server配置遠端獲取配置支持SSH密鑰驗證方式,但並不支持讀取本地密鑰文件獲取密鑰信息,只能將密鑰字符串配置在應用配置文件中。我對MultipleJGitEnvironmentProperties bean進行了增強實現,使其支持此功能。
server.port=9999
spring.application.name=scConfig
#config注冊中心配置
#使用local配置
#spring.profiles.active=native
#spring.cloud.config.server.native.search-locations=file:xxx/WWW/study/springcloud/config
#使用git配置
spring.cloud.config.server.git.uri=git@gitee.com:binglangaimo/springcloud.git
spring.cloud.config.server.git.strict-host-key-checking=false
spring.cloud.config.server.git.private-key=file:C:/Users/xxx/.ssh/id_rsa #支持從本地文件中讀取密鑰信息,保證了密鑰信息的安全
spring.cloud.config.server.git.ignore-local-ssh-settings=false
spring.cloud.config.server.git.default-label=netflix
spring.cloud.config.server.git.search-paths=config
應用開啟Config Server
@EnableConfigServer
測試驗證
- local:http://scconfig:9999/scClient2/local
- git:http://scconfig:9999/netflix/scClient2-local.properties
config 客戶端
maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
應用配置(bootstrap.properties)
spring.application.name=scClient2
spring.profiles.active=local
#從注冊中心獲取配置
spring.cloud.config.uri=http://scconfig:9999
spring.cloud.config.fail-fast=true
測試獲取配置
配置服務總控Spring Boot Admin
說明:
- 參考sc-admin應用實現;
- Spring Boot Admin需要依賴於actuator收集信息,所以請將所有需要監控的服務配置actuator。
maven依賴
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
</dependency>
應用配置
server.port=8080
spring.application.name=scAdmin
#此處為eureka client公共配置,不重復粘貼了
#此處為actuator公共配置,不重復粘貼了
應用開啟AdminServer
@EnableAdminServer // 開啟Admin監控
發送釘釘消息
com.binglangaimo.scadmin.notify.DingDingNotifier實現類
測試地址
代碼倉庫
我的個人gitee-https://gitee.com/binglangaimo/springcloud。(重點申明:代碼僅供學習參考使用,未經作者授權,請勿用於商業用途)。