微服務化是當前一大趨勢,API網關是僅次於註冊中心的存在(上一篇已經講到註冊中心),API網關能夠減小對域名的管理、服務統一鑑權、服務日誌traceId等,內容大可能是以前組內安排的任務,因而把結果分享出來。web
當前對API網關組件的調研維度以下:社區生態熱度、易用性、路由轉發及過濾器性能、當前維護狀態及特色等。spring
pom引用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
yml配置路由轉發
spring:
application:
name: gateway-demo
cloud:
gateway:
routes:
- id: path_route
uri: lb://demo(業務路徑)
order: 0
predicates:
- Path=/exercise/**
filters:
- StripPrefix=1
- TokenCheck
配置局部過濾器
public class TokenCheckGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenCheckGatewayFilterFactory.Config> {
public TokenCheckGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
System.out.println("Welcome to AuthFilter.");
String token = exchange.getRequest().getHeaders().getFirst("token");
if (Config.authToken.equals(token)) {
return chain.filter(exchange);
}
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
};
}
static class Config {
static String authToken = "12345";
}
}
複製代碼
pom引用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
配置路由轉發
zuul:
routes:
api-a:
path: /gate/**
serviceId: service-demo1
#具體註冊到註冊中心的服務如service2
service2:
path: /service2/**
serviceId: service2
配置全局過濾器(zuul只有全局過濾器)
@Component
public class PreFilter extends ZuulFilter {
Logger logger = LoggerFactory.getLogger(PreFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
HttpServletResponse response = requestContext.getResponse();
String requestURI = request.getRequestURI();
logger.info("[ValidateConfigurerAdapter.preHandle] request handle uri is {}", requestURI);
response.setCharacterEncoding("utf-8");
String token = request.getHeader("token");
if (!StringUtils.isEmpty(token) && token.equals("123456")) {
return null;
}
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(401);
return null;
}
}
複製代碼
維度 | springcloudgateway | zuul |
---|---|---|
社區生態 | 社區熱度高 | 社區熱度較低、中文文檔多 |
易用性 | spring cloud 組件集成;基於springboot 2.0;須要項目升級至springboot2.X | spring cloud netflix組件集成zuul1.x版本,1.x版本基於阻塞io;2.X版本就netty,異步非阻塞io,支持長鏈接,但springcloud暫時未集成。zuul 1.x版本基於springboot1.x |
性能 | nacos+spring cloud gateway+service;我的本地壓測;100併發:3ms;500併發:3ms;5000併發:320ms。相關資料:併發較低的狀況下二者同樣,併發較高springcloudgateway是zuul1.x的1.6倍 | eureka+zuul+service。我的本地壓測:100併發:3ms;500併發:5ms;5000併發:267ms |
維護狀態 | springcloud組件,持續更新,版本從2.0.0開始 | springcloud組件僅支持到1.X,zuul core持續維護2.1.4至今 |
重點功能,特色 | 過濾器有global filter和gatewayfilter,分爲全局和局部;基於netty轉發。 | 過濾器僅爲全局過濾器;基於servlet同步阻塞轉發。 |
當前主要使用路由分發以及鑑權功能,zuul和springcloudgateway在路由分發上沒有太大區別。在使用過濾器鑑權時,zuul當前僅能使用全局過濾器,而springcloudgateway既能夠選用全局過濾器,又能夠選擇局部指定路由的過濾器。api
zuul1.X使用servlet轉發,不支持長鏈接,沒法轉發websocket;springboot
springcloudgateway基於netty非阻塞io,支持長鏈接。bash
springcloudgateway相對zuul1.X在關鍵功能、維護狀態、性能等處於領先,當前僅存在項目的springboot2.0的兼容升級問題,若是能夠直接升級至springboot2.0或當前已經使用springboot2.0,建議使用springcloudgateway。websocket