在业务系统中实现对已有的各个业务校验规则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了,这样实现了降级功能的统一管理和规则本身的职责单一性。
相关推荐
3. `mdrproxy.js` 和 `mdrproxy.ts`:这些可能是实现降级过程的代理服务,使用JavaScript(`.js`)和TypeScript(`.ts`)编写。TypeScript是JavaScript的一个超集,提供静态类型检查和更强大的代码结构。 4. `mdr.js...
3. **降级或取消资格**:连续两年未达销售目标、损害企业利益或违反规则的代理商将被降级或取消资格。 **四、违规行为处理** 包括但不限于:主动取消资格、违法违约、未经许可转移资格、跨区销售、恶意竞争、截留...
- **K8S CRD 动态配置规则**:通过 Kubernetes Custom Resource Definition,可以动态配置 Sentinel 规则,进一步提升运维效率。 - **可靠性与弹性**:Sentinel 将继续强化与 Kubernetes HPA 的集成,结合多种指标...
例如,使用Spring Cloud Netflix的Hystrix组件可以实现熔断和降级策略,Zuul或Spring Cloud Gateway作为API网关则提供了服务治理的能力。 【软件工程流程】在设计和实现微服务架构的过程中,遵循软件工程的规范,...
4. **智能路由**: 可根据业务规则动态调整请求路由,实现灰度发布、蓝绿部署等高级功能。 5. **灵活扩展**: 支持SPI(Service Provider Interface)机制,允许用户自定义扩展点,以适应不同的业务需求。 6. **多种...
3. **Proxy**:提供了基于JDK动态代理和CGLIB的接口代理实现。 4. **Cluster**:负责将多个服务提供者实例进行聚合,实现负载均衡。 5. **Router**:定义了服务路由规则,可以根据条件选择不同的服务提供者。 6. **...
4. **熔断与降级**:结合Hystrix,Zuul可以实现服务间的熔断和降级策略,提高系统的容错性。 5. **负载均衡**:Zuul可以集成Ribbon进行客户端负载均衡,自动分发请求到不同的服务实例。 **Zuul的过滤器** 1. **Pre...
在源码中,你可以看到Hystrix如何通过设置降级策略、熔断机制和限流规则来保护系统稳定。降级策略是在服务不可用时提供一个默认的备选方案,避免完全阻塞;熔断机制则是在一段时间内,如果调用失败次数超过预设阈值...
5. **服务降级**:在服务不可用或者性能下降时,Zuul 可以提供降级策略,保证系统的稳定运行。 在“zuuldemoo”项目中,我们可以期待看到以下关键配置和代码结构: 1. **Eureka 客户端配置**:项目中的服务实例...
接口绑定是指使用接口作为定义SQL语句的文件,Mybatis通过动态代理实现接口绑定。插件运行原理是通过JDK的动态代理在Mybatis执行SQL前后进行拦截。 ### ZooKeeper #### 核心概念 ZooKeeper是一个开源的分布式协调...
然而,在实际部署中,由于WebSocket与HTTP协议的差异,我们往往需要借助像Nginx这样的反向代理服务器来实现Socket.IO服务的代理。本文将深入探讨在使用Nginx代理Socket.IO服务时可能遇到的问题以及解决方案。 首先...
* 动态代理(cglib 与 JDK) * Spring 事务的实现方式 * Spring 事务的底层原理 * 如何自定义注解实现功能 * Spring MVC 的运行流程 * Spring MVC 的启动流程 * Spring 的单例实现原理 * Spring 框架中用到的设计...
4. **服务降级与熔断**:通过集成Hystrix,Zuul可以实现服务降级和熔断策略,防止因某个服务故障导致整个系统崩溃。 5. **安全控制**:Zuul可以作为统一的安全入口,进行权限验证、API访问控制等,保护后端服务不受...
sentinel-envoy-rls-token-server-1.7.2.jar 是与 Envoy 集成的 Sentinel 相关组件,Envoy 是一款高性能的服务网格代理,Sentinel 通过这个组件实现了与 Envoy 的资源预留系统(RLS,Resource Reservation System)...
Eureka作为服务注册与发现中心,Hystrix实现服务降级和熔断,Zuul或Gateway作为API网关,负责路由转发和权限校验。 四、关键技术 1. **Spring Boot**:作为基础框架,简化了Spring应用的初始搭建以及开发过程,...
7. **路由与治理**:灵活的路由规则,实现灰度发布、金丝雀测试等高级功能。 8. **服务治理**:动态调整服务间的依赖关系,支持微服务的弹性扩展和缩容。 Service Mesh的出现是为了解决传统服务治理中的痛点,比如...
7. Dao接口的工作原理:MyBatis通过代理生成接口的实现类,利用动态代理机制完成接口与Mapper XML的绑定。 8. Mybatis分页原理及插件:利用limit语句进行分页,插件可以通过拦截器链进行处理。 9. Mybatis如何封装...
- **动态代理机制**:Dubbo内部使用JDK动态代理或CGLIB实现远程接口和服务动态代理。 - **集群容错策略**:包括Failover、Failfast、Failsafe等不同的集群容错方案。 #### 三、Dubbo配置详解 - **dubbo.xml配置...
Envoy 是一款流行的服务网格代理,而 RLS 功能允许 Envoy 在接收到请求时,先向 Sentinel Token 服务器申请令牌,只有获得令牌的服务实例才能继续处理请求,以此实现流控。 1. **Token 分发**:当客户端(Envoy)...
尽管TCC引入了一定的性能开销和运维成本,但通过动态降级策略,能够在保证业务连续性的同时,应对不同的服务级别需求。 5. **其他技术细节**:包括使用lua进行安全防护,支持多种编程语言,结合静态和动态扫描工具...