系统关闭时,Tomcat 无法使用 init.d 脚本正确关闭 - 无法重新启动

系统关闭时,Tomcat 无法使用 init.d 脚本正确关闭 - 无法重新启动

我想在系统启动时自动在 Redhat 7 服务器(RHEL7)上启动 Apache Tomcat 7。

为了做到这一点,我执行了以下步骤:

  • 创建以下 init.d 脚本并使其可执行(运行良好)
  • 将 init.d tomcat 脚本的链接放在 rc 文件中(实际上也可以正常工作)

问题在于 Tomcat 无法启动,因为相应的端口(尤其是 AJP-Port)已被使用(仅在系统重新启动后;简单使用 init.d 脚本不会导致问题)。我猜想它要么没有正常关闭,要么启动了两次,并因此导致问题。

如果我重新启动系统,Tomcat 会尝试启动。当我尝试访问我的网页时,我只会看到一个空白页。

这是catalina.out它开始失败的地方(端口 8005 失败的示例,但我在 8009 和 8080 上也遇到了同样的问题):

20-Apr-2020 20:24:00.813 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /opt/apache-tomcat-8.0.32/webapps/ROOT has finished in 79 ms
20-Apr-2020 20:24:00.821 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-127.0.0.1-8080"]
20-Apr-2020 20:24:00.831 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 58427 ms
20-Apr-2020 20:24:00.831 SEVERE [main] org.apache.catalina.core.StandardServer.await StandardServer.await: create[localhost:8005]: 
 java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
    at java.net.ServerSocket.bind(ServerSocket.java:375)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at org.apache.catalina.core.StandardServer.await(StandardServer.java:420)
    at org.apache.catalina.startup.Catalina.await(Catalina.java:717)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:663)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:351)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:485)

20-Apr-2020 20:24:00.832 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-127.0.0.1-8080"]
20-Apr-2020 20:24:00.832 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"]
20-Apr-2020 20:24:00.832 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service Catalina
2020-04-20 20:24:00,856 [localhost-startStop-1] DEBUG o.x.shutdown                   - Stopping XWiki... 

执行完 后pgrep java,我必须手动终止该进程。然后我就可以毫无问题地启动 Tomcat。

当然,我可以使用 手动终止该进程pkill -9 java,然后启动它。由于此过程是自动化的,因此我不能每次都简单地终止该进程。

我使用 Tomcat 8 在 Debian 9 服务器上测试了自动启动 - 一切运行正常。

您知道如何解决或至少绕过这个错误吗?

附录

我的 server.xml 文件:

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->

    <!-- <Connector port="8009"
    enableLookups="false" redirectPort="8443" protocol="AJP/1.3"         URIEncoding="UTF-8" /> -->

    <Connector port="8080" protocol="HTTP/1.1" 
               proxyName="example.com"
               address="localhost" 
               connectionTimeout="20000"
               redirectPort="8443" 
           URIEncoding="UTF-8" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation that requires the JSSE
         style configuration. When using the APR/native implementation, the
         OpenSSL style configuration is required as described in the APR/native
         documentation -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" 
    URIEncoding="UTF-8"
    address="127.0.0.1"/>   



    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">
      <Valve className="org.apache.catalina.valves.RemoteIpValve"
        internalProxies="127\.0\.[0-1]\.1"
        remoteIpHeader="x-forwarded-for"
        requestAttributesEnabled="true"
        protocolHeader="x-forwarded-proto"
        protocolHeaderHttpsValue="https"/>

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
      [...]
      </Host>
    </Engine>
  </Service>
</Server>

catalina.out 关机时(摘录):

20-Apr-2020 20:22:26.607 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [xwiki] created a ThreadLocal with key of type [com.xpn.xwiki.store.migration.AbstractDataMigrationManager.ThreadLock] (value [com.xpn.xwiki.store.migration.AbstractDataMigrationManager$ThreadLock@7f9e8cb9]) and a value of type [java.lang.Integer] (value [0]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
20-Apr-2020 20:22:26.607 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [xwiki] created a ThreadLocal with key of type [org.apache.solr.logging.MDCLoggingContext$1] (value [org.apache.solr.logging.MDCLoggingContext$1@21089b81]) and a value of type [java.lang.Integer] (value [0]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
20-Apr-2020 20:22:26.623 INFO [Thread-15] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-127.0.0.1-8080"]
20-Apr-2020 20:22:26.714 INFO [Thread-15] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"]
20-Apr-2020 20:22:26.767 INFO [Thread-15] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-127.0.0.1-8080"]
20-Apr-2020 20:22:26.768 INFO [Thread-15] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-8009"]
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0

相关内容