之前在学习erlang OTP的时候,看到在OTP中实现了工人-监工模式,就是在定义一个工作者进程的时候,同时为器分配了一个overseer(监工),监工啥事儿也不作,就专门负责工作者进程是否正常工作,有无任务异常情况发生,当时看到在机制觉得不以为然觉得就这么几行代码没什么大不了的。

当我最近用java代码来实现分布式编程的时候发现要做一个稳定的,可靠的系统并不是那么容易,之前在单机系统中默认不会不会出任何问题的共享变量操作,进程间通信。在分布式系统中zookeeper锁操作异常,远程socke长连接断连,一切都变得不是那么可靠了,甚至要默许这种异常成为常态。

但是系统还要保证是4个9的稳定性,按照以前的策略是,发生异常的地方,进行函数重试等,于是乎系统的代码开始变得冗余,杂乱起来。

erlang OTP的策略是,默认异常是一种常态,出问题了没有关系,只要将整个进程重启,重启的逻辑由监工进程负责,这样对于工作进程内部执行的逻辑还是高内聚的,清晰的。初始化的时候还可以设置监工进程的重启规则,比如一分钟之内如果超过5次异常,就认为系统中的崩溃啦,就会执行终止业务进程的逻辑。

按照这个逻辑,我在java中也简单实现了监工-工人模式,代码如下:

import java.util.concurrent.ExecutorService;
import java.uil.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;/*** 工人和监工模式实现*/
public class TaskOverseer {private final OverSeer oversee;private final long timeInterval;private static final ExecutorService threadPool = Executors.newCachedThreadPool();private int maxErrorCount;public TaskOverseer(long duration, TimeUnit timeunit, int maxErrorCount) {super();this.maxErrorCount = maxErrorCount;this.timeInterval = timeunit.toMillis(duration);this.oversee = new OverSeer();this.oversee.setDaemon(true);this.oversee.start();}private final AtomicInteger count = new AtomicInteger();private final AtomicLong timestampe = new AtomicLong(System.currentTimeMillis());protected void startWork() throws Exception {}protected void recycleResource() {}private class OverSeer extends Thread {public OverSeer() {super("Overseer thhread");}@Overridepublic void run() {try {while (true) {synchronized (this) {System.out.println("launch a worker task");threadPool.execute(new Worker());this.wait();}}} catch (InterruptedException e) {throw new RuntimeException(e);}}}private class Worker implements Runnable {@Overridepublic void run() {try {startWork();} catch (Throwable e) {synchronized (oversee) {recycleResource();final long currentTimestamp = System.currentTimeMillis();if ((currentTimestamp <= (timestampe.get() + timeInterval))&& count.incrementAndGet() > maxErrorCount) {// 终止监工进程oversee.interrupt();throw new RuntimeException("between 1 min "+ count.get() + " errors occur", e);} else {if (currentTimestamp > (timestampe.get() + timeInterval)) {count.set(0);timestampe.set(currentTimestamp);}}oversee.notifyAll();}}}}}

只需继承TaskOverseer类,在构造函数上设置,在多少时间内抛最多多少个异常,如果超过了这个异常数目,系统就会终止。然后按照业务需要覆写startWork这个函数,在里面添加一些业务代码。

​   例如:

public static void main(String[] args) throws Exception {TaskOverseer overseer = new TaskOverseer(1l, TimeUnit.MINUTES, 4) {@Overrideprotected void startWork() throws Exception {Thread.sleep(1000 * 20);throw new Exception("i am die");}};Thread.sleep(10000 * 99);}

按照如上构造函数中定义的,一分钟之内最多发生四次异常,超过这个数目系统就会奔溃。

在startWork方法中会20秒抛出一个异常,一分钟之内最多抛三个异常,所以系统将这样一直运行下去,如果将线程sleep的时间小于15秒的话,系统一段时间之后就会自动奔溃。

​如果用这样的策略来处理分布式环境下的异常,相信可以构建出一个更加稳定健壮的系统。

Java版工人-监工模式实现相关推荐

  1. 小白都能懂的设计模式 java版 静态代理模式实战练习(超详细)

    静态代理: 角色分析: 抽象角色:一般使用接口或者是抽象类来解决 真实角色:被代理的角色 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作 客户:访问代理对象的人 以一个租房子的例子来 ...

  2. 小白都能懂的设计模式 java版 抽象工厂模式 实战练习(超详细)

    比如要生产华为手机,华为路由器,小米手机,小米路由器 先写路由器和手机的接口: package abstract1;//手机产品接口 public interface IphoneProduct {v ...

  3. 模式——工程化实现及扩展(设计模式Java 版)

    -- 模式--工程化实现及扩展(设计模式Java 版) 王翔,孙逊著 ISBN 978-7-121-15638-0 2012年4月出版 定价:59.00元 16开 416页 内 容 简 介 设计模式不 ...

  4. 我的世界java版旁观模式_我的世界:8个被判定为bug的特性,旁观模式:这锅让我来背...

    <我的世界>1.16版本正式发布,但版本初期无论是基岩版,还是java版都存在着很多漏洞,比如缺失的传送门方块,被透视的矿车,失效的烤鱼机等,有的玩家称它们为特性,但这些特性已经被官方证实 ...

  5. 简单工厂模式,工厂方法模式,抽象工厂模式总结-java版

    文章目录 LOG:更新日志 一.简单工厂模式,工厂方法模式,抽象工厂模式定义 二.三种工厂模式的优缺点以及适用场景 三.名词解释 四.简单工厂模式.工厂方法模式与抽象工厂模式之间的区别 五.抽象工厂模 ...

  6. Java设计模式之建造者模式(精髓版)

    目录 1.建造者模式阐述 2.使用Java代码实现建造者模式 3.为什么需要使用建造者模式? 4.建造者模式与工厂方法模式有什么区别? 1.建造者模式阐述 Java 建造者模式是一种创建型设计模式,其 ...

  7. 我的世界java旁观者模式_我的世界基岩版开启旁观者模式教程

    我的世界基岩版中的旁观模式,可以穿过方块, 可以通过左键生物进入它们的视角,那么旁观者模式该如何开启呢,下面就给大家带来我的世界基岩版开启旁观者模式教程,一起来看看吧. 前言 Minecraft中文W ...

  8. 在Java版中被移除的物品,盘点Minecraft曾“移除”的5个物品,Mojang反悔?1.14即将加入!...

    讲台是<我的世界>非常老的一个开发计划,2012年Dinnerbone就表示,非常喜欢讲台这个设计,玩家可以在讲台上阅读和书写.2013年Dinnerbone打算重启讲台计划,但却没有成功 ...

  9. 我的世界java手机版下载1.15_我的世界java版20w16a

    我的世界java版20w16a游戏是一款模拟类型的游戏,整体的性能都进行了升级.在原来的基础上,加强了很多的设备,给玩家带来了更多更好的体验感.超级高清的画面感,加上鲜明的色彩搭配,仿佛使人觉得身临其 ...

最新文章

  1. 自己写的一个tomcat发布脚本
  2. TypeError: 'stepUp' called on an object that does not implement interface HTMLInputElement.
  3. jsp用session判断输入框_[实战小剧场servletamp;jsp] 用户登录及退出功能实现
  4. 那些年,面试被虐过的红黑树 1
  5. 关于SAP Router连接不稳定的改良
  6. [ 转载 ] Handler详解
  7. 图标X轴this显示值自定义
  8. N个数全排列的非递归算法
  9. 成功上岸,心得分享(计算机专业)
  10. 键盘响应c语言,c 键盘响应
  11. Vue验证座机号的同时验证手机号
  12. SReng日志扫描动画教程
  13. 014:针对mdk中STM32程序无法使用printf,产生停留BEAB BKPT 0xAB处问题的解决(转)
  14. Steam流式传输后插耳机没有声音
  15. [verilog] 八位比较器
  16. Python计算思维训练——数组和曲线绘制练习(三)
  17. drop python_用Python做自己的AirDrop 1 - 环境搭建
  18. 【毕业设计】深度学习人脸表情识别系统 - python
  19. Poetry of Today3--琵琶行
  20. 周超臣:支付宝的套路是我走过最长的路

热门文章

  1. win10更改UI字体
  2. layui日历和tui.calendar日程表联动
  3. 某公司iOS开发笔试题
  4. WdgM01- AutoSAR Wdg的分层架构及功能安全分析
  5. python安装和pip安装diango
  6. LightOJ 1234 Harmonic Number(调和级数+欧拉常数)
  7. 色眼识人[转] -- yet another 心理测试
  8. roast和roasting区别_你知道“吐槽”在英语里是 roast 吗?
  9. 假如我国国民生产总值的年增长率为9%,计算十年后我国国民生产总值与现在相比增长多少百分比。
  10. 【Java练手项目七】Java项目实战之天天酷跑