在业务系统中实现对已有的各个业务校验规则Rule的增强,因为太多的Rule实现依赖了外部系统而变得不可控,并且系统对规则基本定位成强校验,这样我们系统的可用性以及稳定性会被外部系统所左右,于是提出了对规则可以动态降级,实现运行时绕过一些规则的校验(当然,需要在业务容忍一致性和系统可用性之间权衡)。同事的想法:提供一个基类来负责执行是否降级的功能,然后每个具体的实现类继承这个基类,在执行真正的规则校验逻辑之前,调用父类的方法判断是否走校验。我觉得这样做的问题有两点,首先,规则本身不应该去关注降级的问题,这样规则的职责更加纯粹。其次,之前已经有很多规则实现,这样做要去改变之前的规则实现,而且是通过继承的方式来修改,同时对每个实现的改动都是类似的,比较机械化。考虑了下,决定使用动态代理对规则实现降级管理。代码实现很简单:
public class DegraderableRuleWrapper implements FactoryBean, BeanNameAware { private final static Logger LOG = LoggerFactory.getLogger(DegraderableRuleWrapper.class); private final static String ITEM_RULE_NAME_SKIP_NAME = "com.***.ruleSkipNameList"; /** * 需要跳过的规则列表 */ private static Set<String> skipRuleNameList = Sets.newHashSet(); /** * 用于分隔字符串的工具类 */ private static final Splitter SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults(); private Rule target; private String ruleName; private Object delegate; public void setTarget(Rule target) { this.target = target; //ruleName = target.getClass().getSimpleName(); } @Override public void setBeanName(String name) { ruleName = name; } @Override public Object getObject() throws Exception { if (delegate == null) { delegate = createProxy(); } return delegate; } private Object createProxy() { @SuppressWarnings("unchecked") Class<?>[] allInterfaces = (Class<?>[]) ClassUtils.getAllInterfaces(target.getClass()).toArray(new Class<?>[0]); Object wrapperedRule = Proxy.newProxyInstance(target.getClass().getClassLoader(), allInterfaces, new SwitchListener()); LOG.warn("create a degraderableRule for rule {}.", ruleName); return wrapperedRule; } @Override public Class<? extends Rule> getObjectType() { return Rule.class; } @Override public boolean isSingleton() { return false; } static{ initialSkipRuleListAndListenChange(); } private static void initialSkipRuleListAndListenChange() { /* * 开始并不主动拉取,而是注册监听,等待异步回调,减少应用启动时间。 */ Diamond.addListener(ITEM_RULE_NAME_SKIP_NAME, Constants.DEFAULT_GROUP, new ManagerListenerAdapter() { @Override public void receiveConfigInfo(String configInfo) { LOG.warn("Got new skipRuleNameList, " + configInfo); Iterable<String> ruleNames = SPLITTER.split(configInfo); Set<String> newSkipRuleNames = Sets.newHashSet(ruleNames); skipRuleNameList = newSkipRuleNames; } }); } private class SwitchListener implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (skipRuleNameList.contains(ruleName)) { LOG.warn("Rule {} is in skipList, skip it.", ruleName); return RuleResult.successResult(); } return method.invoke(target, args); } } }
实现中使用了spring的factorybean,beanname,google的guava工具类以及淘宝开源的diamond集中式静态配置管理工具。PS:diamond主要是实现对集群的配置管理,其他的方式也很多,比如使用zookeeper也可以,当然使用存储+线程定时轮询变化(其实diamond的实现方式就很类似,只不过加上了比较多的容灾功能)也OK。
对于实现需要注意的是这行代码:
Class<?>[] allInterfaces = (Class<?>[]) ClassUtils.getAllInterfaces(target.getClass()).toArray(new Class<?>[0]);
开始的时候直接使用
target.getClass().getInterfaces()
发现继承过来的实现,获取不到类实现的接口,也算是细节的一个点吧。
使用这个规则的地方只需要配置下这个bean即可,配置方式如下:
<bean id="testPlatformRule" class="com.***.rule.DegraderableRuleWrapper"> <property name="target"> <bean class="com.***.rule.impl.TestPlatformRule" /> </property> </bean>
这样其他地方在引用这个bean的时候就已经是进行了降级管理的Rule了,这样实现了降级功能的统一管理和规则本身的职责单一性。
相关推荐
springboot openfeign Sentinel统一降级处理实现代码
斐讯N1、T1一键降级脚本,实现自动降级,同时能够脚本进入线刷模式
互联网高并发解决方案-基于Hystrix实现服务隔离与降级互联网高并发解决方案-基于Hystrix实现服务隔离与降级互联网高并发解决方案-基于Hystrix实现服务隔离与降级互联网高并发解决方案-基于Hystrix实现服务隔离与降级...
想体验更好的降噪功能的朋友可以用这款工具降级固件,最低只能降级到AUA1。 教程:用能连接蓝牙的电脑下载这个降级工具,然后耳机连接电脑,看到软件界面会出现这款蓝牙耳机的型号、电量等信息。软件界面再往下会...
中兴B860AV1.1-T2 降级包。ADB二维码 ,无法用计算器算ADB密码 ,TTL锁死, 唯一降级包, 唯一降级包, 唯一降级包
PSP降级工具 著名黑客someone发布了6.60官方系统降级程序6xx_downgrader_v4,该降级程序支持PSP1000、2000、3000和PSPgo的主板为01G,02G,03G,04G,05G,07G,09G。 6.XX Downgrader是一款给官方系统的PSP进行降级的...
联想工程师专用小工具 网卡驱动降级工具V3.30.1联想工程师专用小工具 网卡驱动降级工具V3.30.1联想工程师专用小工具 网卡驱动降级工具V3.30.1联想工程师专用小工具 网卡驱动降级工具V3.30.1联想工程师专用小工具 ...
面试官:Dubbo怎么实现服务降级,他有什么好处?.doc
vivo机型售后系统降级工具 售后工具 vivo机型专用 专门为系统降级用的软件 需要的友友可以下载使用
HTC Hoot降级文件,HTC Hoot降级文件。
ColorOS 14 降级工具+使用教程 仔细看支持机型 资源说明; 适用机型 Find X6 Pro、Find X6 、Find X5 Pro、Find X5、Find X5 Pro 天玑版、Find X3 Pro、Find X3、Find N2 Flip、Find N2、Find N、Reno 10 Pro+、Reno ...
iPhone5怎么降级?iPhone5降级iOS 7.0.4教程
目前iPhone都可以实现降级,虽然苹果已经关闭了老版本系统的验证,但是并不代表老设备不能降级,白苹果下面就给大家带来iPhone完美降级
iphone4s ios7降级6.13.doc
1、资源内容:基于Matlab实现图像降级自适应算法与攻击数字水印系统(源码+数据+报告).rar 2、适用人群:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业或毕业设计,作为“参考资料”使用。 3、...
郑焱-百度信息流产品动态降级以及故障自愈实践-最终版本.pdf
持久化的规则有:授权规则、降级规则、流控规则、热点规则、系统规则 其他说明:默认请求的nacos地址是127.0.0.1:8848 注意!注意!注意!:这个是源码,需要自己打包,如果需要打包好的请前往...
VIVO机型官方线刷包 降级包固件下载工具 云端网盘链接下载官方线刷固件的工具。 同一个型号多个版本官方线刷固件 降级包下载 支持机型 vivo y32 iqoo u5 iqoo9 iqoo 9pro iqoo neo6 vivo y10 vivo nex10pro x7old ...
htc g11 降级文件