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

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)

我搜索了网络,发现我并不孤单,但还没有找到合适的解决方案,因此我提出了这个问题。

顺便说一句:我不太熟悉 tomcat。哦还有:第一篇帖子!所以请保持友好 ;)

答案1

问题

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

问题在于,Tomcat 很容易陷入某种无法通过其管理端口甚至通过信号将其杀死的情况TERM

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

  1. 通过其管理端口终止 Tomcat。这是默认设置,也是 Tomcat 自己的关闭脚本首先尝试的操作。如果 Java 进程因某种原因挂起,则此方法无效。您在互联网上看到的所有关于人们抱怨 Tomcat 无法停止的报告或多或少都与此有关。这实际上不是 Tomcat 的错。通过此方法创建一个将使整个容器挂起或无法停止的 Web 应用程序非常容易。

  2. 通过向 Java 进程发送TERM信号来终止 Tomcat。这是比 (1) 中更强大的终止 Tomcat 的方法,Tomcat 自己的关闭脚本会尝试此操作,但只有在您已CATALINA_PID在 Tomcat 中设置变量时才会激活此操作setenv.sh。(无论如何都强烈推荐此操作)。通过向 Unix/Linux 进程发送信号来终止进程TERM是操作系统命令的默认设置kill。这是告诉 Unix/Linux 进程终止的礼貌方式。不幸的是,即使在极少数情况下,这也无法终止 Tomcat 进程。

  3. 通过向 Java 进程发送信号来终止 Tomcat KILL。(从 OS 命令行,这将是kill -9 <pid>)。这将总是终止进程,这应该是最后的手段。这里的问题是,即使方法 (1) 和 (2) 失败,标准 Tomcat 关闭脚本也永远不会尝试这样做。因此,如果您真的想确保 Tomcat 已被终止,那么您别无选择,只能围绕 Tomcat 自己的关闭脚本实现自己的包装器脚本。

如果在生产环境中运行 Tomcat,您确实需要考虑是否可以忍受运行时 Tomcat 不会死机(或不会重新启动)的情况service tomcat restart。您可能通过 cron 执行此操作,在这种情况下,您肯定会期望一个确定的结果,对吗?

建议

  • setenv.sh始终使用您定义的Tomcat文件CATALINA_PID。这至少会为您提供上述方法 2。setenv.sh 默认情况下,Tomcat 的文件不存在,因此您必须自己创建它。

  • 围绕 Tomcat 自己的脚本创建一个包装脚本,以确保 Tomcat 确实死亡。

在我工作的地方,我们在所有运行 Tomcat 作为服务的主机上都实现了这一点。对于任何版本的 Unix/Linux,这都是相同的问题/解决方案。

答案2

我今天遇到了这个问题。就我而言,原因是 pid 文件过时了。

完成后,Tomcat 即可正常启动rm /var/run/tomcat6.pid

答案3

我遇到过同样的问题。对我来说,这是由于文件权限/所有者问题而发生的。当init.d/usr/sbin/tomcat6脚本无法读取/etc/tomcat6/tomcat6.conf文件时,的值${CATALINA_BASE}将变为空。因此${CATALINA_BASE}/logs/catalina.out第 60 行变为/logs/catalina.out

答案4

我在 CentOS 上运行 Tomcat7;之前我运行的是 Tomcat6。

为了重新启动 Tomcat,我总是进入 Tomcat 安装的 bin 目录并运行 shutdown.sh,然后运行 ​​startup.sh 您应该能够以这种方式作为后备方法

相关内容