這篇文章主要參考陽哥2020年SpringCloud第二季的內容整理而成
這裏使用新一代SpringCloud的網關,而不是用Zuul,Gateway是基於響應式的,底層使用了Netty,總之就是好用牛逼
1.pom文件的配置
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
主要就是這兩個依賴的引入
2.application.yml的基本配置
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #開啓從註冊中心動態創建路由的功能,利用微服務名進行路由
routes:
- id: payment_routh #路由的ID,沒有固定的規則但要求唯一,建議配合服務名
#uri: http://localhost:8001 #匹配後提供服務的路由地址
uri: lb://cloud-payment-service #匹配後提供服務的路由地址
predicates:
- Path=/payment/get/** #斷言,路徑相匹配的進行路由
- id: payment_routh2 #路由的ID,沒有固定的規則但要求唯一,建議配合服務名
#uri: http://localhost:8001 #匹配後提供服務的路由地址
uri: lb://cloud-payment-service #匹配後提供服務的路由地址
filters:
- AddRequestParameter=X-Request-Id,1024 #過濾器工廠會在匹配的請求頭加上一對請求頭,名爲X-Request-Id,值爲1024
predicates:
- Path=/payment/lb/** #斷言,路徑相匹配的進行路由
- After=2020-03-21T15:44:36.518+08:00[Asia/Shanghai] #允許訪問的時間,在xxx之後
#- Cookie=username,zhouzhou #檢測cookie
#- Header=X-Request-Id, \d+ #請求頭要有X-Request-Id屬性並且值爲正數的正則表達式
eureka:
instance:
hostname: cloud-gateway-service
client: #服務提供者provider註冊進eureka服務列表內
service-url:
register-with-erueka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka
這裏先全部放出來,server.port還有什麼name之類的就不說了,eureka配置,把這個服務註冊進去
這裏主要講解gateway的配置主要就是要配置routes,配置uri和斷言,uri最好不要寫死,而要寫成eureka server中的服務名稱,要開啓這個功能還要打開doscovery.locator這個選項。斷言這一塊,主要就是說明匹配規則的,最重要的一個屬性就是-Path指明瞭匹配的路徑,其他的一些斷言還有過濾器的用法都寫在註釋裏面了。
這裏帶着講解一下實現原理,因爲一般我的文章都是側向與實現的,這裏如果斷言與請求路徑相匹配了,就會轉到目標uri,,主要的兩個過程就是,斷言匹配和路由轉發。三個核心概念時路由,斷言和過濾。 這裏先講了路由和斷言,過濾器放在下面講,我們會實現一個自定義的過濾器。
3.自定義過濾器的配置
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("****************come in MyLogGateWayFilter: " + new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.info("***********用戶名爲null,非法用戶");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
這裏需要實現兩個接口GlobalFilter和Order,這兩個結構是響應式編程還有啥netty裏面給出的一個新的接口,其實和之前servlet的基本實現過程差不多,只是框架底層的實現原理不同,重寫Filter方法。實現網關鑑權和全局日誌記錄。
訪問http://localhost:9527/payment/lb?uname=z3能成功返回接口8001
補充材料,這裏跳轉的controller
@GetMapping(value = "/payment/lb")
public String getPaymentLB() {
return serverPort;
}
謝謝觀看