zoukankan      html  css  js  c++  java
  • Java Service Wrapper 发布Java程序为Windows服务

    Wrapper用途

    在做完一个项目程序后,有时会有两种需求想法:

    • 在每次机器重启后自动运行程序。
    • 在程序运行过程中如果发生了死锁、内存溢出或程序崩溃等问题时程序能自动重启。

    当然。要实现这两种效果的方案有很多。可以在系统引导文件中加入开机运行程序引导,也可以写一个系统监听程序等等。

    现在有一个更简单的解决方案。有一个java程序叫Java Service Wrapper。这是用来在windows或unix/linux系统中将java程序包装成系统服务并执行守护进程。

    Java Service Wrapper有三个版本。professional/standard/community 前两个版本要收费功能也更多。对我们来说,社区版的已经够用了,(对于死锁重启需要收费版的)。

    分析

    从软件的名子上就能看出来。这个软件是用来包装的。我们的程序完成以后会有一个main入口。wrapper就是将这个main方法进行包装再提供自己的一个main入口。这样,我们在运行时都是运行的wrapper的程序。它会建立各种监控和服务,在建立完成后再加载运行被包装的方法。等监控到运行的程序出问题了就会进行相应的处理。

    文件解释

    所需文件(以windows版本为例)
    1.从官网 http://wrapper.tanukisoftware.com 上下载wrapper的软件。
    在这里插入图片描述
    2.我们只需要几个核心的文件
    wrapper.jar 核心文件,位于lib文件夹中
    wrapper.exe 因为是在windows系统中运行所以需要。位于bin文件夹中
    wrapper.dll 因为是在windows系统中运行所以需要。 位于lib文件夹中
    wrapper.conf 核心配置文件,位于src/conf文件夹中。

    实现方式

    针对不同程序有不同的实现方式:
    1.如果你的程序是不间断运行的。则只需要设置配置文件即可。
    2.如果你的程序只是在系统启动时运行一次,或不需要连续运行的,则要加入入口包装类。不然,虽然你的程序已经执行成功且退出了(如:在系统启动时检查下环境再给你的提示信息就结束)。但wrapper会认为你的程序不应该结束,会不停的重启你的服务。这时你要加入包装类就没有这个问题了。

    示例

    创建java测试项目jar包

    1.创建简单的java project
    在这里插入图片描述
    2.创建主类函数。WrapperDemoMain.java

    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class WrapperDemoMain {
    
    	static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    	public static void main(String[] args) {
    		while (true) {
    			try {
    				Date date = new Date();
    				// 输出信息
    				System.out.println("time: " + format.format(date));
    				// 为了更好观察 当前线程睡眠一段随机时间
    				Thread.sleep((int) Math.random() * 10000 + 5000);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

    3.打包当前项目成my_wrapper_demo.jar
    在这里插入图片描述
    在这里插入图片描述
    4.配置Wrapper

    • 解压Wrapper后的文件目录如下:
      在这里插入图片描述
    • 首先将之前打包的my_wrapper_demo.jar包拷贝到lib目录下
      在这里插入图片描述
    • 在conf文件下创建my_wrapper_demo.conf。创建方式可以将wrapper.conf拷贝一份重命名为my_wrapper_demo.conf
    #java.exe所在位置
    wrapper.java.command=D:/Program Files (x86)/Java/jre1.8.0_181/bin/java
    
    #日志级别
    wrapper.java.command.loglevel=DEBUG
    
    #主类入口
    #方式一:使用wrapper自带WrapperSimpleApp的mainClass是固定写法,#wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
    #此时parameter.1配置自己的主程序入口所在类
    #parameter.1是自己的主程序入口所在类(从包名开始)
    wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
    wrapper.app.parameter.1=com.gm.test.WrapperDemoMain
    
    #方式二:mainclass如果写成自己的入口程序自己的程序需要实现wrapper的WrapperListener接口
    #此时parameter.1无需配置,parameter.1=
    
    #依赖的包,第一个是wrapper包,第二个是自己打的包以及程序依赖包
    wrapper.java.classpath.1=../lib/wrapper.jar
    wrapper.java.classpath.2=../lib/*.jar
    
    #固定写法,依赖的wrapper的包
    wrapper.java.library.path.1=../lib
    
    #日志文件位置
    wrapper.logfile=../logs/wrapper.log
    
    #服务名称以及描述信息
    wrapper.console.title=my_wrapper_demo
    wrapper.name=my_wrapper_demo
    wrapper.displayname=my_wrapper_demo
    wrapper.description=my_wrapper_demo
    
    # Initial Java Heap Size (in MB)
    wrapper.java.initmemory=1024
    
    # Maximum Java Heap Size (in MB)
    wrapper.java.maxmemory=1024
    
    • 使用cmd命令行进入wrapper-windows-x86-32-3.5.36in下执行 wrapper -c
      …/conf/my_wrapper_demo.conf进行测试配置信息。显示如下则表示正常启动
      在这里插入图片描述
      wrapper -i
      …/conf/my_wrapper_demo.conf创建系统服务
      在这里插入图片描述
      启动系统服务
      在这里插入图片描述
      在这里插入图片描述
      常用命令
      在这里插入图片描述

    wrapper配置文件详解

    #文件编码,每个配置文件起始位置必须指定该文件的编码格式
    encoding=UTF-8
     
    # 如果包含配置文件出现问题可以使用debug调试模式,去掉一个"#",格式为#include.debug
    #include.debug
     
    # 包含子配置文件,可以是配置信息也可以是许可信息
    include ../conf/wrapper-license.conf
    include ../conf/wrapper2.conf
     
    # 是否开启许可文件debug模式
    wrapper.license.debug=TRUE
     
     
     
    # 指定Wrapper语言,默认使用系统语言
    wrapper.lang=en_US
     
    #指定Wrapper 语言资源位置,如果该文件不存在则默认设置为en_US
    wrapper.lang.folder=../lang
     
     
     
    # Java 程序配置:
    #   (1)默认使用PATH环境变量配置信息则使用下列配置形式
    wrapper.java.command=java
     
    #   (2)如果想单独配置运行程序,则可采用此种配置方式
    set.JAVA_HOME=/java/path
    wrapper.java.command=%JAVA_HOME%/bin/java
     
    # java程序日志级别
    wrapper.java.command.loglevel=INFO
     
     
     
    # Java Main class,也就是程序入口  
    #该类需要实现WrapperListener 接口并保证WrapperManager 得到初始化(调用WrapperManager.start(WrapperListener listener, String[] args) 方法)。
    wrapper.java.mainclass=com.helloworld.hello.HelloWorld
     
     
     
    # Java Classpath配置,必须从序号"1"开始,添加新的jar包后序号递增
    wrapper.java.classpath.1=../lib/wrapper.jar
    wrapper.java.classpath.2=../lib/hello.jar
     
    # Java 类库路径 (Wrapper.DLL 或 libwrapper.so 依赖文件的存放位置)
    wrapper.java.library.path.1=../lib
     
     
     
    # 32/64位选择,true为自动选择
    wrapper.java.additional.auto_bits=TRUE
     
    # Java附加参数
    wrapper.java.additional.1=
     
     
     
    # Java Heap 初始化大小(单位:MB)
    wrapper.java.initmemory=3
     
    # Java Heap 最大值(单位:MB)
    wrapper.java.maxmemory=64
     
     
     
    # 应用程序参数,也就是main函数的String[] args参数值,序号需从"1"开始,例如:
    wrapper.app.parameter.1=g21121
    wrapper.app.parameter.2=http://286.iteye.com/
     
     
     
    # 是否显示debug日志
    wrapper.debug=TRUE
     
    # 控制台信息输出格式
    wrapper.console.format=PM
     
    # 控制台日志级别
    wrapper.console.loglevel=INFO
     
    # 日志文件位置及名称
    wrapper.logfile=../logs/wrapper.log
     
    # 日志文件输出格式
    wrapper.logfile.format=LPTM
     
    # 日志文件日志级别
    wrapper.logfile.loglevel=INFO
     
    # 限制日志文件大小,0为不限制,参数:k,m,g等
    wrapper.logfile.maxsize=10m
     
    # 限制最大日志文件数,0为不限制
    wrapper.logfile.maxfiles=0
     
    # syslog 日志级别
    wrapper.syslog.loglevel=NONE
     
     
     
    # 允许使用非连续编号的属性,例如:path的序号可以打乱
    wrapper.ignore_sequence_gaps=TRUE
     
    # 如果pid文件已经存在则不启动程序
    wrapper.pidfile.strict=TRUE
     
    # 控制台启动时显示的标题
    wrapper.console.title=------------Wrapper Console------------
     
     
     
    # 检测JVM中的死锁线程(需要标准版Wrapper)
    wrapper.check.deadlock=TRUE
    #间隔,单位:秒
    wrapper.check.deadlock.interval=10
    #出现死锁时处理事件
    wrapper.check.deadlock.action=RESTART
    #信息输出级别,FULL:全部;SIMPLE:精简;NONE:无;
    wrapper.check.deadlock.output=FULL
     
     
     
    # 内存溢出检测,Wrapper提供了几种不同的匹配机制
    wrapper.filter.trigger.999=wrapper.filter.trigger.*java.lang.OutOfMemoryError
    wrapper.filter.allow_wildcards.999=TRUE
    wrapper.filter.action.999=NONE
    wrapper.filter.trigger.1000=[Loaded java.lang.OutOfMemoryError
    wrapper.filter.action.1000=NONE
    wrapper.filter.trigger.1001=java.lang.OutOfMemoryError
    #wrapper.filter.trigger.1001=Exception in thread "*" java.lang.OutOfMemoryError
    #wrapper.filter.allow_wildcards.1001=TRUE
    wrapper.filter.action.1001=RESTART
    wrapper.filter.message.1001=The JVM has run out of memory.
     
     
     
    # 邮件基本信息设置
    wrapper.event.default.email.debug=TRUE
    #smtp服务器地址
    wrapper.event.default.email.smtp.host=
    #smtp服务器端口
    wrapper.event.default.email.smtp.port=25
    #邮件主题
    wrapper.event.default.email.subject=[%WRAPPER_HOSTNAME%:%WRAPPER_NAME%:%WRAPPER_EVENT_NAME%] Event Notification
    #发件人地址
    wrapper.event.default.email.sender=<Sender email>
    #收件人地址
    wrapper.event.default.email.recipient=<Recipient email>
    # 指定文件内容
    wrapper.event.jvm_restart.email.body=The JVM was restarted.
    
    Please check on its status.
    
     
     
     
    # 邮件日志相关配置
    wrapper.event.default.email.attach_log=TRUE
    wrapper.event.default.email.maillog.lines=50
    wrapper.event.default.email.maillog.format=LPTM
    wrapper.event.default.email.maillog.loglevel=INFO
     
     
     
    # 触发事件,即当以下事件为true时发送邮件
    wrapper.event.wrapper_start.email=TRUE
    wrapper.event.jvm_prelaunch.email=TRUE
    wrapper.event.jvm_start.email=TRUE
    wrapper.event.jvm_started.email=TRUE
    wrapper.event.jvm_deadlock.email=TRUE
    wrapper.event.jvm_stop.email=TRUE
    wrapper.event.jvm_stopped.email=TRUE
    wrapper.event.jvm_restart.email=TRUE
    wrapper.event.jvm_failed_invocation.email=TRUE
    wrapper.event.jvm_max_failed_invocations.email=TRUE
    wrapper.event.jvm_kill.email=TRUE
    wrapper.event.jvm_killed.email=TRUE
    wrapper.event.jvm_unexpected_exit.email=TRUE
    wrapper.event.wrapper_stop.email=TRUE
    
    
  • 相关阅读:
    【连载】【FPGA黑金开发板】Verilog HDL那些事儿VGA(二十)
    【黑金动力社区】【FPGA黑金开发板】Verilog HDL的礼物 Verilog HDL扫盲文
    FPGA黑金开发板勘误
    触发器入门(转)
    SQL Server 索引结构及其使用(三)[转]
    SQL Server 索引结构及其使用(一)(转)
    项目开发管理二(转)
    Ajax在网页中的简单应用
    Ajax简单介绍
    Asp.Net异步数据绑定
  • 原文地址:https://www.cnblogs.com/gmhappy/p/11864015.html
Copyright © 2011-2022 走看看