Запуск и остановка ScheduledExecutorService в среде Java EE с использованием сервлета
У нас есть требование, когда нам нужно отслеживать детали удаленной JVM через JMX с помощью простого приложения сервлета. Таким образом, до сих пор в автономном приложении
1) Создать JMX-коннектор и получить данные из памяти -> готово 2) Нам нужно постоянно отслеживать и получать записи (2.1 >, которые можно рассматривать как запланированную задачу с постоянной задержкой, и вставлять записи в БД или 2.2> выполняет JMX дает историю, если да, какой MBean для доступа к информации?).
Здесь я планирую использовать интерфейс для регистрации домена, следуя по нему. Есть кнопка запуска и остановки от JSP. Функциональность была, когда мы щелкаем пуск, система запускает планировщик (ScheduledExecutorService) и захватывает записи в фоновом режиме, чтобы выдать историю. Когда использование щелчков прекращается, планировщик должен остановить фоновый процесс. Вопрос в том, как мы можем контролировать и получать объект планировщика?
1) Другими словами, как мы можем запустить и остановить ScheduledExecutorService через сервлеты? запустить поток из одного сервлета и остановить поток из другого сервлета для конкретной задачи?
2) Что если у нас есть кластеризованная среда / среда с балансировкой нагрузки?
В настоящее время я думаю о добавлении каждого ScheduledExecutorService в HashMap, ключом был объект задачи, а значением был ScheduledExecutorService с использованием шаблона описания SingleTon. Есть ли подход по умолчанию. Весь цикл с SingleTon находится в кластерной среде / среде с балансировкой нагрузки, поэтому мы не сможем получить соответствующие объекты обновления.
Ждем вашего ценного предложения.
2 ответа
Если на Java EE 7, попробуйте использовать javax.enterprise.concurrent.ManagedScheduledExecutorService
Затем вы можете выполнить внедрение ресурсов и запустить задачу с кодом, подобным приведенному ниже.
@Resource
ManagedScheduledExecutorService mses;
public void startTask() {
mses.scheduleAtFixedRate(runnable, 10, 10, SECONDS);
}
В Java EE 6 вы можете создать / удалить сервлет, используя API-интерфейс timerservice.
ServletContext
ServletContext
представляет все веб-приложение, запущенное в контейнере сервлетов. Контекст устанавливается до того, как сервлет обработает первый HTTP-запрос, как обещано в спецификации Servlet. В то время как HttpSession
представляет сеанс работы каждого пользователя (технически, поток через ваш код сервлета), ServletContext
представляет область действия всех этих пользователей.
Чтобы подключиться к настройке и удалению контекста сервлета, реализуйте ServletContextListener
, Совет: автоматически разверните слушателя, пометив его @WebListener
аннотаций. Для этого интерфейса требуется пара методов, каждый из которых вызывается при настройке веб-приложения перед обработкой первого запроса сервлета и при разрыве веб-приложения.
Совет: этот метод - хорошее место, чтобы закрыть ScheduledExecutorService
, Потоки, связанные с вашим сервисом-исполнителем, могут сохраняться после завершения работы вашего веб-приложения. Вы, вероятно, не хотите, чтобы это произошло.
Смотрите этот вопрос: Как получить и установить глобальный объект в контексте сервлета Java
Смотрите также этот хороший обзор области применения сервлетов от BalusC.
Получить контекст сервлета
Вы можете получить доступ к текущему сервлету ServletContext
сначала получая доступ к его ServletConfig
,
// … in your Servlet, such as its request handler methods like `doGet` …
ServletContext sc = this.getServletConfig().getServletContext() ;
А как насчет в ServletContextListener
Как мы можем получить доступ к контексту сервлета? Когда вызывается любой из двух методов прослушивателя, передается ServletContextEvent. Оттуда позвоните ServletContextEvent::getServletContext()
,
Хранить объекты как "атрибуты" в контексте сервлета
Так, где хранить глобальные переменные вашего веб-приложения, такие как ваш ScheduledExecutorService
? Контекст сервлета имеет встроенную карту 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
,
Схема охвата
Вот моя диаграмма, чтобы получить представление об иерархии области действия в среде сервлета. Обратите внимание, что каждый слой области имеет свой набор атрибутов, свою собственную карту String
в Object
, По мере того, как вы спускаетесь по диаграмме, каждый набор атрибутов имеет более короткую продолжительность жизни.