SpringCloud系列之網關(Gateway)應用篇
@
目錄
前言
項目版本
網關通路
鑒權配置
限流配置
由于項目采用了微服務架構,業務功能都在相應各自的子產品中,每個業務子產品都是以獨立的項目運作着,對外提供各自的服務接口,如沒有類似網關之類元件的話,相應的鑒權,限流等功能實作起來不能夠進行統一的配置和管理,有了網關後一切都是如此的優雅。剛好新項目中采用了SpringCloud Gateway元件作為網關,就記錄下項目中常用的配置吧。
spring-boot-version:2.2.5.RELEASE
spring-cloud.version:Hoxton.SR3
示例項目還是延續SpringCloud系列原先的示例代碼,引入網關僅僅隻需新增spring-cloud-gateway項目即可。
核心pom.xml(詳細資訊檢視示例源碼,在文章末尾)
org.springframework.cloud
<artifactId>spring-cloud-starter-gateway</artifactId>
bootstrap.yml
server:
port: 9005
spring:
application:
name: springcloud-gateway-service
cloud:
config:
discovery:
enabled: true
service-id: config-server
profile: dev
label: master
gateway:
enabled: true #開啟網關
discovery:
locator:
enabled: true #開啟自動路由,以服務id建立路由,服務id預設大寫
lower-case-service-id: true #服務id設定為小寫
eureka:
client:
service-url:
defaultZone: http://localhost:9003/eureka/
ApiGatewayApplication.java
@EnableDiscoveryClient
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
通路原先spring-cloud-system-server子產品對外提供的接口
http://localhost:9004/web/system/getEnvName通過網關進行通路
http://localhost:9005/system-server/web/system/getEnvName請求能正常傳回,那就說明網關元件已內建進來了,是不是很簡單呢,一行配置項就搞定了,便于展現這邊采用properties配置方式說明
spring.cloud.gateway.discovery.locator.enabled=true
到此網關的基礎配置應用已完成,通過網關通路的請求路徑格式如下
http://網關位址:網關端口/各自服務id/各自服務對外提供的URL通路
這邊将spring-cloud-system-server子產品引入spring security安全認證元件,上代碼。
pom.xml
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
application.properties
spring.security.user.name=test
spring.security.user.password=123456
服務子產品調整完後,重新啟動該子產品,通路對外請求接口,出現認證登入界面說明配置成功。
輸入上述配置項中配置的使用者名和密碼後,接口請求傳回正常。
請求網關位址,通路服務接口按下Enter鍵時會跳轉至服務項目認證頁面,如下
接下來對網關子產品進行相應調整
name: springcloud-gateway-service
security:
user:
name: test
password: 123456
新增安全認證過濾類
SecurityBasicAuthorizationFilter.java
@Component
public class SecurityBasicAuthorizationFilter implements GlobalFilter, Ordered {
@Value("${spring.security.user.name}")
private String username;
@Value("${spring.security.user.password}")
private String password;
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String auth = username.concat(":").concat(password);
String encodedAuth = new sun.misc.BASE64Encoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
String authHeader = "Basic " +encodedAuth;
//headers中增加授權資訊
ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().header("Authorization", authHeader).build();
ServerWebExchange build = exchange.mutate().request(serverHttpRequest).build();
return chain.filter(build);
}
/**
* 優先級
* 數字越大優先級越低
* @return
*/
public int getOrder() {
return -1;
}
重新開機網關項目,重新通路服務位址,傳回正常資料。這邊說明下在測試時最好新開一個無痕視窗或者清理浏覽器緩存後再進行測試,不然因會話緩存會導緻安全認證沒有生效的假象。
SpringCloud Gateway自帶限流功能,但是基于redis,這邊簡單示範下,項目中沒有使用而是使用了阿裡開源的sentinel,後續将介紹下內建sentinel元件。
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
cloud:
gateway:
enabled: true #開啟網關
discovery:
locator:
enabled: true #開啟自動路由,以服務id建立路由,服務id預設大寫
lower-case-service-id: true #服務id設定為小寫
routes:
- id: baidu_route
uri: https://www.baidu.com/
predicates:
- Path=/baidu/**
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@apiKeyResolver}"
redis-rate-limiter.replenishRate: 1 #允許每秒處理多少個請求
redis-rate-limiter.burstCapacity: 5 #允許在一秒鐘内完成的最大請求數
redis:
host: 192.168.28.142
pool: 6379
password: password
database: 1
RequestRateLimiterConfig.java
@Configuration
public class RequestRateLimiterConfig {
@Bean
@Primary
public KeyResolver apiKeyResolver() {
//URL限流,超出限流傳回429狀态
return exchange -> Mono.just(exchange.getRequest().getPath().toString());
}
重新啟動網關項目,通路如下請求位址,會請求跳轉至百度首頁,目前配置項配置為1s内請求數5次,超過5次就會觸發限流,傳回429狀态碼,多次重新整理就會出現如下頁面
http://localhost:9005/baidu/test通過monitor指令實時檢視redis資訊
本次網關項目目錄結構
同系列文章
1-SpringCloud系列之配置中心(Config)使用說明
2-SpringCloud系列之服務注冊發現(Eureka)應用篇
示例源碼
原文位址
https://www.cnblogs.com/chinaWu/p/12731796.html