1. 首页 > 笙耀百科 >

netty断线重连_netty连接断开检测

为什么选择Netty作为基础通信组件

一、什么是Netty

netty断线重连_netty连接断开检测netty断线重连_netty连接断开检测


Netty是一个高性能 事件驱动、异步非堵塞的IO(NIO)Ja开源框架,Jboss提供,用于建立TCP等底层的连接,基于Netty可以建立高性能的Http服务器,快速开发高性能、高可靠性的网络服务器和客户端程序。支持HTTP、 WebSocket 、Protobuf、 Binary TCP |和UDP,Netty已经被很多高性能项目作为其Socket底层基础,如HornetQ Infinispan Vert.x Play Framework Finangle和 Cassandra。其竞争对手是:Apache MINA和 Grizzly。

也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

“快速”和“简单”并不意味着会让你的终应用产生维护性或性能上的问题。Netty 是一个吸收了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

二、不选择Ja原生NIO编程的原因

首先开发出高质量的NIO程序并不是一件简单的事情,除去NIO固有的复杂性和BUG不谈,作为一个NIO服务端,还需要能够处理网络的闪断、客户端的重复接入、客户端的安全认证、消息的编解码、半包读写等情况,如果你没有足够的NIO编程经验积累,一个NIO框架的稳定往往需要半年甚至更长的时间。更为糟糕的是,一旦在生产环境中发生问题,往往会导致跨节点的服务调用中断,严重的可能会导致整个集群环境都不可用,需要重启服务器,这种非正常停机会带来巨大的损失。

从可维护性角度看,由于NIO采用了异步非阻塞编程模型,而且是一个I/O线程处理多条链路,它的调试和跟踪非常麻烦,特别是生产环境中的问题,我们无法进行有效的调试和跟踪,往往只能靠一些日志来辅助分析,定位难度很大。

现在我们总结一下为什么不建议开发者直接使用JDK的NIO类库进行开发,具体原因如下。

1)跨平台与兼容性:NIO算是底层的APIs需依赖系统的IO APIs。但Ja NIO发现在不同系统平台会出现问题。大量测试也耗不少时间;NIO2只支持JDK1.7+,而且没提供DatagramSocket,故NIO2不支持UDP协议。而Netty提供统一接口,同一语句无论在JDK6.X 还是JDK7.X 都可运行,无需关心底层架构功能!

2)JAVA NIO的ByteBuffer构造函数私有,无法扩展。Netty提供了自己的ByteBuffer实现,通过简单APIs对其进行构造、使用和作,一此解决NIO的一些限制。

3)NIO对缓冲区的聚合与分散作可能会导致内存泄漏。直到JDK1.7才解决此问题。

4)NIO的类库和API繁杂,使用麻烦,你需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。

5)使用JAVA NIO需要具备其他的额外技能做铺垫,例如熟悉Ja多线程编程。这是因为NIO编程涉及到Reactor模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的NIO程序。

6)可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题。

7)JDK NIO的BUG,例如臭名昭著的epoll bug,它会导致Selector空轮询,终导致CPU 。声称在JDK 1.6版本的update18修复了该问题,但是直到JDK 1.7版本该问题仍旧存在,只不过该BUG发生概率降低了一些而已,它并没有得到根本性解决。该BUG以及与该BUG相关的问题单可以参见以下链接内容。

异常堆栈如下。

ja.lang.Thread.State: RUNNABLE

at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)

at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.ja:210)

at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.ja:65)

at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.ja:69)

- locked <0x0000000750928190> (a sun.nio.ch.Util$2)

- locked <0x00000007509281a8> (a ja.util.Collections$ UnmodifiableSet)

- locked <0x0000000750946098> (a sun.nio.ch.EPollSelectorImpl)

at sun.nio.ch.SelectorImpl.select(SelectorImpl.ja:80)

at net.spy.memcached.MemcachedConnection.handleIO(Memcached Connection.ja:217)

at net.spy.memcached.MemcachedConnection.run(MemcachedConnection. ja:836)

由于上述原因,在大多数场景下,不建议大家直接使用JDK的NIO类库,除非你精通NIO编程或者有特殊的需求。在绝大多数的业务场景中,我们可以使用NIO框架Netty来进行NIO编程,它既可以作为客户端也可以作为服务端,同时支持UDP和异步文件传输,功能非常强大。

Netty实战三:Netty处理同一个端口上来的多条不同协议的数据

业务场景:跟设备通信,不同的厂家有不同的协议,这时后台服务要兼容,比如说,设备A使用的是String字符串,设备B使用的是byte[],这时候该怎么处理呢,使用自定义解码器,去识别是String,还是byte[],然后转发给相应的业务handler处理

Netty实现长连接的原理

主要逻辑 :

使用netty实现长连接,主要靠心跳来维持服务器端及客户端连接。

主要的实现逻辑如下:

服务器端 :(HeartBeatRespHandler)

1, 服务器在网络空闲作一定时间后,服务端失败心跳计数器加1。

2, 如果收到客户端的ping心跳包,则清零失败心跳计数器,如果连续n次未收到客户端的ping心跳包,则关闭链路,释放资源,等待客户端重连。

客户端 :(HeartBeatReqHandler)

1, 客户端网络空闲在一定时间内没有进行写作时,则发送一个ping心跳包。

2, 如果服务器端未在发送下一个心跳包之前回复pong心跳应答包,则失败心跳计数器加1。

3, 如果客户端连续发送n(此处根据具体业务进行定义)次ping心跳包,服务器端均未回复pong心跳应答包,则客户端断开连接,间隔一定时间进行重连作,直至连接服务器成功。

netty 客户端重连接,用定时器不能实现重连,怎么办

这个要分情况了。 如果是UDP的话,就不存在连接不连接的问题了。因为这个是面向无连接的,直接发送数据即可。 如果是TCP的话,就需要连接了。你应该这么办: 首先每隔一段时间查看是否与服务器断开了,或者根据你具体的要求来查看是否断开。 第...

netty 客户端创建多个连接

netty 客户端需要创建多个连接去连接多个服务端,因为服务方是请求模式,必须我们这边主动发起连接

那是不是我每一个连接都要实例化一个 EventLoopGroup,我觉的不是,EventLoopGroup 是线程池,假设你要连接 10000 个设备,每个连接一个线程都会直接崩掉(10000 个线程要耗费多少资源啊),别说每个连接一个 EventLoopGroup 了。

再说服务端我们有没有每一个连接都创建一个线程呢,没有。服务端一般都是两个线程池, 一个 boss 负责接收连接请求, 一个 work 负责 IO 读写。所以客户端多个连接也是要共用一个 EventLoopGroup 的。客户端不需要接收连接,所以只需要一个EventLoopGroup 就行了。多路复用器 selector 的使用,使得一个线程就可以轮询成千上万个连接。

参考我写的demo理解一下

这里其实演示了首次连接连不上一直重连的场景,还有一种断线重连也很简单, 断线 channeInactivie 时再从新 connect 就行了。

注意 connect(host, port) 后面没有调用 sync 进行同步阻塞,而是注册异步。如果调用 sync 会一直阻塞调用线程直到连接成功或失败。

测试中发现了一个问题, 我的主线程提前结束了,但进程并没有结束,只有把 netty 的线程池 shutdown 以后进程才会退出,这是为什么呢????

因为 JVM 只有在所有非 Daemon 线程都结束时才会退出,由于 netty 的线程还在,所以主线程结束后 JVM 并未退出。

netty http重连机制吗

netty本身实现的长连接,就是一个连接一个worker。worker的数量是有限的(通常是cpu cores+1),所以你的服务器要是连接数多的话,得考虑使用“异步”Request(netty的http没实现这么个功能),或者说“Continuation”,当连接“无事可做”的时候,放...

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息