我在停止和启动 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 是如何被杀死的:
通过其管理端口终止 Tomcat。这是默认设置,也是 Tomcat 自己的关闭脚本首先尝试的操作。如果 Java 进程因某种原因挂起,则此方法无效。您在互联网上看到的所有关于人们抱怨 Tomcat 无法停止的报告或多或少都与此有关。这实际上不是 Tomcat 的错。通过此方法创建一个将使整个容器挂起或无法停止的 Web 应用程序非常容易。
通过向 Java 进程发送
TERM
信号来终止 Tomcat。这是比 (1) 中更强大的终止 Tomcat 的方法,Tomcat 自己的关闭脚本会尝试此操作,但只有在您已CATALINA_PID
在 Tomcat 中设置变量时才会激活此操作setenv.sh
。(无论如何都强烈推荐此操作)。通过向 Unix/Linux 进程发送信号来终止进程TERM
是操作系统命令的默认设置kill
。这是告诉 Unix/Linux 进程终止的礼貌方式。不幸的是,即使在极少数情况下,这也无法终止 Tomcat 进程。通过向 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 您应该能够以这种方式作为后备方法