CentOS 6上的tomcat6:无法停止/重新启动服务

我有这个问题停止和启动tomcat6(包回购)。 我见过几个CentOS 6和RHEL 6盒子。

症状是,当我想重新启动或停止tomcat6它只是失败。 这似乎只是在运行了一段时间后才发生。 我有一个新的CentOS 6安装,并能够重新启动,但现在不再。

这就是我所看到的:

# service tomcat6 restart Stopping tomcat6: [FAILED] Starting tomcat6: [FAILED] 

当我尝试通过/usr/sbin/tomcat6

 # /usr/sbin/tomcat6 stop /usr/sbin/tomcat6: line 60: /logs/catalina.out: No such file or directory 

并从/var/log/tomcat6/catalina.out输出:

 Oct 22, 2012 4:53:31 PM org.apache.catalina.startup.Catalina stopServer SEVERE: Catalina.stop: java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384) at java.net.Socket.connect(Socket.java:546) at java.net.Socket.connect(Socket.java:495) at java.net.Socket.<init>(Socket.java:392) at java.net.Socket.<init>(Socket.java:206) at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:424) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 

我搜查了networking,我可以看到我并不孤单,但没有find一个合适的解决scheme,因此我的问题。

顺便说一句:我不太熟悉tomcat。 哦,并且:第一篇文章! 所以很好;)

问题

标准的Tomcat关机脚本的问题在于它不够强大。 当你使用发行版的服务脚本来停止Tomcat时,你最终只会调用Tomcat自己的closures脚本。 CentOS在这方面也不例外。 出于这个原因,您需要熟悉Tomcat的closures脚本可以为您做什么,最重要的是它不会做 :它实际上并不能保证Tomcat死亡。 离得很远。

问题在于,Tomcat很容易陷入某种无法通过pipe理端口或甚至TERM信号TERM

让我们回顾一下Tomcat如何按照升级的顺序被杀死的:

  1. 通过pipe理端口杀死Tomcat。 这是默认的,这是Tomcat自己的closures脚本首先尝试的。 如果Java进程由于某种原因挂起,它将不起作用。 你在互联网上看到的所有人们抱怨Tomcat不会停下来的报道或多或less总是在这个胡同里。 这不是真正的Tomcat的错。 它很容易创build一个networking应用程序,将使整个容器挂起或不可能通过这种方法停止。

  2. 通过向Java进程发送一个TERM信号来杀死Tomcat。 这是杀死Tomcat的一个比在(1)中更强的方法,Tomcat自己的closures脚本会尝试这样做,但是只有当你在Tomcat setenv.sh设置了CATALINA_PIDvariables时才会激活它。 (在任何情况下都强烈推荐)。 通过发送一个TERM信号来杀死Unix / Linux进程是操作系统kill命令的默认值。 告诉Unix / Linux进程死掉的礼貌的方式。 不幸的是即使这样,在极less数情况下也不会杀死Tomcat进程。

  3. 通过向Java进程发送一个KILL信号来杀死Tomcat。 (从操作系统命令行,这将kill -9 <pid> )。 这将永远杀死进程,应该是最后的手段。 这里的问题是,即使方法(1)和(2)失败,标准的Tomcatclosures脚本也不会尝试这个。 所以,如果你真的想确保Tomcat已经被杀死,那么你别无select,只能围绕Tomcat自己的closures脚本实现自己的包装脚本。

如果在一个生产环境中运行Tomcat,你真的需要考虑一下,如果你可以忍受Tomcat不死(或者没有重启)的情况,比如你运行service tomcat restart 。 你可能正在通过cron来做这件事情,你肯定会期待一个确定的结果,对吗?

build议

  • 总是使用定义CATALINA_PID的Tomcat setenv.sh文件。 这至less会给你上面的方法#2。 Tomcat的setenv.sh文件在默认情况下不存在,因此您必须自己创build它。

  • 用Tomcat自己的脚本创build一个包装脚本,确保Tomcat确实死亡。

在我工作的地方,我们已经在运行Tomcat作为服务的所有主机上实现了这一点。 对于Unix / Linux的任何变体,它都是同样的问题/解决scheme。

我今天遇到了这个。 在我的情况下,原因是一个陈旧的PID文件。

Tomcat在执行rm /var/run/tomcat6.pid之后就开始了。

我面临同样的问题。 对我来说,这是由于文件许可/所有者问题。 当init.d/usr/sbin/tomcat6脚本无法读取/etc/tomcat6/tomcat6.conf文件时, ${CATALINA_BASE}值变为空。 因此,第60行中的${CATALINA_BASE}/logs/catalina.out变为/logs/catalina.out

我在CentOS上运行Tomcat7; 以前我在运行Tomcat6。

为了重新启动Tomcat,我总是进入Tomcat安装的bin目录并运行shutdown.sh,然后启动.sh作为回退方法,您应该可以这样做