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 < 10
Generate stream success.
Persist rule success. Rule name is Cpu Alarm
Parse threshold success. Threshold is cpuRate < 10
Generate stream success.
Roll persist rule. Rule name is
Roll Generate stream.
Roll parse threshold. Threshold is cpuRate < 10