故乡的云。上古的玉。随手的诗。十九岁的你。 每日签到 收藏本站
登陆 / 注册 搜索

USERCENTER


查看:5453   回复: 2

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

[复制链接]
发新帖
跳转到指定楼层
楼主
仗剑天涯吾是土豪 发表于 2017-11-22 00:19:43 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。
3 T5 l& a. j$ ^/ f7 D9 }) `2 w* Z0 P) m7 f6 ]. H5 M2 b
 1-服务器.png 科普贴——Netty是干嘛的?

; d1 N* n$ ^; K/ d% b4 n0 Z. Z        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。$ x. l- x: o: K4 e8 A
; b+ v4 l9 i! V( o0 a. _' i
 2-服务器.jpg 科普贴——Netty是干嘛的?

4 q* }1 p* Q! c) ^$ P) ^/ `        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。
; U, D6 p+ Z7 K& ~- i
2 C) m' y, ^% }3 Y        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。
& h! q2 i1 o4 c2 g# K9 B9 \! F+ y: X6 N; O% q& v! |: S
        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。
* i; p) Z6 M9 X1 ?. S8 w6 M4 P
: L/ T; U/ [% S- [5 w2 ?$ o) k        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:
4 {9 t9 x" X& Z8 w8 a        
& f( G& u2 |5 a9 ?2 Q) B% z) Z
        GET /orders/1 HTTP/1.1                                                                                             6 G; X2 y9 L# V- t. V* k
        Host: order.myshop.com
# e. {2 T! L) b& G% l& o" [        User-Agent: Mozilla/5.0 (Windows NT 6.1; )
( n$ L$ g/ Z0 J( V* n        Accept: text/html;
5 k+ x% C4 E: ~) h3 |- o% K  V3 n        Accept-Language: en-US,en;
* |; V, f: r7 t  ^$ P        Accept-Encoding: gzip
$ Z  P  m6 z& H) r1 C$ f        Connection: keep-alive
* A1 s/ W# J( X- y$ B) i        ......
0 M# {, y, |  A6 P* q
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。
: @4 Y7 s9 ~) s8 m. H. g1 G; w( D# K0 H: G. j( O1 l
        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。- Y; M6 ~! \6 v

& ?, v$ n. \/ |
 3-请求.png 科普贴——Netty是干嘛的?
: K, [1 K4 M2 ]" Z# h
        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。" N3 n# N9 I! c! M/ D/ ~( p( ~

9 G  b; B" N8 T) x. |# x        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。: f1 j$ N2 V! d, j5 E) X

2 i7 \/ }- g8 z- D        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。# I# \/ ~5 h* p; N
$ Z/ b0 [9 t5 F0 d. g# T
 4-请求.png 科普贴——Netty是干嘛的?

, D& Y, e+ A) y3 w! t0 R        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。" |& @( n4 o5 W4 n; {* a  g

7 y' R" F) y1 C: i8 F+ B0 x" A        好了,就是Java NIO了!+ o; q. k5 a+ C- M( C9 d  |

, z1 Y  H6 a  D; [! f" v+ _6 B        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。
# j6 _+ I$ }: f6 O3 C. L( C, n7 y9 j+ u2 y" A! _9 z$ h4 G. j
        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。4 B- I9 U) G9 j/ U9 `$ F* u: Y

3 j6 l0 N' d2 J5 s        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。 8 s/ j* j3 M0 R

( j4 W. T( r' n& h, {+ i
#f465:
4 ]/ D9 i4 s: V; V! L
        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。/ L, \4 J$ s4 I

1 O& c, W5 P) @        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!0 y4 \0 F# {8 f; |8 Q% b4 f
  M1 i4 O) l5 p& U1 _
        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?2 S8 Q6 [6 W5 i- H2 Q
# Z7 o5 [" B+ ^# I9 {
        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:2 B9 z& l& y$ m6 W
, @- I/ U4 ^* E. o4 X! d( e
#f465:
/ o% ^1 w6 k7 A
        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。
% w9 j' i9 s" G' Q2 q" [
7 w; f% N; ~; T  ~9 q4 I$ i2 j- K# Z        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。
! S; ]4 n1 h0 J' q) h8 l* u
4 x8 K5 k% L  T, ]- }        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。' P) S; c; R5 w  [& W* V5 x: A

; k5 h) Z% ?0 T+ N2 ]$ @        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。8 u5 j9 c$ x( t& W, q
: x. [% t+ e' d; k1 T3 d. G
        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。 ! @( A/ m1 Q8 _; n0 y
. L& C4 P# s- d0 D
        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。
6 ]! @8 l0 {" @. C% ], k" d1 J* O1 G5 T( m0 [+ x) [
        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。2 @/ O0 |6 O, J( p3 v3 K9 w

4 w- q" u6 U$ A5 x% |' z* n# O; R        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。
+ q! i4 \: J" G0 w6 s6 V5 \  A+ m  j. k
本文来自微信公众号:码农翻身(有修改)
3 H% m+ j/ O, \6 O7 Z( r作者老刘& k/ W" l- u* A1 ~
# Y1 W; n% X/ ?9 {

夏雨初晴「出类拔萃」 发表于 2018-1-20 22:41:57 | 只看该作者
我要把你这篇帖子牢牢的记在心里,刻在脑海里;
# W+ G. @1 l8 P2 e$ J% f我要去学活字印刷,把这篇帖子印成铅字;; A6 c4 Z1 a. r5 M/ B! l
我要去学雕刻,把这篇帖子雕成雕像;0 i9 F1 m; F. G2 z9 o" G  B# N5 o  I
我要去学作诗,把这篇帖子改为不朽的诗篇;
; P# T. d( r) R, [3 r; s我要去学作词,把这篇帖子改为歌词;
4 s+ E: N. p- }我要去学歌唱,把这篇帖子广为流唱;
" y- k4 G2 ~* s, `我要去学说梦话,在梦里也要深情的朗诵;. A9 V) U& s- i. n! `: W9 O! R7 S
我要去学刺青,把这篇帖子刺在每个人的身上!
# ?3 j! ^) n$ g) d' A我要做黑客,把所有的网站都改成这篇帖子;
: F0 f! Q! J' y7 r( w- A: N我要做法官,让所有的囚犯都抄写这篇帖子;
' q. G' W; I( F$ {; ^& K我要做中国移动的董事长,给所有手机用户群发这篇帖子;
% z! s4 D) ^( T! j5 `' e7 c- X我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;3 n4 a: G2 v7 T4 \5 U
我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏「出类拔萃」 发表于 2018-1-20 22:42:06 | 只看该作者
感谢分享~
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

关于我们|小黑屋|手机版|Archiver|古黑论

GMT+8, 2019-9-21 06:21 , Processed in 0.039699 second(s), 27 queries , Gzip On, Redis On.

© 2015-2019 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表