离别并不痛苦,因为我们都微笑着。 收藏本站
登陆 / 注册 搜索

阅读: 6.9K   回复: 2

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

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

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

主题破百
        随着移动互联网的爆发性增长,小明公司的电子商务系统访问量越来越大,由于现有系统是个单体的巨型应用,已经无法满足海量的并发请求,拆分势在必行。
. n; i5 k6 V. e5 b; {9 N7 F- G/ ?% G. j& k$ w8 ?
科普贴——Netty是干嘛的? 1-服务器.png
) b% I3 g$ Z8 O" h
        在微服务的大潮之中, 架构师小明把系统拆分成了多个服务,根据需要部署在多个机器上,这些服务非常灵活,可以随着访问量弹性扩展。
; N8 n( ~8 x0 j# X8 Z" {$ N! _6 @$ G0 T) Q: ^$ Q' Z; G( ^
科普贴——Netty是干嘛的? 2-服务器.jpg

) i( Y: W7 h3 E# n        世界上没有免费的午餐, 拆分成多个“微服务”以后虽然增加了弹性,但也带来了一个巨大的挑战:服务之间互相调用的开销。. l3 o  k! R" m! R6 }: `" @5 V' t

/ `* _! |3 x6 y" y, N$ z! t% C+ j        比如说:原来用户下一个订单需要登录,浏览产品详情,加入购物车,支付,扣库存等一系列操作,在单体应用的时候它们都在一台机器的同一个进程中,说白了就是模块之间的函数调用,效率超级高。 * L/ A5 d$ _0 e* m/ k8 O, v

# P2 y1 P' V: b        现在好了,服务被安置到了不同的服务器上,一个订单流程,几乎每个操作都要越网络,都是远程过程调用(RPC), 那执行时间、执行效率可远远比不上以前了。
8 s, }6 {' y) d6 F% j# y( ?) ?5 H, b9 Z# ~
        远程过程调用的第一版实现使用了HTTP协议,也就是说各个服务对外提供HTTP接口。 小明发现,HTTP协议虽然简单明了,但是废话太多,仅仅是给服务器发个简单的消息都会附带一大堆无用信息:
& M; l" M, L: d1 ?; @0 J8 y1 H        
: C/ F4 ^+ e" b: Q6 y" P, {8 }
        GET /orders/1 HTTP/1.1                                                                                             
7 m" a8 B4 W0 v$ P3 h9 R        Host: order.myshop.com* ~2 z" J( d, ]4 p; {
        User-Agent: Mozilla/5.0 (Windows NT 6.1; )+ s# I, B. |4 J  _; G7 E( q6 T* U
        Accept: text/html;5 c$ d& g. Y& z  z- C4 I1 I
        Accept-Language: en-US,en;/ Q4 K: K! Y" a* L2 t2 @" ~
        Accept-Encoding: gzip
  ?* L2 S5 C$ Z( e2 E        Connection: keep-alive  ]4 P  d+ a$ [
        ......
' I- k8 w" f+ d6 ^6 {
看看那User-Agent,Accept-Language ,这个协议明显是为浏览器而生的!但是我这里是程序之间的调用,用这个HTTP有点亏。能不能自定义一个精简的协议? 在这个协议中我只需要把要调用方法名和参数发给服务器即可,根本不用这么多乱七八糟的额外信息。8 ?2 v8 Q+ L. a( p* c" S3 h' u

8 ]' [' S* L) _: F        但是自定义协议客户端和服务器端就得直接使用“低级”的Socket了,尤其是服务器端,得能够处理高并发的访问请求才行。小明复习了一下服务器端的socket编程,最早的Java是所谓的阻塞IO(Blocking IO), 想处理多个socket的连接的话需要创建多个线程, 一个线程对应一个。
6 g1 q, @$ W7 A4 z- d) R+ x2 H! X
科普贴——Netty是干嘛的? 3-请求.png
$ `/ w  F* j0 W. c# Y
        这种方式写起来倒是挺简单的,但是连接(socket)多了就受不了了,如果真的有成千上万个线程同时处理成千上万个socket,占用大量的空间不说,光是线程之间的切换就是一个巨大的开销。9 V0 h: U( b6 w! Z" c- N& w

1 Y1 q/ Q5 L1 D" v* X4 h9 c        更重要的是,虽然有大量的socket,但是真正需要处理的(可以读写数据的socket)却不多,大量的线程处于等待数据状态(这也是为什么叫做阻塞的原因),资源浪费得让人心疼。
5 ]5 ~  Z/ S1 M' e- P+ |, [- p9 [+ O
        后来Java为了解决这个问题,又搞了一个非阻塞IO(NIO:Non-Blocking IO,有人也叫做New IO), 改变了一下思路:通过多路复用的方式让一个线程去处理多个Socket。# Z, m! D- X/ a( u9 |1 B) J

9 T$ X2 I' Y' U/ Y2 c% f
科普贴——Netty是干嘛的? 4-请求.png

8 e2 U9 X' w. b! m8 o6 D6 P, @. R        这样一来,只需要使用少量的线程就可以搞定多个socket了,线程只需要通过Selector去查一下它所管理的socket集合,哪个Socket的数据准备好了,就去处理哪个Socket,一点儿都不浪费。" [: A5 M+ U; f+ |6 e0 E
3 S- B  q; P3 U2 D4 h6 _
        好了,就是Java NIO了!
; G+ @: U" p3 @) e; K
. ?; }! Y$ k9 n1 |1 _' `$ }5 L        小明先定义了一套精简的RPC的协议,里边规定了如何去调用一个服务,方法名和参数该如何传递,返回值用什么格式......等等。然后雄心勃勃地要把这个协议用Java NIO给实现了。
9 }1 Q! L" O; Y, a1 M7 V! Q4 l1 f) K# h
        可是美好的理想很快被无情的现实给击碎, 小明努力了一周就意识到自己陷入了一个大坑之中,Java NIO虽然看起来简单,但是API还是太“低级”了,有太多的复杂性,没有强悍的、一流的编程能力根本无法驾驭,根本做不到高并发情况下的可靠和高效。& M2 \6 }+ @6 i2 g
( Y: e& k% M( }- {- O
        小明不死心,继续向领导要人要资源,一定要把这个坑给填上,挣扎了6个月以后,终于实现了一个自己的NIO框架,可以执行高并发的RPC调用了。
( r- ~  ^$ I- O9 F: F/ U
. S. e9 ]) k. t9 Z- u! i: c
#f465:
( o" h0 X% R$ F+ p) T
        然后又是长达6个月的修修补补,小明经常半夜被叫醒:生产环境的RPC调用无法返回了! 这样的Bug不知道改了多少个。! c6 t0 z- d, O3 T) w8 k

1 [0 L4 g1 E: P        在那些不眠之夜中,小明经常仰天长叹:我用NIO做个高并发的RPC框架怎么这么难呐!
7 a1 i3 o; R; A5 q* T! @' ~
8 _" b, x$ M* M; h: G        一年之后,自研的框架终于稳定,可是小明也从张大胖那里听到了一个让他崩溃的消息: 小明你知道吗?有个叫Netty的开源框架,可以快速地开发高性能的面向协议的服务器和客户端。 易用、健壮、安全、高效,你可以在Netty上轻松实现各种自定义的协议!咱们也试试?
- Y/ M0 F# J# \6 @* F
( t. H% T5 e' F" Q        小明赶紧研究,看完后不由得“泪流满面”:这东西怎么不早点出来啊!#391:) y4 k9 w+ A9 {

8 N3 X, Z# L, a0 ?$ k( J  b
#f465:
* q6 t3 G7 R0 h2 l) |
        好了,这个故事我快编不下去了,要烂尾了。说说Netty到底是何方神圣, 要解决什么问题吧。
  q! v" x9 D2 [# a% Q: \+ B! s+ a) h" U; F1 {- m
        像上面小明的例子,想使用Java NIO来实现一个高性能的RPC框架,调用协议,数据的格式和次序都是自己定义的,现有的HTTP根本玩不转,那使用Netty就是绝佳的选择。/ n8 ]! S2 j4 r& i
. Z) r. N( Q1 I; u- M5 Y0 d
        其实游戏领域是个更好的例子,长连接,自定义协议,高并发,Netty就是绝配。- x* U& |" W, a" _3 W+ \9 A7 [* ~) ?
# `: C( X" g" s$ {6 H
        因为Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。9 B. T! ~( v% c+ q# o

9 ]$ Z4 z& u" ]8 M) s        注意几个关键词,首先它是个框架,是个“半成品”,不能开箱即用,你必须得拿过来做点定制,利用它开发出自己的应用程序,然后才能运行(就像使用Spring那样)。
8 z! e9 o- v2 _8 x5 g5 a7 t2 s) b/ x1 u
8 x' M+ o( M) M6 _6 p        一个更加知名的例子就是阿里巴巴的Dubbo了,这个RPC框架的底层用的就是Netty。
% j1 b3 [& }* n1 s: ?0 B2 A. ^' L* k9 q7 Z
        另外一个关键词是高性能,如果你的应用根本没有高并发的压力,那就不一定要用Netty了。
  e' i/ w8 ~; s2 d4 Q5 M6 }. H/ O+ o' c) I
        netty是个单纯的nio框架,要做一个好用完整的RPC框架的话还有很多封装工作要做。可以用thrift框架试试,完整的rpc框架,不过要用于大型集群服务,还要做一个统一服务注册和发现服务,可以用zookeeper做。  U* d( \' N8 C$ i5 F
& b- o1 g- i1 f3 \. n, R. y4 l' K
本文来自微信公众号:码农翻身(有修改)
% f# d0 ^. C6 w8 L作者老刘
  L  d0 t' s5 W# i4 E/ C& {, F6 S$ {0 s( j" O


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

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

我要把你这篇帖子牢牢的记在心里,刻在脑海里;* m8 ^. R4 ?* t9 f& [3 W2 Y  {
我要去学活字印刷,把这篇帖子印成铅字;
/ t0 P- x5 P7 |) K( R. e+ h我要去学雕刻,把这篇帖子雕成雕像;/ g* c8 ~( U' V) ]
我要去学作诗,把这篇帖子改为不朽的诗篇;
3 |) m8 E7 x" V6 V" a我要去学作词,把这篇帖子改为歌词;( g5 F; T* i$ B/ T$ @3 L
我要去学歌唱,把这篇帖子广为流唱;
4 g  H& i. R; [" @% t% G/ O1 K, G7 x我要去学说梦话,在梦里也要深情的朗诵;
! q4 d0 [) s# J* X我要去学刺青,把这篇帖子刺在每个人的身上!$ V2 C/ e# d8 k# N; f
我要做黑客,把所有的网站都改成这篇帖子;
; J5 F( `8 Y9 S! Z/ Z2 u$ n+ V我要做法官,让所有的囚犯都抄写这篇帖子;
. D) h& Y1 k$ P1 `7 q: B# c我要做中国移动的董事长,给所有手机用户群发这篇帖子;' C* g, Q: N0 p. M
我要做微软总裁,把所有的电脑操作系统都改为这篇帖子;1 h% `& k' |8 _6 m! e) {
我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368:
微雨黄昏 「出类拔萃」 2018-1-20 22:42 |显示全部楼层

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

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

本版积分规则

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

GMT+8, 2020-8-5 18:20 , Processed in 0.044370 second(s), 21 queries , Redis On.

© 2015-2020 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表