语言是java,请问有两个启动器的是什么呢? java | 您所在的位置:网站首页 › 请问轻便的反义词是什么呢 › 语言是java,请问有两个启动器的是什么呢? java |
背景 现在很多软件都支持集群部署,但是测试环境通常资源有限,所以一般通过单台机器模拟集群部署(使用不同端口,运行相同jar包),本文的目的就是通过多种方式实现此需求。 两个程序1、jar程序 程序 只包含一个main方法,用于启动程序,输出进程ID 路径:C:/demo.jar(windows) /demo.jar(Linux) 2、启动程序 包含main方法的程序 多种方式1、通过URLClassLoader加载jar程序(windows平台) 2、通过java -jar命令启动jar程序(windows平台) 3、通过复制原始jar文件,启动不同的jar程序(windows平台) 4、通过Linux Shell脚本启动(Linux平台) 方式一1、通过URLClassLoader加载jar程序(windows平台) ① 说明 启动程序多次加载jar程序 2) jar程序和启动程序使用相同进程,非独立进程,无实际意义,仅介绍 启动jar程序:运行启动程序main方法 终止jar程序:停止启动程序(因为共用同一个进程,终止主程序,jar程序会同时终止) 2、代码 程序 @SpringBootApplication public class DemoStarter { public static void main(String[] args) { // 获取进程Id String name = ManagementFactory.getRuntimeMXBean().getName(); String processId = name.split("@")[0]; System.out.println(processId); SpringApplication.run(DemoStarter.class, args); } }
② 启动程序 import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; public class Starter1 { public static void main(String[] args) throws Exception { start("7001"); start("7002"); start("7003"); } private static void start(String port) throws Exception { String path = "file:" + "C:/demo.jar"; URLClassLoader classLoader = new URLClassLoader(new URL[]{new URL(path)}); // jar程序的启动类完整路径 Class demo = classLoader.loadClass("DemoStarter"); Method method = demo.getMethod("main", String[].class); method.invoke(null, (Object) new String[]{port}); } }方式二 1、通过java -jar命令启动jar包(windows平台) ① 说明 启动程序使用命令多次启动jar包 动态构建cmd命令(不同参数),启动相同jar程序,各个jar程序使用不同进程 启动jar程序 运行启动程序main方法 保存各个进程ID到文件 终止jar程序 根据保存的进程ID停止各个jar程序 2、代码 程序(同方式一) ② 启动程序 import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; public class Starter2 { public static void main(String[] args) throws Exception { cmd("7001"); cmd("7002"); cmd("7003"); // 根据文件中的进程Id终止程序 killByProcessId("PID1"); killByProcessId("PID2"); killByProcessId("PID3"); } private static void cmd(String port) throws Exception { String cmd = "java -jar -Dserver.port=" + port + " " + "C:/demo.jar"; Process p = Runtime.getRuntime().exec(cmd); InputStream is = p.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); // 获取进程Id(DemoStarter-->main方法 // reader.readLine()第一行为System.out.println(processId)输出内容 String processId; while ((processId = reader.readLine()) != null) { break; } is.close(); reader.close(); // 这里可以将进程ID保存到文件中 System.out.println("processId:" + processId); } private static void killByProcessId(String processId) throws Exception { String cmd = "taskkill /F /PID \"" + processId + "\""; Runtime.getRuntime().exec(cmd); } }方式三 1、通过复制原始jar文件,启动不同的jar程序(windows平台) ① 说明 复制原始jar包,生成新的jar包 动态构建cmd命令(不同参数、不同jar包名称),启动不同jar包,各个jar包使用不同进程 启动jar程序 运行启动程序的main方法 保存各个进程ID到文件 ③ 终止程序 根据保存的进程ID停止各个jar程序 复制jar文件需要时间,但可以解决启动相同jar包可能存在的问题 2、代码 程序(同方式一) ④ 启动程序 import org.apache.commons.io.FileUtils; import java.io.BufferedReader; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; public class Starter3 { public static void main(String[] args) throws Exception { copyCmd(); // 根据文件中的进程Id终止程序 killByProcessId("PID1"); killByProcessId("PID2"); killByProcessId("PID3"); } private static void copyCmd() throws Exception { File srcFile = new File("C:/demo.jar"); File destiFile2 = new File("C:/demo2.jar"); File destiFile3 = new File("C:/demo3.jar"); // 删除之前复制的jar包 FileUtils.forceDelete(destiFile2); FileUtils.forceDelete(destiFile3); FileUtils.copyFile(srcFile, destiFile2); FileUtils.copyFile(srcFile, destiFile3); copy("java -jar -Dserver.port=7001 C:/demo.jar"); copy("java -jar -Dserver.port=7002 C:/demo2.jar"); copy("java -jar -Dserver.port=7003 C:/demo3.jar"); } private static void copy(String cmd) throws Exception { Process p; p = Runtime.getRuntime().exec(cmd); InputStream is = p.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); // 获取进程Id(DemoStarter-->main方法 // reader.readLine()第一行为System.out.println(processId)输出内容 String processId; while ((processId = reader.readLine()) != null) { break; } is.close(); reader.close(); // 这里可以将进程ID保存到文件中 System.out.println("ProcessId:" + processId); } private static void killByProcessId(String processId) throws Exception { String cmd = "taskkill /F /PID \"" + processId + "\""; Runtime.getRuntime().exec(cmd); } }方式四 1、通过Linux Shell脚本启动(Linux平台) 执行java -jar命令 根据端口获取进程ID 根据进程ID终止程序 2、代码 程序(同方式一) 命令 1) 启动程序 #!/bin/bash java -jar -Dserver.port=7001 /demo.jar java -jar -Dserver.port=7002 /demo.jar java -jar -Dserver.port=7003 /demo.jar
2) 终止程序 #!/bin/bash pid1=`netstat -anp | grep 7001 | awk '{printf $7}' | cut -d/ -f1` pid2=`netstat -anp | grep 7002 | awk '{printf $7}' | cut -d/ -f1` pid3=`netstat -anp | grep 7003 | awk '{printf $7}' | cut -d/ -f1` kill ${pid1} kill ${pid2} kill ${pid3}问题&总结 方式一可以通过调用method.invoke传递参数 其它方式可通过jar命令传递参数 启动程序通过Process启动jar程序并获取jar程序进程ID 多次启动jar程序时报错:”unable to register MBean” 设置参数spring.jmx.enabled=false 根据端口号获取进程ID(windows) netstat -ano|findstr "7001 7002 7003" 根据进程ID停止进程(windows) taskkill /F /PID "1"
|
CopyRight 2018-2019 实验室设备网 版权所有 |