简体   繁体   English

使用servlet在Java EE环境中启动和停止ScheduledExecutorService

[英]Start & Stop a ScheduledExecutorService in Java EE environment using servlet

We have a requirement where in we need to monitor remote JVM details via JMX using a simple servlet application. 我们需要使用简单的servlet应用程序通过JMX监视远程JVM细节。 So things done till now in a standalone application is 所以在独立应用程序中完成的工作是

1) Creat a JMX connector & get the Memory data --> done 2) We need to constantly monitor & get the records (2.1 > which can be considered as scheduled task at constant delay & insert the records into DB Or 2.2> does the JMX gives the history if yes which MBean to access for the info?). 1)创建一个JMX连接器并获取内存数据 - >完成2)我们需要不断监视和获取记录(2.1>可以被视为计划任务的恒定延迟并将记录插入DB或2.2>是否JMX给出了历史记录,如果是,哪个MBean可以访问该信息?)。

Here I am planning to use an interface to register the domain , followed to it. 在这里,我打算使用一个界面来注册域,然后就可以了。 Have start & stop button from JSP. 有来自JSP的启动和停止按钮。 The functionality been when we click start the system will run the scheduler (ScheduledExecutorService ) & capture the records at background to give the history. 单击启动系统时的功能将运行调度程序(ScheduledExecutorService)并在后台捕获记录以提供历史记录。 When the uses clicks stop the scheduler has to stop the background process. 当使用点击停止时,调度程序必须停止后台进程。 The question is how can we control & get the object of a scheduler ? 问题是我们如何控制和获取调度程序的对象?

1) In other words how can we start & stop a ScheduledExecutorService via servlets ? 1)换句话说,我们如何通过servlet启动和停止ScheduledExecutorService? start a thread from one servlet & stop a thread from another servlet for a particular task ? 从一个servlet启动一个线程并从一个特定任务的另一个servlet中停止一个线程?

2) What if we have a clustered/load balanced environment ? 2)如果我们有集群/负载平衡环境怎么办?

Currently am thinking of adding each ScheduledExecutorService into HashMap , key been the task object & value been the ScheduledExecutorService using SingleTon desgin pattern. 目前我正在考虑将每个ScheduledExecutorService添加到HashMap中,关键是任务对象和值是使用SingleTon设计模式的ScheduledExecutorService。 Is there any default approach. 有没有默认方法。 The loop whole with SingleTon is in clustered/load balanced environment we may not be able to get the appropriate update objects. 使用SingleTon的整个循环处于集群/负载平衡环境中,我们可能无法获得适当的更新对象。

Looking forward for your valuable suggestion. 期待您的宝贵建议。

If on java ee 7, try using the javax.enterprise.concurrent.ManagedScheduledExecutorService 如果在java ee 7上,请尝试使用javax.enterprise.concurrent.ManagedScheduledExecutorService

Then you can do a resource injection and start the task with code similiar to below. 然后,您可以执行资源注入并使用类似于下面的代码启动任务。

@Resource
ManagedScheduledExecutorService mses;

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

In Java EE 6 you could have a servlet create/remove using the timerservice API 在Java EE 6中,您可以使用timerservice API创建/删除servlet

ServletContext

A ServletContext represents your entire web app as running in the Servlet container. ServletContext表示您在Servlet容器中运行的整个Web应用程序。 The context is established before the first HTTP request is processed by the servlet, as promised by the Servlet spec . 在Servlet处理第一个HTTP请求之前建立上下文,如Servlet规范所承诺的那样。 While a HttpSession represents each user's work session (technically, a thread through your servlet code), a ServletContext represents the scope across all those users. 虽然HttpSession代表每个用户的工作会话(从技术上讲,是一个通过servlet代码的线程),但ServletContext代表所有这些用户的范围。

To hook into the set-up and tear-down of the servlet context, implement a ServletContextListener . 要挂钩servlet上下文的设置和拆除,请实现ServletContextListener Tip: Auto-deploy your listener by marking it with @WebListener annotation. 提示:通过使用@WebListener注释对其进行标记来自动部署侦听器。 That interface requires a pair of methods, each called when your web app is being set-up before the first Servlet request is handled and when your web app is being torn-down. 该接口需要一对方法,每个方法在您处理第一个Servlet请求之前以及当您的Web应用程序被拆除之前设置Web应用程序时调用。

Tip: That tear-down method is a good place to shut down your ScheduledExecutorService . 提示:该拆卸方法是关闭ScheduledExecutorService的好地方。 The threads associated with your executor service may survive after your web app ends. 在您的Web应用程序结束后,与您的执行程序服务关联的线程可能会存在。 You likely do not want that to happen. 你可能不希望这种情况发生。

See this Question: How to get and set a global object in Java servlet context 请参阅此问题: 如何在Java servlet上下文中获取和设置全局对象

See also this nice summary of Servlet scope by BalusC. 另请参阅BalusC 对Servlet范围这个很好的总结

Fetch the servlet context 获取servlet上下文

You can access the current servlet's ServletContext by first accessing its ServletConfig . 您可以访问当前servlet的ServletContext首先访问其ServletConfig

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

And how about in a ServletContextListener , how do we access the servlet context? 那么在ServletContextListener ,我们如何访问servlet上下文? When either of the two methods on the listener is called, a ServletContextEvent is passed. 当调用侦听器上的两个方法中的任何一个时,将传递ServletContextEvent From there call ServletContextEvent::getServletContext() . 从那里调用ServletContextEvent::getServletContext()

Store objects as ”attributes” on servlet context 将对象存储为servlet上下文中的“属性”

So where to store your web app's global variables such as your ScheduledExecutorService ? 那么在哪里存储您的Web应用程序的全局变量,例如ScheduledExecutorService The servlet context has a built in map of String to Object . servlet上下文具有StringObject的内置映射。 These are called “attributes”. 这些被称为“属性”。 Call setAttribute( String , Object ) to store an attribute mapping. 调用setAttribute( String , Object )来存储属性映射。 So make up a name for your ScheduledExecutorService to use a key into this map. 因此,为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.

Later you can fetch your ScheduledExecutorService in the same manner. 稍后您可以以相同的方式获取ScheduledExecutorService You will need to cast from Object to the known class, in this case 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 ; 

You can ask for a list of all stored attribute names by calling ServletContext::getAttributeNames . 您可以通过调用ServletContext::getAttributeNames来请求所有存储的属性名称的列表。

Diagram of scope 范围图

Here is a diagram of mine to get an idea of the hierarchy of scope in a Servlet environment. 下面是我的图表,以了解Servlet环境中范围的层次结构。 Note how each layer of scope has its set of attributes, its own map of String to Object . 请注意每个范围层如何具有其属性集,它自己的String to Object映射。 As you go down the diagram, each set of attributes has a shorter lifespan. 在图表中,每组属性的生命周期都较短。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM