Tomcat启动完成后再执行一个指定的方法 - 不影响Tomcat的启动时间

本文主要介绍Tomcat启动真正完成后(即在eclipse的控制台上出现类似于Server started in 2300ms这样的消息后)执行一个操作。

如下的3种方法都是在Tomcat启动过程中执行的,这样会影响Tomcat的启动时间,从而造成Tomcat不能启动成功: 
1.配置一个Servlet默认自动启动。 
2.配置一个Listener来启动 
3.实现Spring的InitializingBean接口 

要想不影响Tomcat的启动,便联想到了异步调用 。即无非就是新创建了一个线程来单独执行,这样Tomcat执行到相应的操作就可以直接继续下去了,不会处于等待的状态,避免了启动超时。基于这样的思想,可以有两种方法来完成:

 

方法一:使用如上三种方式中的任何一种来在启动Tomcat的过程中执行相应的方法,然后在执行的过程中使用另一个线程来执行:比如说将要执行的方法所在的类继承HttpServlet并在web.xml中配置,然后在该Servlet的init中去调用想要执行的方法时(假设这个方法名叫start()),启动另一个线程来执行,具体代码如下。

 

Java代码 复制代码  收藏代码
  1. /**  
  2.  *   
  3.  */  
  4. package com.ebay.montage.pm;   
  5.   
  6.   
  7. import java.util.concurrent.Callable;   
  8. import java.util.concurrent.FutureTask;   
  9.   
  10. import javax.servlet.ServletException;   
  11. import javax.servlet.http.HttpServlet;   
  12.   
  13. import org.apache.log4j.Logger;   
  14. import org.springframework.beans.factory.annotation.Value;   
  15. import org.springframework.scheduling.annotation.Scheduled;   
  16. import org.springframework.stereotype.Component;   
  17.   
  18. import com.ebay.montage.pm.collector.NucleonEventDataCollector;   
  19. import com.ebay.montage.pm.constants.CMConstants;   
  20. import com.ebay.montage.pm.utils.ConfigurationUtils;   
  21. import com.ebay.montage.pm.utils.LoggerUtils;   
  22. import com.ebay.system.ShutdownAwaitLatch;   
  23.   
  24. /**  
  25.  * Trigger to consume data from Nucleon Event Bus  
  26.  *   
  27.  * @author Josh Wang(Sheng)  
  28.  *  
  29.  * @email  swang6@ebay.com  
  30.  */  
  31. @Component("processor")   
  32. public class NucleonEventProcessor extends HttpServlet {   
  33.        
  34.     private static final long serialVersionUID = -9045451275234606838L;   
  35.   
  36.     private static final Logger log = Logger.getLogger(NucleonEventProcessor.class);   
  37.        
  38.     // Servlet的init方法会在Tomcat启动的时候执行   
  39.     @Override  
  40.     public void init() throws ServletException {   
  41.         FutureTask<String> task = new FutureTask<String>(new Callable<String>(){   
  42.   
  43.            @Override  
  44.            public String call() throws Exception {   
  45.         start(); // 使用另一个线程来执行该方法,会避免占用Tomcat的启动时间   
  46.         return "Collection Completed";   
  47.            }   
  48.                
  49.         });   
  50.            
  51.         new Thread(task).start();   
  52.     }   
  53.   
  54.         // 希望Tomcat启动结束后执行的方法   
  55.     private void start() {   
  56.         if (ConfigurationUtils.isEnableEventCollector()) {   
  57.             String topic = CMConstants.NUCLEON_EVENT_TOPIC;   
  58.                
  59.             new NucleonEventDataCollector().collect(topic);   
  60.                
  61.             LoggerUtils.info(log, "NuclenonEventDataCollector started to consume data from Collector Bus - NUCLEON_EVENT_TOPIC: " + topic);        
  62.             new ShutdownAwaitLatch().awaitForShutdown();   
  63.             LoggerUtils.info(log, "Complete processing and publishing Event Data");   
  64.   
  65.         } else {   
  66.             log.info("There disable the collector, please enable it on dev/qa/prod property if needed");   
  67.         }   
  68.            
  69.     }   
  70.   
  71.   
  72. }  
/**
 * 
 */
package com.ebay.montage.pm;


import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.ebay.montage.pm.collector.NucleonEventDataCollector;
import com.ebay.montage.pm.constants.CMConstants;
import com.ebay.montage.pm.utils.ConfigurationUtils;
import com.ebay.montage.pm.utils.LoggerUtils;
import com.ebay.system.ShutdownAwaitLatch;

/**
 * Trigger to consume data from Nucleon Event Bus
 * 
 * @author Josh Wang(Sheng)
 *
 * @email  swang6@ebay.com
 */
@Component("processor")
public class NucleonEventProcessor extends HttpServlet {
	
	private static final long serialVersionUID = -9045451275234606838L;

	private static final Logger log = Logger.getLogger(NucleonEventProcessor.class);
	
	// Servlet的init方法会在Tomcat启动的时候执行
	@Override
	public void init() throws ServletException {
		FutureTask<String> task = new FutureTask<String>(new Callable<String>(){

	       @Override
	       public String call() throws Exception {
		start(); // 使用另一个线程来执行该方法,会避免占用Tomcat的启动时间
		return "Collection Completed";
	       }
			
		});
		
		new Thread(task).start();
	}

        // 希望Tomcat启动结束后执行的方法
	private void start() {
		if (ConfigurationUtils.isEnableEventCollector()) {
			String topic = CMConstants.NUCLEON_EVENT_TOPIC;
			
			new NucleonEventDataCollector().collect(topic);
			
			LoggerUtils.info(log, "NuclenonEventDataCollector started to consume data from Collector Bus - NUCLEON_EVENT_TOPIC: " + topic);		
			new ShutdownAwaitLatch().awaitForShutdown();
			LoggerUtils.info(log, "Complete processing and publishing Event Data");

		} else {
			log.info("There disable the collector, please enable it on dev/qa/prod property if needed");
		}
		
	}


}

 web.xml中的配置

 

 

 

Java代码 复制代码  收藏代码
  1. <servlet>   
  2.     <servlet-name>event-collector</servlet-name>   
  3.     <servlet-class>com.ebay.montage.pm.NucleonEventProcessor</servlet-class>   
  4.     <load-on-startup>5</load-on-startup>   
  5. </servlet>   
  6.   
  7. <servlet-mapping>   
  8.     <servlet-name>event-collector</servlet-name>   
  9.     <url-pattern>/event-collect</url-pattern>   
  10. </servlet-mapping>  
    <servlet>
    	<servlet-name>event-collector</servlet-name>
    	<servlet-class>com.ebay.montage.pm.NucleonEventProcessor</servlet-class>
    	<load-on-startup>5</load-on-startup>
    </servlet>
    
    <servlet-mapping>
    	<servlet-name>event-collector</servlet-name>
    	<url-pattern>/event-collect</url-pattern>
    </servlet-mapping>

 

 

方法二:使用Spring的Timer或者是著名的Quartz在Tomcat启动后再执行该方法,Spring中的Timer非常简单,这个地方不想讲解了,Quartz相对更复杂些,下面主要介绍下在Spring中怎么样使用Quartz来实现上面的需求:

实现Job接口的任务实现类 :

Java代码   收藏代码
  1. public class InitJob implements Job {  
  2.   
  3.     @Override  
  4.     public void execute(JobExecutionContext arg0) throws JobExecutionException {  
  5.         // TODO Auto-generated method stub  
  6.     }  
  7.       
  8.     public void executeA() throws JobExecutionException {  
  9.         // TODO Auto-generated method stub  
  10.         .........  
  11.     }  

 

 

Spring配置文件中配置的任务 

Xml代码   收藏代码
  1. <bean id="initJob" class="com.xxx.services.InitJob" />  
  2. <!--定时器任务配置(开始)-->       
  3.     <!--配置JOB-->  
  4.     <bean id="initJobDetail"  
  5.         class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
  6.         <property name="targetObject" ref="initJob" />  
  7.         <property name="targetMethod" value="executeA" />  
  8. <!--         <property name="arguments" /> -->  
  9.     </bean>  
  10.     <!--配置Trigger-->  
  11.     <bean id="initTrigger"    
  12.         class="org.springframework.scheduling.quartz.SimpleTriggerBean">    
  13.         <property name="jobDetail" ref="initJobDetail" />    
  14.         <property name="startDelay" value="1000" />  
  15.         <property name="repeatInterval" value="0" />  
  16.         <property name="repeatCount" value="0" />  
  17.     </bean>  
  18.     <!--配置Scheduler-->  
  19.     <bean id="schedulerFactory"    
  20.         class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">    
  21.         <property name="triggers">    
  22.             <list>    
  23.                 <ref bean="initTrigger" />    
  24.             </list>    
  25.         </property>    
  26.         <property name="autoStartup" value="true"/>  
  27.     </bean>  
  28.     <!--定时器任务配置(结束)-->  
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Alpha / Beta /Stable 当为发布投票时,审阅者指定他们认为发布已达到的稳定性级别。一个新的主要版本的初始版本通常在几个月的时间内从Alpha过渡到Beta到Stable。但是,稳定级别仅在Java规范发布实现已完成时可用。这意味着在所有其他方面被认为稳定的版本,如果规格不是最终的,仍然可以标记为Beta。 下载页面将始终显示最新的稳定版本和任何新的Alpha或Beta版本(如果存在)。Alpha和Beta版本始终在下载页面上清楚地标记。 稳定性是一个主观判断,你应该总是仔细阅读版本注释任何版本,你打算使用。如果你是一个释放的早期采用者,我们很乐意听到你关于它的稳定性意见,表决部分:它发生在上开发邮件列表。 Alpha版本可能含有大量的规范和/或显著的bug需要未经测试/缺少的功能,并且预计不会稳定地任何时间运行。 Beta版本中可能含有一些未经测试的功能和/或一些相对较小的错误。Beta版本预计不会稳定运行。 Stable的版本可能包含少量相对较小的错误。稳定的释放用于生产使用,预计可以稳定运行长时间。 Apache Tomcat 9.x Apache Tomcat上9.x的是发展的当前焦点,它建立在Tomcat 8.0.x和实现了目前草案的Servlet 4.0规范,也将执行 JSP 2.4?,EL 3.1?,目前对WebSocket的1.2? 和JASPIC 1.1 规范工作的一次更新上这些规范为Java EE 8除此之外启动时,它包括以下显著改进: 添加对HTTP / 2的支持(需要APR /本地库) 添加对TLS虚拟主机的支持 添加了对使用JSSE连接器(NIO和NIO2)使用OpenSSL for TLS支持的支持。 Apache Tomcat 8.x 的Apache Tomcat 8.x的建立在Tomcat的7.0.x并实施 的Servlet 3.1,JSP 2.3,EL 3.0 和WebSocket的1.1规格。除此之外,还包括以下重大改进: 单个公共资源实现来替换早期版本中提供的多个资源扩展特性。 的Apache Tomcat 8.5.x的支持相同的Servlet,JSP,EL和WebSocket规范的版本的Apache Tomcat 8.0.x. 除此之外,它也实现了JASPIC 1.1规范。还有在许多领域显著变化引擎盖下,从而提高了性能,稳定性和总拥有成本。有关详细信息,请参阅Apache Tomcat 8.5更改日志。 Apache Tomcat 7.x 的Apache Tomcat 7.x的建立在Tomcat中6.0.x的改进和实现的Servlet 3.0, JSP 2.2,EL 2.2和 WebSocket的1.1规格。除此之外,它还包括以下改进: Web应用程序内存泄漏检测和预防 提高了Manager和Host Manager应用程序的安全性 通用CSRF保护 支持直接在Web应用程序中包含外部内容 重构(连接器,生命周期)和大量的内部代码清理 Apache Tomcat 6.x 的Apache Tomcat 6.x的建立在Tomcat中的5.5.x的改进和实现的Servlet 2.5和 JSP 2.1规范。除此之外,它还包括以下改进: 内存使用优化 高级IO功能 重构聚类 Tomcat的6的用户应该知道,Tomcat的团队已经公布了 的生命日期为Tomcat 6.x的结束。Tomcat 6.x的用户应该计划在Tomcat 6.x到达生命周期之前进行升级。 Apache Tomcat 5.x 的Apache Tomcat 5.x的是可以从档案下载。 的Apache Tomcat 5.5.X支持相同的Servlet和JSP规范版本的的Apache Tomcat 5.0.x中 还有在许多领域显著变化引擎盖下,从而提高了性能,稳定性和总拥有成本。有关详细信息,请参阅Apache Tomcat 5.5 Changelog。 的Apache Tomcat 5.0.x版在很多方面在Apache Tomcat 4.1的改进,其中包括: 性能优化和减少的垃圾收集 重构的应用程序部署器,具有可选的独立部署器,允许在Web应用程序投入生产之前进行验证和编译 使用JMX和管理器Web应用程序完成服务器监视 可扩展性和可靠性增强 改进了Taglibs的处理,包括高级池和标签插件 改进的平台集成,与本机Windows和Unix包装器 使用JMX嵌入 增强的安全管理器支持 集成会话聚类 扩展文档 Apache Tomcat 4.x 的Apache Tomcat 4.x版可以从档案下载。 的Apache Tomcat 4.x的实现了基于全新架构的新的servlet容器(称为卡特琳娜)。4.x的版本中实现的Servlet 2.3和JSP 1.2 规范。 的Apache Tomcat 4.1.x的是的Apache Tomcat 4.0.x的的重构,并含有显著增强功能,包括: 基于JMX的管理功能 JSP和Struts的管理Web应用程序 新的Coyote连接器(HTTP / 1.1,AJP 1.3和JNI支持) 重写Jasper JSP页面编译器 性能和内存效率提高 增强了与开发工具集成的管理应用程序支持 自定义Ant任务可以直接从build.xml脚本与管理器应用程序交互 的Apache Tomcat 4.0.x的。Apache Tomcat 4.0.6是旧的生产质量版本。4.0 servlet容器(卡塔利娜)已经从地上爬起来的灵活性和性能开发。4.0版实现了Servlet 2.3和JSP 1.2规范的最终发布版本。根据规范的要求,Apache Tomcat 4.0还支持为Servlet 2.2和JSP 1.1规范构建的Web应用程序,无需更改。 Apache Tomcat 3.x Apache Tomcat上3.X可以从档案下载。 版本3.3是当前生产质量放行了Servlet 2.2和JSP 1.1规范。Apache Tomcat 3.3是Apache Tomcat 3.x体系结构的最新延续; 它比3.2.4更先进,这是“老”的生产质量释放。 版本3.2.4是“旧的”生产质量版本,现在仅在维护模式。 版本3.1.1是旧版本。 所有的Apache Tomcat 3.X版本跟踪其遗产回到原来的Servlet和JSP实现,Sun公司捐赠给Apache软件基金会。该3.X版本都实现了支持Servlet 2.2和JSP 1.1规范。 的Apache Tomcat 3.3.X。版本3.3.2是当前的生产质量版本。它继续在3.2版本中开始的重构,并将其转化为其逻辑结论。3.3版本提供了更多的模块化设计,允许通过添加和删除控制servlet请求处理的模块来定制servlet容器。此版本还包含许多性能改进。 的Apache Tomcat 3.2.X。版本3.2自3.1以来增加了几个新功能; 主要的努力是重构内部以提高性能和稳定性。3.2.1版本,如3.1.1,是一个安全补丁。版本3.2.2修复了大量的错误和所有已知的规范合规性问题。版本3.2.3是一个安全更新,关闭一个严重的安全漏洞。版本3.2.4是一个小错误修复版本。所有Apache Tomcat 3.2.3之前版本的用户都应该尽快升级。除了修复关键安全相关的错误,Apache Tomcat 3.2.x分支上的开发已停止。 的Apache Tomcat 3.1.X。3.1版本包含对Apache Tomcat 3.0的几个改进,包括servlet重新加载,WAR文件支持和为IIS和Netscape Web服务器添加的连接器。最新的维护版本3.1.1包含了对安全问题的修复。Apache Tomcat 3.1.x没有进行积极的开发。Apache Tomcat 3.1的用户应该更新到3.1.1以关闭安全漏洞,强烈建议他们迁移到当前的生产版本Apache Tomcat 3.3。 的Apache Tomcat 3.0.x的。初始Apache Tomcat版本。
最近学习Nginx+tomcat实现 负载均衡。 首先大家注意: 本文章中没有session共享,关于session共享我会在下一篇中讲解,先实现Nginx+tomcat负载均衡再实现session共享。 从网上查了好多资料,多走了很多弯路,现在把自己成功的方法拿出来与大家分享。 Window7 我是在Win7上做的。不是什么Linux,网上好多资料,特别麻烦。 Nginx Nginx 比较好找到,直接去网上下载 网址: http://nginx.org/en/download.html 版本不作要求了,(比如1.2.9版本),都有。 JDK JAVA的各种环境都要有。 版本不要求 Tomcat 这里我给大家提供tomcat6 Tomcat各种版本的下载地址我也提供给大家:http://tomcat.apache.org/download-60.cgi 大家可以先用我tomcat6 学会了,在下载自己需要的版本。 词条科普 另外我把实现过程中遇到的知识点都总结好了,一起提供给大家学习。 步骤: 注:本例程以一台win7机器为例子,即同一台机器上装一个nginx和2个Tomcat。 且安装了JDK。 便于管理将用到的资料放在一个文件夹下 我在D盘 创建 server 文件夹 . 1. Nginx 下载直接解压缩到server,点nginx.exe 执行 安装后如果可用,可在任务管理其中找到如图类似,并且在浏览器中输入 http://localhost/ 浏览器显示如下两个图 说明成功 2.Tomcat 同样将自己下载的或者我提供的tomcat 放到D盘的server下不过要复制成两份或者多份。 命名如:(便于区别 我们只用两个来讲解 ,多个tomcat和两个原理是一样的) 1、server.xml配置 我们需要在一台机器上跑 2 个不同的 tomcat ,避免出现端口被占用的情况,为了规范统一,我们修改全部tomca端口。分别找到tomcat6的1和2 的conf下的 server.xml。 修改Server端口 找到Server将: 改为 XXXX 在这里表示不同的端口:我的两个 tomcat 分别使用 8005和8006; 2.1.2、修改Connector端口 找到Connector将: 改为 XXXX 在这里表示不同的端口:我的两个 tomcat 分别使用 8081和8082; 2.1.3、修改Engine端口 找到Engine将: 改为 tomcatX 在这里表示不同的tomcat,我的两个 tomcat 分别使用 tomcat1和tomcat2;来区分。 这个设置是主要用以tomcat的集群。 如果看不懂可以去看我提供的tomcat我已经改好了。 启动tomcat服务 分别到两个tomcat下,直接双击D:\server\apache-tomcat-6.0.39_1\bin\startup.bat启动tomcat1 D:\server\apache-tomcat-6.0.39_2\bin\startup.bat启动tomcat2 出现以下页面表示启动成功 在浏览器中输入 http://localhost:8081 http://localhost:8082 出现 标示成功 3、Nginx+Tomcat负载均衡配置 首先创建两个文件,这两个文件 我来提供,将这两个文件拷入Nginx的conf文件夹下 1.proxy.conf 文件内容 #负责代理转发 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_
Quartz是一个开源的调度框架,常用于定时任务的调度和执行。当我们将Quartz集成到Tomcat中,并希望在Tomcat启动执行一次任务时,可以按照以下步骤进行配置。 首先,我们需要在Tomcat的web.xml文件中配置一个Servlet,用于接收Tomcat启动的事件通知。在该Servlet的初始化方法中,我们可以通过调用Quartz的Scheduler实例的start方法启动Quartz的调度器,以便开始任务的调度。 然后,我们需要定义一个Quartz的Job类,该类实现了Quartz的Job接口。在Job类中,我们可以实现我们需要执行的任务逻辑。例如,如果我们希望在Tomcat启动时打印一条日志,则可以在Job类的execute方法执行打印日志的逻辑。 接下来,我们需要在Quartz的配置文件(例如quartz.properties)中配置需要执行的Job。在配置文件中,我们可以指定调度任务的执行时间和频率。例如,我们可以使用Cron表达式来定义定时任务的执行时间,如每天的凌晨2点执行一次。 最后,我们将配置文件和Job类放置在项目的classpath目录下,并将其添加到Tomcat的类路径中。 当我们启动Tomcat时,Tomcat会初始化Servlet,并触发Servlet的初始化方法。在初始化方法中,我们会调用Quartz的Scheduler实例的start方法,从而启动Quartz的调度器。Quartz的调度器会按照配置文件中的设定,执行我们定义的任务逻辑,例如打印一条日志。 总结起来,通过在Tomcat中集成Quartz,并在Tomcat启动执行一次任务,我们可以使用Tomcat启动事件通知机制,在Quartz中定义和调度任务,并在任务启动执行我们所需的逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值