Netty API使用总结

简介: Netty API使用总结

Q1:服务器主动关闭连接后,客户端没有监听到socket关闭的事件。

想象中,调用org.jboss.netty.channel.Channel.close();-->GateServerHandler.closeRequested-->channelDisconnected-->channelClosed-->client

实际上,调用org.jboss.netty.channel.Channel.close();-->GateServerHandler.closeRequested 就停止了,导致游戏实现上,玩家重复登陆,客户端没法收到服务器已经关闭了同一玩家前面建立的连接,所以客户端表现为无法断开与服务器的连接。

后来发现少了这样的一句话,导致closeRequested 就停止了。

public void closeRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
    ctx.sendDownstream(e);
  }

closeRequested 一般为服务器主动发起的关闭,另外,关于channelDisconnected和channelClosed的区别,看源码:

org.jboss.netty.channel.socket.nio.NioWorker.java

//netty version: 3.1.5GA
//file: org.jboss.netty.channel.socket.nio.NioWorker.java
//method: static void close(NioSocketChannel channel, ChannelFuture future)
//line: 581
future.setSuccess();
if (connected) {
    fireChannelDisconnected(channel);
}
if (bound) {
    fireChannelUnbound(channel);
}
cleanUpWriteBuffer(channel);
fireChannelClosed(channel);

我们可以看到,在上述代码中,在close channel的时候,会先判断当前channel是否处于connected状态,即是否已经成功地与远程地址建立了连接,如果是的话,就触发channelDisconnected事件;最后,再统一触发channelClosed事件。

也就是说,任何对NioWorker.close(NioSocketChannel channel, ChannelFuture future)方法的调用都会触发channelClosed事件,这些事件可能包括如下几种:

1. 已经与远程主机建立的连接,远程主机主动关闭连接,或者网络异常连接被断开的情况

2. 已经与远程主机建立的连接,本地客户机主动关闭连接的情况

3. 本地客户机在试图与远程主机建立连接时,遇到类似与connection refused这样的异常,未能连接成功时

而只有当本地客户机已经成功的与远程主机建立连接(connected)时,连接断开的时候才会触发channelDisconnected事件,即对应上述的1和2两种情况。

上述猜想已经通过编写测试代码,模拟不同的情况得到了证实。

Q2:一个Boss线程(一个服务器端口对于一个)--->接收到客户端连接--->生成Channel--->交给Work线程池(多个Work线程)来处理。

一个连接会绑定一个worker线程,选择的线程算法如下:

public E nextWorker() {

       return (E) workers[Math.abs(workerIndex.getAndIncrement() % workers.length)];

   }

按顺序循坏往复。

这个连接的所有接受消息和发送消息最终都会由这个worker来执行

在写出消息时,如果不是IO线程,则会写入到发消息队列里,由IO worker线程去处理,如果是IO 线程则直接写出去

监控点:UnpooledSendBuffer.transferTo

http://www.haogongju.net/art/2034726

http://xsh5324.iteye.com/blog/1915534

具体的Work线程---读完已接收的数据到ChannelBuffer---触发ChannelPipeline中的ChannelHandler链来处理业务逻辑。

注意:执行ChannelHandler链的整个过程是同步的,如果业务逻辑的耗时较长,会将导致Work线程长时间被占用得不到释放,从而影响了整个服务器的并发处理能力。

所以,为了提高并发数,一般通过ExecutionHandler线程池来异步处理ChannelHandler链(worker线程在经过ExecutionHandler后就结束了,它会被ChannelFactory的worker线程池所回收)。

Boostrap.bind 方法包含两个参数NioServerSocketChannelFactory、ChannelPipelineFactory。NioServerSocketChannelFactory包含连个线程池bossExecutor和workerExecutor,workerExecutor: 包含缺省为处理器个数×2个NioWorker进程。

对于ExecutionHandler需要的线程池模型,Netty提供了两种可选:

1) MemoryAwareThreadPoolExecutor 通过对线程池内存的使用控制,可控制Executor中待处理任务的上限(超过上限时,后续进来的任务将被阻塞),并可控制单个Channel待处理任务的上限,防止内存溢出错误;

2) OrderedMemoryAwareThreadPoolExecutor 是 MemoryAwareThreadPoolExecutor 的子类。除了MemoryAwareThreadPoolExecutor 的功能之外,它还可以保证同一Channel中处理的事件流的顺序性,这主要是控制事件在异步处理模式下可能出现的错误的事件顺序,但它并不保证同一Channel中的事件都在一个线程中执行(通常也没必要)。

Q3:如果压力测试写日志频率较高,会阻塞netty发送消息,需要给日志起单独线程

Q4:默认netty起来后,如果用Executors.newCachedThreadPool(),默认会起1个boss线程,8个work线程,但实际上后台并不需要这么多work,

// Configure the server.

ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),

Executors.newSingleThreadExecutor()));

发现,其他客户端连上来后,断开后,就再也没法连了,

Executors.newSingleThreadExecutor()换成Executors.newFixedThreadPool(1) 就没问题了。

netty客户端这边一个ClientBootstrap  可以连多个server

Q5:字节打印,很漂亮

ByteBufUtil.hexDump(byte[] array)

ByteBufUtil.prettyHexDumpbyte[] array)

目录
相关文章
|
2月前
|
API
Netty API网关实操系列(三)
Netty API网关实操系列(三)
|
2月前
|
存储 运维 架构师
Netty API网关实操系列(二)
Netty API网关实操系列(二)
|
2月前
|
安全 应用服务中间件 API
Netty API网关实操系列(一)
Netty API网关实操系列(一)
|
安全 Java Linux
Netty4 使用总结
Netty4 使用总结
54 0
|
存储 缓存 NoSQL
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)
本文将要分享的是如何从零实现一套基于Netty框架的分布式高可用IM系统,它将支持长连接网关管理、单聊、群聊、聊天记录查询、离线消息存储、消息推送、心跳、分布式唯一ID、红包、消息同步等功能,并且还支持集群部署。
13498 1
|
6月前
|
消息中间件 Oracle Dubbo
Netty 源码共读(一)如何阅读JDK下sun包的源码
Netty 源码共读(一)如何阅读JDK下sun包的源码
127 1
|
11月前
|
NoSQL Java Redis
跟着源码学IM(十二):基于Netty打造一款高性能的IM即时通讯程序
关于Netty网络框架的内容,前面已经讲了两个章节,但总归来说难以真正掌握,毕竟只是对其中一个个组件进行讲解,很难让诸位将其串起来形成一条线,所以本章中则会结合实战案例,对Netty进行更深层次的学习与掌握,实战案例也并不难,一个非常朴素的IM聊天程序。 原本打算做个多人斗地主练习程序,但那需要织入过多的业务逻辑,因此一方面会带来不必要的理解难度,让案例更为复杂化,另一方面代码量也会偏多,所以最终依旧选择实现基本的IM聊天程序,既简单,又能加深对Netty的理解。
162 1
|
6月前
|
编解码 前端开发 网络协议
Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读
Netty Review - ObjectEncoder对象和ObjectDecoder对象解码器的使用与源码解读
155 0
|
6月前
|
编解码 安全 前端开发
Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读
Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读
250 0
|
分布式计算 网络协议 前端开发
【Netty底层数据交互源码】
【Netty底层数据交互源码】