HTTP服务器之因此称为HTTP服务器,是由于编码解码协议是HTTP协议,若是协议是Redis协议,那它就成了Redis服务器,若是协议是WebSocket,那它就成了WebSocket服务器,等等。程序员
使用Netty你就能够定制编解码协议,实现本身的特定协议的服务器。数据库
上面咱们说的是一个传统的多线程服务器,这个也是Apache处理请求的模式。在高并发环境下,线程数量可能会建立太多,操做系统的任务调度压力大,系统负载也会比较高。那怎么办呢?缓存
因而NIO诞生了,NIO并非Java独有的概念,NIO表明的一个词汇叫着IO多路复用。它是由操做系统提供的系统调用,早期这个操做系统调用的名字是select,可是性能低下,后来渐渐演化成了Linux下的epoll和Mac里的kqueue。咱们通常就说是epoll,由于没有人拿苹果电脑做为服务器使用对外提供服务。而Netty就是基于Java NIO技术封装的一套框架。为何要封装,由于原生的Java NIO使用起来没那么方便,并且还有臭名昭著的bug,Netty把它封装以后,提供了一个易于操做的使用模式和接口,用户使用起来也就便捷多了。服务器
那NIO到底是什么东西呢?多线程
NIO的全称是NoneBlocking IO,非阻塞IO,区别与BIO,BIO的全称是Blocking IO,阻塞IO。那这个阻塞是什么意思呢?并发
因此传统的多线程服务器是BlockingIO模式的,从头至尾全部的线程都是阻塞的。这些线程就干等在哪里,占用了操做系统的调度资源,什么事也不干,是浪费。框架
那么NIO是怎么作到非阻塞的呢。它用的是事件机制。它能够用一个线程把Accept,读写操做,请求处理的逻辑全干了。若是什么事都没得作,它也不会死循环,它会将线程休眠起来,直到下一个事件来了再继续干活,这样的一个线程称之为NIO线程。高并发
while true { events = takeEvents(fds) // 获取事件,若是没有事件,线程就休眠 for event in events { if event.isAcceptable { doAccept() // 新连接来了 } elif event.isReadable { request = doRead() // 读消息 if request.isComplete() { doProcess() } } elif event.isWriteable { doWrite() // 写消息 } } }
NIO的流程大体就是上面的伪代码描述的过程,跟实际真实的代码有较多差别,不过对于初学者,这样理解也是足够了。性能
Netty是创建在NIO基础之上,Netty在NIO之上又提供了更高层次的抽象。优化
在Netty里面,Accept链接可使用单独的线程池去处理,读写操做又是另外的线程池来处理。
Accept链接和读写操做也可使用同一个线程池来进行处理。而请求处理逻辑既可使用单独的线程池进行处理,也能够跟放在读写线程一块处理。线程池中的每个线程都是NIO线程。用户能够根据实际状况进行组装,构造出知足系统需求的并发模型。
Netty提供了内置的经常使用编解码器,包括行编解码器[一行一个请求],前缀长度编解码器[前N个字节定义请求的字节长度],可重放解码器[记录半包消息的状态],HTTP编解码器,WebSocket消息编解码器等等。
Netty提供了一些列生命周期回调接口,当一个完整的请求到达时,当一个链接关闭时,当一个链接创建时,用户都会收到回调事件,而后进行逻辑处理。
Netty能够同时管理多个端口,可使用NIO客户端模型,这些对于RPC服务是颇有必要的。
Netty除了能够处理TCP Socket以外,还能够处理UDP Socket。
在消息读写过程当中,须要大量使用ByteBuffer,Netty对ByteBuffer在性能和使用的便捷性上都进行了优化和抽象。
总之,Netty是Java程序员进阶的必备神器。若是你知其然,还想知其因此然,必定要好好研究下Netty。若是你以为Java枯燥无谓,Netty则是从新开启你对Java兴趣大门的钥匙。
转载连接:https://www.zhihu.com/question/24322387/answer/282001188