## 流量暴涨
随着流量上涨,现有的系统无法满足海量并发请求,架构师把系统拆分成多个服务,根据需要在多个机器上,这些服务非常灵活,可以随访问量弹性扩展
![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180823140740.png?picgo)
但是拆分成微服务之后增加了弹性,但也带来了巨大的挑战:服务之间互相调用的开销增加了。
比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。
现在因为都被安置在不同的服务器上,一个订单流程,几乎所有的操作都要跨越网络,都是**远程过程调用(RPC)**,执行时间和执行效率都不比以前了。
## RPC
远程过程调用的第一版实现使用了HTTP协议,虽然简单明了,但是废话太多。比如说简单发一个消息就会附带一堆无用的信息
~~~
Host: order.myshop.com
User-Agent: Mozilla/5.0 (Windows NT 6.1;)
Accept: text/html;
Accept-Language: en-US,en;
Accept-Encoding: gzip
Connection: keep-alive
......
~~~
看看那 User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个 HTTP 有点亏
能否定义一个精简的协议,这个协议只需要把调用方法名和参数发给服务器即可。
但是自定义协议客户端和服务器端就直接使用低级的Socket,尤其是服务器端,得能处理高并发访问请求才行。
最早的Java IO是所谓的阻塞IO,想处理多个socket的话,需要创建多个线程。
![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180823143543.png?picgo)
这种方式如果有多个线程同时处理多个socket,即占空间,线程之间的切换开销也巨大
更重要的是,虽然socket很多,但是真正需要处理的(可以读写数据的socket)却不多,大量线程处于等待状态(这也是为什么是阻塞IO的原因)
后来Java又搞了个NIO,通过多路复用的方式让一个线程处理多个Socket
![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180823143731.png?picgo)
线程只需要通过Selector去查一下所管理的socket集合,哪个socket准备好了,就去处理哪个socket
人们先定义了一套精简的RPC协议,里面规定了如何调用一个服务,方法名和参数如何传递,返回值用啥格式。然后想用Java NIO来实现。
但是Java NIO看上去很简单,但API还是太低级了
不过有个叫Netty的开源框架,可以快速得开发高性能面向协议的服务器和客户端。
想使用 Java NIO 来实现一个高性能的 RPC 框架,调用协议,数据的格式和次序都是自己定义的,现有的 HTTP 根本玩不转,那使用 Netty 就是绝佳的选择。
其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty 就是绝配。
因为 Netty 本身就是一个基于 NIO 的网络框架, 封装了 Java NIO 那些复杂的底层细节,给你提供简单好用的抽象概念来编程。
注意几个关键词,首先它是个**框架**,是个 “半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用 Spring 那样)。
一个更加知名的例子就是阿里巴巴的 Dubbo 了,这个 RPC 框架的底层用的就是 Netty。
另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用 Netty 了。