Java案例如何实现服务网关?

wen python案例 3

Java实现服务网关的几种方案

服务网关是微服务架构中的重要组件,主要功能包括路由转发、负载均衡、认证鉴权、限流熔断等,以下是几种常见的Java实现方案:

Java案例如何实现服务网关?

Spring Cloud Gateway(推荐方案)

Spring Cloud Gateway 是基于Spring WebFlux的非阻塞式网关。

基础配置示例:

// application.yml
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=X-Request-Color, blue
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
          filters:
            - StripPrefix=1

Java配置方式:

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/user/**")
                .filters(f -> f
                    .stripPrefix(1)
                    .addRequestHeader("X-Request-Color", "blue"))
                .uri("lb://user-service"))
            .route("order-service", r -> r
                .path("/api/order/**")
                .filters(f -> f.stripPrefix(1))
                .uri("lb://order-service"))
            .build();
    }
}

全局过滤器示例:

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求路径
        String path = exchange.getRequest().getURI().getPath();
        // 白名单路径直接放行
        if (path.contains("/login") || path.contains("/register")) {
            return chain.filter(exchange);
        }
        // 获取token进行验证
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (StringUtils.isEmpty(token)) {
            // 返回401未授权
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        // 验证token逻辑...
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return -100; // 优先级最高
    }
}

自定义Netty网关

基于Netty实现高性能网关:

public class NettyGatewayServer {
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        ch.pipeline()
                            .addLast(new HttpServerCodec())
                            .addLast(new HttpObjectAggregator(65536))
                            .addLast(new GatewayHandler());
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture future = bootstrap.bind(8080).sync();
            future.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    static class GatewayHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
            // 路由逻辑
            String uri = request.uri();
            // 转发到目标服务
            forwardRequest(ctx, request, uri);
        }
    }
}

基于Zuul 1.x(已停止维护)

虽然官方已停止更新,但仍有大量项目使用:

@EnableZuulProxy
@SpringBootApplication
public class ZuulGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulGatewayApplication.class, args);
    }
}
@Component
public class AuthZuulFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre"; // 前置过滤器
    }
    @Override
    public int filterOrder() {
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        // 认证逻辑
        String token = request.getHeader("Authorization");
        if (token == null || !validateToken(token)) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            return null;
        }
        return null;
    }
}

Kong + Java插件

Kong网关配合Java插件实现:

// 在Kong中加载Java插件
@KongPlugin(name = "java-auth-plugin")
public class AuthPlugin implements Plugin {
    @Override
    public void access(PluginContext context) {
        Request request = context.getRequest();
        // 认证逻辑
        String token = request.getHeaders().getFirst("Authorization");
        if (!validateToken(token)) {
            context.setResponse(HttpStatus.UNAUTHORIZED, "Unauthorized");
        }
    }
}

完整的功能实现示例

一个完整的网关需要实现以下核心功能:

@Component
public class CompleteGatewayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        // 1. 限流
        if (!rateLimit(request)) {
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }
        // 2. 认证
        if (!authenticate(request)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        // 3. 日志记录
        logRequest(request);
        // 4. 添加请求头
        ServerHttpRequest modifiedRequest = request.mutate()
            .header("X-Gateway", "true")
            .build();
        // 5. 路由转发(由Spring Cloud Gateway自动完成)
        return chain.filter(exchange.mutate().request(modifiedRequest).build());
    }
    private boolean rateLimit(ServerHttpRequest request) {
        // 实现限流逻辑(如基于Redis的令牌桶)
        return true;
    }
    private boolean authenticate(ServerHttpRequest request) {
        // 实现认证逻辑
        return true;
    }
    private void logRequest(ServerHttpRequest request) {
        // 日志记录
    }
    @Override
    public int getOrder() {
        return -100;
    }
}

选择建议

方案 适用场景 优点 缺点
Spring Cloud Gateway 新项目、Spring Cloud生态 功能完善、非阻塞、社区活跃 学习曲线较陡
Zuul 1.x 老项目迁移 成熟稳定 阻塞式、已停止维护
Netty自研 高性能定制需求 完全可控、性能极致 开发成本高
Kong 已使用Kong的场景 与Kong生态集成好 需要额外部署Kong

推荐使用Spring Cloud Gateway作为Java微服务的网关解决方案。

抱歉,评论功能暂时关闭!