socket监控进程,并对程序执行有关操作。

之前写了一篇《socket之flume监控系统》,但由于生产环境上的端口限制,so要做一些优化和改善。那这篇就是前作的优化篇吧。

需求是:1、每隔1分钟获取客户端所运行的application的运行状态,这里采用的是通过命令获取该application的进程。客户机有AIX、LINUX、WINDOWS三种平台,AIX跟LINUX大同小异。

2、不定时给客户端发送指令,包括重启、关闭application,更新application的文件。


废话不多说,贴代码。

客户端代码:

package com.coreware.client;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import com.coreware.util.FileUtil;
import com.coreware.util.OperateUtil;

public class MonitorClient {
	private static Timer timer = new Timer();
	private static String configFile = "config.properties";// 配置文件
	private static Properties pro = null;// 加载属性文件,读取数据库连接配置信息
	private long timeout = 60000;// 发送数据间隔时间
	private static final String SUCCESS_MSG = "SUCCESS";// 成功标识符
	private static final String FAILED_MSG = "FAILED";// 失败标识符
	private static final String REPLACE = "replace";// 操作命令
	private static final String RESTART = "restart";// 操作命令
	private static final String STOP = "stop";// 操作命令
	private DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public MonitorClient(File file) {
		loadConfig(file);
		String time = pro.getProperty("timeout");
		if (time != null)
			timeout = Long.valueOf(time);
		timer.schedule(new Handler(), 1000, timeout);
	}

	public void loadConfig(File file) {//加载配置文件
		try {
			if(pro==null){
				pro = new Properties();
				FileInputStream fis = new FileInputStream(file);
				pro.load(fis);
				fis.close();
			}
		} catch (FileNotFoundException e) {
			System.err.println("The file [" + file.getName() + "] not found!");
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(0);
		}
	}

	class Handler extends TimerTask {//操作类
		private Socket s;
		private OutputStream out;
		private PrintWriter w;
		
		@Override
		public void run() {
			try {
				String ip = pro.getProperty("server.ip");
				String port = "9099";
				if (pro.getProperty("server.port") != null)
					port = pro.getProperty("server.port");
				s = new Socket(ip, Integer.parseInt(port));
				String connectTime=df.format(new Date());
				System.out.println("-------connect server at "+connectTime+" -------");
				s.setOOBInline(false);
				s.setSoTimeout(60000);
				out = s.getOutputStream();
				w = new PrintWriter(out,true);
				String msg = sendMsg(s);//发送application状态
				w.println(msg);
				w.flush();
				InputStream in = s.getInputStream();
				int _count = 0; 
				while (_count == 0) { 
				    _count = in.available(); 
				}
				byte[] _b = new byte[_count]; 
				int _len= in.read(_b);//获取服务端反馈及指令
				String command=new String(_b,0,_len).trim();
				if("ok".equalsIgnoreCase(command)) {//打印反馈结果
					System.out.println("send message success!");
				}else if(REPLACE.equalsIgnoreCase(command)) {//执行更新文件命令
					System.out.println("execute replace...");
					int sumL = 0;
					OperateUtil.stop();<span style="font-family: Arial, Helvetica, sans-serif;">//关闭application</span>
					DataInputStream dis = new DataInputStream(in);
					String name = dis.readUTF();
					long length = dis.readLong();
					String flumePath=OperateUtil.getPath();
					File file = new File(flumePath+name);
					if (!file.exists()) {
						file.createNewFile();
					}
					byte[] buf = new byte[1024];
					int read = 0;

					BufferedOutputStream bout = new BufferedOutputStream(
							new FileOutputStream(file));
					System.out.println("start read file...");
					while(sumL<length){//接收文件
						read = dis.read(buf);
						sumL += read;
						bout.write(buf, 0, read);
						bout.flush();
					}
					bout.close();
					if (length == sumL){
						System.out.println("done! the file size is " + sumL + " kb");
						String fileName=file.getName();
						String filePath=file.getParent();
						System.out.println("file path:"+filePath);
						if(fileName.endsWith(".zip")){//如果是zip文件,需要解压
							FileUtil.unZip(file, filePath);
							if(file.isFile()&&file.exists()){
								boolean flag = file.getAbsoluteFile().delete();
								System.out.println("The file[" + fileName + "]delete success:" + flag);
							}
						}
						String result = OperateUtil.start();//启动application
						w.println(result);
						w.flush();
					}
					dis.close();
				} else if (RESTART.equalsIgnoreCase(command)) {//执行启动命令
					System.out.println("execute restart...");
					String result = FAILED_MSG;
					OperateUtil.stop();
					result = OperateUtil.start();
					w.println(result);
					w.flush();
				} else if (STOP.equalsIgnoreCase(command)) {//执行停止命令
					System.out.println("execute stop...");
					String result = FAILED_MSG;
					if (OperateUtil.stop()) {
						result = SUCCESS_MSG;
					}
					w.println(result);
					w.flush();
				}
				if (in != null)
					in.close();
				if (out != null)
					out.close();
				if (w != null)
					w.close();
				s.close();
				if (s.isClosed()) {
					System.out.println("The connect has disconnected");
				}
			} catch (IOException e) {
				if(e.getMessage().indexOf("Connection refused: connect")!=-1){
					System.err.println("disconnected or server not running!");
				}else{
					e.printStackTrace();
				}
				try {
					s.close();
					timer.cancel();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				System.exit(0);
			}
		}

		private String sendMsg(Socket s){//发送消息
			StringBuffer sb = new StringBuffer();
			String hostName = "";
			try{
				hostName = InetAddress.getLocalHost().getCanonicalHostName();
			}catch (UnknownHostException e) {
				System.err.println("Get local host failed!"+e.getMessage());
			}
			boolean isAlive = OperateUtil.isAlive();
			String status="0";
			if (isAlive)status = "1";
			String ip=s.getLocalAddress().toString().replaceAll("/", "");
			String version = OperateUtil.getVersion();
			sb.append("name=" + hostName + ",");
			sb.append("ip=" + ip + ",");
			sb.append("port=" + s.getLocalPort() + ",");
			sb.append("status=" + status + ",");
			sb.append("version=" + version);
			
			return sb.toString();
		}
	}

	public static void main(String[] args) {
		String fileName=configFile;
		if(args.length>0)
			fileName=args[0];
		//System.out.println("==========fileName:"+fileName);
		File file=new File(fileName);
		new MonitorClient(file);
	}
}

服务端代码:

package com.coreware.socket;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import javax.servlet.ServletContext;

import com.coreware.model.FlumeInfo;

/**
 * 接收客户端application状态信息存进表格。先查询是否有机器的记录,如果有使用update,否则使用insert
 * 
 * @author T430
 * 
 */
public class MonitorSocket {
	private LinkedBlockingQueue<FlumeInfo> queue = new LinkedBlockingQueue<FlumeInfo>();
	private ExecutorService handler = Executors.newFixedThreadPool(20);
	private ExecutorService executor = Executors.newCachedThreadPool();
	public static Hashtable<String, String> commandList = new Hashtable<String, String>();
	public static Hashtable<String, String> resultList = new Hashtable<String, String>();
	private static final String SUCCESS_MSG = "SUCCESS";// 成功标识符
	private static final String FAILED_MSG = "FAILED";// 失败标识符
	private ServerSocket server;
	private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public MonitorSocket(ServletContext servletContext) {
		executor.execute(new Handler(servletContext));
		executor.execute(new Task(queue));
	}

	public static Hashtable<String, String> getCommandList() {
		return commandList;
	}

	public static Hashtable<String, String> getResultList() {
		return resultList;
	}

	public static synchronized void setCommandList(Hashtable<String, String> commandList) {
		MonitorSocket.commandList = commandList;
	}

	class Handler implements Runnable {//操作类
		private ServletContext servletContext;

		public Handler(ServletContext servletContext) {
			this.servletContext = servletContext;
		}

		public void run() {
			Socket s = null;
			DataOutputStream dos = null;
			try {
				String portStr = this.servletContext.getInitParameter("socketPort");
				int port = Integer.parseInt(portStr);
				server = new ServerSocket(port);
				System.out.println("Waiting for client connect……");
				while (true) {
					s = server.accept();
					String connectTime = df.format(new Date());
					String clien = s.getInetAddress().toString().replaceAll("/", "");
					System.out.println("------" + clien + " connect at " + connectTime + " ------");
					s.setSoTimeout(60000);
					InputStream in = s.getInputStream();
					OutputStream out = s.getOutputStream();
					PrintWriter w = new PrintWriter(out, true);
					BufferedReader br = new BufferedReader(new InputStreamReader(in));
					String msg = br.readLine();
					System.out.println("client msg:" + msg);
					if (msg.length() > 0 && !SUCCESS_MSG.equals(msg) && !FAILED_MSG.equals(msg)) {
						putQueue(msg);
					}
					if (!commandList.isEmpty()) {
						String command = commandList.get(clien);
						if (command != null) {
							commandList.remove(clien);
							String[] commands = command.split(";");
							String cmd = commands[1];
							System.out.println("server command:" + cmd);
							if (cmd.equals("0")) {//发送重启指令
								w.println("restart");
								w.flush();
							} else if (cmd.equals("1")) {//发送更新文件指令
								w.println("replace");
								w.flush();
								String fileName = commands[2];
								File file = new File(fileName);
								if (!file.exists()) {
									System.out.println("file[" + fileName + "]not found");
									in.close();
									out.close();
									w.close();
									br.close();
									s.close();
									return;
								}
								BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
								dos = new DataOutputStream(out);
								String name = file.getName();
								long length = file.length();
								String dir = commands[3] + File.separator + name;
								System.out.println("dir=" + dir);
								dos.writeUTF(dir);//发送客户端文件存放地址
								dos.writeLong(length);//文件大小
								dos.flush();
								int len = 0;
								byte[] buf = new byte[1024];
								while ((len = bis.read(buf)) != -1) {//发送文件
									dos.write(buf, 0, len);
									dos.flush();
								}
								bis.close();
							} else if (cmd.equals("2")) {//发送关闭指令
								w.println("stop");
								w.flush();
							}
							int count = 0;
							while (count == 0) {
								count = in.available();
							}
							byte[] b = new byte[count];
							int len = in.read(b);//获取客户端反馈结果
							String result = new String(b, 0, len).trim();
							System.out.println("execute result:" + result);
							resultList.put(clien, result);
						}
					}
					w.print("ok");
					w.flush();
					Thread.currentThread().sleep(1000);
					try {
						do {
							//发送一条特殊的信息,客户端设置setOOBInline(false),则会忽略;
							//如果客户端已经close的话,话报错,用来判断客户端是否close
							s.sendUrgentData(0xFF);
						} while (!s.isClosed());
					} catch (IOException e) {
						if (dos != null)
							dos.close();
						br.close();
						out.close();
						w.close();
						s.close();
						if (s.isClosed()) {
							System.out.println("The connect has disconnected");
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void putQueue(String msg) throws Exception {
		String createTime = df.format(new Date());
		String[] strs = msg.split(",");
		FlumeInfo info = new FlumeInfo();
		for (String str : strs) {
			String[] texts = str.split("=");
			String s = texts[0];
			if ("name".equals(s)) {
				info.setName(texts[1]);
			} else if ("ip".equals(s)) {
				info.setIP(texts[1]);
			} else if ("port".equals(s)) {
				info.setPort(texts[1]);
			} else if ("status".equals(s)) {
				String status = texts[1];
				info.setStatus(status);
			} else if ("version".equals(s)) {
				info.setVersion(texts[1]);
			}
		}
		info.setCode("code");
		info.setCreateTime(createTime);
		queue.put(info);
	}

	public void closeServerSocket() {
		try {
			server.close();
			executor.shutdown();
		} catch (IOException e) {
			System.err.println("close server error");
			e.printStackTrace();
		}
	}
}


 
 

有的操作类省略了。大家可以到这里去下载完整的代码:

客户端:去下载

服务端:去下载


你可能感兴趣的:(优化,socket)