五十年来和五百年内,中国人写白话文的前三名是李敖,李敖,李敖,嘴巴上骂我吹牛的人,心里都为我供了牌位。 收藏本站
登陆 / 注册 搜索

阅读: 7.3K   回复: 2

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

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

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

主题破百
        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。8 O6 l5 I- }1 m6 v" w! x' H

, \; M0 I, ~0 x3 T' |
科普贴——Netty是干嘛的? 1-服务器.png

) s2 h) I2 N1 `& O        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。
' m1 I7 }( s# o' p" p; }5 x4 |7 k7 y% g* {# ]+ P
科普贴——Netty是干嘛的? 2-服务器.jpg

; n, s$ [4 L! Y" K6 T: g3 `        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。
5 a3 T2 J- [0 ?% z, B
1 _8 S$ C3 F* a- t5 r5 Q/ @        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。 3 m& K5 O. P2 Z0 h+ ~, a' l' h

9 M1 z( z+ {& D0 }        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。1 }" J" y! w4 Z) Q5 }

8 ~) N0 b$ z( F. h( T, o2 Y        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:
/ T2 T5 S. S* P: H+ k        " H  o* d8 R1 `  Y+ i
        GET /orders/1 HTTP/1.1                                                                                             
8 i! c8 K# _0 _  E% Z  _        Host: order.myshop.com& J$ J& e7 v7 C8 w% {3 y( k% ?
        User-Agent: Mozilla/5.0 (Windows NT 6.1; )
+ j) g" v& ~4 p6 P# J! o        Accept: text/html;4 Z# ]% U( K; D3 z  M1 w5 Q
        Accept-Language: en-US,en;
9 ]8 I7 O% g& ?0 u! v6 |        Accept-Encoding: gzip
3 L6 G- T0 {8 @        Connection: keep-alive0 @' `' P4 x0 J9 m- V$ i' G; W& H
        ......

8 f( b+ ~0 r. w  Z" \* ~' K看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。2 |6 b5 B6 N5 D) G! [3 p
) g6 C# d; E, A- K* L! m; Z4 j  _
        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。% a# `( o$ A8 E- W
# E6 G7 r& K% t  c
科普贴——Netty是干嘛的? 3-请求.png
( E) Q$ v5 I8 a6 O( b* W5 u- [% S
        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。
& V; q. m  o2 R/ E/ F+ G7 E: W
$ u6 M8 m( G3 R( F0 J& u0 M        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。
& e6 ^, _1 f7 {, {* o2 d1 t& g* [- v
        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。
4 C( @! J. P8 W
9 j  E4 f) _. F' q6 h
科普贴——Netty是干嘛的? 4-请求.png
) A) h% c! |  E+ _3 ]
        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。1 g7 |1 V# F; w2 X

  b: W' a3 ]9 O1 t! {$ v        好了,就是Java NIO了!
0 n- B. B$ h1 c% P) e" Z$ a
# o5 |0 y# \; b        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。
  |4 U) o; r, y$ D5 N3 m9 {$ h6 ^5 C! a4 ^1 Z
        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。- G* r* u( ?4 s2 E: B+ Y2 p: w9 X  l
4 v  s+ ~" k5 i3 n4 [0 [+ W
        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。
1 T- J- v! x. @- L# {" |3 L! @; x) B7 _
#f465:

# @% f! Z9 O7 I& v        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。. e  `( u- y$ i9 ^0 d8 R. f7 E
% x( i! L2 e" J  ]8 h. x
        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!, B4 J! x+ p% [" Q0 y0 l. G  n

5 i) g  b$ v0 c5 ^9 F0 E7 b, _        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?
$ h; _: Y- Z8 m0 X
% _6 `% t5 p& g: v% U% W& R        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:+ `- y7 K* x! H; m' L

5 l& u& K9 f7 e$ e/ Y! C( n
#f465:

' L# ?: O( q2 \! j5 u        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。: O- \) _+ S5 _. e# {+ T; m4 l

3 c, @$ x6 I. w2 g1 O        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。" }* F0 N$ U9 @' q
( B) T0 \0 W0 ^$ O) A! o  l
        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。
6 u" b7 x8 b/ C
  V7 ^0 K- `3 X        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。: J9 C: q7 p0 q  |7 @

! H  F2 T6 t* k; h. P+ s, h        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。
) B1 a: j$ T# |7 ^) j2 u/ ~" [+ i
! C; W( X8 F+ B' l( \$ f        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。
* ^  x7 o' E; r. J: o$ I9 b
; W( R" T3 P; e7 r- c, z        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。
: k: [1 d' f$ C3 j2 z  L4 m4 P0 H8 ?2 s! i& P  `, C# v! p
        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。# q2 X, C7 d# J. N1 x( L

2 h% P" D" H9 V; N* j0 j* p本文来自微信公众号:码农翻身(有修改)
/ e: \2 E! X! w( }6 I作者老刘
: z( o; \* R9 R! }, X8 l0 w& D7 z5 a/ g: M/ c
上一篇
下一篇


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

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

我要把你这篇帖子牢牢的记在心里,刻在脑海里;
% M$ m. p# n& ^6 G9 S/ e) i* @' u我要去学活字印刷,把这篇帖子印成铅字;
2 @7 X: y0 [! o+ b我要去学雕刻,把这篇帖子雕成雕像;
7 o: W/ g! z8 e我要去学作诗,把这篇帖子改为不朽的诗篇;- v+ K( Z1 K, q; a# I; H* M! b0 s
我要去学作词,把这篇帖子改为歌词;
+ u  ]/ V/ k* P我要去学歌唱,把这篇帖子广为流唱;/ D: g( y5 o( J" k7 b1 D4 u) \
我要去学说梦话,在梦里也要深情的朗诵;1 c0 c- ]3 B/ a; F/ m( K: V
我要去学刺青,把这篇帖子刺在每个人的身上!2 p) Z7 t* X1 H5 \& N% _0 i0 W
我要做黑客,把所有的网站都改成这篇帖子;8 O5 k  q: S/ g/ b. B6 C. V
我要做法官,让所有的囚犯都抄写这篇帖子;+ ]. H* C3 Q7 r2 k/ O, |2 u
我要做中国移动的董事长,给所有手机用户群发这篇帖子;
: W7 I+ F3 A1 n+ ?. E5 G& d我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;
9 q9 W& f" k! r我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏 「出类拔萃」 2018-1-20 22:42 |显示全部楼层

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

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

本版积分规则

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

GMT+8, 2021-2-25 04:09 , Processed in 0.034383 second(s), 21 queries , Redis On.

© 2015-2020 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表