小东子的个人技术专栏

重点关注Android、Java、智能硬件、JavaEE、react-native,Swift,微信小程序


  • 首页

  • 归档

  • 标签
小东子的个人技术专栏

dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(十二)之 spring中RabbitMQ延迟队列的实现

发表于 2017-02-27   |   字数统计: 1,344(字)   |   阅读时长: 6(分)

在前面写过一篇dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(七)RabbitMQ工作原理和Spring的集成
,今天在进一步使用一下RabbitMQ的延迟队列的实现。

1. 简介

RabbitMQ如何实现延迟队列:延迟队列存储的对象肯定是对应的延迟消息,所谓”延迟消息”是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费。

2. RabbitMQ的延迟队列使用场景

场景一:在订单系统中,一个用户下单之后通常有30分钟的时间进行支付,如果30分钟之内没有支付成功,那么这个订单将进行一场处理。这是就可以使用延迟队列将订单信息发送到延迟队列。

场景二:用户希望通过手机远程遥控家里的智能设备在指定的时间进行工作。这时候就可以将用户指令发送到延迟队列,当指令设定的时间到了再将指令推送到只能设备。

3.RabbitMQ实现延迟队列

AMQP协议,以及RabbitMQ本身没有直接支持延迟队列的功能,但是可以通过TTL和DLX模拟出延迟队列的功能。

3.1 TTL(Time To Live)

RabbitMQ可以针对Queue和Message设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为dead letter
RabbitMQ针对队列中的消息过期时间有两种方法可以设置。

  1. 通过队列属性设置,队列中所有消息都有相同的过期时间。
  2. 对消息进行单独设置,每条消息TTL可以不同。

如果同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就成为dead letter

详细可以参考:RabbitMQ之TTL(Time-To-Live 过期时间)

3.2 DLX (Dead-Letter-Exchange)

RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可选)两个参数,如果队列内出现了dead letter,则按照这两个参数重新路由。

x-dead-letter-exchange:出现dead letter之后将dead letter重新发送到指定exchange x-dead-letter-routing-key:指定routing-key发送队列出现dead letter的情况有:消息或者队列的TTL过期 队列达到最大长度 消息被消费端拒绝(basic.reject or basic.nack)并且requeue=false,利DLX,当消息在一个队列中变成死信后,它能被重新publish到另一个Exchange。这时候消息就可以重新被消费。

4.案例的实现

4.1 rabbit.properties

1
2
3
4
rabbit_username=lidong1665
rabbit_password=123456
rabbit_host=192.168.0.107
rabbit_port=5672

4.2 spring-rabbitmq.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.7.xsd">
<!--配置connection-factory,指定连接rabbit server参数 -->
<rabbit:connection-factory id="rabbitConnectionFactory"
username="${rabbit_username}"
password="${rabbit_password}"
host="${rabbit_host}"
port="${rabbit_port}"/>
<!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
<rabbit:admin id="connectAdmin" connection-factory="rabbitConnectionFactory" />
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="3"/>
<property name="maxPoolSize" value="5"/>
<property name="queueCapacity" value="15"/>
</bean>
<bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />
<rabbit:topic-exchange name="delayChangeTest"
declared-by="connectAdmin" delayed="true">
<rabbit:bindings>
<rabbit:binding queue="delay_queue"
pattern="order.delay.notify"
/>
</rabbit:bindings>
</rabbit:topic-exchange>
<!--定义queue 配置延迟队列的信息-->
<rabbit:queue name="delay_queue"
durable="true"
auto-declare="true"
auto-delete="false"
declared-by="connectAdmin">
</rabbit:queue>
<rabbit:template id="rabbitTemplate2" connection-factory="rabbitConnectionFactory"
exchange="delayChangeTest"/>
<bean id="orderConsumer" class="com.lidong.dubbo.core.util.customer.OrderConsumer"></bean>
<rabbit:listener-container
connection-factory="rabbitConnectionFactory"
acknowledge="manual"
channel-transacted="false"
message-converter="jsonMessageConverter">
<rabbit:listener queues="queueTest"
ref="messageReceiver" method="onMessage"/>
</rabbit:listener-container>
</beans>

####4.3 创建生产者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.lidong.dubbo.core.spittle.service;
import com.lidong.dubbo.api.spittle.service.IMessageProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @项目名称:lidong-dubbo
* @类名:MessageProducerImp
* @类的描述:
* @作者:lidong
* @创建时间:2017/2/4 上午10:01
* @公司:chni
* @QQ:1561281670
* @邮箱:lidong1665@163.com
*/
@Service
public class MessageProducerServiceImp implements IMessageProducer {
private Logger logger = LoggerFactory.getLogger(MessageProducerServiceImp.class);
@Resource
private RabbitTemplate rabbitTemplate2;
@Override
public void sendMessage(Object message) {
logger.info("to send message:{}",message);
final int xdelay= 300*1000;
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//发送延迟消息
rabbitTemplate2.convertAndSend("order.delay.notify", message,
new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message)
throws AmqpException {
//设置消息持久化
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
//设置延迟时间(5分钟后执行)
message.getMessageProperties().setDelay(xdelay);
logger.info("----"+sf.format(new Date()) + " Delay sent.");
return message;
}
});
}
}

4.4 创建消费者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.lidong.dubbo.core.util.customer;
import com.rabbitmq.client.Channel;
import org.activiti.engine.impl.util.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
/**
* @项目名称:lidong-dubbo
* @类名:OrderConsumer
* @类的描述:
* @作者:lidong
* @创建时间:2017/2/25 下午12:59
* @公司:chni
* @QQ:1561281670
* @邮箱:lidong1665@163.com
*/
public class OrderConsumer implements ChannelAwareMessageListener {
private Logger logger = LoggerFactory.getLogger(OrderConsumer.class);
@Override
public void onMessage(Message message, Channel channel) throws Exception {
logger.info("[延时消息]" + message.getMessageProperties());
if (message != null) {
long deliveryTag = message.getMessageProperties().getDeliveryTag();
logger.debug("deliveryTag= "+deliveryTag);
//手动确认
channel.basicAck(deliveryTag,false);
}
}
}

发送消息之后。消费5分钟之后接受到消息,开始处理。

代码地址

小东子的个人技术专栏

dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(十一)之 spring中定时器quartz的整合续集(Quartz集群配置)

发表于 2017-02-27   |   字数统计: 1,126(字)   |   阅读时长: 5(分)

前面写过一篇关于dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(九)之 spring中定时器quartz的整合。今天主要来继续总结quartz在集群中的使用。

1、说明

  1. quartz可以通过jdbc直连连接到MYSQL数据库,读取配置在数据库里的job初始化信息,并且把job通过java序列化到数据库里,这样就使得每个job信息得到了持久化,即使在jvm或者容器挂掉的情况下,也能通过数据库感知到其他job的状态和信息。
  2. quartz集群各节点之间是通过同一个数据库实例(准确的说是同一个数据库实例的同一套表)来感知彼此的。

    2、数据库表的创建

    创建quartz要用的数据库表,此sql文件在:quartz-2.2.3\docs\dbTables。此文件夹下有各个数据库的sql文件,mysql选择tables_mysql.sql。总共有11张表。
  • QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息
  • QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括 Cron表达式和时区信息
  • QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息
  • QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger 组的信息
  • QRTZ_SCHEDULER_STATE 存储少量的有关 Scheduler 的状态信息,和别的 Scheduler实例(假如是用于一个集群中)
  • QRTZ_LOCKS 存储程序的悲观锁的信息(假如使用了悲观锁)
  • QRTZ_JOB_DETAILS 存储每一个已配置的 Job 的详细信息
  • QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener 的信息
  • QRTZ_SIMPLE_TRIGGERS 存储简单的Trigger,包括重复次数,间隔,以及已触的次数
  • QRTZ_BLOG_TRIGGERS Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)
  • QRTZ_TRIGGER_LISTENERS 存储已配置的 TriggerListener 的信息
  • QRTZ_TRIGGERS 存储已配置的 Trigger 的信息

####3、 quartz.properties的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#调度标识名 集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName = MyScheduler
#线程数量
org.quartz.threadPool.threadCount = 10
#线程优先级
org.quartz.threadPool.threadPriority = 5
#数据保存方式为持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#数据库平台
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#表的前缀
org.quartz.jobStore.tablePrefix = QRTZ_
#库的别名
org.quartz.jobStore.dataSource = myDS
# Cluster开启集群
org.quartz.jobStore.isClustered = true
#ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId = AUTO
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/db_my?characterEncoding=utf-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 5

####4.创建任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.lidong.dubbo.core.util.quartz;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* @项目名称:lidong-dubbo
* @类名:SpringQtz
* @类的描述: 作业类的调度
* @作者:lidong
* @创建时间:2017/2/8 下午5:41
* @公司:chni
* @QQ:1561281670
* @邮箱:lidong1665@163.com
*/
public class SpringQtz extends QuartzJobBean{
static Logger logger = LoggerFactory.getLogger(SpringQtz.class);
private static int counter = 0;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
long ms = System.currentTimeMillis();
logger.error(" SpringQtz start 执行");
logger.info("-------"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(ms))+" "+"(" + counter++ + ")");
}
}

5.spring-quartz.xml的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 定义调用对象和调用对象的方法 -->
<bean id="SpringQtzJobDetail"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.lidong.dubbo.core.util.quartz.SpringQtz"/>
<property name="durability" value="true"/>
<property name="group" value="job_work"/>
<property name="name" value="job_work_name"/>
</bean>
<bean id="SpringQtzJobDetail1"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.lidong.dubbo.core.util.quartz.SpringQtzDemo"/>
<property name="durability" value="true"/>
<property name="group" value="job_work1"/>
<property name="name" value="job_work_name1"/>
</bean>
<!-- ======================== 调度触发器 ======================== -->
<bean id="CronTriggerBean"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="SpringQtzJobDetail"></property>
<!-- cron表达式 -->
<property name="cronExpression" value="0/20 * * * * ?"></property>
</bean>
<bean id="CronTriggerBean1"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="SpringQtzJobDetail1"></property>
<!-- cron表达式 -->
<property name="cronExpression" value="0/30 * * * * ?"></property>
</bean>
<!-- ======================== 调度工厂 ======================== -->
<bean id="SpringJobSchedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="configLocation" value="classpath:config/quartz.properties"/>
<!--启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了-->
<property name="overwriteExistingJobs" value="true"/>
<property name="triggers">
<list>
<ref bean="CronTriggerBean" />
<ref bean="CronTriggerBean1" />
</list>
</property>
<property name="jobDetails">
<list>
<ref bean="SpringQtzJobDetail" />
<ref bean="SpringQtzJobDetail1" />
</list>
</property>
</bean>
</beans>

####6. 分别部署到两台Tomcat服务器查看效果

第1个tomcat的结果:
这里写图片描述

第2个omcat的结果:
这里写图片描述

可以看到。任务不会重复执行。

代码地址

小东子的个人技术专栏

Error:Failed to complete Gradle execution. Cause: Unknown command-line option '-X'解决方法

发表于 2017-02-27   |   字数统计: 60(字)   |   阅读时长: 1(分)

今天新建android studio项目时候。突然遇到如下问题:

这里写图片描述

很是操蛋。最后发现时候用于Setting->compiler -
Command-line Optons:-Xmx2048m导致的。

解决办法是将Command-line Optons的参数删除,设置为空就ok了

这里写图片描述

小东子的个人技术专栏

dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3(十)之Spring MVC中使用 Swagger2 构建Restful API

发表于 2017-02-27   |   字数统计: 503(字)   |   阅读时长: 2(分)

##1、Swagger2是什么?
Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件。
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。

##2、Swagger2官网
官网地址
这里写图片描述

##3.Swagger2的入门教程

####3.1Swagger2的maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 构建Restful API -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>

####3.2RestApiConfig的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.lidong.dubbo.web.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @项目名称:lidong-dubbo
* @类名:RestApiConfig
* @类的描述: Restapi的基本配置
* @作者:lidong
* @创建时间:2017/2/11 上午10:01
* @公司:chni
* @QQ:1561281670
* @邮箱:lidong1665@163.com
* @使用方法:Restful API 访问路径: http://localhost:8080/lidong-dubbo-web/swagger-ui.html
*/
@EnableWebMvc
@EnableSwagger2
@Configuration
@ComponentScan(basePackages ="com.lidong.dubbo")
public class RestApiConfig extends WebMvcConfigurationSupport {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.lidong.dubbo.web"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SpringMVC中使用Swagger2构建RESTful APIs")
.termsOfServiceUrl("https://github.com/lidong1665")
.contact(new Contact("请叫我小东子","http://blog.csdn.net/u010046908","lidong1665@163.com"))
.version("1.0.0")
.build();
}
}

###3.3在Controller中添加

1
2
3
4
5
6
7
8
9
10
11
12
@ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long")
@RequestMapping(value = "getUserForid/{id}", method = RequestMethod.GET)
@ResponseBody
public String getUser(@PathVariable int id) {
try {
return JsonUtil.bean2json(userService.getUserById(id));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

###3.4结果
这里写图片描述

代码地址

小东子的个人技术专栏

dubbo2.5-spring4-mybastis3.2-springmvc4-mongodb3.4-redis3.2整合(九)之 spring中定时器quartz的整合

发表于 2017-02-27   |   字数统计: 1,094(字)   |   阅读时长: 5(分)

今天来总结一下。Spring中quartz的使用。

1、Quartz是什么?

Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。

2、Quartz的分类

2.1、按照作业类的继承方式来分,可以分为两类

  1. 作业类需要继承自特定的作业类基类,如Quartz中需要继承自org.springframework.scheduling.quartz.QuartzJobBean;java.util.Timer中需要继承自java.util.TimerTask。
  2. 作业类即普通的java类,不需要继承自任何基类。

注意:推荐使用第二种方式,因为这样所以的类都是普通类,不需要事先区别对待。

2.2、按照任务调度的触发时机来分,这里主要是针对作业使用的触发器,主要有以下两种:

  1. 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean

  2. 每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean

注意:并非每种任务都可以使用这两种触发器,如java.util.TimerTask任务就只能使用第一种。Quartz和spring task都可以支持这两种触发条件。

3、添加Quartz依赖

1
2
3
4
5
6
<!-- 定时器的使用 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>

4、Spring中quartz的使用(作业类即普通的java类的使用)

4.1、定义作业类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.lidong.dubbo.core.util.quartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @项目名称:lidong-dubbo
* @类名:SpringQtz
* @类的描述: 作业类的调度
* @作者:lidong
* @创建时间:2017/2/8 下午5:41
* @公司:chni
* @QQ:1561281670
* @邮箱:lidong1665@163.com
*/
public class SpringQtz {
static Logger logger = LoggerFactory.getLogger(SpringQtz.class);
private static int counter = 0;
/**
* 调度的方法
*/
public void execute() {
long ms = System.currentTimeMillis();
logger.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(ms))+" "+"(" + counter++ + ")");
}
}

4.2、在Spring中配置作业类

1
2
<!-- 要调用的工作类 -->
<bean id="SpringQtzJob" class="com.lidong.dubbo.core.util.quartz.SpringQtz" />

4.3 、定义调用对象和方法

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 定义调用对象和调用对象的方法 -->
<bean id="SpringQtzJobMethod"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 调用的类 -->
<property name="targetObject">
<ref bean="SpringQtzJob" />
</property>
<!-- 要执行的方法名称 -->
<property name="targetMethod">
<value>execute</value>
</property>
</bean>

4.4、配置调度触发器

1
2
3
4
5
6
7
8
<!-- ======================== 调度触发器 ======================== -->
<bean id="CronTriggerBean"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!--作业详情 -->
<property name="jobDetail" ref="SpringQtzJobMethod"></property>
<!-- cron表达式 -->
<property name="cronExpression" value="0/10 * * * * ?"></property>
</bean>

4.5、配置调度工厂

1
2
3
4
5
6
7
8
9
10
<!-- ======================== 调度工厂 ======================== -->
<bean id="SpringJobSchedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="CronTriggerBean" />
<ref bean="CronTriggerBean1" />
</list>
</property>
</bean>

5、quartz的cron 表达式

一个cron表达式至少有6个,是按照空格来分割的时间元素。
按照顺序为:

  1. 秒 0-59
  2. 分钟 0-59
  3. 小时 0-23
  4. 天 (月)1-31
  5. 月 0-31
  6. 天 (星期)1-7
  7. 年份 1970- 递增

    给几个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"30 * * * * ?" 每半分钟触发任务
"30 10 * * * ?" 每小时的10分30秒触发任务
"30 10 1 * * ?" 每天1点10分30秒触发任务
"30 10 1 20 * ?" 每月20号1点10分30秒触发任务
"30 10 1 20 10 ? *" 每年10月20号1点10分30秒触发任务
"30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
"30 10 1 ? 10 * 2011" 2011年10月每天1点10分30秒触发任务
"30 10 1 ? 10 SUN 2011" 2011年10月每周日1点10分30秒触发任务
"15,30,45 * * * * ?" 每15秒,30秒,45秒时触发任务
"15-45 * * * * ?" 15到45秒内,每秒都触发任务
"15/5 * * * * ?" 每分钟的每15秒开始触发,每隔5秒触发一次
"15-30/5 * * * * ?" 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
"0 0/3 * * * ?" 每小时的第0分0秒开始,每三分钟触发一次
"0 15 10 ? * MON-FRI" 星期一到星期五的10点15分0秒触发任务
"0 15 10 L * ?" 每个月最后一天的10点15分0秒触发任务
"0 15 10 LW * ?" 每个月最后一个工作日的10点15分0秒触发任务
"0 15 10 ? * 5L" 每个月最后一个星期四的10点15分0秒触发任务
"0 15 10 ? * 5#3" 每个月第三周的星期四的10点15分0秒触发任务

基本上就这么多了。

代码地址:

1234…10
李东

李东

细节决定成败,点滴铸就辉煌

46 文章
18 标签
© 2017 李东
由 Hexo 强力驱动
主题 - NexT.Pisces