天天看点

Zuul 2.0 服务架构 + Netty + filters

作者:梦幻随风的互联网笔记

Zuul 2.0 服务架构新特性

Zuul 2.0 服务架构 + Netty + filters

Netty作为高性能异步网络通讯框架,在dubbo,rocketmq,sofa等知名开源框架中都有使用,使用netty server作为网关监听服务器监听客户端发来的请求,

然后把请求转发到前置过滤器(inbound filters)进行处理,

处理完毕后再把请求使用http client 到具体的后端服务器进行处理,

处理完毕后再把结果交给后者过滤器(outbound filters)进行处理,

然后把处理结果通过nettyServer写回客户端

protected void channelRead0(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof HttpRequest) {
            HttpRequest request = this.request = (HttpRequest) msg;

            //收到客户端的100-Continue协议请求,说明客户端要post数据给服务器
            if (HttpUtil.is100ContinueExpected(request)) {
                notify100Continue(ctx);
            }

            buffer.setLength(0);
            uri = request.uri().substring(1);
        }

        if (msg instanceof HttpContent) {
            HttpContent httpContent = (HttpContent) msg;
            ByteBuf content = httpContent.content();
            if (content.isReadable()) {
                buffer.append(content.toString(GATEWAY_OPTION_CHARSET));
            }

            //获取post数据完毕
            if (msg instanceof LastHttpContent) {
                LastHttpContent trace = (LastHttpContent) msg;

                System.out.println("[NETTY-GATEWAY] REQUEST : " + buffer.toString());

                //根据netty-gateway.properties、netty-route.properties匹配出最终转发的URL地址
                url = matchUrl();
                System.out.println("[NETTY-GATEWAY] URL : " + url);

                //http请求异步转发处理,不要阻塞当前的Netty Handler的I/O线程,提高服务器的吞吐量。
                Future<StringBuilder> future = executor.submit(new Callable<StringBuilder>() {
                    @Override
                    public StringBuilder call() {
                        return HttpClientUtils.post(url, buffer.toString(), GATEWAY_OPTION_HTTP_POST);
                    }
                });

                future.addListener(new FutureListener<StringBuilder>() {
                    @Override
                    public void operationComplete(Future<StringBuilder> future) throws Exception {
                        if (future.isSuccess()) {
                            respone = ((StringBuilder) future.get(GATEWAY_OPTION_HTTP_POST, TimeUnit.MILLISECONDS));
                        } else {
                            respone = new StringBuilder(((Signal) future.cause()).name());
                        }
                        latch.countDown();
                    }
                });

                try {
                    latch.await();
                    writeResponse(respone, future.isSuccess() ? trace : null, ctx);
                    ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
           

而zuul2.0使用netty作为异步通讯,可以大大加大并发请求量