## 12.6 使用 ActiveMQ消息调度 延迟发送消息

### 12.6 使用ActiveMQ消息调度延迟发送消息

The ability to schedule a message to be delivered after a delay, or at regular intervals,is an extremely useful feature provided by ActiveMQ. One unique benefit is that messagesthat are scheduled to be delivered in the future are stored persistently, so thatthey can survive a hard failure of an ActiveMQ broker and be delivered on restart.You specify that you want a message to be delivered at a later time by setting welldefinedproperties on the message. For convenience, the well-known property namesare defined in the org.apache.activemq.ScheduledMessage interface. These propertiesare shown in table 12.2.

ActiveMQ消息调度 实现的消息延迟发送或者在按照固定时间的间隔实现间隔发送的功能十分有用.其中一个独一无二的好处是消息调度设置为延迟发送的消息将会被持久化存储,因而在ActiveMQ代理严重失效是消息不会丢失并且在代理重启后会继续发送消息.你可以通过严格定义消息的属性来设置如何延迟发送消息.为方便起见,常用的延迟发送消息相关的属性都在org.apache.activemq.ScheduledMessage接口中有定义,如表12.2所示.

Table 12.2 TransportConnector properties for updating clients of cluster changes

Property name Type Description
AMQ_SCHEDULED_DELAY  false The time in milliseconds that a message will wait before being scheduled to be delivered by the broker
AMQ_SCHEDULED_PERIOD false The time in milliseconds after the start time to wait before scheduling the message again
AMQ_SCHEDULED_REPEAT false The number of times to repeat scheduling a message for delivery
AMQ_SCHEDULED_CRON String

表12.2 更新客户端集群时需要修改的TransportConnector属性

AMQ_SCHEDULED_DELAY false 消息延迟发送的延迟时间(单位毫秒)
AMQ_SCHEDULED_PERIOD false 代理启动后,发送消息之前的等待时间(单位毫秒)
AMQ_SCHEDULED_REPEAT false 调度消息发送的重复次数
AMQ_SCHEDULED_CRON  String 使用一个cron实体设置消息发送调度

To have a message wait for a period of time before its delivered, you only need to setthe AMQ_SCHEDULED_DELAY property. Suppose you want to publish a message fromyour client, but have it actually delivered in 5 minutes time. You’d need to do somethinglike the following in your client code:

  MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long delayTime = 5 * 60 * 1000;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delayTime);
producer.send(message);

ActiveMQ will store the message persistently in the broker, and when it’s scheduled, itwill deliver it to its destination. This is important, because although you’ve specifiedthat you want the message to be delivered in 5 minutes time, if the destination is aqueue, it will be posted to the end of the queue. So the actual delivery time will bedependent on how many messages already exist on the queue awaiting delivery.

You can also use a the AMQ_SCHEDULED_PERIOD and AMQ_SCHEDULED_REPEAT propertiesto have messages delivered at a fixed rate. The following example will send a message100 times, every 30 seconds:

  MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long delay = 30 * 1000;
long period = 30 * 1000;
int repeat = 99;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT,COUNT repeat);
producer.send(message);

Note that we specified the repeat as being 99, as the first message + 99 = 100. If youschedule a message to be sent once, the message ID will be the same as the one youpublished. If you schedule a repeat, or use the AMQ_SCHEDULED_CRON property toschedule your message, then ActiveMQ will create a unique message ID for the deliveredmessage.

Cron is a well-known job scheduler on Unix systems, and it uses an expressionstring to denote when a job should be scheduled. ActiveMQ uses the same syntax, asdescribed next:

Cron是Unix系统中任务调度器,它使用一个字符串来表示一个任务何时需要被执行.ActiveMQ使用同样的预防,如下文本描述:

.--------------------     minute (0 - 59)
|  .-----------------     hour (0 - 23)
|  |  .--------------     day of month (1 - 31)
|  |  |  .-----------     month (1 - 12) - 1 = January
|  |  |  |  .--------     day of week (0 - 7) (Sunday=0 or 7
|  |  |  |  |
*  *  *  *  *


For example, if you want to schedule a message to be delivered at 2 a.m. on the twelfthday of every month, you’d need to do the following:

  MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON,"0 2 12 * *");
producer.send(message);

You can combine scheduling with cron and a simple delay and repeat, but the cronentry will always take precedence. For example, instead of sending one message at 2a.m. on the twelfth day of every month, you may want to schedule 10 messages to bedelivered every 30 seconds:

  long delay = 30 * 1000;
long period = 30 * 1000;
int repeat = 9;
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON,"0 2 12 * *");
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT,COUNT repeat);
producer.send(message);

In this section we’ve looked at how to schedule messages for sometime in the futureusing ActiveMQ. You should now be able to send messages after a delay, send multipleinstances of the same message at regular intervals, and use a cron entry to schedulemessage delivery.

微信赞赏  支付宝赞赏