集群环境下的问题

1.解决上传文件同步的问题

集群后就是多个Tomcat或其它web容器了,即和两个线程读同一个resource的问题是一样的,还好,我们原有上传文件是专门有一台文件伺服器的,这个问题不大,两个tomcat都往一台file server里上传,文件伺服器已经帮我们解决了同名文件冲突的这个问题了,如果原先的做法是把文件上传到Tomcat的目录中,那问题就大了,
来看:
集群环境中,对于用户来说一切操作都是透明的,他也不知道我有几个Tomcat的实例运行在那边。
用户一点上传,可能上传到了Tomcat2中,但是下次要显示这个文件时,可能用到的是Tomcat1内的jsp或者是class,对不对?

于是,因为你把图片存在了Tomcat的目录中,因此导致了Tomcat1在显示图片时,取不到Tomcat2目录中存放的图片。
因此我们在工程一开始就强调存图片时要用一台专门的文件服务器或者是FTP服务器来存,就是为了避免将来出现这样的问题。


2.解决Quartz在集群环境中的同步问题

多个节点就有多个Quartz一起在跑。多个QuartzJob一起跑一件事情,会发生什么事情,是个程序员都知道。

多个Quartz一起在跑的时候,他们是如何通过通信的呢?

Quartz框架已经为我们提供了集群环境下的解决方案

1.先在src目录下配置quartz.properties属性配置文件,这是要告诉Quartz我要给它做持久化操作

org.quartz.scheduler.instanceName: QuartzScheduler1  
org.quartz.scheduler.rmi.export: false  
org.quartz.scheduler.rmi.proxy: false  
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false  

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool  
org.quartz.threadPool.threadCount: 10  
org.quartz.threadPool.threadPriority: 5  
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true  
org.quartz.jobStore.isClustered = true   
org.quartz.jobStore.misfireThreshold: 60000  

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX  

org.quartz.jobStore.dataSource = myMySQL  
org.quartz.dataSource.myMySQL.driver = com.mysql.jdbc.Driver  
org.quartz.dataSource.myMySQL.URL = jdbc:mysql://127.0.0.1:3306/test  
org.quartz.dataSource.myMySQL.user = root  
org.quartz.dataSource.myMySQL.password = admin 
org.quartz.dataSource.myMySQL.maxConnections = 10  

2.执行下载的源码下的sql:我的路径是:quartz-2.2.2\docs\dbTables

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set 
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;


CREATE TABLE QRTZ_JOB_DETAILS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (          
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR(1) NULL,
    BOOL_PROP_2 VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CALENDARS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_FIRED_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);

CREATE TABLE QRTZ_SCHEDULER_STATE
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);


commit;

3.添加log4j.properties配置文件,显示执行的信息

log4j.rootLogger=error,default  

log4j.appender.default=org.apache.log4j.ConsoleAppender  
log4j.appender.default.layout=org.apache.log4j.PatternLayout  
log4j.appender.default.layout.ConversionPattern=%d{[MM-dd HH\:mm\:ss]}->%m%n  

log4j.logger.MyJob=info,MyJob      
log4j.appender.MyJob=org.apache.log4j.RollingFileAppender       
log4j.additivity.MyJob=false      
log4j.appender.MyJob.File=/log/MyJob.log      
log4j.appender.MyJob.MaxFileSize=10MB      
log4j.appender.MyJob.MaxBackupIndex=0      
log4j.appender.MyJob.layout=org.apache.log4j.PatternLayout      
log4j.appender.MyJob.layout.ConversionPattern=%d{MM-dd HH\:mm\:ss}->%m%n  

4.执行的代码

package com.ysdit.spring5.test;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.AnnualCalendar;

import com.ysdit.spring5.quartz.RemindJob;

public class QuartzTest {
    public static Logger myJobLog = Logger.getLogger("MyJob");

    /**
     * @param args
     * @throws SchedulerException
     */
    public static void main(String[] args) throws Exception {


        try {
            SchedulerFactory factory = new StdSchedulerFactory();
            Scheduler scheduler = factory.getScheduler();

            AnnualCalendar cal = new AnnualCalendar();
            // 2016-1-14这一天不执行任何任务
            Calendar c = new GregorianCalendar(2016, 1, 14);
            cal.setDayExcluded(c, true);

            TriggerKey tKey = new TriggerKey("TriggerKey", "TriggerKey-Group");
            JobKey jKey = new JobKey("JobKey", "JobKey-Group");

            if (scheduler.checkExists(tKey)) {
                Trigger trigger = scheduler.getTrigger(tKey);
                scheduler.rescheduleJob(tKey, trigger);
                scheduler.addCalendar("exclude", cal, false, false);
            } else {

                JobDetail job = JobBuilder.newJob(RemindJob.class)
                        .withIdentity(jKey).build();

                SimpleTrigger trigger = TriggerBuilder
                        .newTrigger()
                        .withIdentity(tKey)
                        .startAt(
                                new Date(System.currentTimeMillis() + 5 * 1000))
                        .withSchedule(
                                SimpleScheduleBuilder.simpleSchedule()
                                        .withIntervalInSeconds(2)
                                        .withRepeatCount(5))
                        .modifiedByCalendar("exclude").build();

                scheduler.scheduleJob(job, trigger);
            }
            scheduler.start();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

4.1使用Cron表达式的代码

package com.ysdit.spring5.test;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.calendar.AnnualCalendar;

import com.ysdit.spring5.quartz.RemindJob;

public class Quartz {
    public static Logger myJobLog = Logger.getLogger("MyJob");
    static {
        try {

            SchedulerFactory factory = new StdSchedulerFactory();
            Scheduler scheduler = factory.getScheduler();

            AnnualCalendar cal = new AnnualCalendar();
            // 2016-1-13这一天不执行任何任务
            Calendar c = new GregorianCalendar(2016, 1, 13);
            cal.setDayExcluded(c, true);

            TriggerKey tKey = new TriggerKey("TriggerKey", "TriggerKey-Group");
            JobKey jKey = new JobKey("JobKey", "JobKey-Group");

            if (scheduler.checkExists(tKey)) {
                Trigger trigger = scheduler.getTrigger(tKey);
                scheduler.rescheduleJob(tKey, trigger);

            } else {
                scheduler.addCalendar("exclude", cal, false, false);
                JobDetail job = JobBuilder.newJob(RemindJob.class)
                        .withIdentity(jKey).build();

                CronTrigger trigger = (CronTrigger) TriggerBuilder
                        .newTrigger()
                        .withIdentity(tKey)
                        .startAt(
                                new Date(System.currentTimeMillis() + 5 * 1000))
                        // .endAt(new Date(System.currentTimeMillis() + 5 * 1000
                        // + 60
                        // * 1000))
                        .withSchedule(
                                CronScheduleBuilder
                                        .cronSchedule("1/3 * * * * ?"))
                        .modifiedByCalendar("exclude").build();

                scheduler.scheduleJob(job, trigger);
            }

            scheduler.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5.Spring配置Quartz

<beans>    
        <!-- 要调用的工作类 -->
        <bean id="quartzJob" class="com.kay.quartz.QuartzJob"></bean>
        <!-- 定义调用对象和调用对象的方法 -->
        <bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <!-- 调用的类 -->
            <property name="targetObject">
                <ref bean="quartzJob"/>
            </property>
            <!-- 调用类中的方法 -->
            <property name="targetMethod">
                <value>work</value>
            </property>
        </bean>
        <!-- 定义触发时间 -->
        <bean id="doTime" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail">
                <ref bean="jobtask"/>
            </property>
            <!-- cron表达式 -->
            <property name="cronExpression">
                <value>10,15,20,25,30,35,40,45,50,55 * * * * ?</value>
            </property>
        </bean>
        <!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序  -->
        <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="doTime"/>
                </list>
            </property>
        </bean>

</beans>

6.Quartz中Cron表达式配置,
这里写图片描述
参考
Cron表达式详解-资料1
Cron常规时间表达式-资料2

所用的jar包:quartz-2.2.2.jar,quartz-jobs-2.2.2.jar

其依赖的,c3p0-0.9.1.1.jar,log4j-1.2.16.jar,slf4j-api-1.7.7.jar,slf4j-log4j12-1.7.7.jar。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一缕阳光直射你的心扉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值