From 5b5a067713224490d76338bc58d744147a3060f9 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 5 Jan 2019 20:31:20 +0800 Subject: [PATCH] docs: add hystrix-thread-pool-current-limiting - Update index.html - Add hystrix-thread-pool-current-limiting.md - Update hystrix-introduction and circuit-breaker --- README.md | 3 ++- .../hystrix-circuit-breaker.md | 2 +- .../high-availability/hystrix-introduction.md | 1 + .../hystrix-thread-pool-current-limiting.md | 19 ++++++++++++++++++ .../img/bulkhead-partition.jpg | Bin 0 -> 7057 bytes img/bulkhead-partition.jpg | Bin 0 -> 7057 bytes index.html | 1 + 7 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 docs/high-availability/hystrix-thread-pool-current-limiting.md create mode 100644 docs/high-availability/img/bulkhead-partition.jpg create mode 100644 img/bulkhead-partition.jpg diff --git a/README.md b/README.md index 841b91c..672c34e 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ - [如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试?](/docs/distributed-system/dubbo-service-management.md) - [分布式服务接口的幂等性如何设计(比如不能重复扣款)?](/docs/distributed-system/distributed-system-idempotency.md) - [分布式服务接口请求的顺序性如何保证?](/docs/distributed-system/distributed-system-request-sequence.md) -- [如何自己设计一个类似 Dubbo 的 rpc 框架?](/docs/distributed-system/dubbo-rpc-design.md) +- [如何自己设计一个类似 Dubbo 的 RPC 框架?](/docs/distributed-system/dubbo-rpc-design.md) ### 分布式锁 - [Zookeeper 都有哪些应用场景?](/docs/distributed-system/zookeeper-application-scenarios.md) @@ -89,6 +89,7 @@ - [基于 request cache 请求缓存技术优化批量商品数据查询接口](/docs/high-availability/hystrix-request-cache.md) - [基于本地缓存的 fallback 降级机制](/docs/high-availability/hystrix-fallback.md) - [深入 Hystrix 断路器执行原理](/docs/high-availability/hystrix-circuit-breaker.md) +- [深入 Hystrix 线程池隔离与接口限流](/docs/high-availability/hystrix-thread-pool-current-limiting.md) ### 高可用系统 - 如何设计一个高可用系统? diff --git a/docs/high-availability/hystrix-circuit-breaker.md b/docs/high-availability/hystrix-circuit-breaker.md index f6247e5..5fd28a8 100644 --- a/docs/high-availability/hystrix-circuit-breaker.md +++ b/docs/high-availability/hystrix-circuit-breaker.md @@ -172,7 +172,7 @@ ProductInfo(id=1, name=iphone7手机, price=5599.0, pictureList=a.jpg,b.jpg, spe 之后的 9 次请求,都不会执行 run() 方法,也就不会打印以下信息。 -``` +```c 调用接口查询商品数据,productId=-1 ``` diff --git a/docs/high-availability/hystrix-introduction.md b/docs/high-availability/hystrix-introduction.md index 5497d52..cfe80e2 100644 --- a/docs/high-availability/hystrix-introduction.md +++ b/docs/high-availability/hystrix-introduction.md @@ -1,4 +1,5 @@ ## 用 Hystrix 构建高可用服务架构 +参考 [Hystrix Home](https://github.com/Netflix/Hystrix/wiki#what)。 ### Hystrix 是什么? 在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是**依赖服务**,有的时候某些依赖服务出现故障也是很正常的。 diff --git a/docs/high-availability/hystrix-thread-pool-current-limiting.md b/docs/high-availability/hystrix-thread-pool-current-limiting.md new file mode 100644 index 0000000..9994821 --- /dev/null +++ b/docs/high-availability/hystrix-thread-pool-current-limiting.md @@ -0,0 +1,19 @@ +## 深入 Hystrix 线程池隔离与接口限流 +前面讲了 Hystrix 的 request cache 请求缓存、fallback 优雅降级、circuit breaker 断路器快速熔断,这一讲,我们来详细说说 Hystrix 的线程池隔离与接口限流。 + +![hystrix-process](/img/hystrix-process.png) + +Hystrix 通过判断线程池或者信号量是否已满,超出容量的请求,直接 Reject 走降级,从而达到限流的作用。 + +限流是限制对后端的服务的访问量,比如说你对 MySQL、Redis、Zookeeper 以及其它各种后端中间件的资源的访问的限制,其实是为了避免过大的流量直接打死后端的服务。 + +### 线程池隔离技术的设计 +Hystrix 采用了 Bulkhead Partition 舱壁隔离技术,来将外部依赖进行资源隔离,进而避免任何外部依赖的故障导致本服务崩溃。 + +> **舱壁隔离**,是说将船体内部空间区隔划分成若干个隔舱,一旦某几个隔舱发生破损进水,水流不会在其间相互流动,如此一来船舶在受损时,依然能具有足够的浮力和稳定性,进而减低立即沉船的危险。 + +![bulkhead-partition](/img/bulkhead-partition.jpg) + +Hystrix 对每个外部依赖用一个单独的线程池,这样的话,如果对那个外部依赖调用延迟很严重,最多就是耗尽那个依赖自己的线程池而已,不会影响其他的依赖调用。 + +### Hystrix 应用线程池机制的场景 diff --git a/docs/high-availability/img/bulkhead-partition.jpg b/docs/high-availability/img/bulkhead-partition.jpg new file mode 100644 index 0000000000000000000000000000000000000000..15c9915db407d32b489696bba89e47dca1f646e8 GIT binary patch literal 7057 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 literal 0 HcmV?d00001 diff --git a/img/bulkhead-partition.jpg b/img/bulkhead-partition.jpg new file mode 100644 index 0000000000000000000000000000000000000000..15c9915db407d32b489696bba89e47dca1f646e8 GIT binary patch literal 7057 zcmbtYbyO2>+umq~q;wA$Fc6TCkZv{*x6vgzdJIMh3ep$|W0W)^qog|}q!CnFN>Zdm z1tb*s{Jr1%#lPSA?&tdFj&t4jd7g9bbDigE?rH_V0M~=*0f0atVCe4wTwMZE^*p@M z{QlTLoHP11zk5J{um5c+DQ7GOgZ1&34EFHyz@S|`93`rO-sekHkYhy9Kj<^5} z+9$x@-qFX!KG-n;jSKK_a}Tih4|HR9;J^(iW2p|QJ{=LNiw!c%7kdjgT zlhtAX07*$nNyx~7WR&F8e@lRWQvh;C3MTM%X-Z~IB#VHIqn{wFR%9}j5XuSnvWE>K zE2nMZ>>ouatou0emxK9#bN^?Pf1-^4tK+|;^MGrlz`vuBG6K{A=f$Z+lK&f!-9jYc zy|tq!N0Af1w(HhsL21psL$=F^F=$Pzs?!mK;z;) zm%&8A`bozod|g2a*S$@&z0c)~D%3G|sYyr7l0NiVmPx+w;|evib9lf$0v?Qk!$e5C zeiTeWt#k*?;LSev``8>0v9k=`owie6X6?0Y)O39&~N3tVMeo=AYeucCY|U zb0UY{vkYuiqWd53HB~oly}+QAvl~~%HhWSlafFn_XL+rPD@?i+`S8N+=bAxj<&&N* z!;vz~?I@pQ7v0AjXb7Y`w;W`Bh}S$4On%ylfWrTckSc-+Xh9M+-FQu|*|fq92o+J^ zw7;qIy^Kv&wz%;MdQT zma!R)F&k1PY2Z)oy!xk^+uz__Z5ryH5gnF)pb=}yTo#_XYSuKg3RI${3^!|Ai#GUt z{j8S;^|qgTKKY2<_E9|^uFK#VC`yu_2;N^;N6Dnb;7#`LS>86M%`j>#?$Bwj4XW3( z?s&d=jSy#pT$RL}t>YivXG#c0>}w`j-*O340`A_a^sh3X*7v>jg_DsRZ5UF*T&Qq^ znXs&!xb<{Z-KsY?2xqD)PQg8F+z|}93l!rOzPWqEt; z&d=30^smdvOho*orqKxGZz{YQp2j=HN|jaEb2F0Z%qvX4#>d7}eZ$k1K~Gs<`T z$)@mB&@R1crl9xJXDyK)@5$Wzv2^fia~&l5=8!3Fou5o%WvL%NN7u zt`<@_yHM#sRl7BTr_<5zM@T*`B{1gsihnHiwx_fWTFeY;5!?7(h51D9NerlCN^SWF zhfl=DY^?K>gnLgB3B$YxSRWT!eViXrcC*{m(%l9+C;?ToWoF!oPT-Cb6@WAo*FCu~ z)hi4V6wko0>1!4$cd5zVWIAT*65wtbwX+ z_e?EHj51!KI`>Q9Y; zLLA*Mr{wAS`XljCE*aUTCHqv+k*&Z%%iYVGqOOA&HOI6p_kLX<&x_IK2TnkVp~sP5=I@rXk2{q^aW3)uvvFLJr4A)B>@Zb@ z?4z)#@Zu+zqDt^q?ig=Zj8~It=!8O?#K$PZ_s|L@n#fi=a~RJpfD&}>F6L{L2SBO$68q6^=~E*`WTNR>%8l>e&-sS%XM+;^^!B zSG<@-qI+Vst~0guPwIiG%O6$0$9^3;BhbISETBJgQ2dg7NGLTaWLSwELp?MMGk*Xi zkdrg{q}G4>NPZjSkoiO5*~k6J55H+h-EDIH(&XkfI8e!V56~8_aWfq#X;D{N-%x-A< z@tOFlBgIfP6|4~`*^%}nBMYa8A-1AEZ;oFq5>g3Iq~E7e^2UmZ9rdiAfd++aKoA8A zct^wByV7=^zVy_&9x`T8I$ZcmJ2p1EP?}mUF~eMlZ%iDaa~*ouad2_#LR3Bs?K_ik zUs~$BT<&u}UW|-&%R)BJXy(2U9f*}#i36xr*PdS0HRkb)cS?p6lh(36M!aWvY;Jrp zY&^}vv%!7tmU!I!mDY^6-?g(h-7XN3Cj-`VVNp3Z#T#OTm`sC7y8+h@&2_BydHFxB z**5Z~nJN@Tf4t6=I;!pRuv}bok)U}FTc3%R{{BJgB5SyH-bcn^(GmX4+hHLGOk;tB zF0aEO&D1+TP4j|6of-xk!!F-S{#l%HvUjk0CZPT93SdUSuPHb?)h(0*O6rnxyPZ0i z8kBFlg2PpNWs%v|w!1Jq*x-zA1N(ryx#@K?vMy}eG&|{WlR@p4PUwmhbuP}ywqMJg zP0L1N1FL7{r|2PwGtb*#eoE_f@-VWjQnr$Thw+xU`>syBFL^v8gil#Nzm%MefNXL2 z&AHRutfrgCTVCHZX)(xQ(AJIER*-P#vi08hlStHr!QVGcyEv54P4h|?uk{u0&#)SK zTz|I}F1+$c433J4`T$f8NB-`+*cn?je%*DeSV}?v3$afxc~<@tjJ(7qASPmB0<>WM zU5}+xQ~d})LwBw<5myMYNjX8NpbfLFyPi}EGaFP-tsy#=p0@gNv#*pA_N^aL zM#&JA$P(QlW&fqY{t;u5cwZS+kAD^p@VA-0y>)JDZw%(+^64mwl8`kKWyHdum5WqI z$!|c}!4HKJal+LW?&dbO?Xmqw^_=3mTc#mk!MV_sIeL^vd5&`9_$S6-nrs;td#S`| zilMYCz^Ht3OwkGTJb`)V3<&RjKSZT3b{b$rQ86n@`()QThBA7=vPA+ul4CtR3LmNK z{B#hLMj*GXbkFA`6>S^#H0mp0TS6C3Fn1g_awy(y7Wy$3;+=(#L*Dv5k=17BLq(Of zTRQ5guZX5nqIP##RcjU6Ab9mwD&cBghZ9m`dnm=~$E|KeCg(+Wl)d`Ashs?kDes6! zVN^%2ktNZa{he;6!1@Jx#-tYeQbMspG%^-2J`rTCk5fP#a<9 z3H@=~@#~)MG^3Mo;3l9CUC;`7cm?z<18oAw9EB`#$+!OB`my^kDyr3wwlHcJ@j-5|PoOcNZK&Ru(wTLm{|>&Sg$j-*S^Pt3N*@Zc zJLuusuhM_fG^)EFv4TQzGumq+N2XrJl7CO`g&RKrrGL!g*3TnvM)if`>@c`Jne|o{ zLqp?ZRB8q&haF*T(FikF6+5JO_df0eQHgpKj=}LrsctPZ7F9mP-4i0dBk={9oE?|a znyt-5r?3>~#|s>-=^Zr)0yq>`j!iZA)->gKH=<>%B@|A_dqQ_ZaO=LVo|@h@Bbt~7 zr4d&8J9)ryk~%S#u4jXuko7yAn{Kky!4T~%*4;aAQA0^w_eU;$nS%%gDJ?}Jq;iHO z32abAUNjxI`%Fo;vUOXUtpVUoxU^vM&Qq+IP*YNEMd}1 zx=3zA->Hk-PGKP%ECc~N=VdXO62bP+g`xg1;LAXZ0XE@TKO5H{RHe`XJnG%RL}h1? z|B`YfJVL}Xl7pWJrwRPGX8C840KR#B-x35kAKE`#8dzQ~E(_=PH0zTN*w5^5Ev?!{ zI5v%QJ67<#4?6RkWAV#>$f(IvDn+|2^^TZY9-zo%I%P=(7GC%DJ|sMl8^l%hgl_`4 z?&Z~q(M(7xu*JNd>dwD;I^HJ~N`5eLCFJm}0pV(+Yyz9)0e4wNevIXUS;0gr5w~Q#LU%tgm z<9ul$Y1j%?PNonDO{#dXfAR5RlOexTSB$l|OTwNpJ)68yo7WojmM}vX-u!s}^C}=8 zJ!=$_;i{E6$*ELo)In5i-Wu`|1HFgn(vnx|uuk;JZ|WLNUWa4|r-1uX7QfvyzT5SEAN2$%2mnw5 zK%hHqzts_XCh6=o^Jvg~iSUrBdD>nvLMDxVuS{dMdS#Y_F4k6RV){HXOjM#!j9#_= zP*H!bst6nE$ugsbjvbE1X$2K}ix?V54pN?&E1sJ(t4*`CqvlPK5-(0phe;*-`a)m_ zBU#Ap>gIqlK9>(V+m?P+A0!bzGYbK)FzrT|CSJ#8Qfkyla&vSPsw&JtWj0`mPfR5P zz5QTsLHrvOZi+5_7qhCeRapNMr|w(itYTr7j(#Iw*)EYO8ixfo=fumgR~MpCTxSdw zSQ>-7(4mnBIZs;@iQo?`IZPTbW7&RkBfCI}2D$0oJCdPPcg+I{TDEt6Op9&jYu_uI zbX@_uT)dX^r}(u@hpGwTUJs{^a**p_quW41p-^8x6BH!CeAent)5wtb4Z zOh>bq3(X|V^9MHC4=q$CUZ`rg%wIiVCa(mFF~o)GhinDsJw}%Zj8)#np$HLiv}m*k(JC`D>3y zYy#W6uGj&M2v>B*(x%Yu7BAhithX{aA>6KOcQf z?V9K7(DZvrynFZvrpNyHd5eVvMIcY-pfGVyjklePkF9n`+;y)=fQA;P$kE&OvL7Ro zCw&=M^~ViSHzadZk~tqi{3E|MS;U7(ZLP_-UKcc%l>H|2C3|WUQ^_B<3hoXL>Lt|C zpCb@N9jDPc*Z5k`CRgU_im7K0qrY&YZo}@kbgT|c5E;J~82l0(ER7wXCS8}usNauR z&QD08a2d$-zQqv-Louf*GKY?$qE3gY?{W;tu^#s>LceaSI(#*Usb8aACrBSwJa8>I z4*PPiC>A|=;IW%qmc9A$#m@DaiF*=q+TZXoP+N?5LQ3Kz4qBXGd8oK#B{|5NflAiD|C7YOuSXu(Hx%rc#+iT_rw$#Di^?R@07T$ow16dryt*4%8K>KTulqK4a64LhB$$$ad_XtGU^VwmIF zUYdy0U7Rlk<-qlB|1LNJG=!@Bw7FO0&M{uqF}>htbN9fYM9kiMp_Ri|4^W z;=Ic3N%^_Q&Z}Rnnc%fb{RZT=8~aG;dy$DsY3F*z7-^RDIY&||OhXJ&a1J0Wf-zIu*Y<*02R>28dxwt9QC)4~+tD{M1VmXnrLCgPbJQc{RbIaQl7QE~T-`d= z<0G^vQE408A^1oTXcJN}b@2dIL)7c&uZPacdBwSy7pY6cWd;gs&dnOWtX<3fDr%jntUTUZNMyN3a!$va#U;btCc>lC8_eBQzOBpw-NtCl^yJ{zk@ zUapX5ehqe)4%+_CVq!Jw2V7ztSAbzVinCHMv~MXOW?DYw?M&u#nC9=8>f)}8;;QLW z|K!NQN(%e(zd~>w#8oFURI|7O*D0;Gb5dr2c%0*jm0)F70?I&fYZ26HRh5iI*rfUR z#p8>jiW&}mj-GJL7siUZeZTvqBsH}RA_j!1_I!DLLd#Mj@}`X5YE1x@xGr!zl>Yh^ z;PLYGqg=|yDTp?Rw;*}jR&$R5uSz-p%7j>~<6b;lhNbn#XL{=N1&`AsA@`3~wc5;n zTalG^(tQl}4(+pEZF@vzWexjNfiNnwh8Ch;6gl;BrCWK z^_Dt_4g317?goFRwS`&33guC<4?Q6)DjSvZ{^hu;F**FJjrZ66#cvre#`;_Biq2vO zwW2!OVOlmGg)e(knId4^KB(H{Xiaw_RO7#(8MDi^$aVKg*7mdKKUEXMdf#%gRG#S? zc$aDJRr~U_6)GK-+9~@bc}||VU-P<;>9r{aCuwM^L9xO1{@e(9QIC7nbSsjt0L5+Nk0;uDyIgNr4Jd?A)L#Jxq7|Hk z>ph445G@i|C{04)^gfOCNS+uIm$>oFkRAhLa_(TQf$&)2y=jL1O8beZHX*4+&YS zmLFh;7HRs<0>Y$Gkk literal 0 HcmV?d00001 diff --git a/index.html b/index.html index 2df609e..ce85ae5 100644 --- a/index.html +++ b/index.html @@ -53,6 +53,7 @@ +