Apache Commons Daemon软件是用于将Java应用程序作为服务器进程运行的一组实用程序和Java支持类。这些在Unix术语中通常称为“守护进程”(因此得名)。在Windows上,它们称为“服务”。
自1994年以来,Java编程语言获得了强有力的发展,并不仅仅是applet和客户端应用程序,在服务器应用程序领域也是安全可靠和高性能的开发工具。Java平台的主要缺点在于,直到今天,启动Java应用程序的唯一可移植的方式仍然是依赖于单个入口,即:public static void main(String [])方法。
对于客户端应用程序,具有单入口点是一种有效的解决方案,在这种情况下,用户可以交互方式命令用户退出应用程序(可以在调用System.exit(int)方法时终止虚拟机进程),但是在那种情况下如果应用程序不是交互式的(服务器应用程序),则当前没有可移植的方式来通知虚拟机其即将关闭。
用Java编写的服务器应用程序可能必须先执行多个任务,然后才能关闭虚拟机进程。例如,对于Servlet容器,在关闭VM进程之前,可能需要将会话序列化到磁盘,并且需要销毁Web应用程序。
解决此问题的一种常见方法是创建(例如)ServerSocket并等待发出特定消息。收到消息后,将执行关闭服务器应用程序所需的所有操作,最后,将调用System.exit方法来终止虚拟机进程。但是,此方法有一些缺点和风险:
在系统范围内关闭的情况下,操作系统可能会直接关闭虚拟机进程,而不会通知正在运行的服务器应用程序。
如果攻击者发现了要发送给服务器的关闭消息并找到了发送此消息的方法,则攻击者可以轻松地中断服务器的操作,而绕过操作系统中实现的所有安全限制。
大多数多用户操作系统已经具有启动和停止服务器应用程序的方式。在基于Unix的操作系统下,非交互式服务器应用程序称为守护程序,并由操作系统使用一组指定的 信号进行控制。在Windows下,此类程序称为服务 ,并由对应用程序二进制文件中定义的特定功能的适当调用控制,但是尽管处理该问题的方式有所不同,但在两种情况下,操作系统都可以通知服务器应用程序即将关闭,并且应用程序能够在执行过程被破坏之前执行某些任务。
守护程序由两部分组成。一个用C编写,它与操作系统建立接口,另一个用Java编写,提供Daemon API。
支持Win32和类UNIX(linux/mac)的平台。
对于Win32平台,请使用procrun。
对于类UNIX(linux/mac)的平台,请使用jsvc。
守护程序组件的软件包名称为: org.apache.commons.daemon。
原始项目来自Jakarta Tomcat 4.0项目。
Windows存档(例如,commons-daemon-1.2.3-bin-windows.zip)中包含2个不同的可执行文件:
prunsrv.exe-用于将应用程序作为服务运行的服务应用程序。
prunmgr.exe-用于监视和配置已安装服务的GUI管理器应用程序。
prunmgr.exe是适用于所有平台架构的应用程序。
prunsrv.exe可执行文件有2种不同版本,可用于不同的平台架构。顶级目录中的版本适用于32位(x86)架构平台。较低级别的目录适用于AMD / EMT 64位系统。不再支持Itanium。
Windows应用程序prunsrv.exe用于将应用程序作为服务安装。安装后,prunmgr.exe可用于监视和重新配置服务。
Procrun是允许Windows用户将Java应用程序(例如Tomcat)包装为Windows系统服务(Windows Service)的一组应用程序。
可以将服务设置为在计算机启动时自动启动,并且在没有用户登录到计算机的情况下继续运行。
Prunmgr是用于监视和配置procrun服务的GUI应用程序。
每个命令行指令的形式为// XX [// ServiceName],如果省略//ServiceName参数,则默认使用“文件名称”作为服务名称(ServiceName)。
可用的命令行选项:
//ES 编辑服务配置(Edit service configuration) 这是个默认操作. 调用它不需要提供任何配置选项(options)。启动GUI应用程序,并允许修改服务配置、启动服务和停止服务。
//MS 监听服务(Monitor service) 启动GUI应用程序,并将其最小化到系统托盘。
//MR 监听和运行服务(Monitor & run service) 启动GUI应用程序,并将其最小化到系统托盘。如果当前服务还没有运行,则会启动服务。
//MQ 退出监听(Monitor Quit) 停止任何正在运行的服务的监听器。
Prunsrv是用于将应用程序作为Windows系统服务(Windows Service)运行的服务应用程序。
可以转换任何应用程序(不仅仅是Java应用程序)以作为Windows系统服务(Windows Service)运行。
如果//ServiceName被省略,默认使用文件名作为服务名称
命令 | 描述 | 中文描述 |
---|---|---|
//TS | 将服务作为控制台应用程序运行 这是默认操作。如果没有提供任何选项,则调用这个。 | |
//RS | Run the service | 仅从ServiceManager调用 |
//ES | Start (execute) the service | 启动服务 |
//SS | Stop the service | 停止服务 |
//US | Update service parameters | 更新服务参数 |
//IS | Install service | 安装服务 |
//DS | Delete service | 删除服务,如果服务当前正在运行,则首先停止该服务 |
//PS | Print service | 在命令行显示当前服务的配置 |
//PP[//seconds] | Pause | 暂停服务,默认值为60秒 |
//VS | Version | 控制台回显版本号 |
//? | Help | 控制台回显帮助手册 |
命令 | 描述 | 补充描述 |
---|---|---|
run | Run the service as a console application | 等同于//TS |
service | Run the service | 等同于RS |
start | Start the service | 等同于//ES |
stop | Stop the service | 等同于//SS |
update | Update service parameters | 等同于//US |
install | Install service | 等同于//IS |
delete | Delete service | 等同于//DS |
Print service | 等同于//PS | |
pause [seconds] | Pause | 等同于//PP[//seconds] |
version | Version | 等同于//VS |
help | Help | //? |
命令行参数基于覆盖原则,重复参数会被后面的参数覆盖。
–参数,用于配置单值参数
++参数,用于配置多值参数,++参数配合-参数来配置多值
参数一览表
Parameter Name | Default | Description |
---|---|---|
–Description | 服务名称说明(最多1024个字符)。 | |
–DisplayName | ServiceName | 服务显示名称。 |
–Install | procrun.exe //RS//ServiceName | 安装图标。 |
–Startup | manual | 服务启动模式可以延迟,自动或手动。 |
–Type | Service type can be interactive to allow the service to interact with the desktop. This option can only be used with the LocalSystem account. | |
++DependsOn | 该服务所依赖的服务列表。使用#或;分隔。 | |
++Environment | 将以key = value形式提供给服务的环境变量列表。它们用#或;分隔。 | |
–User | –User参数设置的用户帐户密码 | |
–Password | –User参数设置的用户帐户密码 | |
–ServiceUser | 指定服务将在其下运行的帐户的名称。使用DomainName \ UserName形式的帐户名。服务进程将以该用户身份登录。 | |
–ServicePassword | 通过–ServiceUser参数设置的用户帐户密码。 | |
–LibraryPath | 添加到搜索路径中的目录,用于查找JVM的DLL。 | |
–JavaHome | JAVA_HOME | 设置不同于JAVA_HOME环境变量中定义的JAVA_HOME |
–Jvm | auto | 使用自动(即从Windows注册表中找到JVM)或指定jvm.dll的完整路径。您可以在此处使用环境变量扩展。指定自动时,将使用以下搜索顺序:(1)注册表中定义的当前Java运行时库(2)注册表中定义的当前JRE(3)为服务明确配置的JavaHome(4)注册表中定义的当前JDK。 |
++JvmOptions | -Xrs | 将以-D或-X形式显示的选项列表,这些选项将传递给JVM。使用#或;分隔选项 。 |
++JvmOptions9 | 在Java 9或更高版本上运行时,将以-D或-X形式显示的选项列表将传递给JVM。使用#或;分隔选项。 | |
–Classpath | 设置Java类路径(在exe模式下不使用)。 | |
–JvmMs | 初始内存池大小,以MB为单位(在exe模式下不使用)。 | |
–JvmMx | M最大内存池大小(以MB为单位)(在exe模式下不使用)。 | |
–JvmSs | 线程堆栈大小(以KB为单位)(在exe模式下不使用)。 | |
–StartMode | 一个JVM,Java的或exe文件。这些模式是:jvm - 启动Java进程。取决于jvm.dll,请参阅–Jvm。Java - 与exe相同,但会自动使用默认Java可执行文件,即%JAVA_HOME%\ bin \ java.exe。确保正确设置了JAVA_HOME,或使用–JavaHome提供正确的位置。如果两者均未设置,则procrun将尝试从Windows注册表中查找默认的JDK(而非JRE)。exe - 将图像作为单独的进程运行。 | |
–StartImage | 运行可执行文件。仅适用于exe模式。 | |
–StartPath | 起始映像可执行文件的工作路径。 | |
–StartClass | Main | 包含启动方法的类。适用于jvm和Java模式。 |
–StartMethod | main | 务启动时要调用的方法的名称。必须是static void 修饰的main(string[] args)方法仅适用于jvm模式。在Java模式下,始终使用main方法。注意:在jvm模式下,在调用stop方法之前,start方法不应返回值。注意:在jvm模式下,在调用stop方法之前,start方法不应返回。 |
++StartParams | 将传递给StartImage或StartClass的参数列表。使用#或 ;分隔参数。 | |
–StopMode | 一个JVM,Java的或exe文件。 | |
–StopImage | 将在Stop服务信号上运行的可执行文件。仅适用于exe模式。 | |
–StopPath | 停止图像可执行文件的工作路径。不适用于JVM模式。 | |
–StopClass | Main | 将在“停止”服务信号上使用的类。适用于jvm和Java模式。 |
–StopMethod | main | 服务停止时要调用的方法的名称。必须是static void并修饰的main(String args[])。仅适用于jvm模式。在Java模式下,始终使用main方法。 |
++StopParams | 将传递给StopImage或StopClass的参数列表。使用#或 ;分隔参数。 | |
–StopTimeout | No Timeout | 定义procrun等待服务正常退出的超时时间(单位:秒)。 |
–LogPath | %SystemRoot%\System32\LogFiles\Apache 定义日志记录的路径。 | |
–LogPrefix | commons-daemon | 定义服务日志文件名前缀。 |
–LogLevel | Info | 定义日志记录级别,可以是Error/Info/Warn/Debug(不区分大小写)。 |
–LogJniMessages | 0 | 将此非零值(例如1)设置为在procrun日志文件中捕获JVM jni调试消息。如果正在使用stdout / stderr重定向,则不需要。仅适用于jvm模式。 |
–StdOutput | 重定向标准输出文件名。 | |
–StdError | 重定向的stderr文件名。 | |
–PidFile | 定义用于存储正在运行的进程ID的文件名。实际文件在LogPath目录中创建。 |
(1)安装服务
prunsrv //IS//TestService --DisplayName=“Test Service”
–Install=prunsrv.exe --Jvm=auto --StartMode=jvm --StopMode=jvm
–StartClass=org.apache.SomeStartClass --StartParams=arg1;arg2;arg3
–StopClass=org.apache.SomeStopClass --StopParams=arg1#arg2
(2)运行服务
prunsrv //ES//TestService
(3)停止服务
prunsrv //SS//TestService
(4)删除服务
prunsrv //DS//TestService
(1)main方法
命令行:
–Classpath MyClass.jar
–StartMode jvm --StartClass MyClass --StartParams start
–StopMode jvm --StopClass MyClass --StopParams stop
代码实现:
class MyClass;
//jvm模式下,须保证主线程不会停止,即使有异常也不能让该main方法执行结束
static void main(String [] args){
String mode = args[0];
if("stop".equals(mode)){
// process service stop function
return;
} else if ("start".equals(mode){
// process service start function
}
//other code
}
(2)指定start方法和stop方法
命令行:
–Classpath MyClass.jar
–StartMode jvm --StartClass MyClass --StartMethod start
–StopMode jvm --StopClass MyClass --StopMethod stop
代码实现:
class MyClass;
// jvm模式下,须保证主线程不会停止,即使有异常也不能让该start方法执行结束
static void start(String [] args){
// process service start function
}
static void stop(String [] args){
// process service stop function
}
}
基本服务定义在注册表项下维护:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services<ServiceName>
其他参数存储在注册表中的以下位置:
HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\ProcRun 2.0<ServiceName>\Parameters
在64位Windows上,procrun始终使用32位注册表视图来存储配置。这意味着参数将存储在内部:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\ProcRun 2.0<ServiceName>