文档章节

linux下,利用shell和js实现进程信息收集和控制的简单方法

皮鞋铮亮
 皮鞋铮亮
发布于 2015/12/03 16:45
字数 977
阅读 1111
收藏 43

一、目的:

1、收集java进程中那些外部很难获取的信息

2、控制java进程;

二、结构:

三、控制过程:

1、通过shell命令,向js发送命令字符串;

2、js将命令字符串通过socket传递给java进程内的监听器;

3、监听器根据命令调用相关的采集器和控制器;实现控制或采集;

四、实现效果:

五:代码:

1、shell脚本:sctl.sh

#!/usr/bin/env bash

function check_java (){
    JAVA_PATH=`which java 2>/dev/null`
    if [ "x$JAVA_PATH" != "x" ]; then
        _javacmd=java
    elif [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]];  then
        _javacmd="$JAVA_HOME/bin/java"
    else
        echo "ERROR: java Not find!"
    fi

    if [[ "$_javacmd" ]]; then
        version=$("$_javacmd" -version 2>&1 | awk -F '"' '/version/ {print $2}')
        if [[ "$version" < "1.6" ]]; then
            echo "download rhino.jar"
        elif [[ "$version" < "1.8" ]]; then
            jsi='jrunscript -f'
            WITH_ARGS=''
        else
            jsi='jjs -scripting'
            WITH_ARGS='--'
        fi
    fi
}
check_java

$jsi server.js $WITH_ARGS $@

2、js代码:server.js

(function(){
    var root = typeof self == 'object' && self.self === self && self ||
        typeof global == 'object' && global.global === global && global ||
        this;
    var args = root.arguments;
    var command = args.pop();
    var s = new java.net.Socket("localhost", 9090);
    var os = new java.io.PrintWriter(s.getOutputStream(), true);
    var is = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream()));
    var write = function(str){
        new java.io.PrintWriter(os).println(str);
        os.flush();
    };
    if(command) write(command);
    var connected = true;
    while(connected){
        var msg = is.readLine();
        if(msg=="#END#"){
            connected =false;
            print(msg);
        }else if(msg==null) {
            connected = false;
        } else {
            print(msg);
        }
    }
})();

3、监听器代码:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created with IntelliJ IDEA.
 * Desc: 管理端口服务
 * 负责接收管理请求命令,并返回命令结果
 */
public class ControlListener extends Thread {
    private final static Logger logger = LogManager.getLogger("net");
    boolean flag = true;
    int consolePort = 9090;

    public ControlListener(String name, int port) {
        super(name);
        consolePort = port;
    }

    public void interrupt() {
        this.flag = false;
        super.interrupt();
    }

    public void run() {

        logger.info("control listener started at " + consolePort);

        ServerSocket listener = null;
        try {
            listener = new ServerSocket(consolePort);
            while (flag) {

                Socket socket = listener.accept();
                BufferedReader socketReader =
                        new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String str = socketReader.readLine();
                if (str == null) {
                    continue;
                }
                if (!str.equals("exit")) {
                    logger.info("accept control CMD: " + str);
                    String returnStr = Console.execute(str.trim());
                    socket.getOutputStream().write((returnStr + "\r\n#END#\r\n").getBytes());
                } else {
                    socketReader.close();
                }
            }
            logger.info("control listener stoped");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (listener!=null) {
                    listener.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4、主控类代码:

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created with IntelliJ IDEA.
 * Desc: 主控类
 */
public class Console {

    private final static Map<String, IControl> consoleCmdFactory = new ConcurrentHashMap<>();

    public static void regCmd(String cmd,IControl cls){
        if (null != cmd && null != cls) {
            consoleCmdFactory.put(cmd, cls);
        }
    }

    public static String execute(String cmd){
        IControl control = consoleCmdFactory.get(cmd);
        if (null == control){
            return "非法命令请求!";
        }else{
            return control.execute();
        }
    }

    public static void close(){
        for(Map.Entry<String,IControl> entry : consoleCmdFactory.entrySet()){
            try {
                entry.getValue().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}

5、控制器或收集器接口:

import java.io.Closeable;

/**
 * Desc: 控制进程接口,所有的采集器,控制器都需要实现此接口的execute和close方法.
 * 1,execute方法返回的String就是所要打印的系统信息,需要业务端自行进行定义.
 * 2,close方法是考虑在收集系统信息时可能会打开一些需要关闭的内容(比如线程),在close方法中进行释放.
 */
public interface IControl extends Closeable{
    /**
     * execute方法返回的String就是所要打印的系统信息,需要业务端自行进行定义.
     * @return 返回执行结果字符串
     */
    String execute ();
}

6、一个收集器的实例:

import com.gvsoft.communication.console.IControl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created with IntelliJ IDEA.
 * Desc: 服务端并发情况收集器
 */
public class ConcurrentGather implements IControl {

    private final static Logger logger = LogManager.getLogger("net");
    ConcurrentCounter concurrentCounter = null;
    private static AtomicInteger readCount = new AtomicInteger(0);
    private static AtomicInteger writeCount = new AtomicInteger(0);

    private Integer concurrentReadCount;
    private Integer concurrentWriteCount;

    public ConcurrentGather() {
        if (null == concurrentCounter) {
            concurrentCounter = new ConcurrentCounter("ConcurrentCounter");
            concurrentCounter.start();
        }
    }

    public static void increasingRead() {
        readCount.incrementAndGet();

    }

    public static void increasingWrite() {
        writeCount.incrementAndGet();
    }

    public Integer getAvgReadCount() {
        return concurrentReadCount;
    }

    public Integer getAvgWriteCount() {
        return concurrentWriteCount;
    }

    @Override
    public String execute() {
        String statusStr;
        statusStr = "并发状态收集器打印结果如下:\r\n" + "每秒读取包(包含通讯层):" + getAvgReadCount() + "\r\n" +
                "每秒写入包(包含通讯层):" + getAvgWriteCount() + "\r\n";
        return statusStr;
    }

    @Override
    public void close() throws IOException {
        concurrentCounter.interrupt();
    }

    class ConcurrentCounter extends Thread {

        ConcurrentCounter(String name) {
            super(name);
        }

        private boolean flag = true;

        @Override
        public void interrupt() {
            this.flag = false;
            super.interrupt();
        }

        @Override
        public void run() {
            Integer cycle = 10;
            while (flag) {
                concurrentReadCount = readCount.get() / cycle;
                concurrentWriteCount = writeCount.get() / cycle;
                readCount.set(0);
                writeCount.set(0);
                try {
                    Thread.sleep(cycle * 1000);
                } catch (InterruptedException e) {
                    logger.info(this.getName() + "线程已经被中止!");
                }
            }
        }
    }
}

具体代码请参看:http://git.oschina.net/java616/

可以通过Console的静态方法regCmd注册新的命令字符串和对应的实现类;通过继承IControl接口实现这些类。

© 著作权归作者所有

皮鞋铮亮
粉丝 36
博文 12
码字总数 11603
作品 0
沈阳
私信 提问
Linux 的进程间通信:管道

本文由云+社区发表 作者:邹立巍 前言 管道是UNIX环境中历史最悠久的进程间通信方式。本文主要说明在Linux环境上如何使用管道。阅读本文可以帮你解决以下问题: 什么是管道和为什么要有管道?...

腾讯云加社区
03/06
20
0
Qt嵌入浏览器(六)——实现JS通信接口

本篇简介 上一节中,我们完成了CEF各基本组件的封装,并完成了浏览器基本功能的实现。>>点这里回顾上节内容 本节我们将尝试扩展所实现的各组件,实现浏览器与页面的双向通信。 本篇的小目标:...

ArcDriver
2018/08/18
0
0
Linux管理员常用网络资源(收集帖)

本文给力,收集的是Linux管理员常用网络资源。笨兔兔想会对各位Linux系统管理员会有用的。如果喜欢,拿走即可。 Corntab Corntab是一款简易的网络crontab端,无需安装,轻松创建crontab语句。...

fly_xiang
2014/12/14
214
0
网站数据统计分析之一:日志收集原理及其实现

网站数据统计分析工具是网站站长和运营人员经常使用的一种工具,比较常用的有谷歌分析、百度统计 和 腾讯分析等等。所有这些统计分析工具的第一步都是网站访问数据的收集。目前主流的数据收集...

大数据之路
2014/07/19
18.2K
3
探秘 Google 酝酿中名叫 Fuchsia 的神秘新系统

计算机与汽车都很多相似的地方,消费者无需懂得底层的纷繁复杂,只要它能开启并使用就行了——Android、Windows、OS X、以及Linux,也都是如此。当然,在开发出来之后,它们仍需经过多年的磨...

花仲马
2016/08/23
4.7K
14

没有更多内容

加载失败,请刷新页面

加载更多

mysql概览

学习知识,首先要有一个总体的认识。以下为mysql概览 1-架构图 2-Detail csdn |简书 | 头条 | SegmentFault 思否 | 掘金 | 开源中国 |

程序员深夜写bug
今天
8
0
golang微服务框架go-micro 入门笔记2.2 micro工具之微应用利器micro web

micro web micro 功能非常强大,本文将详细阐述micro web 命令行的功能 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架...

非正式解决方案
今天
6
0
前端——使用base64编码在页面嵌入图片

因为页面中插入一个图片都要写明图片的路径——相对路径或者绝对路径。而除了具体的网站图片的图片地址,如果是在自己电脑文件夹里的图片,当我们的HTML文件在别人电脑上打开的时候图片则由于...

被毒打的程序猿
今天
8
0
Flutter 系列之Dart语言概述

Dart语言与其他语言究竟有什么不同呢?在已有的编程语言经验的基础上,我们该如何快速上手呢?本篇文章从编程语言中最重要的组成部分,也就是基础语法与类型变量出发,一起来学习Dart吧 一、...

過愙
今天
5
0
rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部