想让你的Java应用向Windows服务那样方便么?想让Linux上也实现相似的功能么?想不用写shell脚本来实现么?那么一起来了解Java Service Wrapper吧!
Java Service Wrapper是日本.tanukisoftware的主打产品,所有版本和特性如下表:
特征 |
专业 |
标准 |
社区 |
能够运行Windows服务 |
√ |
√ |
√ |
能够运行一个UNIX守护 |
√ |
√ |
√ |
无代码集成 |
√ |
√ |
√ |
捕获和JVM的所有控制台输出到日志 |
√ |
√ |
√ |
灵活的路径配置,包括通配符 |
√ |
√ |
√ |
自定义的工作目录 |
√ |
√ |
√ |
JVM监控并重新启动功能 |
√ |
√ |
√ |
单实例执法 |
√ |
√ |
√ |
能够控制进程优先级 |
√ |
√ |
√ |
触发的JVM关闭,重新启动和线程转储 |
√ |
√ |
√ |
相对内存限制 |
√ |
√ |
Χ |
Consoleless二进制(视窗) |
√ |
√ |
Χ |
可定制的图标(视窗) |
√ |
√ |
Χ |
可定制的启动画面(视窗) |
√ |
√ |
Χ |
控制使用的时区和事件日志输出 |
√ |
√ |
Χ |
提醒邮件 |
√ |
Χ |
Χ |
事件的命令 |
√ |
Χ |
Χ |
定时事件 |
√ |
Χ |
Χ |
许可证 |
|
||
社区许可证(GPL) |
Χ |
Χ |
√ |
服务器许可证 |
√ |
√ |
Χ |
开发许可 |
√ |
√ |
√ |
OK,那么让我们从第一个Service开始,假定我们有这样一个需求:一个应用程序启动脚本如下:
java -cp lib\a.jar;lib\b.jar org.ds3783.Main
我们的目标是将这个应用做成Windows和Linux服务。可能有人会问可以跨平台么?答案是:YES!
Step 1:从http://wrapper.tanukisoftware.org上下载适合你的版本,这里我们用的是社区版。
Step 2:分别下载Linux和Windows版本的Java Service Wrapper,并解压缩。
Step 3:创建以下目录结构:
/ 根目录,用于存放安装、删除服务的脚本
/wrapper wrapper的主目录
/lib 应用jar包所存放位置
/classes 用于存放应用的class文件或者相关配置文件
Step 4:重写wrapper.conf。这里建议书写两份:winwrapper.conf和linuxwrapper.conf其中重点关注以下几项配置:
# Java q启动命令
wrapper.java.command=java
# Java Main class 如果这里要使用自定义的Main类,那么该类建议实现WrapperListener接口,否则wrapper将无法检测到应用的运行状态!
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
# Java Classpath (include wrapper.jar) 添加Java包路径
# 必须从1开始
wrapper.java.classpath.1=../classes
wrapper.java.classpath.2=wrapper.jar
wrapper.java.classpath.3=../libs/a.jar
wrapper.java.classpath.4=../libs/ab.jar
# Java Additional Parameters
#注意如果应用中main方法在服务期间不退出的话必须将此选项设置为FALSE!
wrapper.java.additional.1=-Dorg.tanukisoftware.wrapper.WrapperSimpleApp.waitForStartMain=FALSE
# wrapper所需文件路径(location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=wrapper
# Initial Java Heap Size (in MB)
wrapper.java.initmemory=256
# Maximum Java Heap Size (in MB)
wrapper.java.maxmemory=1024
# 应用Main类
wrapper.app.parameter.1=net.ds3783.Main
# Windows下控制台标题
wrapper.console.title=测试服务
# 服务名
wrapper.ntservice.name=Test_Service
#以下配置仅需在Windows下配置
# 用于显示的服务名(服务管理中的名字)
wrapper.ntservice.displayname=My Test Service
# 服务描述
wrapper.ntservice.description=这是我第一个服务
# 所依赖服务名
# wrapper.ntservice.dependency.1=
# 服务启动状态. AUTO_START or DEMAND_START
wrapper.ntservice.starttype=AUTO_START
# 是否允许服务于桌面互动.
wrapper.ntservice.interactive=false
Step 5:在wrapper目录下放入以下文件:
2009-08-28 18:02 15,103 libwrapper.so
2009-10-08 17:34 5,482 linuxwrapper.conf
2009-10-08 15:43 5,470 winwrapper.conf
2009-08-28 17:43 202,752 wrapper.dll
2009-08-28 17:43 96,069 wrapper.jar
2009-08-28 17:43 51,203 wrappertest.jar
Step 6:在/目录下放入:
2009-08-28 18:02 133,848 wrapper
2009-08-28 17:43 233,984 wrapper.exe
2009-12-14 19:53 19,713 wrapper.sh
2009-12-14 19:53 122 installService.cmd
2009-12-14 19:53 122 removeService.cmd
installService.cmd:
@wrapper.exe -i wrapper\winwrapper.conf
@wrapper.exe -t wrapper\winwrapper.conf
removeService.cmd:
@wrapper.exe -p winwrapper.conf
@wrapper.exe -r winwrapper.conf
Wrapper.sh可以参照src\bin\sh.script.in
# Application
APP_NAME=”Server_TEST”
APP_LONG_NAME=”Server_TEST”
# Wrapper
WRAPPER_CMD=”./wrapper”
WRAPPER_CONF=”./wrapper/linuxwrapper.conf”
#如果在CentOS上部署则需要修改原有代码
# Build the nice clause
if [ “X$PRIORITY” = “X” ]
then
CMDNICE=””
else
CMDNICE=”nice -$PRIORITY”
fi
为:
# Build the nice clause
if [ “X$PRIORITY” = “X” ]
then
CMDNICE=”nice”
else
CMDNICE=”nice -$PRIORITY”
fi
Final Step:Windows下运行installService.cmd,linux下需要给warpper和wrapper.sh赋予执行权限,并且执行wrapper.sh start即可。
最后总结,Java Service Wrapper是一个非常优秀的服务安装解决方案,具体问题需要根据实际情况来做出合理的配置,详情请参开官方文档。
但是,配置过程中也遇见一些困难和麻烦之处,例如classpath的配置比较麻烦,尤其那个最后的计数部分,会是很麻烦的部分。另外,在CentOS上运行的时候未能正确识别出操作系统导致找不到nice命令。