我们需要使用简单的servlet应用程序通过JMX监视远程JVM详细信息。所以直到现在在独立应用程序中完成的事情是
1)创建一个JMX连接器&获取内存数据 - > DONE 2)我们需要不断监控和得到记录 (2.1>可以被视为持续延迟的计划任务&将记录插入DB或2.2> JMX是否提供历史记录,如果是,哪个MBean可以访问该信息?)。
这里我打算使用一个界面来注册域,然后就可以了。有开始&来自JSP的停止按钮。我们点击启动系统时的功能将运行调度程序(ScheduledExecutorService)&捕获背景记录以提供历史记录。当使用点击停止时,调度程序必须停止后台进程。问题是我们如何控制和获取调度程序的对象?
1)换句话说,我们怎样才能开始&通过servlets停止ScheduledExecutorService?从一个servlet开始一个线程&从另一个servlet停止某个特定任务的线程?
2)如果我们有一个集群/负载均衡的环境怎么办?
目前我正在考虑将每个ScheduledExecutorService添加到HashMap中,关键是任务对象&值是使用SingleTon设计模式的ScheduledExecutorService。有没有默认方法。使用SingleTon的整个循环处于集群/负载平衡环境中,我们可能无法获得适当的更新对象。
期待您的宝贵建议。
答案 0 :(得分: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答案 1 :(得分:1)
ServletContext
ServletContext
表示您在Servlet容器中运行的整个Web应用程序。如Servlet spec所承诺的那样,在servlet处理第一个HTTP请求之前建立上下文。虽然HttpSession
表示每个用户的工作会话(从技术上讲,是一个通过servlet代码的线程),但ServletContext
表示所有这些用户的范围。
要挂钩servlet上下文的设置和拆除,请实现ServletContextListener
。提示:通过使用@WebListener
注释对其进行标记来自动部署侦听器。该接口需要一对方法,每个方法在您处理第一个Servlet请求之前以及当您的Web应用程序被拆除之前设置Web应用程序时调用。
提示:这种拆卸方法是关闭ScheduledExecutorService
的好地方。在您的Web应用程序结束后,与您的执行程序服务关联的线程可能会存在。你可能不希望这种情况发生。
请参阅此问题:How to get and set a global object in Java servlet context
另请参阅BalusC的this nice summary of Servlet scope。
您可以首先访问其ServletConfig
来访问当前servlet的ServletContext
。
// … in your Servlet, such as its request handler methods like `doGet` …
ServletContext sc = this.getServletConfig().getServletContext() ;
在ServletContextListener
中,我们如何访问servlet上下文?当调用侦听器上的两个方法中的任何一个时,将传递ServletContextEvent。从那里拨打ServletContextEvent::getServletContext()
。
那么在哪里存储您的网络应用的全局变量,例如ScheduledExecutorService
? servlet上下文具有String
到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环境中范围的层次结构。请注意每个范围层如何具有其属性集,其自己的String
到Object
地图。在图表中,每组属性的生命周期都会缩短。