Java 当JVM达到某个堆大小时,如何停止骆驼路由?
我使用ApacheCamel连接到各种端点,包括JMS主题,并写入数据库。有时数据库连接失败(无论出于何种原因,数据库问题、网络漏洞等),来自主题订阅者的消息开始备份。在某一点上,有太多备份的消息等待写入数据库,以致应用程序抛出内存不足错误。到目前为止,我了解所有这些 我遇到的问题如下:当应用程序在最终放弃并接受内存不足之前疯狂地尝试垃圾收集时,应用程序停止工作,但仍处于活动状态。这意味着JMS提供程序仍将主题订阅者视为活动的,但不会读取主题以外的任何内容,因此提供程序开始将消息排队。最终,当最大深度用完时,提供者也会失败Java 当JVM达到某个堆大小时,如何停止骆驼路由?,java,jvm,heap,apache-camel,Java,Jvm,Heap,Apache Camel,我使用ApacheCamel连接到各种端点,包括JMS主题,并写入数据库。有时数据库连接失败(无论出于何种原因,数据库问题、网络漏洞等),来自主题订阅者的消息开始备份。在某一点上,有太多备份的消息等待写入数据库,以致应用程序抛出内存不足错误。到目前为止,我了解所有这些 我遇到的问题如下:当应用程序在最终放弃并接受内存不足之前疯狂地尝试垃圾收集时,应用程序停止工作,但仍处于活动状态。这意味着JMS提供程序仍将主题订阅者视为活动的,但不会读取主题以外的任何内容,因此提供程序开始将消息排队。最终,当最
如何将应用程序配置为在达到某个堆使用率时断开连接,或者在内存不足时更快地完全停止运行?我相信有一些JVM参数允许应用程序在内存不足时更快地终止自己,但我想知道这是不是最好的解决方案,或者是否有其他方法?首先,我认为您应该使用能够刷新失败连接的JDBC连接池。因此,您首先不会遇到所描述的场景。如果数据库/网络问题持续时间很短,则至少不会 接下来,我将通过应用生产者流控制来保护消息代理(至少在ActiveMQ中是这样调用的)。即,如果超过某个内存阈值,则阻止消息生产者提交更多消息。如果阈值设置正确,那么这将防止您的MessageBroker崩溃 至于您最初的问题:我将使用JMX来监视VM。如果某些指标(例如内存)超过阈值,则可以通过MBeans Camel exposes挂起或关闭路由或整个Camel上下文。您可以使用Camel上下文方法
.stop()
,.start()
,挂起()
和恢复()控制(启动/停止和挂起/恢复)Camel路由
您可以旋转一个单独的线程来监视当前VM内存,并在满足特定条件时停止所需的路由
new Thread() {
@Override
public void run() {
while(true) {
long free = Runtime.getRuntime().freeMemory();
boolean routeRunning = camelContext.isRouteStarted("yourRoute");
if (free < threshold && routeRunning) {
camelContext.stopRoute("yourRoute");
} else if (free > threshold && !routeRunning) {
camelContext.startRoute("yourRoute");
}
// Check every 10 seconds
Thread.sleep(10000);
}
}
}
谢谢你,拉尔夫。不幸的是,在我目前的项目中(这是一家非常大的公司,有着大量的文书工作),我不得不使用我得到的hibernate配置和可用的MessageBroker。不过,我会询问如何让他们设置“流量控制”的等效项。为了监视虚拟机,虚拟机是否可以监视自身?有没有一个现成的骆驼机制来实现这一点?或者它必须是一个单独的VM通过JMX进行监控吗?是的,您可以自己监控,但我怀疑它是否非常健壮。您需要在VM加载时采取操作。这意味着需要采取行动的进程是已经过载的VM的一部分。许多监视工具,例如,允许您通过JMX监视VM度量,并在违反阈值时自动触发操作,例如在MBean上调用方法。也许你应该告诉你的运营人员他们使用什么样的工具来监控你的生产环境。
route("sample").from("jms://myqueue")
// Handle SQL Exceptions by shutting down the route
.onException(SQLException.class)
.process(new Processor() {
// This processor spawns a new thread that stops the current route
Thread stop;
@Override
public void process(final Exchange exchange) throws Exception {
if (stop == null) {
stop = new Thread() {
@Override
public void run() {
try {
// Stop the current route
exchange.getContext().stopRoute("sample");
} catch (Exception e) {}
}
};
}
// start the thread in background
stop.start();
}
})
.end()
// Standard route processors go here
.to(...);