0.學習目標
- 會配置Hystix熔斷
- 會使用Feign進行遠程調(diào)用
- 能獨立搭建Zuul網(wǎng)關
- 能編寫Zuul的攔截器
1.Hystix
1.1.簡介
Hystix赴捞,即熔斷器可很。
主頁:https://github.com/Netflix/Hystrix/
Hystix是Netflix開源的一個延遲和容錯庫睛驳,用于隔離訪問遠程服務蒜田、第三方庫稿械,防止出現(xiàn)級聯(lián)失敗。
1.2.熔斷器的工作機制:
正常工作的情況下冲粤,客戶端請求調(diào)用服務API接口:
當有服務出現(xiàn)異常時溜哮,直接進行失敗回滾,服務降級處理:
當服務繁忙時色解,如果服務出現(xiàn)異常茂嗓,不是粗暴的直接報錯,而是返回一個友好的提示科阎,雖然拒絕了用戶的訪問述吸,但是會返回一個結(jié)果。
這就好比去買魚锣笨,平常超市買魚會額外贈送殺魚的服務蝌矛。等到逢年過節(jié),超時繁忙時错英,可能就不提供殺魚服務了入撒,這就是服務的降級。
系統(tǒng)特別繁忙時椭岩,一些次要服務暫時中斷茅逮,優(yōu)先保證主要服務的暢通,一切資源優(yōu)先讓給主要服務來使用判哥,在雙十一献雅、618時,京東天貓都會采用這樣的策略塌计。
1.3.動手實踐
1.3.1.引入依賴
首先在user-consumer中引入Hystix依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
1.3.2.開啟熔斷
1.3.2.改造消費者
我們改造user-consumer挺身,添加一個用來訪問的user服務的DAO,并且聲明一個失敗時的回滾處理函數(shù):
@Component
public class UserDao {
@Autowired
private RestTemplate restTemplate;
private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
@HystrixCommand(fallbackMethod = "queryUserByIdFallback")
public User queryUserById(Long id){
long begin = System.currentTimeMillis();
String url = "http://user-service/user/" + id;
User user = this.restTemplate.getForObject(url, User.class);
long end = System.currentTimeMillis();
// 記錄訪問用時:
logger.info("訪問用時:{}", end - begin);
return user;
}
public User queryUserByIdFallback(Long id){
User user = new User();
user.setId(id);
user.setName("用戶信息查詢出現(xiàn)異常锌仅!");
return user;
}
}
-
@HystrixCommand(fallbackMethod="queryUserByIdFallback")
:聲明一個失敗回滾處理函數(shù)queryUserByIdFallback章钾,當queryUserById執(zhí)行超時(默認是1000毫秒)墙贱,就會執(zhí)行fallback函數(shù),返回錯誤提示贱傀。 - 為了方便查看熔斷的觸發(fā)時機嫩痰,我們記錄請求訪問時間。
在原來的業(yè)務邏輯中調(diào)用這個DAO:
@Service
public class UserService {
@Autowired
private UserDao userDao;
public List<User> queryUserByIds(List<Long> ids) {
List<User> users = new ArrayList<>();
ids.forEach(id -> {
// 我們測試多次查詢窍箍,
users.add(this.userDao.queryUserById(id));
});
return users;
}
}
1.3.3.改造服務提供者
改造服務提供者,隨機休眠一段時間丽旅,以觸發(fā)熔斷:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id) throws InterruptedException {
// 為了演示超時現(xiàn)象椰棘,我們在這里然線程休眠,時間隨機 0~2000毫秒
Thread.sleep(new Random().nextInt(2000));
return this.userMapper.selectByPrimaryKey(id);
}
}
1.3.4.啟動測試
然后運行并查看日志:
id為9、10榄笙、11的訪問時間分別是:
id為12的訪問時間:
因此,只有12是正常訪問,其它都會觸發(fā)熔斷拄查,我們來查看結(jié)果:
1.3.5.優(yōu)化
雖然熔斷實現(xiàn)了,但是我們的重試機制似乎沒有生效,是這樣嗎匠抗?
其實這里是因為我們的Ribbon超時時間設置的是1000ms:
?而Hystix的超時時間默認也是1000ms射赛,因此重試機制沒有被觸發(fā)秆麸,而是先觸發(fā)了熔斷坷随。
所以房铭,Ribbon的超時時間一定要小于Hystix的超時時間。
我們可以通過hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
來設置Hystrix超時時間温眉。
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMillisecond: 6000 # 設置hystrix的超時時間為6000ms
2.Feign
在前面的學習中缸匪,我們使用了Ribbon的負載均衡功能,大大簡化了遠程調(diào)用時的代碼:
String baseUrl = "http://user-service/user/";
User user = this.restTemplate.getForObject(baseUrl + id, User.class)
如果就學到這里类溢,你可能以后需要編寫類似的大量重復代碼豪嗽,格式基本相同,無非參數(shù)不一樣豌骏。有沒有更優(yōu)雅的方式龟梦,來對這些代碼再次優(yōu)化呢?
這就是我們接下來要學的Feign的功能了窃躲。
2.1.簡介
有道詞典的英文解釋:
?為什么叫偽裝计贰?
Feign可以把Rest的請求進行隱藏,偽裝成類似SpringMVC的Controller一樣蒂窒。你不用再自己拼接url躁倒,拼接參數(shù)等等操作,一切都交給Feign去做洒琢。
項目主頁:https://github.com/OpenFeign/feign
2.2.快速入門
2.2.1.導入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2.2.Feign的客戶端
@FeignClient("user-service")
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
- 首先這是一個接口秧秉,F(xiàn)eign會通過動態(tài)代理,幫我們生成實現(xiàn)類衰抑。這點跟mybatis的mapper很像
-
@FeignClient
象迎,聲明這是一個Feign客戶端,類似@Mapper
注解。同時通過value
屬性指定服務名稱 - 接口中的定義方法砾淌,完全采用SpringMVC的注解啦撮,F(xiàn)eign會根據(jù)注解幫我們生成URL,并訪問獲取結(jié)果
改造原來的調(diào)用邏輯汪厨,不再調(diào)用UserDao:
@Service
public class UserService {
@Autowired
private UserFeignClient userFeignClient;
public List<User> queryUserByIds(List<Long> ids) {
List<User> users = new ArrayList<>();
ids.forEach(id -> {
// 我們測試多次查詢赃春,
users.add(this.userFeignClient.queryUserById(id));
});
return users;
}
}
2.2.3.開啟Feign功能
我們在啟動類上,添加注解劫乱,開啟Feign功能
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients // 開啟Feign功能
public class UserConsumerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
- 你會發(fā)現(xiàn)RestTemplate的注冊被我刪除了织中。Feign中已經(jīng)自動集成了Ribbon負載均衡,因此我們不需要自己定義RestTemplate了
2.2.4.啟動測試:
訪問接口:
正常獲取到了結(jié)果衷戈。
2.3.負載均衡
Feign中本身已經(jīng)集成了Ribbon依賴和自動配置:
?因此我們不需要額外引入依賴狭吼,也不需要再注冊RestTemplate
對象。
另外脱惰,我們可以像上節(jié)課中講的那樣去配置Ribbon,可以通過ribbon.xx
來進行全局配置窿春。也可以通過服務名.ribbon.xx
來對指定服務配置:
user-service:
ribbon:
ConnectTimeout: 250 # 連接超時時間(ms)
ReadTimeout: 1000 # 通信超時時間(ms)
OkToRetryOnAllOperations: true # 是否對所有操作重試
MaxAutoRetriesNextServer: 1 # 同一服務不同實例的重試次數(shù)
MaxAutoRetries: 1 # 同一實例的重試次數(shù)
2.4.Hystix支持
Feign默認也有對Hystix的集成:
?只不過拉一,默認情況下是關閉的。我們需要通過下面的參數(shù)來開啟:
feign:
hystrix:
enabled: true # 開啟Feign的熔斷功能
但是旧乞,F(xiàn)eign中的Fallback配置不像Ribbon中那樣簡單了蔚润。
1)首先,我們要定義一個類尺栖,實現(xiàn)剛才編寫的UserFeignClient嫡纠,作為fallback的處理類
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public User queryUserById(Long id) {
User user = new User();
user.setId(id);
user.setName("用戶查詢出現(xiàn)異常!");
return user;
}
}
2)然后在UserFeignClient中延赌,指定剛才編寫的實現(xiàn)類
@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
3)重啟測試:
我們關閉user-service服務除盏,然后在頁面訪問:
2.5.請求壓縮(了解)
Spring Cloud Feign 支持對請求和響應進行GZIP壓縮,以減少通信過程中的性能損耗挫以。通過下面的參數(shù)即可開啟請求與響應的壓縮功能:
feign:
compression:
request:
enabled: true # 開啟請求壓縮
response:
enabled: true # 開啟響應壓縮
同時者蠕,我們也可以對請求的數(shù)據(jù)類型,以及觸發(fā)壓縮的大小下限進行設置:
feign:
compression:
request:
enabled: true # 開啟請求壓縮
mime-types: text/html,application/xml,application/json # 設置壓縮的數(shù)據(jù)類型
min-request-size: 2048 # 設置觸發(fā)壓縮的大小下限
注:上面的數(shù)據(jù)類型掐松、壓縮大小下限均為默認值踱侣。
2.6.日志級別(了解)
前面講過,通過logging.level.xx=debug
來設置日志級別大磺。然而這個對Fegin客戶端而言不會產(chǎn)生效果抡句。因為@FeignClient
注解修改的客戶端在被代理時,都會創(chuàng)建一個新的Fegin.Logger實例杠愧。我們需要額外指定這個日志的級別才可以待榔。
1)設置com.leyou包下的日志級別都為debug
logging:
level:
com.leyou: debug
2)編寫配置類,定義日志級別
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
這里指定的Level級別是FULL流济,F(xiàn)eign支持4種級別:
?- NONE:不記錄任何日志信息究抓,這是默認值猾担。
- BASIC:僅記錄請求的方法,URL以及響應狀態(tài)碼和執(zhí)行時間
- HEADERS:在BASIC的基礎上刺下,額外記錄了請求和響應的頭信息
- FULL:記錄所有請求和響應的明細绑嘹,包括頭信息、請求體橘茉、元數(shù)據(jù)工腋。
3)在FeignClient中指定配置類:
@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class, configuration = FeignConfig.class)
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
4)重啟項目,即可看到每次訪問的日志:
3.Zuul網(wǎng)關
通過前面的學習畅卓,使用Spring Cloud實現(xiàn)微服務的架構(gòu)基本成型擅腰,大致是這樣的:
我們使用Spring Cloud Netflix中的Eureka實現(xiàn)了服務注冊中心以及服務注冊與發(fā)現(xiàn);而服務間通過Ribbon或Feign實現(xiàn)服務的消費以及均衡負載翁潘;通過Spring Cloud Config實現(xiàn)了應用多環(huán)境的外部化配置以及版本管理趁冈。為了使得服務集群更為健壯,使用Hystrix的融斷機制來避免在微服務架構(gòu)中個別服務出現(xiàn)異常時引起的故障蔓延拜马。
在該架構(gòu)中渗勘,我們的服務集群包含:內(nèi)部服務Service A和Service B,他們都會注冊與訂閱服務至Eureka Server俩莽,而Open Service是一個對外的服務旺坠,通過均衡負載公開至服務調(diào)用方。我們把焦點聚集在對外服務這塊扮超,直接暴露我們的服務地址取刃,這樣的實現(xiàn)是否合理,或者是否有更好的實現(xiàn)方式呢出刷?
先來說說這樣架構(gòu)需要做的一些事兒以及存在的不足:
- 首先璧疗,破壞了服務無狀態(tài)特點。
- 為了保證對外服務的安全性馁龟,我們需要實現(xiàn)對服務訪問的權(quán)限控制病毡,而開放服務的權(quán)限控制機制將會貫穿并污染整個開放服務的業(yè)務邏輯,這會帶來的最直接問題是屁柏,破壞了服務集群中REST API無狀態(tài)的特點啦膜。
- 從具體開發(fā)和測試的角度來說,在工作中除了要考慮實際的業(yè)務邏輯之外淌喻,還需要額外考慮對接口訪問的控制處理僧家。
- 其次,無法直接復用既有接口裸删。
- 當我們需要對一個即有的集群內(nèi)訪問接口八拱,實現(xiàn)外部服務訪問時,我們不得不通過在原有接口上增加校驗邏輯,或增加一個代理調(diào)用來實現(xiàn)權(quán)限控制肌稻,無法直接復用原有的接口清蚀。
面對類似上面的問題,我們要如何解決呢爹谭?答案是:服務網(wǎng)關枷邪!
為了解決上面這些問題,我們需要將權(quán)限控制這樣的東西從我們的服務單元中抽離出去诺凡,而最適合這些邏輯的地方就是處于對外訪問最前端的地方东揣,我們需要一個更強大一些的均衡負載器的 服務網(wǎng)關。
服務網(wǎng)關是微服務架構(gòu)中一個不可或缺的部分腹泌。通過服務網(wǎng)關統(tǒng)一向外系統(tǒng)提供REST API的過程中嘶卧,除了具備服務路由、均衡負載功能之外凉袱,它還具備了權(quán)限控制
等功能芥吟。Spring Cloud Netflix中的Zuul就擔任了這樣的一個角色,為微服務架構(gòu)提供了前門保護的作用专甩,同時將權(quán)限控制這些較重的非業(yè)務邏輯內(nèi)容遷移到服務路由層面钟鸵,使得服務集群主體能夠具備更高的可復用性和可測試性。
3.1.簡介
官網(wǎng):https://github.com/Netflix/zuul
?Zuul:維基百科:
電影《捉鬼敢死隊》中的怪獸配深,Zuul携添,在紐約引發(fā)了巨大騷亂嫁盲。
事實上篓叶,在微服務架構(gòu)中,Zuul就是守門的大Boss羞秤!一夫當關缸托,萬夫莫開!
3.2.Zuul加入后的架構(gòu)
- 不管是來自于客戶端(PC或移動端)的請求瘾蛋,還是服務內(nèi)部調(diào)用俐镐。一切對服務的請求都會經(jīng)過Zuul這個網(wǎng)關,然后再由網(wǎng)關來實現(xiàn) 鑒權(quán)哺哼、動態(tài)路由等等操作佩抹。Zuul就是我們服務的統(tǒng)一入口。
3.3.快速入門
3.3.1.新建工程
填寫基本信息:
添加Zuul依賴:
3.3.2.編寫啟動類
通過@EnableZuulProxy
注解開啟Zuul的功能:
@SpringBootApplication
@EnableZuulProxy // 開啟Zuul的網(wǎng)關功能
public class ZuulDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulDemoApplication.class, args);
}
}
3.3.3.編寫配置
server:
port: 10010 #服務端口
spring:
application:
name: api-gateway #指定服務名
3.3.4.編寫路由規(guī)則
我們需要用Zuul來代理user-service服務取董,先看一下控制面板中的服務狀態(tài):
- ip為:127.0.0.1
- 端口為:8081
映射規(guī)則:
zuul:
routes:
user-service: # 這里是路由id棍苹,隨意寫
path: /user-service/** # 這里是映射路徑
url: http://127.0.0.1:8081 # 映射路徑對應的實際url地址
我們將符合path
規(guī)則的一切請求,都代理到 url
參數(shù)指定的地址
本例中茵汰,我們將 /user-service/**
開頭的請求枢里,代理到http://127.0.0.1:8081
3.3.5.啟動測試:
訪問的路徑中需要加上配置規(guī)則的映射路徑,我們訪問:http://127.0.0.1:8081/user-service/user/10
?3.4.面向服務的路由
在剛才的路由規(guī)則中,我們把路徑對應的服務地址寫死了栏豺!如果同一服務有多個實例的話彬碱,這樣做顯然就不合理了。
我們應該根據(jù)服務的名稱奥洼,去Eureka注冊中心查找 服務對應的所有實例列表巷疼,然后進行動態(tài)路由才對!
3.4.1.添加Eureka客戶端依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
3.4.2.開啟Eureka客戶端發(fā)現(xiàn)功能
@SpringBootApplication
@EnableZuulProxy // 開啟Zuul的網(wǎng)關功能
@EnableDiscoveryClient
public class ZuulDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulDemoApplication.class, args);
}
}
3.4.3.添加Eureka配置溉卓,獲取服務信息
eureka:
client:
registry-fetch-interval-seconds: 5 # 獲取服務列表的周期:5s
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
3.4.4.修改映射配置皮迟,通過服務名稱獲取
因為已經(jīng)有了Eureka客戶端,我們可以從Eureka獲取服務的地址信息桑寨,因此映射時無需指定IP地址伏尼,而是通過服務名稱來訪問,而且Zuul已經(jīng)集成了Ribbon的負載均衡功能尉尾。
zuul:
routes:
user-service: # 這里是路由id爆阶,隨意寫
path: /user-service/** # 這里是映射路徑
serviceId: user-service # 指定服務名稱
3.4.5.啟動測試
再次啟動,這次Zuul進行代理時沙咏,會利用Ribbon進行負載均衡訪問:
?日志中可以看到使用了負載均衡器:
3.5.簡化的路由配置
在剛才的配置中辨图,我們的規(guī)則是這樣的:
-
zuul.routes.<route>.path=/xxx/**
: 來指定映射路徑。<route>
是自定義的路由名 -
zuul.routes.<route>.serviceId=/user-service
:來指定服務名肢藐。
而大多數(shù)情況下故河,我們的<route>
路由名稱往往和 服務名會寫成一樣的。因此Zuul就提供了一種簡化的配置語法:zuul.routes.<serviceId>=<path>
比方說上面我們關于user-service的配置可以簡化為一條:
zuul:
routes:
user-service: /user-service/** # 這里是映射路徑
省去了對服務名稱的配置吆豹。
3.6.默認的路由規(guī)則
在使用Zuul的過程中鱼的,上面講述的規(guī)則已經(jīng)大大的簡化了配置項。但是當服務較多時痘煤,配置也是比較繁瑣的凑阶。因此Zuul就指定了默認的路由規(guī)則:
- 默認情況下,一切服務的映射路徑就是服務名本身衷快。
- 例如服務名為:
user-service
宙橱,則默認的映射路徑就是:/user-service/**
- 例如服務名為:
也就是說,剛才的映射規(guī)則我們完全不配置也是OK的蘸拔,不信就試試看师郑。
3.7.路由前綴
配置示例:
zuul:
prefix: /api # 添加路由前綴
routes:
user-service: # 這里是路由id,隨意寫
path: /user-service/** # 這里是映射路徑
service-id: user-service # 指定服務名稱
我們通過zuul.prefix=/api
來指定了路由的前綴调窍,這樣在發(fā)起請求時宝冕,路徑就要以/api開頭。
路徑/api/user-service/user/1
將會被代理到/user-service/user/1
3.8.過濾器
Zuul作為網(wǎng)關的其中一個重要功能陨晶,就是實現(xiàn)請求的鑒權(quán)猬仁。而這個動作我們往往是通過Zuul提供的過濾器來實現(xiàn)的帝璧。
3.8.1.ZuulFilter
ZuulFilter是過濾器的頂級父類。在這里我們看一下其中定義的4個最重要的方法:
public abstract ZuulFilter implements IZuulFilter{
abstract public String filterType();
abstract public int filterOrder();
boolean shouldFilter();// 來自IZuulFilter
Object run() throws ZuulException;// IZuulFilter
}
-
shouldFilter
:返回一個Boolean
值湿刽,判斷該過濾器是否需要執(zhí)行的烁。返回true執(zhí)行,返回false不執(zhí)行诈闺。 -
run
:過濾器的具體業(yè)務邏輯渴庆。 -
filterType
:返回字符串,代表過濾器的類型雅镊。包含以下4種:-
pre
:請求在被路由之前執(zhí)行 -
routing
:在路由請求時調(diào)用 -
post
:在routing和errror過濾器之后調(diào)用 -
error
:處理請求時發(fā)生錯誤調(diào)用
-
-
filterOrder
:通過返回的int值來定義過濾器的執(zhí)行順序襟雷,數(shù)字越小優(yōu)先級越高。
3.8.2.過濾器執(zhí)行生命周期:
這張是Zuul官網(wǎng)提供的請求生命周期圖,清晰的表現(xiàn)了一個請求在各個過濾器的執(zhí)行順序。
?- 正常流程:
- 請求到達首先會經(jīng)過pre類型過濾器对雪,而后到達routing類型江咳,進行路由攻礼,請求就到達真正的服務提供者,執(zhí)行請求,返回結(jié)果后,會到達post過濾器捌显。而后返回響應。
- 異常流程:
- 整個過程中总寒,pre或者routing過濾器出現(xiàn)異常扶歪,都會直接進入error過濾器,再error處理完畢后摄闸,會將請求交給POST過濾器善镰,最后返回給用戶。
- 如果是error過濾器自己出現(xiàn)異常贪薪,最終也會進入POST過濾器媳禁,而后返回眠副。
- 如果是POST過濾器出現(xiàn)異常画切,會跳轉(zhuǎn)到error過濾器,但是與pre和routing不同的時囱怕,請求不會再到達POST過濾器了霍弹。
所有內(nèi)置過濾器列表:
?3.8.3.使用場景
場景非常多:
- 請求鑒權(quán):一般放在pre類型,如果發(fā)現(xiàn)沒有訪問權(quán)限娃弓,直接就攔截了
- 異常處理:一般會在error類型和post類型過濾器中結(jié)合來處理典格。
- 服務調(diào)用時長統(tǒng)計:pre和post結(jié)合使用。
3.9.自定義過濾器
接下來我們來自定義一個過濾器台丛,模擬一個登錄的校驗耍缴±危基本邏輯:如果請求中有access-token參數(shù),則認為請求有效防嗡,放行变汪。
3.9.1.定義過濾器類
@Component
public class LoginFilter extends ZuulFilter{
@Override
public String filterType() {
// 登錄校驗,肯定是在前置攔截
return "pre";
}
@Override
public int filterOrder() {
// 順序設置為1
return 1;
}
@Override
public boolean shouldFilter() {
// 返回true蚁趁,代表過濾器生效裙盾。
return true;
}
@Override
public Object run() throws ZuulException {
// 登錄校驗邏輯。
// 1)獲取Zuul提供的請求上下文對象
RequestContext ctx = RequestContext.getCurrentContext();
// 2) 從上下文中獲取request對象
HttpServletRequest req = ctx.getRequest();
// 3) 從請求中獲取token
String token = req.getParameter("access-token");
// 4) 判斷
if(token == null || "".equals(token.trim())){
// 沒有token他嫡,登錄校驗失敗番官,攔截
ctx.setSendZuulResponse(false);
// 返回401狀態(tài)碼。也可以考慮重定向到登錄頁钢属。
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
// 校驗通過徘熔,可以考慮把用戶信息放入上下文,繼續(xù)向后執(zhí)行
return null;
}
}
3.9.2.測試
沒有token參數(shù)時淆党,訪問失斀辍:
?添加token參數(shù)后:
?3.10.負載均衡和熔斷
Zuul中默認就已經(jīng)集成了Ribbon負載均衡和Hystix熔斷機制。但是所有的超時策略都是走的默認值宁否,比如熔斷超時時間只有1S窒升,很容易就觸發(fā)了。因此建議我們手動進行配置:
zuul:
retryable: true
ribbon:
ConnectTimeout: 250 # 連接超時時間(ms)
ReadTimeout: 2000 # 通信超時時間(ms)
OkToRetryOnAllOperations: true # 是否對所有操作重試
MaxAutoRetriesNextServer: 2 # 同一服務不同實例的重試次數(shù)
MaxAutoRetries: 1 # 同一實例的重試次數(shù)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMillisecond: 6000 # 熔斷超時時長:6000ms