2019年阿里云双11活动拼团:https://www.aliyun.com/1111/2019/group-buying-share


生产一个产品,需要依次执行多个步骤,才能完成,那么是使用责任链模式则是极好的。

在性能告警模块开发过程中,创建一条告警规则需要执行阈值解析,中间表生成,流任务生成,规则入库,告警事件入库等诸多操作。如果把这些步骤糅合在一个类中,代码可读性及复杂度往往是灾难的,特别对于这么多步骤的事务性操作,更是力不从心。使用责任链模式,上述问题迎刃而解。

以告警规则创建为例子,简化流程如下

阈值解析 ---> 流任务生成 ---> 规则入库

回滚流程如下

1、 阈值解析失败:回滚阈值解析。

2、 流任务生产失败:回滚流任务生成,阈值解析。

3、 规则入库失败:回滚规则入库,流任务生成,阈值解析。

采用责任链模式编码,思路如下:

1、 编写阈值解析处理器,流任务生成处理器,规则入库处理器,每个处理器包含业务处理方法和回滚方法;

2、 一个处理器业务代码执行完成后主动调用下一个处理器业务方法;

3、 一个处理器业务代码执行失败主动调用本处理器回滚方法,本处理器回滚完成后主动调用上一个处理器回滚方法。

代码如下

1、 抽象处理器

package com.coshaho.learn.handler;/** *  * AbstractRuleHandler.java Create on 2017年5月5日 下午11:20:15     *     * 类功能说明: 告警规则责任链处理节点抽象类 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public abstract class AbstractRuleHandler {    // 上一个处理器    private AbstractRuleHandler preHandler;        // 下一个处理器    private AbstractRuleHandler nextHandler;        /**     * 业务执行     *      * @author coshaho      * @param rule     */    public void doHandle(AlarmRule rule)    {        try        {            doHandleReal(rule);        }        catch(Exception e)        {            // 业务代码执行失败主动回滚            rollBack(rule);            return;        }                // 业务代码执行成功主动调用下一个处理器处理        if(null != nextHandler)        {            nextHandler.doHandle(rule);        }    }        /**     * 事务回滚     *      * @author coshaho      * @param rule     */    public void rollBack(AlarmRule rule)    {        rollBackReal(rule);        // 本处理器业务回滚完成,主动调用前一个处理器业务回滚        if(null != preHandler)        {            preHandler.rollBack(rule);        }    }        /**     * 每个处理器特有的业务处理方法     *      * @author coshaho      * @param rule     * @throws Exception     */    public abstract void doHandleReal(AlarmRule rule) throws Exception;        /**     * 每个处理器特有的业务回滚方法     *      * @author coshaho      * @param rule     */    public abstract void rollBackReal(AlarmRule rule);    private AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler)     {        this.preHandler = preHandler;        return preHandler;    }    public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler)     {        this.nextHandler = nextHandler;        nextHandler.setPreHandler(this);        return nextHandler;    }}

2、阈值解析处理器

package com.coshaho.learn.handler;import org.apache.commons.lang.StringUtils;/** *  * ThresholdParseHandler.java Create on 2017年5月5日 下午11:41:20     *     * 类功能说明:   阈值解析 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public class ThresholdParseHandler extends AbstractRuleHandler{    @Override    public void doHandleReal(AlarmRule rule) throws Exception     {        if(StringUtils.isEmpty(rule.getThreshold()))        {            throw new Exception("Threshold is empty.");        }        System.out.println("Parse threshold success. Threshold is " + rule.getThreshold());    }    @Override    public void rollBackReal(AlarmRule rule)     {        System.out.println("Roll parse threshold. Threshold is " + rule.getThreshold());    }}

3、流任务生成处理器

package com.coshaho.learn.handler;/** *  * StreamGenerateHandler.java Create on 2017年5月5日 下午11:41:43     *     * 类功能说明:   告警流规则生成 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public class StreamGenerateHandler extends AbstractRuleHandler {    @Override    public void doHandleReal(AlarmRule rule) throws Exception     {        System.out.println("Generate stream success.");    }    @Override    public void rollBackReal(AlarmRule rule)     {        System.out.println("Roll Generate stream.");    }}

4、规则入库处理器

package com.coshaho.learn.handler;import org.apache.commons.lang.StringUtils;/** *  * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08     *     * 类功能说明:   告警规则持久化 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public class RulePesistHandler extends AbstractRuleHandler {    @Override    public void doHandleReal(AlarmRule rule) throws Exception {        if(StringUtils.isEmpty(rule.getName()))        {            throw new Exception("Rule name is empty.");        }        System.out.println("Persist rule success. Rule name is " + rule.getName());    }    @Override    public void rollBackReal(AlarmRule rule) {        System.out.println("Roll persist rule. Rule name is " + rule.getName());            }}

5、规则入库处理器

package com.coshaho.learn.handler;import org.apache.commons.lang.StringUtils;/** *  * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08     *     * 类功能说明:   告警规则持久化 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public class RulePesistHandler extends AbstractRuleHandler {    @Override    public void doHandleReal(AlarmRule rule) throws Exception {        if(StringUtils.isEmpty(rule.getName()))        {            throw new Exception("Rule name is empty.");        }        System.out.println("Persist rule success. Rule name is " + rule.getName());    }    @Override    public void rollBackReal(AlarmRule rule) {        System.out.println("Roll persist rule. Rule name is " + rule.getName());            }}

6、告警规则

package com.coshaho.learn.handler;/** *  * AlarmRule.java Create on 2017年5月5日 下午11:40:50     *     * 类功能说明:  告警规则 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public class AlarmRule {    private String name;        private String type;        private String threshold;        public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    public String getThreshold() {        return threshold;    }    public void setThreshold(String threshold) {        this.threshold = threshold;    }}

7、规则创建责任链

package com.coshaho.learn.handler;/** *  * AlarmRuleCreator.java Create on 2017年5月5日 下午11:56:45     *     * 类功能说明:   告警规则创建 * * Copyright: Copyright(c) 2013  * Company: COSHAHO * @Version 1.0 * @Author coshaho */public class AlarmRuleCreator {    private AbstractRuleHandler alarmRuleHandler;    public AlarmRuleCreator()    {        alarmRuleHandler = new ThresholdParseHandler();        alarmRuleHandler.setNextHandler(new StreamGenerateHandler())                .setNextHandler(new RulePesistHandler());    }        public void create(AlarmRule rule)    {        alarmRuleHandler.doHandle(rule);    }    public static void main(String[] args)    {        AlarmRule rule = new AlarmRule();        rule.setThreshold("cpuRate < 10");        rule.setName("Cpu Alarm");                AlarmRuleCreator ruleCreator = new AlarmRuleCreator();        ruleCreator.create(rule);        System.out.println();                rule.setName("");        ruleCreator.create(rule);    }}

测试结果

Parse threshold success. Threshold is cpuRate < 10Generate stream success.Persist rule success. Rule name is Cpu AlarmParse threshold success. Threshold is cpuRate < 10Generate stream success.Roll persist rule. Rule name is Roll Generate stream.Roll parse threshold. Threshold is cpuRate < 10

收藏 打印