Java实时多任务调度过程中的安全监控设计

Java实时多任务调度过程中的安全监控设计,第1张

;     在一系列关联的多任务的实时环境中 如果有一个任务发生失败 可能导致所有任务产生连锁反应 从而造成调度失控的局面 特别是对于核心控制设备尤其重要 为了解决这个问题 必须对每个任务进行实时监控

问题分析

在JAVA环境中 一个任务一般是由一个独立线程来引导实现的 独立线程可能调用一系列子线程 如果在执行过程中 某一个线程发生异常(产生的原因很多 比如软件升级 运行环境改变 系统资抢占等) 那么该线程就会停止运行 直到下次任务重新被提交 对于实时环境来说当前任务是失败的 我们无法预测和完全避免异常的发生 但是可以通过一些技术手段来跟踪任务的状态 从而及时发现问题并恢复正常 减少损失

设计原理

对于一个实时任务而言 执行效率是非常关键的 这意味着不可能考虑用非常复杂的方式来实现任务监控 即使这样可以做的比较完善 同时监控代码本身也会引入一些异常 这就要求监控程序必须简单可靠 能够发现大多数问题 并能及时处理

一个可能的简单实现

我们对每个任务加上一个监控的 壳 调度程序调用这个 壳 来完成对具体任务的引导和监控 相当于每个任务具有自治能力 这样做的好处有

分散控制 不需要修改调度主体程序 不增加调度过程的复杂度 控制灵活 安全性高 对于不同任务可定义不同控制方式和控制参数 封装在任务内部 灵活性好 对个别任务控制代码的修改不会影响其他任务 即任务控制实现松藕合 避免错误扩散 适合团队开发 维护简单 升级方便 对于新的任务加入也无需改变原来调度程序的结构 只需修改任务表及相关参数 这样在性能提高的同时也简化了软件升级过程中的代码维护量

设计实现

每个线程理论上有四种状态

new 线程对象已经创建 但尚未启动 不可运行 runnable 一旦有时间分片机制有空闲的CPU周期 线程立即开始运行 dead 从run()方法退出后 一个线程即消亡 blocked 线程可运行 但有某种东西阻碍了它 调度机制不给它分配任何CPU时间 直到它进入runnable状态

在实际 *** 作中 为了便于描述 我们重新规定了线程的状态

Actived 线程已被激活 处于运行状态 Sleeping 线程完成一个特定任务后退出 进入休眠状态 Dead 线程运行过程中发生异常 终止运行 处于死亡状态

根据上述理论 我们只需要对Actived状态的线程进行监控 也只有对Actived状态监控才有意义 这是对监控模块做出逻辑简化 那么如何实现监控模块对具体任务的监控呢?

对具体任务的监控方式有多种 根据任务的不同 需要采用不同的监控代码 但是在结构上基本相同 这和类的重载概念有点相似 本文附有一个简单的例子

A任务每秒执行一个简单的代数运算 j = / i 并打印结果 我们故意在其中设置了一个异常陷阱 使得执行过程中出现一次被 除的算术异常 下面结合这个例子讲述监控原理

为了监控A 我们设计了一个监控线程M M中定义了一些关键逻辑变量

Keepchecking 持续监控标志 laststatus 保存上次监控状态 maydeadtimes 监控线程可能死亡的计数器 maydeadtimeout 定义判断线程死亡的边界条件 deadtimes 监控线程死亡次数的计数器 deadtimeout 定义判断线程不正常的边界条件

为了适应监控 在A任务中相应增加一些可以被监控的状态和行为

dead 死状态标志 dead = !dead; 改变状态

整个监控就是围绕这些状态标志和行为展开的 A任务定期修改自己的dead标志 dead是一个布尔变量 理论上只要A没有死 那么dead肯定是周期变化的(和心跳概念差不多) M需要做的就是监控dead的变化 为了避免一些偶然因素导致的误判 我们在M中设置了一些计数器和边界值(maydeadtimes和maydeadtimeout) 当M发现A的可能死亡次数超过一定限制后 判断A已死亡 不在继续等待了 作为实时处理 首先注销A的实例 然后重新启动A(和我们计算机死机的复位很像) 然后进入新一轮监控

如果是因为系统偶然因素导致A死亡 那么在随后的新的任务启动过程中一般可以顺利完成 但是万一由于环境参数改变或软件升级存在版本缺陷 A可能始终会产生异常 那么M是否需要耐心地监控下去呢?一个形象的例子是 如果你连续 次开机都失败 你是否会怀疑机器有问题?当然 你会 那么M也应该会

为了对A任务重复多次死亡有一个统计 M中又引入了另外对计数器和边界值(deadtimes和deadtimeout) 和你开计算机的过程一样 如果连续n次都发现A有问题 可以基本肯定不是由于偶然因素引起的 需要对A的代码或系统的环境进行检查 M会发出告警 通知必须要对A进行审查了 然后清空A 自己自动安全退出 如果在核心调度程序中设置一个标志接受M们的告警 就可以有足够理由终止其他任务的执行 可以看见 在A任务发生异常期间 M承担了核心调度程序的维护功能 特别是当任务数量比较多的情况 核心调度程序只能采用排队方式处理任务异常 而且由于处理异常的复杂程度不同 无法保证对多任务异常的实时处理

还要考虑正常情况下A和M的关系 核心调度程序通过M启动A任务后 M处于持续监控状态 当A正常结束任务后 A需要通知M结束监控 这样 当A进入休眠状态后 M也不会占用内存空间 提高了系统资源的利用率

通过以上描述 可以看到 上述监控思想具有清晰的概念和可 *** 作性 占用资源少 为保证系统连续稳定运行创造了条件

具体代码实现附后

运行结果如下

异常情况 正常情况 i= : status=true M read A status = true i= : status=false M read A status = false i= : status=true M read A status = true A bee Exception! M read A status = true M read A status = true M read A status = true A is deaded! M is restarting A! ____________________________ i= : status=false M read A status = false i= : status=true M read A status = true i= : status=false M read A status = false A bee Exception! M read A status = false M read A status = false M read A status = false A is deaded! M is restarting A! ____________________________ i= : status=true M read A status = true i= : status=false M read A status = false i= : status=true M read A status = true A bee Exception! M read A status = true M read A status = true M read A status = true Alert! A is unstable M will stop it (结束) i= : status=true M read A status = true i= : status=false M read A status = false i= : status=true M read A status = true i= : status=false M read A status = false i= : status=true M read A status = true A is Ending M M read A status = true (结束)

结束语

通过给制定任务线程增加监控线程 可以很好地解决实时多任务环境下的安全监控问题 同时避免了核心调度线程事务过分复杂的问题 实践证明 该方法复杂度小 占用资源少 运行可靠 适合复杂条件下的多任务环境

源代码

lishixinzhi/Article/program/Java/gj/201311/27589

首先使用ps -ef 确认你要监控的weblgoic,修改setDomainsh文件 添加如下内容:

JAVA_OPTIONS="${JAVA_OPTIONS} -Dcomsunmanagementjmxremoteport=9999"

JAVA_OPTIONS="${JAVA_OPTIONS} -Dcomsunmanagementjmxremotessl=false "

JAVA_OPTIONS="${JAVA_OPTIONS} -Dcomsunmanagementjmxremotepwdfile=/opt/bea/jrockit90_150_06/jre/lib/management/jmxremotepassword"

# JAVA_OPTIONS="${JAVA_OPTIONS} -Dcomsunmanagementjmxremoteauthenticate=false"

export JAVA_OPTIONS

关于jconsole的访问密码,可在该实例所使用的$JRE_HOME/lib/management/下配置,很重要的两个文件是

jmxremotepasswordtemplate #配置访问用户名与密码

jmxremoteaccess #增加该用户访问权限,

这样配置就好了

当有问题出现时,许多开发人员可能会比较盲目的用这些工具来试探性定位问题,而大多数情况下,这种试探会无功而返。因为这些分析工具主要是侧重Java单方面的分析,比如该系统调用第三方API,如果第三方API有问题,是无法监控到的。还有像文件、DB资源的访问也是是无法监控到的。

除了JAVA自带的监控工具外,我们尝试了第三方的监控工具透视宝,功能相对全面,且易 *** 作。

在功能方面,透视宝都包括:查看执行最慢的10个元素,包括元素执行次数、持续时长和占用时长百分比;查看>

用Open-falcon,Open-falcon是小米运维团队从互联网公司的需求出发,根据多年的运维经验,结合SRE、SA、DEVS的使用经验和反馈,开发的一套面向互联网的企业级开源监控产品。

import javaawtAWTEvent;

import javaawtToolkit;

import javaawteventAWTEventListener;

import javaawteventKeyEvent;

import javaxswingJFrame;

import javaxswingJLabel;

import javaxswingJTextField;

public class Test extends JFrame implements AWTEventListener{

JLabel infoLabel=new JLabel("请输入一个整数!");

JTextField resultField=new JTextField();

String num="";

public void init(){

setLayout(null);

setTitle("求数列和");

setSize(180,105);

infoLabelsetBounds(10, 10, 100, 30);

resultFieldsetBounds(10, 40, 150, 25);

setResizable(false);

setLocationRelativeTo(null);

resultFieldsetFocusable(false);

setDefaultCloseOperation(EXIT_ON_CLOSE);

ToolkitgetDefaultToolkit()addAWTEventListener(this, KeyEventKEY_EVENT_MASK);

add(infoLabel);

add(resultField);

setVisible(true);

}

public static void main(String[] args) {

new Test()init();

}

public void eventDispatched(AWTEvent e) {

KeyEvent keyEvent=(KeyEvent)e;

if(keyEventgetID()==KeyEventKEY_PRESSED){

int keycode=keyEventgetKeyCode();

if(keycode==10){

if(!numequals("")){

infoLabelsetText("\""+num+"\" 的数列和为:");

resultFieldsetText(""+sum(IntegerparseInt(num)));

num="";

}

}else if(keycode>=48 && keycode<=57){

num+=(char)keycode;

infoLabelsetText("当前输入:"+num);

resultFieldsetText("");

}else{

resultFieldsetText("输入错误,重新输入");

num="";

}

}

}

private int sum(int n){

int k=0;

for(int i=1;i<=n;i++){

k+=i;

}

return k;

}

}

输入vi HelloWorldjava 进入HelloWorldjava编辑,写上helloword的代码 public class Heoolworld{ public static void main(String[] args){ Systemoutprint("Hello World!"); } } 按住键盘上的esc键,然后输入:wq保存并退出 输入命令javac H

首先要查谁用CPU最多:显示前10个累计占用CPU时间的进程#ps-e|head-n1;ps-e|grep-v"TIME|0:"|sort+2b-3-n-r|head-n10显示前10个当前占用CPU时间的进程#ps-ef|head-n1;ps-ef|grep-v"C|0:00"|sort+3b-4-n-r|head-n10Aix命令:列出使用内存和Cpu前几位的进程(1)显示10个消耗cpu最多的进程#psaux|head-1;psaux|sort-rn+2|head-10(2)显示10个消耗内存最多的进程#psvx|head-1;psvx|grep-vPID|sort-rn+6|head-10(3)显示10个换页最多的进程#psvx|head-1;psvx|grep-vPID|sort-rn+4|head-10(4)显示10个消耗存储空间最多的进程#psaux|head-1;psaux|sort-rn+3|head-10如何监控进程的内存使用情况(AIX)AIX监控进程内存使用的工具比较多,个人觉得比较方便的有nmon,svmon,其中svmon是AIX自带的工具,需要root权限执行,可以监控进程详细内存使用信息,如:svmon-Ppid(要监控的进程PID)-i1(每秒刷新一次)|greppidAIX下进程内存分析AIX下可以使用psv工具或者svmon工具来分析进程内存。比如:#svmon-P23288-------------------------------------------------------------------------------PidCommandInusePinPgspVirtual64-bitMthrd23288ora_pmon_V829598145118216560NNVsidEsidTypeDescriptionInusePinPgspVirtualAddrRange17813workshmat/mmap11824001182402470017611perscode,largefile/dev96810--0968000workkernelseg398214501823390021804:654746553518018dworksharedlibrarytext28520015806553547642workprocessprivate1127101127面这几个命令组合对于管理RS/6000AIX系统有帮助:(1)显示10个消耗CPU最多的进程:#psaux|head-1;psaux|sort-rn+2|head–10(2)显示10个消耗存储空间最多的进程:#psaux|head-1;psaux|sort-rn+3|head-10(3)按顺序显示系统中受罚的进程:#ps-eakl|head-1;ps-eakl|sort-rn+5(4)按优先级顺序显示系统中的进程:#ps-eakl|sort-n+6|head(5)按处理时间为顺序显示系统中的前十个进程:#psvx|head-1;psvx|grep-vPID|sort-rn+3|head–10(6)按实际内存使用的多少顺序显示系统中的前十个进程:#psvx|head-1;psvx|grep-vPID|sort-rn+6|head–10(7)按换入页面的多少顺序显示系统中的前10个进程:#psvx|head-1;psvx|grep-vPID|sort-rn+4|head-10(责任编辑:优优系统)

以上就是关于Java实时多任务调度过程中的安全监控设计全部的内容,包括:Java实时多任务调度过程中的安全监控设计、如何为java应用程序启用远程jmx监控、Java类应用监控应该监控哪些等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10214300.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存