越是困难,越要抬起头,地上可找不到任何希望! 收藏本站
登陆 / 注册 搜索

阅读: 7.1K   回复: 2

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

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

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

主题破百
        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。8 }$ u1 a! A! y9 J; T: j

  E* x) C3 r2 w* g! S4 M1 d
科普贴——Netty是干嘛的? 1-服务器.png
# O. j# o* }" F; ]
        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。# }9 I* L" E  B1 i7 [

* f& v0 _5 B' k# ?# E" N
科普贴——Netty是干嘛的? 2-服务器.jpg
/ n% a$ E& [( X) _3 f' ^$ `4 m
        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。
% t* _' L3 Q/ e' }3 _. }* E+ m- f1 o3 o4 I' l& z' L! s, ]' l  y' r
        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。
" O- @+ m6 g; y6 T, g: T. b3 f' Y' h5 a# f
        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。( Q. Q% _$ ], v; i# A# ^; A

, r3 G$ ^  I; `& B3 m        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:
( M, x! P8 F0 K& @        2 R& j+ O+ S5 d8 P- q
        GET /orders/1 HTTP/1.1                                                                                             - i4 M2 w9 }) c! J6 H8 V
        Host: order.myshop.com
& }; f) [1 i8 F6 N2 d- c1 C/ i# q        User-Agent: Mozilla/5.0 (Windows NT 6.1; )& w1 ]  r, a% A4 H. R
        Accept: text/html;; c' s- q# L) d2 U( w* Q
        Accept-Language: en-US,en;9 d2 t1 }3 c" ^# C+ {6 n( z
        Accept-Encoding: gzip
. p% [& L& K. \2 g        Connection: keep-alive+ D2 T$ K: ~7 p5 {5 Z- G
        ......
& ]3 T& P! {2 {6 F6 x
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。( ?% s) q; D& h: ^6 p
' v+ [+ S7 A' X: F8 t
        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。! I# q5 v3 O# _. P6 m+ O

; @. w% u. {; X* {- \
科普贴——Netty是干嘛的? 3-请求.png

$ p- {- O8 b( [  R! E' Z        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。5 g* _4 h2 c) M0 H4 T

& M+ |, }4 k" M/ T6 e        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。: |: h0 B0 P# p0 [8 V

3 ]/ h! C/ y, o6 m3 ?        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。
; U( s8 ^( V2 B
3 T( g% B$ U4 N3 u
科普贴——Netty是干嘛的? 4-请求.png

7 U9 Z1 V+ G9 [. l  o: ~        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。1 ]( w3 }. U( r9 E" W' M
: A$ a1 E  ^0 r9 z
        好了,就是Java NIO了!
8 _8 [. v5 ^8 p
( D5 ^9 L( N/ X7 A, R        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。
, y, M. b( o# T6 R
$ B  E) L# N; c  X% N, w) [& F        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。
0 k  e( p  n% j8 v' d& ?; g- o6 b" z; j; N# w9 e; V
        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。 5 w7 {8 x' c  h1 g3 Q5 l' i; R
$ E& c2 ?' a, b% T
#f465:
$ G$ w; B  Z+ v
        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。6 P* P0 }5 D9 |7 {$ K2 [4 P
$ N. k: s. L+ E$ N0 Z
        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!
# f. F3 G. d: w3 @7 n) b1 Q
) `, J$ s8 _" N: O6 {6 c        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?" r- ]& Z5 u  l" G

+ _/ o# P+ b/ p3 |* q1 ~2 a        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:
5 ~% [- S; e/ @' `) @2 E5 _1 G) G2 {# Y- _6 L# C: g# E+ x+ |
#f465:

. h; |: ]9 u: J6 r        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。& h0 x7 H+ @  S5 U
6 r/ t) V2 ]5 I  i: E9 D
        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。3 Z  z" b6 h! I. I- |
  ~3 G  A5 y. l2 X0 X
        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。" B& b% R" e! }+ T
0 Y8 x0 {4 F" H9 N) |" g
        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。
3 F4 c  J% a1 I4 A( r7 x1 O  A& L. k& H8 m9 ?2 M
        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。
) c. c0 P$ t. ^$ S
, S6 V. \7 g( p8 A+ _' j        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。
$ z* z7 M! k2 S
: i+ M% _- T1 x        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。! [* e4 Z' i+ M7 \
( G$ i( ~& S4 N2 w% r
        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。
4 l% T9 G2 V0 ]) {  x
( m8 F! x2 d( y9 ~  l5 r4 _本文来自微信公众号:码农翻身(有修改)
% k' }5 v4 s& o2 O! U% u作者老刘
( h" X& {2 f! k( E6 Y4 T1 e
9 ?, J4 U( i! R) W


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

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

我要把你这篇帖子牢牢的记在心里,刻在脑海里;
7 R4 }5 S3 J  Y+ `8 e我要去学活字印刷,把这篇帖子印成铅字;
2 T8 e! q3 L5 W8 B. o我要去学雕刻,把这篇帖子雕成雕像;, N7 M$ w/ B( c
我要去学作诗,把这篇帖子改为不朽的诗篇;
- s- O9 B! w7 S" {3 d  Q; S我要去学作词,把这篇帖子改为歌词;
8 S& R. n: r. ^! s" _我要去学歌唱,把这篇帖子广为流唱;2 t1 k( g- s9 S- j4 y: g3 H# e& p
我要去学说梦话,在梦里也要深情的朗诵;
  @, h7 S+ |" O我要去学刺青,把这篇帖子刺在每个人的身上!
( v: B# @$ `0 b) y: L我要做黑客,把所有的网站都改成这篇帖子;" M: z9 @, ~: U% C1 H$ J
我要做法官,让所有的囚犯都抄写这篇帖子;+ K: r( x* t! d: _0 U7 ~! F7 S$ z
我要做中国移动的董事长,给所有手机用户群发这篇帖子;  m* a( b, k6 s% g9 z0 F4 O
我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;8 F. X( S" F" e* `+ @
我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏 「出类拔萃」 2018-1-20 22:42 |显示全部楼层

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

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

本版积分规则

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

GMT+8, 2020-11-24 02:59 , Processed in 0.032291 second(s), 22 queries , Redis On.

© 2015-2020 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表