我要拼,装上假牙也要拼! 收藏本站
登陆 / 注册 搜索

阅读: 8.4K   回复: 2

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

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

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

主题破百
        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。' R' `/ M) J- O

2 b, e: z' J: p
科普贴——Netty是干嘛的? 1-服务器.png

6 |7 e* v' }* ^! ~        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。6 D6 u$ L+ b+ R& D: k2 t
( a0 D: Y1 ~2 m5 y: P9 d/ ?# k1 G
科普贴——Netty是干嘛的? 2-服务器.jpg

4 k7 d  u0 `# ]# @/ ^; p3 U. s        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。7 b( O( d6 U2 w7 F6 T; X! H' k& H$ A

; T2 j  A6 D3 v, n! N# x$ x; p" c        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。 6 d6 G  P4 S% E0 ]6 @7 i0 t, r7 O

' D; W! B" e3 m5 Y& t) q- Z, Q        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。
' D) [+ |/ v% y* j" f7 B: H6 H( I* z# y! k: \
        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:
7 y% g# D2 U/ N, J* s7 m        & x& C8 u  u: w: a# p
        GET /orders/1 HTTP/1.1                                                                                             1 B2 ]0 [# M7 w% I0 m
        Host: order.myshop.com
3 p) I; u5 M9 K3 \/ J        User-Agent: Mozilla/5.0 (Windows NT 6.1; )7 n- p2 g/ e9 X( @
        Accept: text/html;3 Q* Q+ x1 E3 x2 u3 z
        Accept-Language: en-US,en;
) A0 Z. }8 f: {1 ?! J. f+ ?        Accept-Encoding: gzip
  [: C9 l# n9 _3 f. o& {2 _# ?        Connection: keep-alive
' G5 |+ u+ ?8 O8 R  F        ......
: ?0 D4 C0 _" C, C& [
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。1 g6 I2 w. H& e: P
/ b+ Y! p3 Y$ b/ u4 N$ Z
        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。/ N( `7 u  L, V, P5 u

6 f: B& Z+ e) g. U
科普贴——Netty是干嘛的? 3-请求.png

% }* C1 O& A( P0 j' B% C( m        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。
8 [, W5 ?1 z# B7 c0 E- y  G% T; f' \+ y4 ?; Y1 L, v) ^5 |. N
        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。8 |% U0 ?( v: U' x: ^/ k- T
2 N8 J9 s" a5 C# w) |" |0 W9 L
        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。& I6 E6 ~& l, ]( x6 {" A: s

- o2 R8 I: Z% y& t: s
科普贴——Netty是干嘛的? 4-请求.png

; l! G: d; c: Z3 a        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。% U; g3 _" G# h" @4 q$ t1 x) z
4 g8 x  C% C7 {
        好了,就是Java NIO了!
4 O* U. K. Q: W" F! p3 ^" V* ]' X8 @3 M8 d1 a  A: z+ n
        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。9 M# b: \4 b1 S3 m8 P3 K
" P, e( p( f: z0 h! f3 f4 Y
        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。) C3 V: \4 N8 l9 d9 W* L/ b. Z
) w. w; _0 [  {7 G. p/ B2 |
        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。 ) L) c2 ~0 |0 M' U/ G6 l% c/ v

+ \% N* k: T( n
#f465:

7 l' t- ~+ s$ ?3 |# ?        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。8 N, h+ B) Y% a9 n/ z

2 L' p0 T4 _( D4 R4 T, a        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!
: Z! V$ @) @1 {) W! K7 H6 m. ^- V3 q/ K( H
        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?* N* r3 `; G  l* r( x' R

3 x4 }  l0 R) P% B- G) H* c+ \0 U# \- p        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:/ ?8 n( j9 @/ s8 d+ o
/ f6 X& H/ a) l
#f465:

2 s: Y+ N/ k$ E: L4 c        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。# j' I  j, J' M+ G, w8 g5 x
# e' a( @) E& `7 x
        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。: `4 \. D* F) F  T( B5 [

& S, R. t" b+ a( l! {2 _        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。& t, S. S3 X! U7 w, s' g

+ z: @1 ]) y7 T- D$ m4 w/ h3 V        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。0 U( ~- a. f, a7 a% F+ c- J
  P! o, u- S$ U% ]/ z( e& u7 Q
        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。 0 K4 Y" S  c, G! ]
3 o' m, E! Y- K+ ^
        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。
6 S% z# |! n$ Y2 i& F; I7 D$ J  T$ ]" D6 C- ~* e5 B
        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。& s% \8 `; G% h# Q$ ?4 a

+ O8 H/ p; m) R6 A        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。
# X  ?  O# V3 `
, ~% m- n& w3 M% A本文来自微信公众号:码农翻身(有修改), X$ A8 P* L, c: h! P4 T5 x! A3 M0 ^
作者老刘* K4 \* ^: `2 P
+ E, Z. V8 q: L5 x
上一篇
下一篇


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

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

我要把你这篇帖子牢牢的记在心里,刻在脑海里;& W9 F- }8 s, F, `1 v
我要去学活字印刷,把这篇帖子印成铅字;
! t9 L: j- F* h, L% t4 v/ j我要去学雕刻,把这篇帖子雕成雕像;6 Y# ~4 F4 k, ?( t, v
我要去学作诗,把这篇帖子改为不朽的诗篇;' N- f9 I5 X$ J0 I1 Y
我要去学作词,把这篇帖子改为歌词;+ h- W* `/ Y6 m& z2 o# U$ `
我要去学歌唱,把这篇帖子广为流唱;
: x1 R6 O. d* P  J" k我要去学说梦话,在梦里也要深情的朗诵;
1 }. p; ?, o- A# U( h/ a+ [我要去学刺青,把这篇帖子刺在每个人的身上!
+ k0 F# h% t- w0 p, q/ N9 |7 w我要做黑客,把所有的网站都改成这篇帖子;
$ ~' T! f. b/ ^' Q6 d" W) A% P我要做法官,让所有的囚犯都抄写这篇帖子;+ e; h" p% w& M2 H
我要做中国移动的董事长,给所有手机用户群发这篇帖子;
6 J. _& F7 H# I2 t+ i我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;
: U/ P' K. B- C" A2 w# u2 n( }我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏 「出类拔萃」 2018-1-20 22:42 |显示全部楼层

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

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

本版积分规则

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

GMT+8, 2021-10-27 17:45 , Processed in 0.027039 second(s), 20 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表