简体   繁体   English

使用Netty搭建http代理服务器的简单方法?

[英]Simple way to use Netty to build an http proxy server?

I'm new to Netty, and am looking at using it to make a simple http proxy server that receives requests from a client, forwards the requests to another server, and then copies the response back to the response for the original request.我是 Netty 的新手,正在考虑使用它来制作一个简单的 http 代理服务器,该服务器接收来自客户端的请求,将请求转发到另一台服务器,然后将响应复制回原始请求的响应。 One extra requirement is that I be able to support a timeout, so that if the proxied server takes too long to respond the proxy will respond by itself and close the connection to the proxied server.一个额外的要求是我能够支持超时,以便如果代理服务器响应时间过长,代理将自行响应并关闭与代理服务器的连接。

I've already implemented such an application using Jetty, but with Jetty I need to use too many threads to keep inbound requests from getting blocked (this is a lightweight app that uses very little memory or cpu, but the latency of the proxied server is high enough that bursts in traffic cause either queueing in the proxy server, or require too many threads).我已经使用 Jetty 实现了这样一个应用程序,但是使用 Jetty 我需要使用太多线程来防止入站请求被阻塞(这是一个使用很少内存或 CPU 的轻量级应用程序,但代理服务器的延迟是足够高以至于流量突发导致在代理服务器中排队,或者需要太多线程)。

According to my understanding, I can use Netty to build a pipeline in which each stage performs a small amount of computation, then releases it's thread and waits until data is ready for the next stage in the pipeline to be executed.根据我的理解,我可以使用 Netty 构建一个管道,其中每个阶段执行少量计算,然后释放它的线程并等待数据准备好以执行管道中的下一个阶段。

My question is, is there a simple example of such an application?我的问题是,是否有此类应用程序的简单示例? What I have so far is a simple modification of the server code for the basic Netty tutorial, but it lacks all support for a client.到目前为止,我对基本 Netty 教程的服务器代码进行了简单的修改,但它缺乏对客户端的所有支持。 I saw the netty client tutorial, but am not sure how to mix code from the two to create a simple proxy app.我看到了 netty 客户端教程,但不确定如何混合两者的代码来创建一个简单的代理应用程序。

public static void main(String[] args) throws Exception {
    ChannelFactory factory =
            new NioServerSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());

    ServerBootstrap bootstrap = new ServerBootstrap(factory);

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            return Channels.pipeline(
                    new HttpRequestDecoder(),
                    new HttpResponseEncoder(),
                    /* 
                     * Is there something I can put here to make a
                     * request to another server asynchronously and
                     * copy the result to the response inside
                     * MySimpleChannelHandler?
                     */
                    new MySimpleChannelHandler()
                    );
        }
    });

    bootstrap.setOption("child.tcpNoDelay", true);
    bootstrap.setOption("child.keepAlive", true);

    bootstrap.bind(new InetSocketAddress(8080));
}

private static class MySimpleChannelHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
        HttpRequest request = (HttpRequest) e.getMessage();
        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.setContent(request.getContent());

        Channel ch = e.getChannel();
        ChannelFuture f = ch.write(response);
        f.addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) {
                Channel ch = future.getChannel();
                ch.close();
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        e.getCause().printStackTrace();

        Channel ch = e.getChannel();
        ch.close();
    }
}

您必须查看LittleProxy才能了解他们是如何在 Netty 之上编写的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM