随着移动互联网的爆发式增长,小明电商系统的访问量越来越大。由于现有系统是一个单一的巨型应用,已经不能满足海量的并发请求。拆分势在必行。在微服务大潮中,架构师小明将系统拆分成多个服务,按需部署在多台机器上。这些服务非常灵活,可以随流量弹性扩展。世界上没有免费的午餐。拆分成多个“微服务”虽然增加了灵活性,但也带来了一个巨大的挑战:服务之间相互调用的开销。例如:原来用户需要登录才能进行下单、浏览商品详情、添加购物车、支付、扣除库存等操作。在单个应用程序的情况下,它们都在一台机器的同一个进程中。说白了,它们就是模块。函数调用之间,效率超高。现在好了,服务已经放在不同的服务器上了。在一个订单流程中,几乎每一个操作都要经过网络,都是远程过程调用(RPC)。执行时间和执行效率都远不如以前。第一个版本的远程过程调用实现使用HTTP协议,也就是说每个服务对外提供一个HTTP接口。小明发现HTTP协议虽然简单明了,但是废话太多了。仅仅向服务器发送一条简单的消息会附加很多无用的信息:GET/orders/1HTTP/1.1Host:order.myshop.comUser-Agent:Mozilla/5.0(WindowsNT6.1;)Accept:text/html;接受语言:en-US,en;Accept-Encoding:gzipConnection:keep-alive......你看那个User-Agent,Accept-Language,这个协议分明是为浏览器而生的!但是我这里是程序间调用,用这个HTTP有点吃亏。你能定制一个简化的协议吗?在这个协议中,我只需要将要调用的方法名和参数发送给服务器即可,不需要那么多乱七八糟的附加信息。但是,自定义协议的客户端和服务端必须直接使用“低级”的Socket,尤其是服务端,必须能够处理高并发的访问请求。小明复习了服务器端socket编程。最早的Java就是所谓的阻塞IO(BlockingIO)。如果要处理多个socket连接,需要创建多个线程,一线程一对应。这个方法写起来挺简单的,但是如果connections(sockets)太多就受不了了。如果真的有上千个线程同时处理上千个socket的话,会占用很大的空间。在线程之间切换是一个巨大的开销。更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)并不多,大量的线程在等待数据(这就是为什么叫阻塞),资源的浪费是巨大的。苦恼。后来为了解决这个问题,Java开发了一种非阻塞IO(NIO:Non-BlockingIO,也有人称之为NewIO),改变了思路:通过多路复用让一个线程处理多个Socket。这样就可以只用少量的线程来处理多个套接字。线程只需要检查它通过选择器管理的套接字集合。哪个套接字的数据准备好,哪个套接字将被处理。没有浪费。嗯,这就是JavaNIO!小明首先定义了一套简化的RPC协议,规定了如何调用一个服务,如何传递方法名和参数,返回值使用什么格式……等等。那么雄心勃勃的就是用JavaNIO来实现这个协议。但美好的理想很快被无情的现实击碎。经过一周的努力,小明发现自己掉进了一个大坑。JavaNIO虽然看起来简单,但是API还是太“低级”了。复杂性,没有强大一流的编程能力是无法控制的,不可能做到高并发下的可靠高效。小明并没有死心,继续向领导和要人索要资源。这个坑,他必须要填。经过6个月的奋斗,他终于实现了自己的NIO框架,可以执行高并发的RPC调用。然后又是6个月的修修补补,小明经常半夜被惊醒:生产环境的RPC调用无法返回!这样的bug不知道改了多少。那些不眠之夜,小明时常仰天长叹:我用NIO搭建一个高并发RPC框架,为什么这么难!一年后,自研框架终于稳定下来,但小明也从张胖子那里听到了一个让他崩溃的消息:小明,你知道吗?有一个名为Netty的开源框架,可以快速开发高性能的面向协议的服务端和客户端。易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义协议!我们也试试?小明连忙研究起来,看完后忍不住“泪流满面”:这东西怎么不早点出来!好吧,我不能再编这个故事了,它要写不完了。先说说Netty是谁,它想解决什么问题。像上面小明的例子,如果你想用JavaNIO实现一个高性能的RPC框架,调用协议、数据格式和顺序都是自己定义的,现有的HTTP根本行不通,那么使用Netty就是一个很好的选择。其实游戏领域是一个更好的例子。Netty非常适合长连接、自定义协议和高并发。因为Netty本身是一个基于NIO的网络框架,它封装了JavaNIO复杂的底层细节,为你提供了简单易用的编程抽象概念。注意几个关键词。首先,它是一个框架,是一个“半成品”。它不能开箱即用。你必须拿它做一些定制,用它来开发你自己的应用程序,然后它才能运行(就像使用Spring一样)。一个比较知名的例子是阿里巴巴的Dubbo。这个RPC框架的底层是Netty。另一个关键词是高性能。如果你的应用完全没有高并发压力,那你可以不用Netty。【本文为专栏作家“刘欣”原创稿件,转载请通过作者微信获取授权公众号coderising】点此查看该作者更多好文
