随着移动互联网的爆发性增加,小明公司的电子商务系统访问量愈来愈大,因为现有系统是个单体的巨型应用,已经没法知足海量的并发请求,拆分势在必行。html
在微服务的大潮之中, 架构师小明把系统拆分红了多个服务,根据须要部署在多个机器上,这些服务很是灵活,能够随着访问量弹性扩展。编程
世界上没有免费的午饭, 拆分红多个“微服务”之后虽然增长了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。浏览器
好比说:原来用户下一个订单须要登陆,浏览产品详情,加入购物车,支付,扣库存等一系列操做,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。 安全
如今好了,服务被安置到了不一样的服务器上,一个订单流程,几乎每一个操做都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上之前了。服务器
远程过程调用的初版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,可是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:网络
GET /orders/1 HTTP/1.1 架构
Host: order.myshop.com并发
User-Agent: Mozilla/5.0 (Windows NT 6.1; )框架
Accept: text/html;socket
Accept-Language: en-US,en;
Accept-Encoding: gzip
Connection: keep-alive
......
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!可是我这里是程序之间的调用,用这个HTTP有点亏。
能不能自定义一个精简的协议? 在这个协议中我只须要把要调用方法名和参数发给服务器便可,根本不用这么多乱七八糟的额外信息。
可是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤为是服务器端,得可以处理高并发的访问请求才行。
小明复习了一下服务器端的socket编程,最先的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的链接的话须要建立多个线程, 一个线程对应一个。
这种方式写起来却是挺简单的,可是链接(socket)多了就受不了了,若是真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。
更重要的是,虽然有大量的socket,可是真正须要处理的(能够读写数据的socket)却很少,大量的线程处于等待数据状态(这也是为何叫作阻塞的缘由),资源浪费得让人心疼。
后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫作New IO), 改变了一下思路:经过多路复用的方式让一个线程去处理多个Socket。
这样一来,只须要使用少许的线程就能够搞定多个socket了,线程只须要经过Selector去查一下它所管理的socket集合,哪一个Socket的数据准备好了,就去处理哪一个Socket,一点儿都不浪费。
好了,就是Java NIO了!
小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。而后雄心勃勃地要把这个协议用Java NIO给实现了。
但是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到本身陷入了一个大坑之中,Java NIO虽然看起来简单,可是API仍是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本没法驾驭,根本作不到高并发状况下的可靠和高效。
小明不死心,继续向领导要人要资源,必定要把这个坑给填上,挣扎了6个月之后,终于实现了一个本身的NIO框架,能够执行高并发的RPC调用了。
而后又是长达6个月的修修补补,小明常常半夜被叫醒:生产环境的RPC调用没法返回了! 这样的Bug不知道改了多少个。
在那些不眠之夜中,小明常常仰天长叹:我用NIO作个高并发的RPC框架怎么这么难呐!
一年以后,自研的框架终于稳定,但是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,能够快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你能够在Netty上轻松实现各类自定义的协议!我们也试试?
小明赶忙研究,看完后不禁得“泪流满面”:这东西怎么不早点出来啊!
好了,这个故事我快编不下去了,要烂尾了。
说说Netty究竟是何方神圣, 要解决什么问题吧。
像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是本身定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。
其实游戏领域是个更好的例子,长链接,自定义协议,高并发,Netty就是绝配。
由于Netty自己就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。
注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来作点定制,利用它开发出本身的应用程序,而后才能运行(就像使用Spring那样)。
一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。
另一个关键词是高性能,若是你的应用根本没有高并发的压力,那就不必定要用Netty了。