我目前有一个tomcat容器 - 在其上运行的servlet监听请求.我需要HTTP请求的结果是作业队列的提交,然后将异步处理.我希望每个"作业"在数据库中连续保存,以便在发生故障时进行跟踪和恢复.我一直在做很多阅读.这是我的选择(注意我必须使用开源的东西).
1)JMS - 使用ActiveMQ(但是在这种情况下谁是该作业的消费者另一个servlet?)
2)让我的请求在数据库中创建一行.在我的Tomcat容器中有一个始终运行的独立servlet - 它使用Quartz Scheduler或java.util.concurrent中提供的实用程序来连续处理作为作业的行(使用线程池).
我倾向于后者,因为查看JMS文档让我头疼,虽然我知道它是一个更强大的解决方案,但我需要相对快速地实现它.在任何情况下,在部署此服务器的早期我都没有预料到会产生巨大的负载.
很多人都认为Spring可能对1或2都有好处.但是我从未使用过Spring,我甚至不知道如何开始使用它来解决这个问题.任何有关如何潜入而无需重新编写整个项目的指针都会很有用.
否则,如果您可以权衡选项1或2,这也是有用的.
澄清:异步过程是屏幕抓取第三方网站,并向原始请求者发送消息通知.第三方网站有点不稳定和缓慢,这就是为什么它将作为异步进程处理(内置几次重试尝试).我还将从该站点提取文件并将其存储在S3中.
我在Web应用程序中调度作业时遇到问题.如果我们必须在Web应用程序中安排作业,我们可以使用java util Timer/TimerTask或Quartz(还有其他调度机制,但我考虑过Quartz).我正在考虑使用哪一个,当我点击网站http://oreilly.com/pub/a/java/archive/quartz.html?page=1时说使用计时器有一个不好的效果,因为它创建了一个线程在最后一行没有容器控制.其他页面讨论了Quartz及其功能,但我可以读到Quartz还使用线程和/或线程池来安排任务.我的猜测是这些线程也不受容器控制
任何人都可以向我澄清这是否可以安全地在我的Web应用程序中使用Quartz而不创建挂起线程或线程锁定问题?提前致谢
我在 Quartz 中设置了一些作业以设定的时间间隔运行。问题是,当服务启动时,它会尝试立即启动所有作业……有没有办法使用 .xml 配置为每个作业添加延迟?
以下是 2 个作业触发器示例:
<simple>
<name>ProductSaleInTrigger</name>
<group>Jobs</group>
<description>Triggers the ProductSaleIn job</description>
<misfire-instruction>SmartPolicy</misfire-instruction>
<volatile>false</volatile>
<job-name>ProductSaleIn</job-name>
<job-group>Jobs</job-group>
<repeat-count>RepeatIndefinitely</repeat-count>
<repeat-interval>86400000</repeat-interval>
</simple>
<simple>
<name>CustomersOutTrigger</name>
<group>Jobs</group>
<description>Triggers the CustomersOut job</description>
<misfire-instruction>SmartPolicy</misfire-instruction>
<volatile>false</volatile>
<job-name>CustomersOut</job-name>
<job-group>Jobs</job-group>
<repeat-count>RepeatIndefinitely</repeat-count>
<repeat-interval>43200000</repeat-interval>
</simple>
Run Code Online (Sandbox Code Playgroud)
如您所见,有 2 个触发器,第一个每天重复,下一个每天重复两次。
我的问题是我希望第一个或第二个工作在另一个之后开始几分钟......(因为它们最终都访问相同的 API,我不想使请求过载)
是否有重复延迟或优先级属性?我找不到任何文件这样说..
有一种情况我想在一段预定时间后调用一个方法,比如30秒或5分钟.
需要在运行时配置时间,这意味着我应该能够动态地将时间从5分钟更改为3分钟.(以编程方式将计时器重置为新的时间间隔)
我正在使用Spring框架开发一个动态Web项目.
我检查了Quartz和Timer类,但它们似乎读取了诸如delay,repeatInterval等参数的XML配置.
我怎样才能做到这一点?Spring是否为此提供任何支持?
先感谢您.
我正在使用 Glassfish 和 CDI 进行注射,(大部分)成功。我似乎无法让 Quartz 作业与注入一起工作 - bean 注释为@Injectnever get injection 。
Quartz 是否使用某种不同的类加载器来阻止注入的发生?
我在 web.xml 中像这样配置 Quartz:
<context-param>
<param-name>quartz:config-file</param-name>
<param-value>quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>quartz:start-scheduler-on-load</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
我的quartz.properties 看起来像:
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.scheduler.instanceId = 1
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml
org.quartz.plugin.jobInitializer.scanInterval = 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
Run Code Online (Sandbox Code Playgroud) dependency-injection glassfish quartz-scheduler cdi glassfish-3
我使用石英、Spring 和 Hibernate 作为 JPA 提供程序。数据库是甲骨文。
我有一种方法可以将文件写入文件系统并使用详细信息更新数据库。可以通过两种方式调用此方法:
我已将石英设置为:
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" scope="singleton">
<property name="autoStartup" value="true"/>
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">FileScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.misfireThreshold">6000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">${driverDelegateClass}</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">5</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
</props>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
这种方法是使用 spring 管理的事务。
问题是当这个方法被石英调度器调用时,文件被创建但数据库没有更新(应该有两个表更新和一个表插入)。
我也启用了 hibernate show_SQL,但在调度程序的情况下,不会记录更新\插入语句。
尽管当 Web 服务请求调用此方法时,这可以正常工作。日志也显示更新\插入语句。
更新 1
总结我的问题,这就是我想要实现的目标:
最后,我希望所有表格都得到更新。 …
我在我的Web应用程序(Servlet Web应用程序)中使用了quartz,下面是quartz.property文件和quartz.job.xml的快照.
quartz.property
#===================================================
# Configure the Job Initialization Plugin
#===================================================
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = jobs.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.jobInitializer.scanInterval = 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
<?xml version='1.0' encoding='utf-8'?>
<job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
version="1.8">
<schedule>
<job>
<name>my-very-clever-job</name>
<group>MYJOB_GROUP</group>
<description>The job description</description>
<job-class>com.acme.scheduler.job.ReportJob</job-class>
</job>
<trigger>
<cron>
<name>my-trigger</name>
<group>MYTRIGGER_GROUP</group>
<job-name>my-very-clever-job</job-name>
<job-group>MYJOB_GROUP</job-group>
<!-- trigger every night at 4:30 am -->
<cron-expression>0 30 4 * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
Run Code Online (Sandbox Code Playgroud)
按顺序,每件事都很好.我需要允许用户按照他们想要的方式更改时间(cron表达式).我的问题是如何动态设置cron表达式.
我有一份石英工作。我需要通过 UI 停止它的处理。我们提供了一个按钮,用户可以在其中单击STOP按钮,然后应停止当前正在运行的进程。但应该恢复进一步的调度。我用谷歌搜索并发现InterruptableJob了石英。
我的问题是,考虑到作业触发了存储过程执行,并且存储过程可能需要很长时间才能完成其执行。我相信InterruptableJob不能使用 InterruptableJob 的中断方法终止存储过程的执行。请有人解释一下在哪种情况下interrupt() of InterruptableJob有用?
我浏览了 http://www.quartz-scheduler.org/api/2.0.0/org/quartz/InterruptableJob.html但不知道在哪种情况下我需要使用它。
谢谢!
在两三天后的生产中,我们开始收到以下异常:
org.jboss.util.NestedSQLException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -3f572ada:f5ff:52482a05:11a4 status: ActionStatus.ABORTED >; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -3f572ada:f5ff:52482a05:11a4 status: ActionStatus.ABORTED >)
at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:95)
at com.rwsol.syb.persistence.jdbc.JDBCDataStore.getPhysicalConnection(JDBCDataStore.java:146)
... 10 more
Caused by: javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -3f572ada:f5ff:52482a05:11a4 status: ActionStatus.ABORTED >
at org.jboss.resource.connectionmanager.TxConnectionManager.getManagedConnection(TxConnectionManager.java:370)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:496)
at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:941)
at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:89)
Run Code Online (Sandbox Code Playgroud)
我们正在为所有夜间石英作业使用专用的批处理服务器。由于这个问题,我们需要每 4-5 天重启一次批处理。2-3 天后,一个作业失败,然后第二天 2-3 个作业失败,最后 4-5 天后所有作业失败。
我曾尝试增加事务超时但没有成功。
请帮助我解决这个问题。
我一直试图关闭烦人的石英调试日志记录。我正在使用 log4j 作为日志记录框架,并且我已经尝试将此行添加到 lg4j 属性文件中
"log4j.logger.org.quartz=ERROR"
Run Code Online (Sandbox Code Playgroud)
我仍然收到大量这些调试日志消息
13:35:44.680 [MyScheduler_QuartzSchedulerThread] DEBUG o.quartz.core.QuartzSchedulerThread - batch acquisition of 0 triggers
Run Code Online (Sandbox Code Playgroud)
我怎样才能关闭这个功能?
编辑。我已将我的配置移至 xml 文件...但仍然遇到同样烦人的问题
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" />
</layout>
</appender>
<logger name="org.quartz" >
<level value="ERROR" />
<appender-ref ref="console" />
</logger>
<logger name="org.hibernate">
<level value="ERROR" />
<appender-ref ref="console" />
</logger>
<logger name="com.mchange.v2.c3p0" additivity="false">
<level value="ERROR" />
<appender-ref ref="console" />
</logger>
<root>
<priority value="ERROR" …Run Code Online (Sandbox Code Playgroud) quartz-scheduler ×10
java ×5
spring ×3
asynchronous ×1
cdi ×1
glassfish ×1
glassfish-3 ×1
hibernate ×1
jms ×1
jobs ×1
jpa ×1
log4j ×1
logging ×1
quartz.net ×1
scheduling ×1
spring-mvc ×1
timer ×1
tomcat ×1
transactions ×1