我需要在我的简单http服务器netty app中跟踪各个客户端的连接(写入,读取字节和速度(每秒字节数))。据我了解,要做到这一点,我必须使用ChannelTrafficShapingHandler
。
必须覆盖哪些方法以及如何进行这些计算?
My ChannelInitializer:
public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec", new HttpServerCodec())
.addLast("traffic", new TrafficShapingHandler(AbstractTrafficShapingHandler.DEFAULT_CHECK_INTERVAL))
.addLast("handler", new HttpServerHandler());
}
}
My SimpleChannelInboundHandler:
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpRequest> {
private static DefaultChannelGroup activeChannels = new DefaultChannelGroup("netty-receiver", ImmediateEventExecutor.INSTANCE);
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
activeChannels.add(ctx.channel());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
if (is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}
String uri = req.getUri().toLowerCase();
Controller controller = ControllerFactory.getController(uri);
FullHttpResponse response = controller.getResponse();
if (controller instanceof HelloController) {
ctx.executor().schedule(() -> ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE), 3, TimeUnit.SECONDS);
} else {
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
public static long getConnectionsQuantity() {
return activeChannels.size();
}
}
答案 0 :(得分:3)
@TMS,为了能够获得统计数据,首先需要选择统计级别:每个频道,全局或两者。
ChannelTrafficShapingHandler
:您必须为每个频道创建一个项目(就像您在管道中所做的那样),它只链接到一个频道。统计数据仅针对每个渠道,而非全球统计。
GlobalTrafficShapingHandler
:您必须在任何频道之前创建它并将其分配给每个频道,但每次都重复使用相同的对象(不重新分配)。统计数据仅为全局,而非每个渠道。
GlobalChannelTrafficShapingHandler
:您必须先创建它(与GlobalTSH一样)并将其分配给每个通道(不重新分配)。统计数据是全球性的,每个渠道。
一旦你决定哪一个适合你,主要有两种方法来获取统计数据:
trafficCounter()
方法访问TrafficCounter对象:
channelTrafficCounters()
访问所有有效渠道的所有TrafficCounters(仅限GlobalChannelTSH)protected void doAccounting(TrafficCounter counter)
方法。您可以查看为Netty制作但最终未在主流中导入的示例,该示例显示了如何扩展和使用它:see here,特别是how to extend GlobalChannelTSH或how to include it in your pipeline here。
当然,你可以看一下the API部分解释这一点。
最后,如果您想同时拥有频道和全局统计信息,您可以选择:
name()
)(GlobalChannelTSH主要是为了限制内存对流量抖动的影响)在两个级别,每个通道和全局上执行此操作,但仅在用于统计信息时,可能不是最佳选择);