无法在 Tomcat webapp 中关闭 Neo4j Jetty 服务器 [英] Unable to shut down Neo4j Jetty server within Tomcat webapp

查看:24
本文介绍了无法在 Tomcat webapp 中关闭 Neo4j Jetty 服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在开发一个使用 Neo4j 的网络应用程序.我们的应用需要部署在Tomcat环境中(客户要求).我们决定嵌入 Neo4j,因为这样我们可以使用 Neo4j 提供的 Java API,它更容易部署并且我们获得了改进的性能.但是,我们还需要访问 REST API,因为我们有一个用 Angular 编写的单页 ​​web 应用程序,它目前正在使用这个接口.然而,嵌入式 Neo4j 数据库不公开 REST api.Neo4j-server 工件包含可以使用嵌入式图形数据库引导码头服务器的代码.所以我们的 Tomcat webapp 正在启动一个 Jetty 服务器.我们可以通过一个端口(8080)上部署在Tomcat中的webapp和另一个端口(7474)上的Neo4j REST接口和Neo4j浏览器访问graphDb.尽管这有点奇怪,但它工作正常,除非我们尝试停止我们的 web 应用程序(例如重新部署).关闭我们的 web 应用程序时,我们从 tomcat 收到以下错误:

Currently I am working on an webapp that utilizes Neo4j. Our app needs to be deployed in a Tomcat environment (customer requirement). We decided to embed Neo4j, because that way we can use the Neo4j provided Java API, it's easier to deploy and we get improved performance. However, we also need access to the REST API, because we have a single page webapp written in Angular that is currently making use this interface. The embedded Neo4j database however does not expose the REST api. The Neo4j-server artifact contains code that can bootstrap a jetty server with an embedded graph database. So our Tomcat webapp is starting a Jetty server. We can access the graphDb via the webapp deployed in Tomcat on one port (8080) and the Neo4j REST interface and Neo4j browser on another port (7474). Though this is a bit odd it works fine, except for when we try to stop our webapp (for redeployment for example). When shutting down our webapp we receive these errors from tomcat:

SEVERE: The web application [/chainmonitor] appears to have started a thread named [GC-Monitor] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [RRD4J Sync Pool [Thread-1]] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [Statistics Gatherer[primitives]] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [pool-1-thread-2] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [DateCache] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-31-selector-3] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-32-selector-0] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-33-selector-1] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-34-selector-2] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-35-selector-4] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-36-selector-5] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-37-acceptor-0-ServerConnector@1425c689{HTTP/1.1}{localhost:7474}] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-38-acceptor-1-ServerConnector@1425c689{HTTP/1.1}{localhost:7474}] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [HashSessionScavenger-0] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/chainmonitor] appears to have started a thread named [qtp835579386-54] but has failed to stop it. This is very likely to create a memory leak.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [org.eclipse.jetty.http.HttpFields$1] (value [org.eclipse.jetty.http.HttpFields$1@4a3d3a5e]) and a value of type [org.eclipse.jetty.http.HttpFields.DateGenerator] (value [org.eclipse.jetty.http.HttpFields$DateGenerator@24f0137b]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:17 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/chainmonitor] created a ThreadLocal with key of type [scala.util.DynamicVariable$$anon$1] (value [scala.util.DynamicVariable$$anon$1@281a099d]) 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.
jun 10, 2014 6:43:27 PM org.apache.catalina.startup.HostConfig undeploy
INFO: Undeploying context [/chainmonitor]
jun 10, 2014 6:43:27 PM org.apache.catalina.startup.ExpandWar deleteDir
SEVERE: [C:devapache-tomcat-7.0.54webappschainmonitorWEB-INFlib] could not be completely deleted. The presence of the remaining files may cause problems
jun 10, 2014 6:43:27 PM org.apache.catalina.startup.ExpandWar deleteDir
SEVERE: [C:devapache-tomcat-7.0.54webappschainmonitorWEB-INF] could not be completely deleted. The presence of the remaining files may cause problems
jun 10, 2014 6:43:27 PM org.apache.catalina.startup.ExpandWar deleteDir
SEVERE: [C:devapache-tomcat-7.0.54webappschainmonitor] could not be completely deleted. The presence of the remaining files may cause problems
jun 10, 2014 6:43:27 PM org.apache.catalina.startup.ExpandWar delete
SEVERE: [C:devapache-tomcat-7.0.54webappschainmonitor] could not be completely deleted. The presence of the remaining files may cause problems

我们的 pom.xml 看起来像这样:

Our pom.xml looks like this:

    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j</artifactId>
        <version>2.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.neo4j.app</groupId>
        <artifactId>neo4j-server</artifactId>
        <version>2.0.3</version>
    </dependency>

这是我们如何启动嵌入式数据库并启动jetty服务器:

This is how we start the embedded database and start the jetty server:

graphDb = (EmbeddedGraphDatabase) new GraphDatabaseFactory().
      newEmbeddedDatabaseBuilder(dataDir).loadPropertiesFromURL(Neo4jPropertiesUrl).newGraphDatabase();
bootstrapper = new WrappingNeoServerBootstrapper(graphDb);

目前neo4j-server.properties 是空的.我没有尝试过很多不同的配置,但这样做似乎没有问题.

Currently neo4j-server.properties is empty. I've not tried many different configurations, but doing so doesn't seem to be a problem.

这是我们如何停止嵌入式数据库和码头服务器:

This is how we stop the embedded database and jetty server:

    @Override
    public void contextDestroyed(ServletContextEvent event) {
​            graphDb.shutdown();
            bootstrapper.stop();
    }

这显然是由Tomcat的内存泄漏保护引起的(http://wiki.apache.org/tomcat/内存泄漏保护).

This is apparently caused by Tomcat's memory leak protection (http://wiki.apache.org/tomcat/MemoryLeakProtection).

结果是我们的webapp只能通过彻底kill掉Tomcat进程(kill -9)才能重新部署,这是非常不可取的.

The result is that our webapp can only be redeployed by completely killing the Tomcat process (kill -9), which is very undesirable.

我们尝试了很多方法:

  • not shutting down the embedded grapbDb. No effect.
  • not explicitly shutting down the bootstrapper. No effect. (the bootstrapper has its own shutdown hook)
  • shutting down the bootstrapper first and then the embedded database.
  • thread immolator: https://github.com/Neo4j/Neo4j/issues/1070 . The code runs and immolates 59 thread local values, but with no apparent effect. Interestingly when I run this in a loop for a minute during the shutdown it keeps saying it immolated 6 values. To me this is an indication that this process does not work at all, because Neo4j takes some time while shutting down.
  • putting in a delay after the shutting down. The reason we tried this is because after tomcat has received a shutdown signal we need to wait a few seconds before actually killing the process otherwise we get an error on our next start that our graph data has been corrupted (with a message that is has not been properly shut down). Delaying by 5+ seconds seems to have an effect too, because afterwards we get only 6 severe errors instead of 16. This is also the reason why I think the immolation process is not working at all.
  • We tried as an alternative to add our embedded Neo4j to a cluster, thus being able to use both the REST api as wel as the embedded Neo4j. However after about four hours trying to get this to work we gave up. During the startup of the embedded Neo4j database our webapplication just froze. After some debugging it very much seemed like a deadlock within Neo4j's code. We tried to set all HA timeout configurations to some smaller values, but with no effect.

问题是由 Neo4j 码头服务器引起的.没有它就不会出现这个问题.不过,我们需要 REST API.你知道我们如何解决这个问题吗?或者您是否有在 Tomcat 环境中使用嵌入式数据库和 REST API 的替代方法?

The problem is caused by the Neo4j jetty server. Without it this problem does not arise. We need the REST API though. Do you know how we can fix this? Or have you got an alternative way to use the embedded database and the REST API within a Tomcat environment?

我们正在使用:

  • Java:1.7.0_60
  • Tomcat 7.0.54
  • Neo4j:2.0.3(我们尝试过 2.1.1,但得到了完全相同的结果)
  • 在 Windows 7 和 Linux Redhat 上观察到相同的行为

推荐答案

我们有一个非常相似的设置和需求.这是我们针对此问题的解决方案.JVM 运行时shutdownHook 在Tomcat 中不起作用,因此我们持有对包含GraphDatabaseService 的包装器对象的引用,并将该包装器放置在存储库管理器对象中.在存储库管理器对象中的方法上使用 @PreDestroy 注释,这将在存储库管理器类被销毁之前关闭存储库.

We have a very similar setup and need. Here is the solution we have for this issue. The JVM Runtime shutdownHook does not work in Tomcat, so we hold a reference to a wrapper object holding our GraphDatabaseService and place that wrapper in a repository manager object. Use the @PreDestroy annotation on a method in the repository manager object which will shutdown the repositories before the repository manager class is destroyed.

import javax.annotation.PreDestroy;

...

@PreDestroy
public void destroy() {
    log.info("Destroying Neo4jRepositoryManager...");
    shutdown(Neo4jPropertyKeys.SANDBOX_DATABASE.getUrlKey());
    shutdown(Neo4jPropertyKeys.PRODUCTION_DATABASE.getUrlKey());
    shutdown(Neo4jPropertyKeys.TEST_DATABASE.getUrlKey());
}

private void shutdown(String urlKey) {
    if(repositories.containsKey(urlKey)) {
        LabeledNodeGraphRepository graphdb = repositories.get(urlKey);
        graphdb.getGraphDatabaseService().shutdown();
        log.info(urlKey + " shutdown...");
    }
}

<bean id="repositoryManager" class="mypath.neo4j.repository.Neo4jRepositoryManager"/>

我们的环境是:

  • Java 1.7.0_72
  • Tomcat 7.0.56
  • Neo4j 2.1.6
  • Spring 4.0.5
  • 球衣 2.1.4

这篇关于无法在 Tomcat webapp 中关闭 Neo4j Jetty 服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆