加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 服务器 > 安全 > 正文

聊聊高并发之隔离术

发布时间:2021-01-08 09:14:23 所属栏目:安全 来源:网络整理
导读:副标题#e# 《聊聊高并发之隔离术》要点: 本文介绍了聊聊高并发之隔离术,希望对您有用。如果有疑问,可以联系我们。 隔离是指将系统或资源分割开,系统隔离是为了在系统发生故障时能限定传播范围和影响范围,即发生故障后不会出现滚雪球效应,从而保证只有出
副标题[/!--empirenews.page--]

《聊聊高并发之隔离术》要点:
本文介绍了聊聊高并发之隔离术,希望对您有用。如果有疑问,可以联系我们。

隔离是指将系统或资源分割开,系统隔离是为了在系统发生故障时能限定传播范围和影响范围,即发生故障后不会出现滚雪球效应,从而保证只有出问题的服务不可用,其他服务还是可用的;而资源隔离有脏数据隔离、通过隔离后减少资源竞争提升性能等.我遇到的比较多的隔离手段有线程隔离、进程隔离、集群隔离、机房隔离、读写隔离、动静隔离、爬虫隔离等.而出现系统问题时可以考虑负载均衡路由、自动/手动切换分组或者降级等手段来提升可用性.

线程隔离

线程隔离主要有线程池隔离,在实际使用时我们会把请求分类,然后交给不同的线程池处理,当一种业务的请求处理发生问题时,不会将故障扩散到其他线程池,从而保证其他服务可用.

我们会根据服务等级划分两个线程池,以下是池的抽象:

<bean id="zeroLevelAsyncContext" class="com.jd.noah.base.web.DynamicAsyncContext" destroy-method="stop">
    <property name="asyncTimeoutInSeconds" value="${zero.level.request.async.timeout.seconds}"/>
    <property name="poolSize" value="${zero.level.request.async.pool.size}"/>
    <property name="keepAliveTimeInSeconds" value="${zero.level.request.async.keepalive.seconds}"/>
    <property name="queueCapacity" value="${zero.level.request.async.queue.capacity}"/>
</bean>
<bean id="oneLevelAsyncContext" class="com.jd.noah.base.web.DynamicAsyncContext" destroy-method="stop">
    <property name="asyncTimeoutInSeconds" value="${one.level.request.async.timeout.seconds}"/>
    <property name="poolSize" value="${one.level.request.async.pool.size}"/>
    <property name="keepAliveTimeInSeconds" value="${one.level.request.async.keepalive.seconds}"/>
    <property name="queueCapacity" value="${one.level.request.async.queue.capacity}"/>
</bean>

进程隔离

在公司发展初期,一般是先进行从0到1,不会一上来就进行系统的拆分,这样就会开发出一些比较大而全的系统,系统中的一个模块/功能出现问题,整个系统就不可用了.首先想到的解决方案是通过部署多个实例,然后通过负载均衡进行路由转发,但是这种情况无法避免某个模块因BUG而出现如OOM导致整个系统不可用的风险.因此此种方案只是一个过渡,较好的解决方案是通过将系统拆分为多个子系统来实现物理隔离.通过进程隔离使得某一个子系统出现问题不会影响到其他子系统.

集群隔离

随着系统的发展,单实例服务无法满足需求了,此时需要服务化技术,通过部署多个服务,形成服务集群来提升系统容量,如下图所示

随着调用方的增多,当秒杀服务被刷会影响到其他服务的稳定性,此时应该考虑为秒杀提供单独的服务集群,即为服务分组,从而当某一个分组出现问题不会影响到其他分组,从而实现了故障隔离,如下图所示

比如注册生产者时提供分组名:


<jsf:provider id="myService" interface="com.jd.MyService" alias="${分组名}" ref="myServiceImpl"/>

消费时使用相关的分组名即可:

<jsf:consumer id="myService" interface="com.jd.MyService" alias="${分组名}"/>

机房隔离

随着对系统可用性的要求,会进行多机房部署,每个机房的服务都有自己的服务分组,本机房的服务应该只调用本机房服务,不进行跨机房调用;其中一个机房服务发生问题时可以通过DNS/负载均衡将请求全部切到另一个机房;或者考虑服务能自动重试其他机房的服务从而提升系统可用性.

一种办法是根据IP(不同机房IP段不一样)自动分组,还一种较灵活的办法是通过在分组名中加上机房名解决:

<jsf:provider id="myService" interface="com.jd.MyService" alias="${分组名}-${机房}" ref="myServiceImpl"/>
<jsf:consumer id="myService" interface="com.jd.MyService" alias="${分组名}-${机房}"/>

读写隔离

如下图所示,通过主从模式将读和写集群分离,读服务只从从Redis集群获取数据,当主Redis集群出现问题时,从Redis集群还是可用的,从而不影响用户访问;而当从Redis集群出现问题时可以进行其他集群的重试.

--先读取从
status,resp = slave_get(key)
if status == STATUS_OK then
 ? ?return status,value
end
--如果从获取失败了,从主获取
status,resp = master_get(key)

动静隔离

当用户访问如结算页时,如果JS/CSS等静态资源也在结算页系统中时,很可能因为访问量太大导致带宽被打满导致出现不可用.

因此应该将动态内容和静态资源分离,一般应该将静态资源放在CDN上,如下图所示

爬虫隔离

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读