4

我们有一个需求,我们需要使用简单的 servlet 应用程序通过 JMX 监控远程 JVM 详细信息。所以到目前为止在独立应用程序中所做的事情是

1) 创建一个 JMX 连接器并获取内存数据 --> 完成 2) 我们需要不断地监控并获取记录(2.1> 这可以被认为是持续延迟的计划任务并将记录插入 DB 或 2.2> 是否如果是,JMX 会给出历史记录,要访问哪个 MBean 以获取信息?)。

这里我打算使用一个接口来注册域,然后就可以了。有来自 JSP 的启动和停止按钮。功能是当我们单击启动时,系统将运行调度程序(ScheduledExecutorService)并在后台捕获记录以提供历史记录。当用户点击停止时,调度程序必须停止后台进程。问题是我们如何控制和获取调度器的对象?

1)换句话说,我们如何通过 servlet 启动和停止 ScheduledExecutorService ?从一个 servlet 启动一个线程并从另一个 servlet 停止一个线程以执行特定任务?

2)如果我们有一个集群/负载平衡的环境怎么办?

目前我正在考虑将每个 ScheduledExecutorService 添加到 HashMap 中,关键是任务对象和值是使用 SingleTon 设计模式的 ScheduledExecutorService。是否有任何默认方法。SingleTon 的整个循环处于集群/负载平衡环境中,我们可能无法获得适当的更新对象。

期待您的宝贵建议。

4

2 回答 2

3

如果在 java ee 7 上,请尝试使用javax.enterprise.concurrent.ManagedScheduledExecutorService

然后您可以进行资源注入并使用类似于下面的代码启动任务。

@Resource
ManagedScheduledExecutorService mses;

public void startTask() {
    mses.scheduleAtFixedRate(runnable, 10, 10, SECONDS);
}

在 Java EE 6 中,您可以使用timerservice API创建/删除 servlet

于 2014-08-11T14:32:16.470 回答
1

ServletContext

AServletContext表示您的整个 Web 应用程序在 Servlet 容器中运行。正如Servlet 规范所承诺的,在 servlet 处理第一个 HTTP 请求之前建立上下文。虽然 aHttpSession代表每个用户的工作会话(从技术上讲,是通过您的 servlet 代码的线程),但 aServletContext代表所有这些用户的范围。

要挂钩到 servlet 上下文的设置和拆卸,请实现一个ServletContextListener. @WebListener提示:通过使用注释标记它来自动部署您的侦听器。该接口需要一对方法,在处理第一个 Servlet 请求之前设置 Web 应用程序以及拆除 Web 应用程序时调用每个方法。

提示:这种拆卸方法是关闭您的ScheduledExecutorService. 与您的执行程序服务关联的线程可能会在您的 Web 应用程序结束后继续存在。您可能不希望这种情况发生。

看到这个问题:How to get and set a global object in Java servlet context

另请参阅BalusC对 Servlet 范围的精彩总结。

获取 servlet 上下文

您可以通过首先访问当前 servletServletContext来访问其ServletConfig.

// … in your Servlet, such as its request handler methods like `doGet` …
ServletContext sc = this.getServletConfig().getServletContext() ;

那么在 aServletContextListener中,我们如何访问 servlet 上下文呢?当调用侦听器上的两个方法中的任何一个时,都会传递一个ServletContextEvent 。从那里打电话ServletContextEvent::getServletContext()

在 servlet 上下文中将对象存储为“属性”

那么在哪里存储你的网络应用程序的全局变量,比如你的ScheduledExecutorServiceStringservlet 上下文有一个to的内置映射Object。这些被称为“属性”。调用setAttribute( String , Object )以存储属性映射。因此,为您ScheduledExecutorService在此地图中使用密钥起一个名称。

ScheduledExecutorService sec = … ; // Instantiated somewhere in your code. 
…
String key = "myScheduledExecutorServiceForXYZ" ;
sc.setAttribute( key , sec );  // Storing the executor service as a generic `Object` for use later.

稍后您可以ScheduledExecutorService以相同的方式获取您的。在这种情况下,您将需要转换Object为已知类ScheduledExecutorService

Object o = sc.getAttribute( key ); // Fetch the `ScheduledExecutorService` from the servlet context’s built-in map of attributes.

// Cast to known class. If in doubt, test first with [`instanceOf`][11].
ScheduledExecutorService sec = ( ScheduledExecutorService ) o ; 

您可以通过调用来请求所有存储的属性名称的列表ServletContext::getAttributeNames

范围图

这是我的一个图表,用于了解 Servlet 环境中的范围层次结构。注意范围的每一层都有它的属性集,它自己的Stringto映射Object。沿着图表向下看,每组属性的生命周期都较短。

在此处输入图像描述

于 2016-12-01T19:43:51.923 回答