微服务之API网关对比

3,901 阅读3分钟

前言

        微服务化是当前一大趋势,API网关是仅次于注册中心的存在(上一篇已经讲到注册中心),API网关可以减少对域名的管理、服务统一鉴权、服务日志traceId等,内容大多是之前组内安排的任务,于是把结果分享出来。

正文

        当前对API网关组件的调研维度如下:社区生态热度、易用性、路由转发及过滤器性能、当前维护状态及特点等。

组件介绍

  1. springcloudgateway,springcloud官方的api网关,基于springboot2.0和springcloud2.0,融入springcloud组件;
  2. zuul,netflex出品的api网关,springcloud集成zuul1.x,且1.x不再支持更新,springcloud不再集成zuul2。

组件使用

1. springcloudgateway

       

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";
 }
}

2. zuul

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。