私はNettyを初めて使用し、クライアントからリクエストを受信し、リクエストを別のサーバーに転送し、レスポンスを元のリクエストのレスポンスにコピーする単純なhttpプロキシサーバーを作成することを検討しています. 1 つの追加要件は、タイムアウトをサポートできることです。これにより、プロキシ サーバーの応答に時間がかかりすぎる場合に、プロキシが自動的に応答し、プロキシ サーバーへの接続を閉じます。
私はすでに Jetty を使用してそのようなアプリケーションを実装しましたが、Jetty ではインバウンド要求がブロックされないようにするためにあまりにも多くのスレッドを使用する必要があります (これはメモリや CPU をほとんど使用しない軽量アプリですが、プロキシ サーバーのレイテンシはトラフィックのバーストがプロキシ サーバーでのキューイングを引き起こすか、必要なスレッドが多すぎるほど高い)。
私の理解によると、Netty を使用して、各ステージが少量の計算を実行するパイプラインを構築し、スレッドを解放して、パイプラインの次のステージが実行されるまでデータの準備が整うまで待機できます。
私の質問は、そのようなアプリケーションの簡単な例はありますか? これまでのところ、基本的な Netty チュートリアルのサーバー コードを単純に変更しただけですが、クライアントのサポートがすべて欠けています。Netty クライアントのチュートリアルを見ましたが、2 つのコードを組み合わせて単純なプロキシ アプリを作成する方法がわかりません。
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();
}
}