微服务化是当前一大趋势,API网关是仅次于注册中心的存在(上一篇已经讲到注册中心),API网关可以减少对域名的管理、服务统一鉴权、服务日志traceId等,内容大多是之前组内安排的任务,于是把结果分享出来。
当前对API网关组件的调研维度如下:社区生态热度、易用性、路由转发及过滤器性能、当前维护状态及特点等。
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既可以选用全局过滤器,又可以选择局部指定路由的过滤器。
zuul1.X使用servlet转发,不支持长连接,无法转发websocket;
springcloudgateway基于netty非阻塞io,支持长连接。
springcloudgateway相对zuul1.X在关键功能、维护状态、性能等处于领先,当前仅存在项目的springboot2.0的兼容升级问题,如果可以直接升级至springboot2.0或当前已经使用springboot2.0,建议使用springcloudgateway。