SpringCloud?Gateway詳細分析實現(xiàn)負載均衡與熔斷和限流
環(huán)境準(zhǔn)備
- 注冊中心Nacos,也可以其他
- springboot 2.6.8
- spring-cloud-dependencies 2021.0.3
1.pom依賴
parent包
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.8</version> </parent>
gateway依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--服務(wù)注冊與發(fā)現(xiàn)--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2021.0.1.0</version> </dependency> <!--遠程服務(wù)路由--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency>
springcloud版本管理
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2.yaml配置
spring:
application:
name: gatewayservice
cloud:
#找對應(yīng)網(wǎng)段的網(wǎng)卡 不配置內(nèi)部服務(wù)就走外網(wǎng)
inetutils:
preferred-networks: 192.168.0
nacos:
discovery:
#nacos注冊地址
server-addr: 192.168.0.221:8848
gateway:
routes:
- id: user
#根據(jù)服務(wù)名轉(zhuǎn)發(fā) 只需要名稱 不用端口
uri: lb://userservice
#ip的形式轉(zhuǎn)發(fā)
# uri: http://127.0.0.1:7540
predicates:
#路由規(guī)則
- Path=/user/**
filters:
#1/去掉前綴 0/保持原路徑
- StripPrefix=1
#跨域配置
globalcors:
cors-configurations:
'[/**]':
# 允許攜帶認證信息
allowCredentials: true
# 允許跨域的源(網(wǎng)站域名/ip),設(shè)置*為全部
allowedOriginPatterns: "*"
# 允許跨域的method, 默認為GET和OPTIONS,設(shè)置*為全部
allowedMethods: "*"
# 允許跨域請求里的head字段,設(shè)置*為全部
allowedHeaders: "*"#本地靜態(tài)路由配置 jar包依賴不一樣
#my-load-balanced-service:
# ribbon:
# listOfServers: http://127.0.0.1:7540,http://127.0.0.1:7541
#輪詢
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
3.路由轉(zhuǎn)發(fā)和負載均衡測試
啟動不同端口的user服務(wù),然后通過gateway調(diào)用
user服務(wù)暴露接口
訪問地址http://127.0.0.1:7500/user/test
@Value("${server.port}") String port; @GetMapping("/test") public String test() { return new Date().getTime() + ":" + port; }
返回結(jié)果輸出
1657261506117:7540
1657261509785:7541
1657261513874:7540
1657261517464:7541
可以正常路由轉(zhuǎn)發(fā)和負載均衡,默認策略是輪詢
4.gateway熔斷實現(xiàn)
熔斷:就是通過在轉(zhuǎn)發(fā)過程中失敗的,從而采取的降級策略。良好的返回提示給前端。
4.1 熔斷代碼
@Component public class FallbackHandler implements ErrorWebExceptionHandler { @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { String message = "服務(wù)正在維護,請稍后再試!"; byte[] bytes = String.format("{\"code\":-1,\"message\":\"%s\",\"data\":null}", message).getBytes(StandardCharsets.UTF_8); DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes); exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON); return exchange.getResponse().writeWith(Flux.just(buffer)); } }
本來是想通過Hystrix
直接配置重定向的,奈何spring-cloud-starter-netflix-hystrix
已經(jīng)不更新了,沒法兼容。直接采用一刀切算了。
4.2 測試
開啟gateway和user服務(wù)訪問后,然后停掉user。結(jié)果如下
{"code":-1,"message":"服務(wù)正在維護,請稍后再試!","data":null}
在這里需要注意的兩個點
- 如果配置的是服務(wù)名,gateway先注冊轉(zhuǎn)發(fā)服務(wù)還沒注冊到Nacos時,訪問就不會走熔斷,會提示
No servers available for service: userservice
- 如果配置的是http地址,無對應(yīng)的服務(wù)存在時則可以正常走熔斷
5.gateway限流
用的是自帶的令牌桶算法,例如總共十個令牌,每秒恢復(fù)一個,那么一秒內(nèi)最大只能獲取10個令牌,超過的則直接控制掉返回429 Too Many Requests
5.1 需要集成redis
pom依賴如下
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
5.2 yaml配置
#引入數(shù)據(jù)庫
redis:
database: 0
host: 192.168.0.100
port: 6379
//限流策略
gateway:
routes:
- id: user
uri: lb://userservice
predicates:
- Path=/user/**
filters:
#名稱不可修改
- name: RequestRateLimiter
args:
#限流策略名 通過代碼注入到spring容器中去
key-resolver: "#{@ipKeyResolver}"
#令牌桶每秒填充平均速率
redis‐rate‐limiter.replenishRate: 1
#令牌桶總?cè)萘?br /> redis‐rate‐limiter.burstCapacity: 2
# 每次請求獲取的令牌數(shù)
redis-rate-limiter.requestedTokens: 1
上述配置含義:針對ip限流,總令牌數(shù)2,沒秒恢復(fù)一個,每次獲取一個。也就是說一秒內(nèi)超過2次則會被限流。
注意上述限流配置缺一不可,不然啟動也不會報錯,也不會生效,重點是轉(zhuǎn)發(fā)也不成功了
5.3 注入到spring容器
//針對ip限流 @Primary @Bean(value = "ipKeyResolver") public KeyResolver ipKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()); } //針對路徑限流 // @Bean(name = "apiKeyResolver") public KeyResolver apiKeyResolver() { return exchange -> Mono.just(exchange.getRequest().getPath().value()); }
5.4 測試
訪問http://127.0.0.1:7500/user/test
,一秒內(nèi)訪問三次
redis截圖
網(wǎng)頁端截圖
限流生效!
到此這篇關(guān)于SpringCloud Gateway詳細分析實現(xiàn)負載均衡與熔斷和限流的文章就介紹到這了,更多相關(guān)SpringCloud Gateway負載均衡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring Cloud Gateway層限流實現(xiàn)過程
- SpringCloud Gateway的熔斷限流配置實現(xiàn)方法
- SpringCloud Gateway實現(xiàn)限流功能詳解
- 深入學(xué)習(xí)spring cloud gateway 限流熔斷
- Spring Cloud Gateway不同頻率限流的解決方案(每分鐘,每小時,每天)
- spring cloud gateway整合sentinel實現(xiàn)網(wǎng)關(guān)限流
- spring cloud gateway 限流的實現(xiàn)與原理
- 詳解Spring Cloud Gateway 限流操作
- Gateway實現(xiàn)限流的一些常見方式
相關(guān)文章
Java輸入學(xué)號、姓名、年齡并對其進行輸出的實現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Java輸入學(xué)號、姓名、年齡并對其進行輸出的實現(xiàn)方法,在計算機編程中,輸出學(xué)號和姓名是一個常見的任務(wù),文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-09-09從Android源碼剖析Intent查詢匹配的實現(xiàn)
這篇文章主要介紹了從Android源碼剖析Intent查詢匹配的實現(xiàn),Intent部分的源碼為Java代碼,需要的朋友可以參考下2015-07-07解決java.sql.SQLException:The?server?time?zone?value?&apo
這篇文章主要介紹了解決java.sql.SQLException:The?server?time?zone?value?'?D1ú±ê×?ê±??'?is?unrecognized問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03springboot集成redis并使用redis生成全局唯一索引ID
本文主要介紹了springboot集成redis并使用redis生成全局唯一索引ID,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03java讀取圖片并轉(zhuǎn)化為二進制字符串的實現(xiàn)方法
這篇文章主要介紹了java讀取圖片并轉(zhuǎn)化為二進制字符串的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09