- 如何進行線上debug。
- 如何在gateway自定義路由規則去進行請求分發,讓請求打到叢集模式下我們想要的節點。
1.配置remote debug
1.在啟動引數配置引數:
-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6364
2.新建remote
3.啟動remote
2.gateway改造
我個人的需求是把某個使用者的請求,打到我想要的節點(開啟了debug模式的節點),避免因為叢集節點的負載導致請求打到其他節點,也避免影響其他使用者的正常請求流程。
我的做法是攔截請求頭中的Authorization=xxx進行判斷,因此參考了gateway的路由策略:
gateway 路由匹配策略
而gateway自帶的路由策略是透過regix(正則匹配)來實現的,因此我做了以下改造:
1.新增HeaderValueRoutePredicateFactory
public class HeaderValueRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderValueRoutePredicateFactory.Config> {
private static final String KEY_1 = "headerName";
private static final String KEY_2 = "headerValue";
public HeaderValueRoutePredicateFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(KEY_1, KEY_2);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
List<String> values = exchange.getRequest().getHeaders().getOrDefault(config.getHeaderName(),
Collections.emptyList());
if (values.isEmpty()) {
return false;
}
boolean match = values.stream().allMatch(item -> item.equals(config.getHeaderValue()));
if (match) {
log.info("debug模式route策略已觸發");
}
return match;
}
@Override
public Object getConfig() {
return config;
}
@Override
public String toString() {
return String.format("HeaderName: %s headerValue=%s", config.getHeaderName(), config.getHeaderValue());
}
};
}
public static class Config {
private String headerName;
private String headerValue;
public String getHeaderName() {
return headerName;
}
public Config setHeaderName(String headerName) {
this.headerName = headerName;
return this;
}
public String getHeaderValue() {
return headerValue;
}
public Config setHeaderValue(String headerValue) {
this.headerValue = headerValue;
return this;
}
}
}
程式碼筆記:
- 獲取系統快取路由策略(可以看閘道器中配置的全部策略)
org.springframework.cloud.gateway.route.CachingRouteLocator#getRoutes - 獲取路由策略(根據請求條件匹配)
org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping#getHandlerInternal - 獲取路由策略(根據請求條件匹配)
org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping#lookupRoute
2.配置類
@Configuration
public class Config {
@Bean
public HeaderValueRoutePredicateFactory headerValueRoutePredicateFactory() {
return new HeaderValueRoutePredicateFactory();
}
}
3.修改gateway配置
spring:
cloud:
gateway:
routes:
# 當請求路徑為/ims/**會被該規則路由
- id: ims
uri: lb://ims
predicates:
- Path=/ims/**
filters:
- StripPrefix=1
# 當請求頭中帶有Authorization=ff4a4ce5-5276-4263-b817-34d1ce553421且路徑為/ims/**會被該規則路由
- id: ims-debug
uri: lb://ims-debug
# 配置-1是為了讓該路由策略在id: ims 前面進行判斷,否則會觸發id=ims的路由策略,不會觸發id=ims-debug的路由策略
order: -1
predicates:
- Path=/ims/**
- HeaderValue=Authorization,ff4a4ce5-5276-4263-b817-34d1ce553421
filters:
- StripPrefix=1
3.nacos配置
1.正常的節點配置
-Dspring.application.name=ims
2.debug的節點配置
-Dspring.application.name=ims-debug
本質上ims和ims-debug是同一服務,只是服務名不同,區分開是為了方便路由
4.其他問題
- 正常情況下,如果是生產環境,ims-debug服務即使開啟了debug模式,但會因為網路問題導致辦公網的本地無法進行連線。這種情況我們可以讓運維申請跳板機、VPN來對接專用網路,另外debug的對外埠也要申請好。
- 我在網上還看到其他的線上debug方式 點選跳轉他人連結,因此我這種方式未必適合所有人(但是都沒有考慮叢集下請求如果不進入當前節點的問題),本人只是折中。
- 即使你學會了也沒什麼用,正常情況下不會讓開發者進行線上debug。作者本人也只是心血來潮。