默认
打赏 发表评论 3
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
详解Netty的优雅退出机制和原理
阅读(90504) | 评论(3 收藏9 淘帖1 3
微信扫一扫关注!

一.前言


“退出”是每个程序的必备功能,因为太平常,多数程序员都对这不以为然。但在大型分布式应用中,因各模块、服务等都是分布式部署和协作,这种RPC式的场景下,如何让某个模块或服务优雅地“退出”,则远非调用一个Kill指令这么简单。本文将详述NIO框架Netty是如何实现“优雅”地“退出”的。

1更多NIO框架文章


详见即时通讯网的NIO框架精选文章专辑:http://www.52im.net/forum.php?mod=collection&action=view&ctid=9

2NIO框架源码在线地址


MINA-2.x地址是:http://docs.52im.net/extend/docs/src/mina2/
MINA-1.x地址是:http://docs.52im.net/extend/docs/src/mina1/
Netty-4.x地址是:http://docs.52im.net/extend/docs/src/netty4/
Netty-3.x地址是:http://docs.52im.net/extend/docs/src/netty3/

3NIO框架其它在线资源


MINA-2.x API文档(在线版):http://docs.52im.net/extend/docs/api/mina2/
MINA-1.x API文档(在线版):http://docs.52im.net/extend/docs/api/mina1/
Netty-4.x API文档(在线版):http://docs.52im.net/extend/docs/api/netty4/
Netty-3.x API文档(在线版):http://docs.52im.net/extend/docs/api/netty3/

二.进程的优雅退出


Kill -9 PID带来的问题


在Linux上通常会通过kill -9 pid的方式强制将某个进程杀掉,这种方式简单高效,因此很多程序的停止脚本经常会选择使用kill -9 pid的方式。

无论是Linux的Kill -9 pid还是windows的taskkill /f /pid强制进程退出,都会带来一些副作用:对应用软件而言其效果等同于突然掉电,可能会导致如下一些问题:

  • 缓存中的数据尚未持久化到磁盘中,导致数据丢失;
  • 正在进行文件的write操作,没有更新完成,突然退出,导致文件损坏;
  • 线程的消息队列中尚有接收到的请求消息还没来得及处理,导致请求消息丢失;
  • 数据库操作已经完成,例如账户余额更新,准备返回应答消息给客户端时,消息尚在通信线程的发送队列中排队等待发送,进程强制退出导致应答消息没有返回给客户端,客户端发起超时重试,会带来重复更新问题;
  • 其它问题等...

Java如何优雅地退出


Java的优雅停机通常通过注册JDK的ShutdownHook来实现,当系统接收到退出指令后,首先标记系统处于退出状态,不再接收新的消息,然后将积压的消息处理完,最后调用资源回收接口将资源销毁,最后各线程退出执行。

通常优雅退出需要有超时控制机制,例如30S,如果到达超时时间仍然没有完成退出前的资源回收等操作,则由停机脚本直接调用kill -9 pid,强制退出。

三.如何实现Netty的优雅退出


要实现Netty的优雅退出,首先需要了解通用Java进程的优雅退出如何实现。下面我们先讲解下优雅退出的实现原理,并结合实际代码进行讲解。最后看下如何实现Netty的优雅退出。

信号简介


信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的,它是进程间一种异步通信的机制。以Linux的kill命令为例,kill -s SIGKILL pid (即kill -9 pid) 立即杀死指定pid的进程,SIGKILL就是发送给pid进程的信号。

信号具有平台相关性,Linux平台支持的一些终止进程信号如下所示:

详解Netty的优雅退出机制和原理_QQ20160606-1.png

Windows平台存在一些差异,它的一些信号举例如下:SIGINT(Ctrl+C中断)、SIGILL、SIGTERM (kill发出的软件终止)、SIGBREAK (Ctrl+Break中断)。

信号选择:为了不干扰正常信号的运作,又能模拟Java异步通知,在Linux上我们需要先选定一种特殊的信号。通过查看信号列表上的描述,发现 SIGUSR1 和 SIGUSR2 是允许用户自定义的信号,我们可以选择SIGUSR2,为了测试方便,在Windows上我们可以选择SIGINT。

Java程序的优雅退出


首先看下通用的Java进程优雅退出的流程图:

详解Netty的优雅退出机制和原理_a.png

第一步,应用进程启动的时候,初始化Signal实例,它的代码示例如下:
Signal sig = new Signal(getOSSignalType());
其中Signal构造函数的参数为String字符串,也就是2.1.1小节中介绍的信号量名称。

第二步,根据操作系统的名称来获取对应的信号名称,代码如下:
private String getOSSignalType()
   {
       return System.getProperties().getProperty("os.name").
                 toLowerCase().startsWith("win") ? "INT" : "USR2";
    }
判断是否是windows操作系统,如果是则选择SIGINT,接收Ctrl+C中断的指令;否则选择USR2信号,接收SIGUSR2(等价于kill -12 pid)指令。

第三步,将实例化之后的SignalHandler注册到JDK的Signal,一旦Java进程接收到kill -12 或者 Ctrl+C则回调handle接口,代码示例如下:
Signal.handle(sig, shutdownHandler);

其中shutdownHandler实现了SignalHandler接口的handle(Signal sgin)方法,代码示例如下:

详解Netty的优雅退出机制和原理_2.png

第四步,在接收到信号回调的handle接口中,初始化JDK的ShutdownHook线程,并将其注册到Runtime中,示例代码如下:
private void invokeShutdownHook()
 {
        Thread t = new Thread(new ShutdownHook(), "ShutdownHook-Thread");
        Runtime.getRuntime().addShutdownHook(t);
 }

第五步,接收到进程退出信号后,在回调的handle接口中执行虚拟机的退出操作,示例代码如下:
Runtime.getRuntime().exit(0);

虚拟机退出时,底层会自动检测用户是否注册了ShutdownHook任务,如果有,则会自动将ShutdownHook线程拉起,执行它的Run方法,用户只需要在ShutdownHook中执行资源释放操作即可,示例代码如下:
class ShutdownHook implements Runnable
{
        @Override
        public void run() {
                System.out.println("ShutdownHook execute start...");
                System.out.print("Netty NioEventLoopGroup shutdownGracefully...");
                try {
                        TimeUnit.SECONDS.sleep(10);//模拟应用进程退出前的处理操作
                } catch (InterruptedException e) {
                                e.printStackTrace();
                }
                System.out.println("ShutdownHook execute end...");
        System.out.println("Sytem shutdown over, the cost time is 10000MS");
                }
}

下面我们在Windows环境中对通用的Java优雅退出程序进行测试,打开CMD控制台,拉起待测试程序,如下所示。

启动进程:
详解Netty的优雅退出机制和原理_3.png

查看线程信息,发现注册的ShutdownHook线程没有启动,符合预期:
详解Netty的优雅退出机制和原理_4.png

在控制台执行Ctrl+C,使进程退出,示例如下:
详解Netty的优雅退出机制和原理_5.png

如上图所示,我们定义的ShutdownHook线程在JVM退出时被执行,作为测试程序,它休眠10S之后退出,控制台打印的相关信息如下:
详解Netty的优雅退出机制和原理_6.png

下面我们总结下通用的Java程序优雅退出的技术要点:
详解Netty的优雅退出机制和原理_7.png

Netty的优雅退出


在实际项目中,Netty作为高性能的异步NIO通信框架,往往用作基础通信框架负责各种协议的接入、解析和调度等,例如在RPC和分布式服务框架中,往往会使用Netty作为内部私有协议的基础通信框架。

当应用进程优雅退出时,作为通信框架的Netty也需要优雅退出,主要原因如下:

  • 尽快的释放NIO线程、句柄等资源;
  • 如果使用flush做批量消息发送,需要将积攒在发送队列中的待发送消息发送完成;
  • 正在write或者read的消息,需要继续处理;
  • 设置在NioEventLoop线程调度器中的定时任务,需要执行或者清理。

下面我们看下Netty优雅退出涉及的主要操作和资源对象:

详解Netty的优雅退出机制和原理_8.png

Netty的优雅退出总结起来有三大步操作:

  • 把NIO线程的状态位设置成ST_SHUTTING_DOWN状态,不再处理新的消息(不允许再对外发送消息);
  • 退出前的预处理操作:把发送队列中尚未发送或者正在发送的消息发送完、把已经到期或者在退出超时之前到期的定时任务执行完成、把用户注册到NIO线程的退出Hook任务执行完成;
  • 资源的释放操作:所有Channel的释放、多路复用器的去注册和关闭、所有队列和定时任务的清空取消,最后是NIO线程的退出。

下面我们具体看下如何实现Netty的优雅退出。

Netty优雅退出的接口和总入口在EventLoopGroup,调用它的shutdownGracefully方法即可,相关代码如下:
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();

除了无参的shutdownGracefully方法,还可以指定退出的超时时间和周期,相关接口定义如下:

详解Netty的优雅退出机制和原理_9.png

EventLoopGroup的shutdownGracefully工作原理下个章节做详细讲解,结合Java通用的优雅退出机制,即可实现Netty的优雅退出,相关伪代码如下:
//统一定义JVM退出事件,并将JVM退出事件作为主题对进程内部发布
//所有需要优雅退出的消费者订阅JVM退出事件主题
//监听JVM退出的ShutdownHook被启动之后,发布JVM退出事件
//消费者监听到JVM退出事件,开始执行自身的优雅退出
//如果所有的非守护线程都成功完成优雅退出,进程主动退出
//如果到了退出的超时时间仍然没正常退出,则由停机脚本通过kill -9 pid强杀进程,强制退出

总结一下:

JVM的ShutdownHook被触发之后,调用所有EventLoopGroup实例的shutdownGracefully方法进行优雅退出。由于Netty自身对优雅退出有较完善的支持,所以实现起来相对比较简单。

一些误区


在实际工作中,由于对优雅退出和资源释放的原理不太清楚,或者对Netty的接口不太了解,很容易把优雅退出和资源释放混淆,导致出现各种问题。

如下案例:本意是想把某个Channel关闭,但是却调用了Channel关联的EventLoop的shutdownGracefully,导致把EventLoop线程和注册在该线程持有的多路复用器上所有的Channel都关闭了。

错误代码如下所示:
ctx.channel().eventLoop().shutdownGracefully();

正确的做法如下所示:调用channel的close方法,关闭链路,释放与该Channel相关的资源:
ctx.channel().close();

除非是整个进程优雅退出,一般情况下不会调用EventLoopGroup和EventLoop的shutdownGracefully方法,更多的是链路channel的关闭和资源释放。

四.Netty优雅退出原理分析


Netty优雅退出涉及到线程组、线程、链路、定时任务等,底层实现细节非常复杂,下面我们就层层分解,通过源码来剖析它的实现原理。

NioEventLoopGroup


NioEventLoopGroup实际是NioEventLoop的线程组,它的优雅退出比较简单,直接遍历EventLoop数组,循环调用它们的shutdownGracefully方法,源码如下:

详解Netty的优雅退出机制和原理_1.png

NioEventLoop


调用NioEventLoop的shutdownGracefully方法,首先就是要修改线程状态为正在关闭状态,它的实现在父类SingleThreadEventExecutor中,它们的继承关系如下:

详解Netty的优雅退出机制和原理_2.png

SingleThreadEventExecutor的shutdownGracefully代码比较简单,就是修改线程的状态位,需要注意的是修改时需要对并发调用做判断,如果是由NioEventLoop自身调用,则不需要加锁,否则需要加锁,代码如下:

详解Netty的优雅退出机制和原理_3.png

解释下为什么要加锁,因为shutdownGracefully是public的方法,任何能够获取到NioEventLoop的代码都可以调用它,在Netty中,业务代码通常不需要直接获取NioEventLoop并操作它,但是Netty对NioEventLoop做了比较厚的封装,它不仅仅只能读写消息,还能够执行定时任务,并作为线程池执行用户自定义Task。因此在Channel中将获取NioEventLoop的方法开放了出来,这就意味着用户只要能够获取到Channel,理论上就会存在并发执行shutdownGracefully的可能,因此在优雅退出的时候做了并发保护。

完成状态修改之后,剩下的操作主要在NioEventLoop中进行,代码如下:

详解Netty的优雅退出机制和原理_4.png

我们继续看下closeAll的实现,它的原理是把注册在selector上的所有Channel都关闭,但是有些Channel正在发送消息,暂时还不能关,需要稍后再执行,核心代码如下:

详解Netty的优雅退出机制和原理_5.png

循环调用Channel Unsafe的close方法,下面我们跳转到Unsafe中,对close方法进行分析。

AbstractUnsafe


AbstractUnsafe的close方法主要做了如下几件事:

1.判断当前该链路是否有消息正在发送,如果有则将关闭操作封装成Task放到eventLoop中稍后再执行:
详解Netty的优雅退出机制和原理_a.png

2.将发送队列清空,不再允许发送新的消息:
详解Netty的优雅退出机制和原理_b.png

3.调用SocketChannel的close方法,关闭链路:
详解Netty的优雅退出机制和原理_c.png

4.调用pipeline的fireChannelInactive,触发链路关闭通知事件:
详解Netty的优雅退出机制和原理_d.png

5.最后是调用deregister,从多路复用器上取消SelectionKey:
详解Netty的优雅退出机制和原理_e.png

至此,优雅退出流程已经完成,这是否意味着NioEventLoop线程可以退出了,其实并非如此。

在此处,只是做了Channel的关闭和从Selector上的去注册,总结如下:

  • 通过inFlush0来判断当前是否正在发送消息,如果是,则不执行Channel关闭动作,放入NIO线程的任务队列中稍后再执行close()操作;
  • 因为已经不允许新的发送消息加入,一旦发送操作完成,就执行链路关闭、触发链路关闭事件和从Selector上取消注册操作。

之前已经说了,NioEventLoop除了I/O读写之外,还兼具定时任务执行、关闭ShutdownHook的执行等,如果此时有到期的定时任务,即使Chanel已经关闭,但是仍然需要继续执行,线程不能退出。下面我们具体分析下TaskQueue的处理流程。

TaskQueue


NioEventLoop执行完closeAll()操作之后,需要调用confirmShutdown看是否真的能够退出,它的处理逻辑如下。

1.执行TaskQueue中排队的Task,代码如下:
详解Netty的优雅退出机制和原理_1.png

2.执行注册到NioEventLoop中的ShutdownHook,代码如下:
详解Netty的优雅退出机制和原理_2.png

3.判断是否到达优雅退出的指定超时时间,如果达到或者过了超时时间,则立即退出,代码如下:
详解Netty的优雅退出机制和原理_3.png

4.如果没到达指定的超时时间,暂时不退出,每隔100MS检测下是否有新的任务加入,有则继续执行:
详解Netty的优雅退出机制和原理_4.png

在confirmShutdown方法中,夹杂了一些对已经废弃的shutdown()方法的处理,例如:
详解Netty的优雅退出机制和原理_5.png

调用新的shutdownGracefully系列方法,该判断条件是永远都不会成立的,因此对于已经废弃的shutdown相关的处理逻辑,不再详细分析。

到此为止,confirmShutdown方法讲解完毕,confirmShutdown返回true,则NioEventLoop线程正式退出,Netty的优雅退出完成,代码如下:
详解Netty的优雅退出机制和原理_6.png

疑问解答


1runAllTasks重复执行问题


在NioEventLoop的run方法中,已经调用了runAllTasks方法,为何紧随其后,在confirmShutdown中有继续调用runAllTasks方法呢,疑问代码如下:

详解Netty的优雅退出机制和原理_1.png

原因主要有两个:

  • 为了防止定时任务Task或者用户自定义的线程Task的执行过多占用NioEventLoop线程的调度资源,Netty对NioEventLoop线程I/O操作和非I/O操作时间做了比例限制,即限制非I/O操作的执行时间,如上图红框中代码所示。有了执行时间限制,因此可能会导致已经到期的定时任务、普通任务没有执行完,需要等待下次Selector轮询继续执行。在线程退出之前,需要对本该执行但是没有执行完成的Task进行扫尾处理,所以在confirmShutdown中再次调用了runAllTasks方法;
  • 在调用runAllTasks方法之后,执行confirmShutdown之前,用户向NioEventLoop中添加了新的普通任务或者定时任务,因此需要在退出之前再次遍历并处理一遍Task Queue。

2优雅退出是否能够保证所有在通信线程排队的消息全部发送出去


实际是无法保证的,它只能保证如果现在正在发送消息过程中,调用了优雅退出方法,此时不会关闭链路,继续发送,如果发送操作完成,无论是否还有消息尚未发送出去,在下一轮Selector的轮询中,链路将会关闭,没有发送完成的消息将会被丢弃,甚至是半包消息。

它的处理原理图如下:

详解Netty的优雅退出机制和原理_2.png

它的原理比较复杂,现对主要逻辑处理进行解读:

  • 调用优雅退出之后,是否关闭链路,判断标准是inFlush0是否为true,如果为False,则会执行链路关闭操作;
  • 如果用户是类似批量发送,例如每达到N条或者定时触发flush操作,则在此期间调用优雅退出方法,inFlush0为False,链路关闭,积压的待发送消息会被丢弃掉;
  • 如果优雅退出时链路正好在发送消息过程中,则它不会立即退出,等待发送完成之后,下次Selector轮询的时候才退出。在这种场景下,又有两种可能的场景。

场景A:如果一次把积压的消息全部发送完,没有发生写半包,则不会发生消息丢失。

场景B:如果一次没有把消息发送完成,此时Netty会监听写事件,触发Selector的下一次轮询并发送消息,代码如下:
详解Netty的优雅退出机制和原理_3.png

Selector轮询时,首先处理读写事件,然后再处理定时任务和普通任务,因此在链路关闭之前,还有最后一次继续发送的机会,代码如下:
详解Netty的优雅退出机制和原理_4.png

如果非常不幸,再次发送仍然没有把积压的消息全部发送完毕,再次发生了写半包,那无论是否有积压消息,执行AbstractUnsafe.close的Task还是会把链路给关闭掉,原因是只要完成一次消息发送操作,Netty就会把inFlush0置为false,代码如下:
详解Netty的优雅退出机制和原理_5.png
链路关闭之后,所有尚未发送的消息都将被丢弃。

可能有些读者会有疑问,如果在第二次发送之后,执行AbstractUnsafe.close之前,业务正好又调用了flush操作,inFlush0是否会被修改成True呢?这个是不可能的,因为从Netty 4.X之后线程模型发生了变更,flush操作不是由用户线程执行,而是由Channel对应的NioEventLoop线程执行,所以在两者之间不会发生inFlush0被修改的情况。

Netty 4.X之后的线程模型如下所示:

详解Netty的优雅退出机制和原理_6.png

另外,由于优雅退出有超时时间,如果在超时时间内没有完成积压消息的发送,也会发生消息丢弃的情况。对于上述场景,需要应用层来保证相关的可靠性,或者对Netty的优雅退出机制进行优化。

五.作者简介


详解Netty的优雅退出机制和原理_045312ioz3mphxbxn4p584.jpg 李林锋

2007年毕业于东北大学,2008年进入华为公司从事高性能通信软件的设
计和开发工作,有6年NIO设计和开发经验,精通Netty、Mina等NIO框架。
Netty中国社区创始人,《Netty权威指南》作者。
联系方式:新浪微博 Nettying 微信:Nettying。

全站即时通讯技术资料分类


[1] 网络编程基础资料:
TCP/IP详解 - 第11章·UDP:用户数据报协议
TCP/IP详解 - 第17章·TCP:传输控制协议
TCP/IP详解 - 第18章·TCP连接的建立与终止
TCP/IP详解 - 第21章·TCP的超时与重传
技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)
通俗易懂-深入理解TCP协议(上):理论基础
通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理
理论经典:TCP协议的3次握手与4次挥手过程详解
理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程
计算机网络通讯协议关系图(中文珍藏版)
UDP中一个包的大小最大能多大?
P2P技术详解(一):NAT详解——详细原理、P2P简介
P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
P2P技术详解(三):P2P技术之STUN、TURN、ICE详解
通俗易懂:快速理解P2P技术中的NAT穿透原理
高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少
高性能网络编程(二):上一个10年,著名的C10K并发连接问题
高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了
高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索
不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)
不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)
不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT
不为人知的网络编程(四):深入研究分析TCP的异常关闭
不为人知的网络编程(五):UDP的连接性和负载均衡
不为人知的网络编程(六):深入地理解UDP协议并用好它
网络编程懒人入门(一):快速理解网络通信协议(上篇)
网络编程懒人入门(二):快速理解网络通信协议(下篇)
网络编程懒人入门(三):快速理解TCP协议一篇就够
网络编程懒人入门(四):快速理解TCP和UDP的差异
Netty干货分享:京东京麦的生产级TCP网关技术实践总结
>> 更多同类文章 ……

[2] NIO异步网络编程资料:
Java新一代网络编程模型AIO原理及Linux系统AIO介绍
有关“为何选择Netty”的11个疑问及解答
开源NIO框架八卦——到底是先有MINA还是先有Netty?
选Netty还是Mina:深入研究与对比(一)
选Netty还是Mina:深入研究与对比(二)
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
Netty 4.x学习(一):ByteBuf详解
Netty 4.x学习(二):Channel和Pipeline详解
Netty 4.x学习(三):线程模型详解
Apache Mina框架高级篇(一):IoFilter详解
Apache Mina框架高级篇(二):IoHandler详解
MINA2 线程原理总结(含简单测试实例)
Apache MINA2.0 开发指南(中文版)[附件下载]
MINA、Netty的源代码(在线阅读版)已整理发布
解决MINA数据传输中TCP的粘包、缺包问题(有源码)
解决Mina中多个同类型Filter实例共存的问题
实践总结:Netty3.x升级Netty4.x遇到的那些坑(线程篇)
实践总结:Netty3.x VS Netty4.x的线程模型
详解Netty的安全性:原理介绍、代码演示(上篇)
详解Netty的安全性:原理介绍、代码演示(下篇)
详解Netty的优雅退出机制和原理
NIO框架详解:Netty的高性能之道
Twitter:如何使用Netty 4来减少JVM的GC开销(译文)
绝对干货:基于Netty实现海量接入的推送服务技术要点
Netty干货分享:京东京麦的生产级TCP网关技术实践总结
>> 更多同类文章 ……

[3] 有关IM/推送的通信格式、协议的选择:
简述传输层协议TCP和UDP的区别
为什么QQ用的是UDP协议而不是TCP协议?
移动端即时通讯协议选择:UDP还是TCP?
如何选择即时通讯应用的数据传输格式
强列建议将Protobuf作为你的即时通讯应用数据传输格式
全方位评测:Protobuf性能到底有没有比JSON快5倍?
移动端IM开发需要面对的技术问题(含通信协议选择)
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
理论联系实际:一套典型的IM通信协议设计详解
58到家实时消息系统的协议设计等技术实践分享
详解如何在NodeJS中使用Google的Protobuf
>> 更多同类文章 ……

[4] 有关IM/推送的心跳保活处理:
应用保活终极总结(一):Android6.0以下的双进程守护保活实践
应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)
应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)
Android进程保活详解:一篇文章解决你的所有疑问
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
深入的聊聊Android消息推送这件小事
为何基于TCP协议的移动端IM仍然需要心跳保活机制?
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
>> 更多同类文章 ……

[5] 有关WEB端即时通讯开发:
新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
新手快速入门:WebSocket简明教程
WebSocket详解(一):初步认识WebSocket技术
WebSocket详解(二):技术原理、代码演示和应用案例
WebSocket详解(三):深入WebSocket通信协议细节
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器
使用WebSocket和SSE技术实现Web端消息推送
详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
>> 更多同类文章 ……

[6] 有关IM架构设计:
浅谈IM系统的架构设计
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT
微信后台基于时间序的海量数据冷热分级架构设计实践
微信技术总监谈架构:微信之道——大道至简(演讲全文)
如何解读《微信技术总监谈架构:微信之道——大道至简》
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
17年的实践:腾讯海量产品的技术方法论
移动端IM中大规模群消息的推送如何保证效率、实时性?
现代IM系统中聊天消息的同步和存储方案探讨
>> 更多同类文章 ……

[7] 有关IM安全的文章:
即时通讯安全篇(一):正确地理解和使用Android端加密算法
即时通讯安全篇(二):探讨组合加密算法在IM中的应用
即时通讯安全篇(三):常用加解密算法与通讯安全讲解
即时通讯安全篇(四):实例分析Android中密钥硬编码的风险
即时通讯安全篇(五):对称加密技术在Android平台上的应用实践
即时通讯安全篇(六):非对称加密技术的原理与应用实践
传输层安全协议SSL/TLS的Java平台实现简介和Demo演示
理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享
简述实时音视频聊天中端到端加密(E2EE)的工作原理
移动端安全通信的利器——端到端加密(E2EE)技术详解
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
通俗易懂:一篇掌握即时通讯的消息传输安全原理
>> 更多同类文章 ……

[8] 有关实时音视频开发:
专访微信视频技术负责人:微信实时视频聊天技术的演进
即时通讯音视频开发(一):视频编解码之理论概述
即时通讯音视频开发(二):视频编解码之数字视频介绍
即时通讯音视频开发(三):视频编解码之编码基础
即时通讯音视频开发(四):视频编解码之预测技术介绍
即时通讯音视频开发(五):认识主流视频编码技术H.264
即时通讯音视频开发(六):如何开始音频编解码技术的学习
即时通讯音视频开发(七):音频基础及编码原理入门
即时通讯音视频开发(八):常见的实时语音通讯编码标准
即时通讯音视频开发(九):实时语音通讯的回音及回音消除概述
即时通讯音视频开发(十):实时语音通讯的回音消除技术详解
即时通讯音视频开发(十一):实时语音通讯丢包补偿技术详解
即时通讯音视频开发(十二):多人实时音视频聊天架构探讨
即时通讯音视频开发(十三):实时视频编码H.264的特点与优势
即时通讯音视频开发(十四):实时音视频数据传输协议介绍
即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况
即时通讯音视频开发(十六):移动端实时音视频开发的几个建议
即时通讯音视频开发(十七):视频编码H.264、VP8的前世今生
实时语音聊天中的音频处理与编码压缩技术简述
网易视频云技术分享:音频处理与压缩技术快速入门
学习RFC3550:RTP/RTCP实时传输协议基础知识
简述开源实时音视频技术WebRTC的优缺点
良心分享:WebRTC 零基础开发者教程(中文)
开源实时音视频技术WebRTC中RTP/RTCP数据传输协议的应用
基于RTMP数据传输协议的实时流媒体技术研究(论文全文)
声网架构师谈实时音视频云的实现难点(视频采访)
浅谈开发实时视频直播平台的技术要点
还在靠“喂喂喂”测试实时语音通话质量?本文教你科学的评测方法!
实现延迟低于500毫秒的1080P实时音视频直播的实践分享
移动端实时视频直播技术实践:如何做到实时秒开、流畅不卡
如何用最简单的方法测试你的实时音视频方案
技术揭秘:支持百万级粉丝互动的Facebook实时视频直播
简述实时音视频聊天中端到端加密(E2EE)的工作原理
移动端实时音视频直播技术详解(一):开篇
移动端实时音视频直播技术详解(二):采集
移动端实时音视频直播技术详解(三):处理
移动端实时音视频直播技术详解(四):编码和封装
移动端实时音视频直播技术详解(五):推流和传输
移动端实时音视频直播技术详解(六):延迟优化
理论联系实际:实现一个简单地基于HTML5的实时视频直播
IM实时音视频聊天时的回声消除技术详解
浅谈实时音视频直播中直接影响用户体验的几项关键技术指标
如何优化传输机制来实现实时音视频的超低延迟?
首次披露:快手是如何做到百万观众同场看直播仍能秒开且不卡顿的?
实时通信RTC技术栈之:视频编解码
开源实时音视频技术WebRTC在Windows下的简明编译教程
Android直播入门实践:动手搭建一套简单的直播系统
>> 更多同类文章 ……

[9] IM开发综合文章:
移动端IM中大规模群消息的推送如何保证效率、实时性?
移动端IM开发需要面对的技术问题
开发IM是自己设计协议用字节流好还是字符流好?
请问有人知道语音留言聊天的主流实现方式吗?
IM消息送达保证机制实现(一):保证在线实时消息的可靠投递
IM消息送达保证机制实现(二):保证离线消息的可靠投递
如何保证IM实时消息的“时序性”与“一致性”?
一个低成本确保IM消息时序的方法探讨
IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?
IM群聊消息如此复杂,如何保证不丢不重?
谈谈移动端 IM 开发中登录请求的优化
移动端IM登录时拉取数据如何作到省流量?
浅谈移动端IM的多点登陆和消息漫游原理
完全自已开发的IM该如何设计“失败重试”机制?
通俗易懂:基于集群的移动端IM接入层负载均衡方案分享
微信对网络影响的技术试验及分析(论文全文)
即时通讯系统的原理、技术和应用(技术论文)
开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀
QQ音乐团队分享:Android中的图片压缩技术详解(上篇)
QQ音乐团队分享:Android中的图片压缩技术详解(下篇)
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(下篇)
如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?
>> 更多同类文章 ……

[10] 开源移动端IM技术框架资料:
开源移动端IM技术框架MobileIMSDK:快速入门
开源移动端IM技术框架MobileIMSDK:常见问题解答
开源移动端IM技术框架MobileIMSDK:压力测试报告
>> 更多同类文章 ……

[11] 有关推送技术的文章:
iOS的推送服务APNs详解:设计思路、技术原理及缺陷等
信鸽团队原创:一起走过 iOS10 上消息推送(APNS)的坑
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
扫盲贴:认识MQTT通信协议
一个基于MQTT通信协议的完整Android推送Demo
IBM技术经理访谈:MQTT协议的制定历程、发展现状等
求教android消息推送:GCM、XMPP、MQTT三种方案的优劣
移动端实时消息推送技术浅析
扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别
绝对干货:基于Netty实现海量接入的推送服务技术要点
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
为何微信、QQ这样的IM工具不使用GCM服务推送消息?
极光推送系统大规模高并发架构的技术实践分享
从HTTP到MQTT:一个基于位置服务的APP数据通信实践概述
魅族2500万长连接的实时消息推送架构的技术实践分享
专访魅族架构师:海量长连接的实时消息推送系统的心得体会
深入的聊聊Android消息推送这件小事
基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)
一个基于长连接的安全可扩展的订阅/推送服务实现思路
实践分享:如何构建一套高可用的移动端消息推送系统?
Go语言构建千万级在线的高并发消息推送系统实践(来自360公司)
腾讯信鸽技术分享:百亿级实时消息推送的实战经验
百万在线的美拍直播弹幕系统的实时推送技术实践之路
>> 更多同类文章 ……

[12] 更多即时通讯技术好文分类:
http://www.52im.net/forum.php?mod=collection&op=all

(原文链接:http://www.infoq.com/cn/articles/netty-elegant-exit-mechanism-and-principles

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:传输层安全协议SSL/TLS的Java平台实现简介和Demo演示下一篇:NIO框架详解:Netty的高性能之道

本帖已收录至以下技术专辑

推荐方案
评论 3
尼玛,一个退出机制都钻研的这么深。。。
先收藏,需要的时候再看了,原谅我现在看不进去
签名: 该会员没有填写今日想说内容.
写的真详细,收藏备查。
签名: 星期六,那又怎样,还是得上班
很详细,太棒了
签名: 春节快乐
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部