完善 Hystrix 内容

This commit is contained in:
zhoushitong
2019-11-04 20:50:58 +08:00
committed by Pliza
parent da90d445d7
commit eddf65c7d9
8 changed files with 14 additions and 18 deletions

View File

@@ -3,7 +3,7 @@
### 小型电商网站的商品详情页系统架构 ### 小型电商网站的商品详情页系统架构
小型电商网站的页面展示采用页面全量静态化的思想。数据库中存放了所有的商品信息,页面静态化系统,将数据填充进静态模板中,形成静态化页面,推入 Nginx 服务器。用户浏览网站页面时,取用一个已经静态化好的 html 页面,直接返回回去,不涉及任何的业务逻辑处理。 小型电商网站的页面展示采用页面全量静态化的思想。数据库中存放了所有的商品信息,页面静态化系统,将数据填充进静态模板中,形成静态化页面,推入 Nginx 服务器。用户浏览网站页面时,取用一个已经静态化好的 html 页面,直接返回回去,不涉及任何的业务逻辑处理。
![e-commerce-website-detail-page-architecture-1](/images/e-commerce-website-detail-page-architecture-1.png) ![e-commerce-website-detail-page-architecture-1](./images/e-commerce-website-detail-page-architecture-1.png)
下面是页面模板的简单 Demo 。 下面是页面模板的简单 Demo 。
@@ -28,7 +28,7 @@
用户浏览网页时,动态将 Nginx 本地数据渲染到本地 html 模板并返回给用户。 用户浏览网页时,动态将 Nginx 本地数据渲染到本地 html 模板并返回给用户。
![e-commerce-website-detail-page-architecture-2](/images/e-commerce-website-detail-page-architecture-2.png) ![e-commerce-website-detail-page-architecture-2](./images/e-commerce-website-detail-page-architecture-2.png)
虽然没有直接返回 html 页面那么快,但是因为数据在本地缓存,所以也很快,其实耗费的也就是动态渲染一个 html 页面的性能。如果 html 模板发生了变更,不需要将所有的页面重新静态化,也不需要发送请求,没有网络请求的开销,直接将数据渲染进最新的 html 页面模板后响应即可。 虽然没有直接返回 html 页面那么快,但是因为数据在本地缓存,所以也很快,其实耗费的也就是动态渲染一个 html 页面的性能。如果 html 模板发生了变更,不需要将所有的页面重新静态化,也不需要发送请求,没有网络请求的开销,直接将数据渲染进最新的 html 页面模板后响应即可。

View File

@@ -33,7 +33,7 @@ Hystrix 是高可用性保障的一个框架。Netflix可以认为是国外
调用服务 C只需要 20ms现在因为服务 C 故障了,比如延迟,或者挂了,此时线程会 hang 住 2s 左右。40 个线程全部被卡住,由于请求不断涌入,其它的线程也用来调用服务 C同样也会被卡住。这样导致服务 B 的线程资源被耗尽,无法接收新的请求,甚至可能因为大量线程不断的运转,导致自己宕机。服务 A 也挂。 调用服务 C只需要 20ms现在因为服务 C 故障了,比如延迟,或者挂了,此时线程会 hang 住 2s 左右。40 个线程全部被卡住,由于请求不断涌入,其它的线程也用来调用服务 C同样也会被卡住。这样导致服务 B 的线程资源被耗尽,无法接收新的请求,甚至可能因为大量线程不断的运转,导致自己宕机。服务 A 也挂。
![service-invoke-road](/images/service-invoke-road.png) ![service-invoke-road](./images/service-invoke-road.png)
Hystrix 可以对其进行资源隔离,比如限制服务 B 只有 40 个线程调用服务 C。当此 40 个线程被 hang 住时,其它 60 个线程依然能正常调用工作。从而确保整个系统不会被拖垮。 Hystrix 可以对其进行资源隔离,比如限制服务 B 只有 40 个线程调用服务 C。当此 40 个线程被 hang 住时,其它 60 个线程依然能正常调用工作。从而确保整个系统不会被拖垮。

View File

@@ -11,7 +11,7 @@
这里是整个 8 大步骤的流程图,我会对每个步骤进行细致的讲解。学习的过程中,对照着这个流程图,相信思路会比较清晰。 这里是整个 8 大步骤的流程图,我会对每个步骤进行细致的讲解。学习的过程中,对照着这个流程图,相信思路会比较清晰。
![hystrix-process](/images/hystrix-process.png) ![hystrix-process](./images/new-hystrix-process.jpg)
### 步骤一:创建 command ### 步骤一:创建 command
一个 HystrixCommand 或 HystrixObservableCommand 对象,代表了对某个依赖服务发起的一次请求或者调用。创建的时候,可以在构造函数中传入任何需要的参数。 一个 HystrixCommand 或 HystrixObservableCommand 对象,代表了对某个依赖服务发起的一次请求或者调用。创建的时候,可以在构造函数中传入任何需要的参数。
@@ -64,9 +64,7 @@ final Future<R> delegate = toObservable().toBlocking().toFuture();
也就是说,先通过 toObservable() 获得 Future 对象,然后调用 Future 的 get() 方法。那么,其实无论是哪种方式执行 command最终都是依赖于 toObservable() 去执行的。 也就是说,先通过 toObservable() 获得 Future 对象,然后调用 Future 的 get() 方法。那么,其实无论是哪种方式执行 command最终都是依赖于 toObservable() 去执行的。
![hystrix-process](/images/hystrix-process.png) ### 步骤三:检查是否开启缓存(不太常用)
### 步骤三:检查是否开启缓存
从这一步开始,就进入到 Hystrix 底层运行原理啦,看一下 Hystrix 一些更高级的功能和特性。 从这一步开始,就进入到 Hystrix 底层运行原理啦,看一下 Hystrix 一些更高级的功能和特性。
如果这个 command 开启了请求缓存 Request Cache而且这个调用的结果在缓存中存在那么直接从缓存中返回结果。否则继续往后的步骤。 如果这个 command 开启了请求缓存 Request Cache而且这个调用的结果在缓存中存在那么直接从缓存中返回结果。否则继续往后的步骤。
@@ -122,8 +120,6 @@ observable.subscribe(new Observer<ProductInfo>() {
如果没有 timeout也正常执行的话那么调用线程就会拿到一些调用依赖服务获取到的结果然后 Hystrix 也会做一些 logging 记录和 metric 度量统计。 如果没有 timeout也正常执行的话那么调用线程就会拿到一些调用依赖服务获取到的结果然后 Hystrix 也会做一些 logging 记录和 metric 度量统计。
![hystrix-process](/images/hystrix-process.png)
### 步骤七:断路健康检查 ### 步骤七:断路健康检查
Hystrix 会把每一个依赖服务的调用成功、失败、Reject、Timeout 等事件发送给 circuit breaker 断路器。断路器就会对这些事件的次数进行统计,根据异常事件发生的比例来决定是否要进行断路(熔断)。如果打开了断路器,那么在接下来一段时间内,会直接断路,返回降级结果。 Hystrix 会把每一个依赖服务的调用成功、失败、Reject、Timeout 等事件发送给 circuit breaker 断路器。断路器就会对这些事件的次数进行统计,根据异常事件发生的比例来决定是否要进行断路(熔断)。如果打开了断路器,那么在接下来一段时间内,会直接断路,返回降级结果。

View File

@@ -9,7 +9,7 @@ Hystrix command 执行时 8 大步骤第三步,就是检查 Request cache 是
举个栗子。比如说我们在一次请求上下文中,请求获取 productId 为 1 的数据,第一次缓存中没有,那么会从商品服务中获取数据,返回最新数据结果,同时将数据缓存在内存中。后续同一次请求上下文中,如果还有获取 productId 为 1 的数据的请求,直接从缓存中取就好了。 举个栗子。比如说我们在一次请求上下文中,请求获取 productId 为 1 的数据,第一次缓存中没有,那么会从商品服务中获取数据,返回最新数据结果,同时将数据缓存在内存中。后续同一次请求上下文中,如果还有获取 productId 为 1 的数据的请求,直接从缓存中取就好了。
![hystrix-request-cache](/images/hystrix-request-cache.png) ![hystrix-request-cache](./images/hystrix-request-cache.png)
HystrixCommand 和 HystrixObservableCommand 都可以指定一个缓存 key然后 Hystrix 会自动进行缓存,接着在同一个 request context 内,再次访问的话,就会直接取用缓存。 HystrixCommand 和 HystrixObservableCommand 都可以指定一个缓存 key然后 Hystrix 会自动进行缓存,接着在同一个 request context 内,再次访问的话,就会直接取用缓存。

View File

@@ -13,14 +13,14 @@ Hystrix 实现资源隔离,主要有两种技术:
### 信号量机制 ### 信号量机制
信号量的资源隔离只是起到一个开关的作用,比如,服务 A 的信号量大小为 10那么就是说它同时只允许有 10 个 tomcat 线程来访问服务 A其它的请求都会被拒绝从而达到资源隔离和限流保护的作用。 信号量的资源隔离只是起到一个开关的作用,比如,服务 A 的信号量大小为 10那么就是说它同时只允许有 10 个 tomcat 线程来访问服务 A其它的请求都会被拒绝从而达到资源隔离和限流保护的作用。
![hystrix-semphore](/images/hystrix-semphore.png) ![hystrix-semphore](./images/hystrix-semphore.png)
### 线程池与信号量区别 ### 线程池与信号量区别
线程池隔离技术,并不是说去控制类似 tomcat 这种 web 容器的线程。更加严格的意义上来说Hystrix 的线程池隔离技术,控制的是 tomcat 线程的执行。Hystrix 线程池满后会确保说tomcat 的线程不会因为依赖服务的接口调用延迟或故障而被 hang 住tomcat 其它的线程不会卡死,可以快速返回,然后支撑其它的事情。 线程池隔离技术,并不是说去控制类似 tomcat 这种 web 容器的线程。更加严格的意义上来说Hystrix 的线程池隔离技术,控制的是 tomcat 线程的执行。Hystrix 线程池满后会确保说tomcat 的线程不会因为依赖服务的接口调用延迟或故障而被 hang 住tomcat 其它的线程不会卡死,可以快速返回,然后支撑其它的事情。
线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。 线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。
![hystrix-semphore-thread-pool](/images/hystrix-semphore-thread-pool.png) ![hystrix-semphore-thread-pool](./images/hystrix-semphore-thread-pool.png)
**适用场景** **适用场景**
- **线程池技术**,适合绝大多数场景,比如说我们对依赖服务的网络请求的调用和访问、需要对调用的 timeout 进行控制(捕捉 timeout 超时异常)。 - **线程池技术**,适合绝大多数场景,比如说我们对依赖服务的网络请求的调用和访问、需要对调用的 timeout 进行控制(捕捉 timeout 超时异常)。

View File

@@ -1,7 +1,7 @@
## 深入 Hystrix 线程池隔离与接口限流 ## 深入 Hystrix 线程池隔离与接口限流
前面讲了 Hystrix 的 request cache 请求缓存、fallback 优雅降级、circuit breaker 断路器快速熔断,这一讲,我们来详细说说 Hystrix 的线程池隔离与接口限流。 前面讲了 Hystrix 的 request cache 请求缓存、fallback 优雅降级、circuit breaker 断路器快速熔断,这一讲,我们来详细说说 Hystrix 的线程池隔离与接口限流。
![hystrix-process](/images/hystrix-process.png) ![hystrix-process](./images/hystrix-process.png)
Hystrix 通过判断线程池或者信号量是否已满,超出容量的请求,直接 Reject 走降级,从而达到限流的作用。 Hystrix 通过判断线程池或者信号量是否已满,超出容量的请求,直接 Reject 走降级,从而达到限流的作用。
@@ -12,7 +12,7 @@ Hystrix 采用了 Bulkhead Partition 舱壁隔离技术,来将外部依赖进
**舱壁隔离**,是说将船体内部空间区隔划分成若干个隔舱,一旦某几个隔舱发生破损进水,水流不会在其间相互流动,如此一来船舶在受损时,依然能具有足够的浮力和稳定性,进而减低立即沉船的危险。 **舱壁隔离**,是说将船体内部空间区隔划分成若干个隔舱,一旦某几个隔舱发生破损进水,水流不会在其间相互流动,如此一来船舶在受损时,依然能具有足够的浮力和稳定性,进而减低立即沉船的危险。
![bulkhead-partition](/images/bulkhead-partition.jpg) ![bulkhead-partition](./images/bulkhead-partition.jpg)
Hystrix 对每个外部依赖用一个单独的线程池,这样的话,如果对那个外部依赖调用延迟很严重,最多就是耗尽那个依赖自己的线程池而已,不会影响其他的依赖调用。 Hystrix 对每个外部依赖用一个单独的线程池,这样的话,如果对那个外部依赖调用延迟很严重,最多就是耗尽那个依赖自己的线程池而已,不会影响其他的依赖调用。

View File

@@ -1,7 +1,7 @@
## 基于 Hystrix 线程池技术实现资源隔离 ## 基于 Hystrix 线程池技术实现资源隔离
上一讲提到,如果从 Nginx 开始缓存都失效了Nginx 会直接通过缓存服务调用商品服务获取最新商品数据(我们基于电商项目做个讨论),有可能出现调用延时而把缓存服务资源耗尽的情况。这里,我们就来说说,怎么通过 Hystrix 线程池技术实现资源隔离。 [上一讲](./e-commerce-website-detail-page-architecture.md)提到,如果从 Nginx 开始缓存都失效了Nginx 会直接通过缓存服务调用商品服务获取最新商品数据(我们基于电商项目做个讨论),有可能出现调用延时而把缓存服务资源耗尽的情况。这里,我们就来说说,怎么通过 Hystrix 线程池技术实现资源隔离。
资源隔离,就是说,你如果要把对某一个依赖服务的所有调用请求,全部隔离在同一份资源池内,不会去用其它资源了,这就叫资源隔离。哪怕对这个依赖服务,比如说商品服务,现在同时发起的调用量已经到了 1000但是线程池内就 10 个线程,最多就只会用这 10 个线程去执行,不会说,对商品服务的请求,因为接口调用延时,将 tomcat 内部所有的线程资源全部耗尽。 资源隔离,就是说,你如果要把对某一个依赖服务的所有调用请求,全部隔离在同一份资源池内,不会去用其它资源了,这就叫资源隔离。哪怕对这个依赖服务,比如说商品服务,现在同时发起的调用量已经到了 1000但是线程池内就 10 个线程,最多就只会用这 10 个线程去执行,不会说,对商品服务的请求,因为接口调用延时,将 Tomcat 内部所有的线程资源全部耗尽。
Hystrix 进行资源隔离,其实是提供了一个抽象,叫做 command。这也是 Hystrix 最最基本的资源隔离技术。 Hystrix 进行资源隔离,其实是提供了一个抽象,叫做 command。这也是 Hystrix 最最基本的资源隔离技术。
@@ -110,6 +110,6 @@ public String getProductInfos(String productIds) {
我们回过头来,看看 Hystrix 线程池技术是如何实现资源隔离的。 我们回过头来,看看 Hystrix 线程池技术是如何实现资源隔离的。
![hystrix-thread-pool-isolation](/images/hystrix-thread-pool-isolation.png) ![hystrix-thread-pool-isolation](./images/hystrix-thread-pool-isolation.png)
从 Nginx 开始,缓存都失效了,那么 Nginx 通过缓存服务去调用商品服务。缓存服务默认的线程大小是 10 个,最多就只有 10 个线程去调用商品服务的接口。即使商品服务接口故障了,最多就只有 10 个线程会 hang 死在调用商品服务接口的路上,缓存服务的 tomcat 内其它的线程还是可以用来调用其它的服务,干其它的事情。 从 Nginx 开始,缓存都失效了,那么 Nginx 通过缓存服务去调用商品服务。缓存服务默认的线程大小是 10 个,最多就只有 10 个线程去调用商品服务的接口。即使商品服务接口故障了,最多就只有 10 个线程会 hang 死在调用商品服务接口的路上,缓存服务的 Tomcat 内其它的线程还是可以用来调用其它的服务,干其它的事情。

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB