我写了一个程序,现在我希望将它转换为一个守护进程.由于我是一个菜鸟,对此一无所知,你能告诉我我该怎么做或者你可以给我一些关于它的基本教程或读物吗?我真的想学习如何做到这一点?
谢谢你们
Tomcat文档描述了编译和安装JSVC的过程,该过程可用于将Tomcat作为守护进程运行.据我了解,JSVC有两个好处:
我一直在学习systemd,包括服务单元配置.根据我的有限理解,如果我设置User=tomcat
(使用所需的用户名)并Restart=on-failure
在我的tomcat.service
配置文件中,systemd能够执行与JSVC相同的任务.
使用JSVC,我希望tomcat.service
看起来像这样:
[Unit]
Description=Apache Tomcat
After=network.target
[Service]
Environment=CATALINA_PID=/var/run/tomcat.pid
Environment=JAVA_HOME=/path/to/java
Environment=CATALINA_HOME=/opt/tomcat
...
ExecStart=/opt/tomcat/bin/jsvc \
-Dcatalina.home=${CATALINA_HOME} \
-user tomcat \
-java-home ${JAVA_HOME} \
-pidfile ${CATALINA_PID} \
...
org.apache.catalina.startup.Bootstrap
ExecStop=/opt/tomcat/bin/jsvc \
-pidfile ${CATALINA_PID} \
...
-stop \
org.apache.catalina.startup.Bootstrap
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
使用systemd,我希望tomcat.service
看起来像这样:
[Unit]
Description=Apache Tomcat
After=network.target
[Service]
Type=forking
PIDFile=/var/run/tomcat.pid
User=tomcat
Group=tomcat
Environment=JAVA_HOME=/path/to/java
Environment=CATALINA_HOME=/opt/tomcat
...
Restart=on-failure
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
[Install]
WantedBy=multi-user.target …
Run Code Online (Sandbox Code Playgroud) 我有一个简单的结构:一个包含一批数据的数据jar文件,以及一个使用该数据运行服务的服务jar文件.为了使数据易于替换,我将它们分开,service.jar的classpath包含data.jar所在的目录.
在service.jar中,我使用getResource来加载数据文件.如果数据文件直接位于文件夹中,但是当它们位于data.jar内时失败,则此方法有效;
这失败了:
all
+ globalclasspath
| + data.jar
| + mine.properties
+ daemons
+ service.jar
jsvc -cp globalclasspath:daemons/service.jar (...)
MyClass.class.getClassLoader( ).getResource( "mine.properties" ); // <-- null
Run Code Online (Sandbox Code Playgroud)
但这有效:
all
+ globalclasspath
| + mine.properties
+ daemons
+ service.jar
jsvc -cp globalclasspath:daemons/service.jar (...)
MyClass.class.getClassLoader( ).getResource( "mine.properties" ); // <-- not null
Run Code Online (Sandbox Code Playgroud)
我不想更改类路径(除非我可以将它改为通用的,不依赖于数据jar文件的名称),但是我可以更改getResource字符串(我试过/数据) /mine.properties和/data.jar/mine.properties无济于事.我可以进行更改,以便可以从jar中加载资源吗?
我使用本机编译的jsvc来启动java守护进程.我在openSUSE 32位vm上运行它.代码实现了Apache的守护进程接口,我正在使用以下命令执行deamon.
./jsvc -home jre -errfile logs/jsvc.err -pidfile daemon.pid -cp <my_classpath> com.loader.loaderservice.LoaderDaemon
Run Code Online (Sandbox Code Playgroud)
它启动并运行没有问题.我可以作为普通用户和root用户启动守护进程.但是,当我去终止守护进程时,jsvc会终止进程而不是发出stop命令.
./jsvc -stop -home jre -outfile logs/jsvc.err -errfile logs/jsvc.err -pidfile daemon.pid -cp <my_classpath> com.loader.loaderservice.LoaderDaemon
Run Code Online (Sandbox Code Playgroud)
守护进程终止,但不执行任何关闭步骤(例如,它应该记录,标记数据库中的记录等).我在logs/jsvc.err文件中得到以下内容,并且它不会写任何其他日志:
Service exit with return value 143
Run Code Online (Sandbox Code Playgroud)
在谷歌搜索错误后,我看到一些人都看到了同样的事情,但我无处可寻找一个好的解决方案(http://mail-archives.apache.org/mod_mbox/commons-dev/200401. mbox/%3CPine.GSO.3.96.1040105133739.23375A-100000@merlot.tel.uva.es%3E,http://www.tek-tips.com/viewthread.cfm?qid=1014679,HTTP://三比特. net/mail-archive/tomcat-users/msg03832.html).
更新: 使用Apache的窗口的服务启动器(procrun)我能够毫无问题地启动和停止服务.该问题似乎只与jsvc相关,并且仅在停止守护进程时才会出现.
更新2: 在仔细阅读了http://commons.apache.org/daemon/jsvc.html#Starting_jsvc后,我注意到我正在使用的停止标签通过我指定的pid文件发出了一个kill命令.似乎jsvc实际上并没有通过设计优雅地停止守护进程.这与我所看到的行为一致,因为非常详细的stop方法不会写出任何消息.
-stop stop the service using the file given in the -pidfile option
Run Code Online (Sandbox Code Playgroud)
新问题:
我想使用jsvc启动我的spring启动应用程序,因为它已经在目标系统上,另一种方法是花时间调试shell脚本以获取边缘情况.我已经实现了守护进程接口,因此SpringApplication.run()
被调用Daemon.start()
但是找不到嵌套的jar,因为我绕过了JarLoader
.
有没有办法以编程方式设置正确的类加载器等?
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableConfigurationProperties
public class Application implements Daemon {
private ConfigurableApplicationContext ctx;
private String[] args;
@Override
public void init(DaemonContext context) throws Exception {
args = context.getArguments();
}
@Override
public void start() throws Exception {
ctx = SpringApplication.run(Application.class, args);
}
@Override
public void stop() throws Exception {
ctx.stop();
}
@Override
public void destroy() {
ctx.close();
}
// Main - mostly for development.
public static void main(String[] args) throws Exception {
System.err.println("WARNING - …
Run Code Online (Sandbox Code Playgroud) 我正在编写一个利用jsvc
Java服务作为守护进程启动的应用程序.我需要使用类似的东西,jsvc
因为我的应用程序使用1024以下的端口,但我真的不想以root身份运行它,以便创建的文件由另一个用户拥有.我还希望将依赖关系和配置保持在最低限度,以便所有客户端需求都是JVM并jsvc
安装了二进制文件.
然而,似乎jsvc
有一个主要的问题; 它无法在给定的Unix操作系统上检测到Java的主文件夹,这非常令人沮丧:
$ ./startup.sh
Cannot locate Java home
Run Code Online (Sandbox Code Playgroud)
我至少可以通过手动设置JVM主目录来解决Ubuntu上的问题:
jsvc ... -home /usr/lib/jvm/default-java/ ...
Run Code Online (Sandbox Code Playgroud)
有没有办法从Bash脚本动态确定Java主目录,所以我可以在大多数Unix/Linux上使这个工作?我晚上可以睡得更好,比如:
JAVA_HOME="$( ... )"
jsvc ... -home "$JAVA_HOME" ...
Run Code Online (Sandbox Code Playgroud)
...而不是为每个操作系统进行硬编码.有没有办法,给定java
二进制文件,我可以找到其JVM/JRE的主目录?
我正在尝试使用Apache Commons Daemon使用Daemon接口来守护我的应用程序.它自己的Java应用程序只是写入粗壮的东西.
我编译了jsvc:http://people.apache.org/~mturk/daemon-1.0.10/
(甚至尝试过最新版本:http://people.apache.org/~mturk/daemon-1.0.12/)
并写了这个基本脚本.
do_exec()
{
$EXEC \
-home "$JAVA_HOME" \
-cp $CLASS_PATH \
-outfile $LOG_OUT \
-errfile $LOG_ERR \
-pidfile $PID \
$1 \
$MAIN_CLASS
echo "result: $?"
}
case "$1" in
start)
do_exec
;;
stop)
do_exec "-stop"
;;
restart)
do_exec "-stop"
do_exec
;;
*)
echo "usage: daemon {start|stop|restart}" >&2
exit 3
;;
esac
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试在守护程序未运行时停止守护程序时,我会得到响应代码255.真是棒极了.
但是当我尝试启动守护进程时它已经运行我得到响应代码0.但在我的错误文件中我发现:
Still running according to PID file /tmp/deamon.pid, PID is …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用jsvc将Java应用程序作为Linux服务运行.我找到了如何用jsvc将java程序转换为守护进程?它能够让我大部分时间,但我仍然在努力让类路径得到解决.
我向stderr收到以下错误:
19/04/2013 10:43:18 12233 jsvc.exec错误:找不到守护进程加载器org/apache/commons/daemon/support/DaemonLoader
19/04/2013 10:43:18 12231 jsvc.exec错误:服务退出,返回值为1
似乎运行时无法找到commons-daemon.jar.
我的应用程序是结构化的,以便应用程序本身在一个jar文件中,具有依赖项,包括lib目录中的commons-daemon.
这是我的daemon-script.sh的相关部分:
LIB_DIR = $(PWD)/ lib目录/*
CLASS_PATH = $(PWD)/myapp.jar
$ EXEC -home $ JAVA_EXEC -cp $ CLASS_PATH:$ LIB_DIR -outfile $ LOG_OUT -errfile $ LOG_ERR -pidfile $ PID $ 1 $ CLASS
我尝试了很多变化:相对路径,特别是引用lib/commons-daemon.jar,没有通配符等.有没有人知道如何正常工作?
此外,myapp.jar是一个自执行jar (主要用于测试目的,是的,我仍然需要它作为服务运行),因此manifest.mf包含Class-Path和Main-Class属性.有没有办法让jsvc识别清单?
我有commons-daemon-x.jar
在classpath
.该JSVC成功启动Java VM.但是jsvc
报告它找不到守护进程加载器类,即使它在classpath
.
有谁知道如何解决这个问题?我正在运行Mac OS X 10.8.3.谢谢.
这是jsvc
调试输出的摘录:
...
+-- DUMPING JAVA VM CREATION ARGUMENTS -----------------
| Version: 0x010004
| Ignore Unrecognized Arguments: False
| Extra options: 1
| "-Djava.class.path=commons-daemon-1.0.15.jar:./api-monitor.jar" (0x00000000)
+———————————————————————————
...
Java VM created successfully
Cannot find daemon loader org/apache/commons/daemon/support/DaemonLoader
java_init failed
Service exit with a return value of 1
...
Run Code Online (Sandbox Code Playgroud)
如果有帮助,这是完整的调试输出:
sudo jsvc -jvm server -debug -cp commons-daemon-1.0.15.jar:./api-monitor.jar ApiMonitorDaemon
+-- DUMPING PARSED COMMAND LINE ARGUMENTS -------------- …
Run Code Online (Sandbox Code Playgroud) 我有一个需要在MacOS Sierra中作为守护进程运行的JAR文件,我决定使用Apache Commons Daemon和JSVC来达到这个目的.我知道也许JSVC并不是真的需要用于此目的(它似乎只允许在低范围内打开端口)并且可以通过系统/启动实现相同的功能,因此任何有或没有JSVC的帮助/解决方案都是值得赞赏的.
这就是我从命令行运行jar的方法,它运行正常.它使用端口8085打开WebSocket连接,并等待传入连接.然后,它连接到智能卡读卡器并从卡中获取一些数据.
java -cp "myjar.jar:jars/*" full_class_name
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试使用Apache Commons Daemon接口和JSVC运行相同的jar时,jar正常启动并开始在端口8085中侦听.
./jsvc -debug -cp commons-daemon-1.1.0.jar:myjar.jar:jars/* -cwd . -pidfile /tmp/file.pid full_class_name
Run Code Online (Sandbox Code Playgroud)
问题是,出于某种原因,尝试连接智能卡读卡器时会出现异常.
INFORMACIÓN: WebSocket Registered apps: URLs all start with ws://localhost:8085
may 15, 2018 10:04:37 AM org.glassfish.tyrus.server.Server start
INFORMACIÓN: WebSocket server started.
LISTENING
Daemon started successfully
java_start done
Waiting for a signal to be delivered
create_tmp_file: /tmp/541.jsvc_up
jnasmartcardio.Smartcardio$EstablishContextException: jnasmartcardio.Smartcardio$JnaPCSCException: SCardEstablishContext got response 0x8010001d (SCARD_E_NO_SERVICE: The Smart card resource manager is not running.)
at jnasmartcardio.Smartcardio$JnaTerminalFactorySpi.engineTerminals(Smartcardio.java:81)
at javax.smartcardio.TerminalFactory.terminals(TerminalFactory.java:351)
at apdu4j.TerminalManager.getTheReader(TerminalManager.java:228)
at com.st.middleware.a.a.b.connect(SourceFile:24) …
Run Code Online (Sandbox Code Playgroud)