前段时间分析社区最近发生的故障,发现了一些共性的东西,基本都是由于一些服务提供方的接口问题导致的。
随着服务化的推进,外部服务接口的调用会越来越多,如何在外部接口异常的情况下保持自身系统的稳定是我们必须要思考的问题。
最近花了点时间研究exodus2里面使用的ResourceLimit ,觉得非常适合用于解决我们现在所面临的问题,在阿甘的指导下整理了份文档。
希望能对大家有帮助,十一之后我会整理一套相对完备的解决方案,在社区产品中做试点,希望各位应用负责人多多支持。(附件是word文档)
ResourceLimit 实用指南
一, 遇到的问题
在日常的故障中,我们经常遇到一类问题:由于一两个关键接口出问题,而导致整个应用的连接数被耗光,进而导致整个应用荡掉的情况。生意经就出过类似的故障,由于依赖的DW Hession接口超时,导致线程堵住,这个接口的最大访问线程数没做限制,进而占用了系统所有的请求线程,导致整个应用不可用。
解决上面的问题,需要我们自己主动的对那些核心的,访问量高的,容易出问题的接口和功能点做访问资源限制,这也是设计ResourceLimit 的初衷。通过限制核心类的某个方法可使用的最大并发请求线程数去解决上面的问题。
二,解决方案
原理比较简单,设计一个拦截器,对指定的类和方法进行拦截计数,如果并发请求的线程数小于配置的值,则响应请求,否则ResourceLimit会抛出异常 ,调用方可以捕获并处理这个异常,也可以不做处理,这样便可释放被占用的请求线程资源,保证在接口超时或者发生异常的情况下线程不会都堵在这,确保其他功能和整个应用的可用性。
随着服务化的推进,每个应用的服务化接口越来越多,对接口资源限制的需求越来越强烈,最近百科产品的很多故障都是因为服务提供方的接口问题而间接导致的。通过上面这种方式可以把故障减小到服务接口所涉及到的那块功能点,且影响的范围只涉及并发访问的那几个用户。很大程度上可以保证我们系统的健壮性。
系统大体的设计思路如下图:
三,如何使用
部署很简单,只需要做简单的spring配置即可,不涉及代码修改。
(1) 首先配置拦截的资源,即拦截的类
<bean id="batchPostOfferResourceLimit" class="com.alibaba.china.biz.common.quota.SynchronizedResource">
<property name="resourceCount">
<value>10</value> //允许的最大并发线程数
</property>
<property name="resourceName">
<value>BatchPostOffer</value> //资源名称--只要唯一即可
</property>
</bean>
(2) 配置拦截的方法
<bean id="batchPostOfferResourceLimitInterceptor" class="com.alibaba.china.biz.common.quota.ResourceLimitIntercepter">
<property name="methodName">
<value>doUploadExcel</value>
</property>
<property name="synchronizedResource">
<ref bean="batchPostOfferResourceLimit"/>
</property>
</bean>
(3) 把拦截器加入到该类的spring配置中
<!-- 批量发布Offer(通过Excel上传),使用了资源限制器 -->
<bean id="batchOfferAO" class="org.springframework.aop.framework.ProxyFactoryBean"
parent="baseAO">
<property name="interceptorNames">
<list>
<value>batchPostOfferResourceLimitInterceptor</value> //拦截器名称
<value>batchOfferAOTarget</value> //代理的Target bean类
</list>
</property>
</bean>
以上就是使用拦截器的全部代码。
使用的时候,有一点大家要注意,
(1) 最大并发线程数不可设置太大,因为:太大==没有,拦截就没啥意义了。
(2) 最大并发线程数也不可设置太小,太小会导致该接口的很多请求被block住,对响应时间有影响。因此最好结合接口的访问频率,做一个并发数评估,合理设置并发数大小。
四,参考资料
具体的使用代码细节大家可以参考exodus2中的src/conf/exodus2/bean/biz-quota.xml的配置。
Java拦截器模式请参考:http://sakyone.iteye.com/blog/471434