我决定以人类的一个方法来感激你,我打算以身相许! 收藏本站
登陆 / 注册 搜索

阅读: 7.5K   回复: 2

[# 网络基础] 科普贴——Netty是干嘛的?

仗剑天涯论坛大牛 2017-11-22 00:19 |显示全部楼层

今生相逢便是缘分,何苦去怨恨,何苦去仇视。

主题破百
        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。
: Q9 q0 d( I7 W% C" z2 U
$ X! ^4 J0 M7 u$ m* K0 h- ]
科普贴——Netty是干嘛的? 1-服务器.png
. e0 P. A+ ?0 ]" N7 U, O. E: x
        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。
4 {2 b4 P/ Q# W- |
( j- z& t) J" X1 t# `% G
科普贴——Netty是干嘛的? 2-服务器.jpg

& I& A6 V3 s7 B: O9 z' }        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。& J; e: {2 P. C2 j+ Y

7 ^3 _0 r2 U9 a6 ]        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。
# D. N5 P' w+ ]/ B1 G7 k& E: B
! h/ ~6 V) b8 n5 u3 u7 O        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。
& X! W/ q, {6 d! |3 }
+ R  S, {4 Y4 {7 T/ `4 n2 p        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:
9 N$ b% G) M$ e$ L! n8 t5 r        
( d* D$ l) t0 E9 i
        GET /orders/1 HTTP/1.1                                                                                             
1 `9 V5 N! A! ~        Host: order.myshop.com5 L# S5 I, R0 S  Q, h1 e
        User-Agent: Mozilla/5.0 (Windows NT 6.1; )
* k, ]* p; k5 r8 l        Accept: text/html;) B. K2 O1 v! U1 \5 C2 f0 p
        Accept-Language: en-US,en;
" @& i" ?' W) Q) D+ @% q; v7 c" M        Accept-Encoding: gzip$ l# K  b  w( I! o$ ]
        Connection: keep-alive8 t5 f) X! a& m5 u
        ......
' r5 U! |2 w% ~; V5 p
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。
/ h' |/ ~) _# n5 c, Q$ U! C8 j0 |3 _3 o3 Y
        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。
+ P- x. v: X  \- @0 V! A. y6 x" y8 e2 X$ t5 \' v4 @2 c% i
科普贴——Netty是干嘛的? 3-请求.png
: E# x8 {$ S) @! |
        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。8 U0 {- @' Z1 {3 S
# D( e1 Z" L% l# ?* i! R
        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。9 [/ m0 n* U- A$ G* M

/ X3 X- q" B+ \: c  r3 e+ Y& M        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。+ J4 T5 G# R' @0 L, ?" m# r
; C- O# t- \$ V
科普贴——Netty是干嘛的? 4-请求.png

8 z. p1 @; g) k0 L3 U7 h        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。
9 F4 c. Y; t" r+ c4 L0 t8 _: I% t: [! i- V" B8 s
        好了,就是Java NIO了!: p" D( D, c4 {4 e

4 N' p+ e, r4 a* S- j        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。8 ?( b- P" j+ a  i
: q; i+ R& c$ f
        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。
, c) L0 [% r1 c! c6 d! G
# J, {  G% \3 a  ?$ v3 z        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。
0 C, K* b/ v" Q: E1 f# j: j: y$ V4 y' p) U
#f465:
. h1 F4 W4 X0 T+ o. N2 m) v
        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。- g  p1 o3 i/ h* F! ~3 h( [
2 L5 y* W& q# |- ?* |$ ?
        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!9 r. @, o/ \2 e2 m+ C
# a  c$ R3 q) c# y
        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?
5 Z; E$ n2 B8 E1 I  s- ?% Z+ k# k- ^* P1 F5 w# r! p
        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:, M% j7 B' i! X% S- y8 C! C% C
4 X. B0 |9 z$ N$ Q) ^) ^
#f465:

5 p# M/ ?. C" ~& \: a        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。
1 s( r' @" I4 |: l
3 s. ~) q) }$ t/ T        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。; L/ r6 [3 @1 @: h

( J4 X: S1 W+ y8 I1 C" l        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。7 ?, E+ `, }1 ?6 z9 m4 ^

- M. @5 f' e' ^$ f* l+ h! m        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。# N9 X3 u+ s& W; i5 _# J1 \
* X  F6 B4 v- D0 G- t- T$ |' Z
        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。 / T) q1 F: U2 s9 `7 _

+ V/ B: X  p/ A/ s3 u' @        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。 8 F( G: U; m! s$ U! A% E3 X

4 U7 w/ P$ W& C1 ~+ G- o6 ?        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。
2 g8 T  d9 Z. W6 v
& [; e6 w) G. `# V        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。
# u, ]3 |# r6 u2 w1 K
+ @& `" T% B, @0 W" a7 e  P3 }本文来自微信公众号:码农翻身(有修改)
2 n; Y; @& x+ F1 y, o8 K; l1 q作者老刘
( o  }# ]* h. e) V: B- z  a2 V6 K; V6 K. y+ S0 [4 r: L
上一篇
下一篇


夏雨初晴 「出类拔萃」 2018-1-20 22:41 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

我要把你这篇帖子牢牢的记在心里,刻在脑海里;( @5 ]4 }6 I9 w: T
我要去学活字印刷,把这篇帖子印成铅字;- X8 g7 d* g4 e4 @
我要去学雕刻,把这篇帖子雕成雕像;
% Z6 \3 O* S2 u2 Y$ L$ f, d7 S我要去学作诗,把这篇帖子改为不朽的诗篇;
# n0 z' _/ ?2 K4 F& p3 e- C我要去学作词,把这篇帖子改为歌词;
( M  h5 m2 q8 ?; m' p我要去学歌唱,把这篇帖子广为流唱;
: \4 C; w) S* H, ?# a我要去学说梦话,在梦里也要深情的朗诵;
5 t% }# d! H: w& z我要去学刺青,把这篇帖子刺在每个人的身上!; X6 G) A6 ?6 _% Y- _$ c6 D
我要做黑客,把所有的网站都改成这篇帖子;
) G+ ~2 B* y1 Z5 L* e& U我要做法官,让所有的囚犯都抄写这篇帖子;( ]% f2 H3 P, l' z. [, p
我要做中国移动的董事长,给所有手机用户群发这篇帖子;
/ l2 h4 ~- H  V) _% z9 w# M' B我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;
, ^: J1 S7 U5 j0 L$ n我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏 「出类拔萃」 2018-1-20 22:42 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

感谢分享~
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2021-5-6 23:42 , Processed in 0.038289 second(s), 22 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表