Spring-Cloud簡易全家桶實踐
目標組合為:Eureka+Ribbon+Feign+Hystrix+Actuator+Dashboard+Config+Zuul
此處只為基本使用的關鍵點和范例的解讀,源碼閱讀后續再補充
注意點:
1.注意使用的spring-cloud的各個組件的版本需要能對應
這里有一個可能有坑的地方是,各個組件間或多或少會有依賴,實踐時因為倉庫受限緣故,選用的啟動器或組件有時候會因為倉庫中下載不到而手動切換版本,如果切換的版本有不兼容,代碼明面上不會有提示(很坑),但是對應組件就是不會生效(很坑double)。印象中maven-repository有依賴的最低版本提示的,但是當前用ali系不能訪問這個倉庫,用ali倉庫雖然包的樹結構很優雅,但是並沒有找到有提示版本最低依賴的地方(這里demo偷懶的解決版本是都采用最新版本)。這里有嘗試用IDEA+maven多倉庫來解決,但是嘗試了幾次,setting中的多倉庫配置在IDEA中未能生效,這里后續還要研究下。(可以考慮用maven本身不加IDEA來解決這個問題)
當前demo的版本依賴如下:
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<starter.version>1.4.7.RELEASE</starter.version>
2.spring-cloud組件本身有更迭,所使用的配置方式可能版本間存在差異
1和2點個人覺得也是部分公司不選用全套Spring-Cloud的緣由。因為存在版本依賴和配置更迭問題,Spring-Cloud雖然開箱即用,但是版本更迭中可能會存在較大修改(比如配置這種)。如果公司本身場景很復雜,要面對很多極限情況,最好使用自己團隊能完全把控和修改的框架。(當然,不選用全套並不意味着一個不選,不學習其精華)
Eureka關鍵點:
Eureka是做服務注冊的,Eureka保證了CAP(C:強一致性,A:高可用性,P:分區容錯性,三者中能選2)中的AP(如果一個服務掛掉,不會立馬被同步,也就是無法保證P)。Zookeeper保證了CP(Zookeeper的一個問題是,如果master節點掛掉, 重新選舉過程中服務會不可用,服務癱瘓,也就是沒法保證A)。
Eureka分服務器和客戶端的概念
服務器:
服務器當前范例為單獨部署,依賴和配置如下(私以為單獨部署的方式很費解....)
依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
配置示范:(不做過多解讀,閱讀源碼時再來詳細解讀)
server:
port: 7001
eureka:
instance:
hostname: eurka7001.com
client:
registerWithEureka: false
fetchRegistry: false
service-url:
defaultZone: http://127.0.0.1:7002/eureka,http://127.0.0.1:7003/eureka/
spring:
application:
name: eurekaserver01
啟動注解:
@EnableEurekaServer
客戶端:
依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
配置示范:
eureka:
client: #客戶端注冊進eureka服務列表內
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/,http://127.0.0.1:7003/eureka/
instance:
instance-id: provider01-x
prefer-ip-address: true #訪問路徑可以顯示IP地址
啟動注解:
@EnableEurekaClient
@EnableDiscoveryClient //印象中這個也是必要的,尚未閱讀源碼還不太確定
Ribbon關鍵點:
Ribbon用於做客戶端負載均衡,此處沒有單獨用,而是集合Feign一起用
依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
使用方式:
@Configuration
public class ConfigBean //boot -->spring applicationContext.xml --- @Configuration配置 ConfigBean = applicationContext.xml
{
@Bean
@LoadBalanced//Spring Cloud Ribbon是基於Netflix Ribbon實現的一套客戶端 負載均衡的工具。
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Bean
public IRule myRule() {
//return new RoundRobinRule();
return new RandomRule();//達到的目的,用我們重新選擇的隨機算法替代默認的輪詢。
// return new RetryRule();
}
}
注意:
@RibbonClient可以對指定實例做定制化的負載均衡(但是這里有一個坑,這里定制化指定的規則類不能被Spring自動掃描到,否則會成為所有實例通用的負載均衡規則)
Feign關鍵點
Feign是一個http請求的輕量級調度框架。
依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
使用Feign首先要能發現服務(這里使用Eureka的服務發現,對應代碼就不在這里寫了),通常也會和hystrix一起使用
使用代碼
@FeignClient(value = "PROVIDER-01"
, fallbackFactory = TestServiceFallbackFactory.class
)
public interface TestService {
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String pringTest();
}
配置項:
feign:
hystrix:
enabled: true
Hystrix關鍵點
Hystrix是斷路器的意思,主要用於添加延遲容忍和容錯邏輯。另外Hystrix好像也是可以和Hystrix-dashboard一起使用來做分布式服務數據的監控
依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
使用:
@FeignClient(value = "PROVIDER-01"
, fallbackFactory = TestServiceFallbackFactory.class
)
@Component //注意這里要組件化
public class TestServiceFallbackFactory implements FallbackFactory<TestService> {
@Override
public TestService create(Throwable throwable) {
return new TestService() {
@Override
public String pringTest() {
return "大爺呀,出錯了呀!沒服務可用了呀";
}
};
}
}
Hystrix-Dashboard關鍵點
很可恥的木有搞成功,是單服務簡單部署,但是抓取不到服務。看了一下對應的集成了hystrix端,也沒有對應的服務信息。應該還是在版本或者配置上有問題導致的服務端沒有注冊hystrix信息,所以dashboard這邊采集不到導致的。具體問題后續看源碼時再來解決。
Actuator關鍵點
這個就可以認為是一個工具包,提供對於實例信息的補充信息定制
依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
使用范例:
info:
app.name: test-provider
company.name: www.test.com
build.artifactId: $project.artifactId$
build.version: $project.version$
Config
尚未實踐
Zuul
依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<!-- 這個不能少,不然發現不了服務的 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
配置:
# Eureka的配置信息就不在這里寫了
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/,http://127.0.0.1:7003/eureka/
instance:
instance-id: test-zuul
prefer-ip-address: true
zuul:
prefix: /
ignored-services: "*"
routes:
test:
serviceId: providername #注意這里是對應暴露服務的spring.application.name
path: /test/**
開啟標簽
@EnableZuulProxy
這里如果不引入Eureka的依賴會有
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: providername
的報錯。如果配置寫錯會有其他奇奇怪怪的(比如訪問eureka配置寫錯的話,會自動訪問到默認的eureka地址去,也就是128.0.0.1:8761上.... 囧囧,不要問我為什么會知道...)
總結
整體感覺全家桶可配置化程度比較高,做簡單demo實踐的過程還算比較容易。但也正因為可配置化程度較高,意味着要想做到較高的定制化,需要對於底層有一定的了解才行。