喜欢大胸只是本能,喜欢贫乳才是审美。 收藏本站
登陆 / 注册 搜索

阅读: 9K   回复: 2

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

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

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

主题破百
        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。
% i% j. y& q' V/ A0 J8 C5 W# J% S' [% Y$ D  r% c8 ]* c2 Q
科普贴——Netty是干嘛的? 1-服务器.png
  ^. Z$ T4 ?% f
        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。
7 i" ?& M& W6 L7 T" P4 b6 Z# ^+ N" x1 ^
科普贴——Netty是干嘛的? 2-服务器.jpg

. V: o0 {5 C( Y4 n9 ^9 I        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。
( W/ r) I& C0 R8 X: p2 T1 U5 }
6 z7 ?( L+ N9 U! }0 l' f# J8 m; T        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。 , x' J$ o6 {4 y! ^/ z
& j( D2 M# e* J, {3 a! J
        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。* p2 ^2 Q5 ^8 b8 }- X0 p" g3 O+ l

3 C1 v  \% G) \2 |        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:+ Q7 ~/ t/ ~! l; p. H- \
        4 ?, k7 P& P  x
        GET /orders/1 HTTP/1.1                                                                                             : N, ], \$ V+ W
        Host: order.myshop.com
. k0 u# K) {5 r        User-Agent: Mozilla/5.0 (Windows NT 6.1; )
* m( _0 X6 u) i4 i. H( w, A. b' f        Accept: text/html;
5 f; [0 J. @) ^0 Z        Accept-Language: en-US,en;
2 y6 X# a! J  `        Accept-Encoding: gzip
/ _2 J8 H, a' k  a1 I; U$ P) a        Connection: keep-alive
' k# c) |! I/ O" h+ b6 ?9 N        ......
$ P( [* a+ U; i$ _8 s
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。
! V& k/ L2 Z8 f! n# }( V) z! X; T" Y$ q0 N8 v
        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。/ K2 c" [& K& ~. c& R  ~  K
/ z1 ~2 O5 c# V9 {2 f: }' k6 A
科普贴——Netty是干嘛的? 3-请求.png
1 H; ?$ h# J9 o9 k- n: [/ c. L
        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。
" A5 Z4 f6 }$ L3 c/ {0 X9 k  y* W' \7 J5 }( g
        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。
: p8 C7 B4 P2 V) l7 i
9 K* z$ M4 ^: R  s% e8 {        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。6 u0 I6 }9 n6 d, ^, U

0 W& C: m1 o- W4 A
科普贴——Netty是干嘛的? 4-请求.png

, Q$ v. `% R4 u1 e        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。2 _9 E. L& u* G3 @! ?# v' N
6 z; `5 @2 u5 P
        好了,就是Java NIO了!
, R5 {8 m+ J' Z5 C( U  p! H0 f$ g4 w0 Y) G1 y- N
        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。
9 j  D+ ]4 A: a9 ?0 L" h& s* N2 d
' Y, p% [! |7 o. L2 q4 [4 P3 S        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。
. R7 ]1 `. u1 K4 g( O0 ~0 d  E4 C( C4 `9 p- t: ^) M/ m
        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。 ' t+ v' M( q7 u% q

! Z* @# j$ E% n! h9 o) H  `' G- J" k
#f465:
) P8 ^& M( @2 F
        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。* c7 h7 L2 S8 g; c. `# l

4 h5 I, Y7 F. \# Z, D* j( l        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!
( f" u, c8 H$ q3 K: g. s/ N# `6 I+ G& m1 q' ]  X
        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?# J' X- _) j) ^) t
6 A' m% n9 j4 ~' L# I
        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:
8 }/ b! n8 [  k% d/ d3 _- e( k9 X" A# R! n& q; F, B
#f465:

9 P; @6 F9 {# a1 G$ S: j* y9 m! F        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。4 q3 |$ M' a! H4 a7 b5 A' Z$ d
9 [" T. y0 |& E; K
        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。4 x  q5 d" g7 f1 X* r$ m- m9 C
, ^4 ?$ d: o' |
        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。
$ a2 M, t4 k! c8 h
) b' @7 [2 \; M8 o        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。
' Y! ^0 ?$ \, d8 n
" v7 f5 }+ g" Y$ ?" }, E$ }" Z9 k        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。 8 |7 {: n6 s4 H
1 Z- `# B# u3 b0 K: k6 @) E
        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。 % e! q/ }0 n& K+ N  X* d1 c
7 r% W6 ~  }0 E) t  _  B$ ^1 D. @
        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。5 a2 V! i, P' T$ O$ E) A

# ]  p9 |( Q2 x        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。( w4 y  a; o; Q' O5 V$ Y' E
0 w- X" t# E, t
本文来自微信公众号:码农翻身(有修改)
+ x9 l' t. i1 B( T' e5 j8 F作者老刘
; b  U. Q7 b, l+ x
$ @8 z( I# A2 v! {3 y- Y4 a
上一篇
下一篇

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

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

我要把你这篇帖子牢牢的记在心里,刻在脑海里;" j$ P8 i6 ~4 N3 R
我要去学活字印刷,把这篇帖子印成铅字;
1 k9 H0 d, Q+ j+ y我要去学雕刻,把这篇帖子雕成雕像;
- t0 i0 M& E3 n) a5 g我要去学作诗,把这篇帖子改为不朽的诗篇;" H- j9 Z9 w! }$ {. t9 x
我要去学作词,把这篇帖子改为歌词;* I5 T" i# v  M2 S* q, t' h$ ]$ H
我要去学歌唱,把这篇帖子广为流唱;
! z6 A$ c; Q1 ~我要去学说梦话,在梦里也要深情的朗诵;
6 J  ~. }3 @: _/ }# M我要去学刺青,把这篇帖子刺在每个人的身上!
# A; u/ n. e5 f$ K8 o0 |: z% ~) j8 T我要做黑客,把所有的网站都改成这篇帖子;) j5 k, G1 H4 b4 c: S7 m
我要做法官,让所有的囚犯都抄写这篇帖子;9 x; n5 s9 m% }* \, [! e4 O1 @
我要做中国移动的董事长,给所有手机用户群发这篇帖子;# l9 c. Z5 ]* V; u! l  u& r# w
我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;( n& m& }9 A. H  L/ {4 E! Q: K
我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏 「出类拔萃」 2018-1-20 22:42 |显示全部楼层

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

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

本版积分规则

快速回复 返回列表