我正在尝试使用hornetq core-api预定消息api,以便在30秒后发送消息 队列不耐用并在hornetq配置文件中定义
val message:String ={...} //some string
val clientMessage:ClientMessage =session.createMessage(false)
clientMessage.getBodyBuffer.writeString(message)
clientMessage.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, System.currentTimeMillis() + 30000)
//expecting to deliver the message after 30 seconds
producer.send(MyQueue,clientMessage)
然而,当我查看日志时,似乎消息已发送并在同一时间到达。我应该定义其他什么吗?我错过了什么吗?
添加代码:
class HornetQMessageTest extends FunSuite with ShouldMatchers {
test("scheduleMessage") {
def createServerLocator: ServerLocator = {
var map = new java.util.HashMap[String, Object]
map.put("host", "127.0.0.1")
map.put("port", "5445")
val transConf = new TransportConfiguration(classOf[NettyConnectorFactory].getName,map)
val locator = HornetQClient.createServerLocatorWithoutHA(transConf)
locator.setConfirmationWindowSize(1024^2)//confirmationWindowSize
locator.setBlockOnDurableSend(false)
locator.setBlockOnNonDurableSend(false)
locator.setClientFailureCheckPeriod(5000) //keepAlivePing
locator.setConnectionTTL(10000) //connection TTL
locator
}
val serverLocator: ServerLocator = createServerLocator
val sessionFactory: ClientSessionFactory = serverLocator.createSessionFactory()
val receiverSession = sessionFactory.createSession(true, true, 0)
val senderSession =sessionFactory.createSession(true, true, 0)
val queue = "atestq"
def closeHorentQClient() {
receiverSession.close()
senderSession.close()
sessionFactory.close()
serverLocator.close()
}
senderSession should not be null
receiverSession should not be null
val query: QueueQuery = senderSession.queueQuery(new SimpleString(queue))
if (query == null || !query.isExists) senderSession.createQueue(queue,queue,false)
val producer: ClientProducer = senderSession.createProducer(queue)
val message = senderSession.createMessage(false)
message.getBodyBuffer().writeString("This is my string........")
val deliverytime = System.currentTimeMillis() + 30000
message.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, deliverytime)
println("Message Sent "+deliverytime)
senderSession.start()
producer.send(message)
receiverSession.start()
val consumer = receiverSession.createConsumer(queue)
val message2 = consumer.receive(50000)
val messageBody = message2.getBodyBuffer().readString()
println("received message: "+messageBody +" after" + ((System.currentTimeMillis()-deliverytime)/1000)+" seconds ")
message2 should not be null
System.currentTimeMillis() should be >= deliverytime
assert(messageBody == "This is my string........")
message2.acknowledge()
// Make sure no more messages
closeHorentQClient()
} }
测试结果:
Message Sent 1392198959686
received message: This is my string........ after-29 seconds
1392198929758 was not greater than or equal to 1392198959686
答案 0 :(得分:1)
我们正在使用Scheduled Executor,并且使用一些操作系统... scheduler.schedule(在30秒内)在比你想象的更短的时间内调用我们的Runnable。我已经在Windows上看到过这个问题了很多。
确保您了解计划时间是基于服务器的时间(而不是客户端的时间)。将您的客户端时间与服务器同步。
我们最近在2.4.0上做了很多改进,我不认为你会再次遇到这个问题,因为我们现在验证时间,不再相信ScheduledExecutor。
如果您更新操作系统,您将不会看到此问题..它通常是实时的内核问题,并且没有等待等待。
或者,如果您可以使用不再信任此行为的2.4.0。
我已经在MAC上使用2.2.eap5尝试了这个代码而没有2.4.0上的补丁并且它有效。这几乎是你的测试转换为java。
public void testSomething() throws Exception
{
// then we create a client as normal
ClientSessionFactory sessionFactory = createSessionFactory(locator);
ClientSession receiverSession = sessionFactory.createSession(true, true, 0);
ClientSession senderSession = sessionFactory.createSession(true, true, 0);
String queue = "atestq";
ClientSession.QueueQuery query = senderSession.queueQuery(new SimpleString(queue));
if (query == null || !query.isExists()) senderSession.createQueue(queue, queue, false);
ClientProducer producer = senderSession.createProducer(queue);
ClientMessage message = senderSession.createMessage(false);
message.getBodyBuffer().writeString("This is my string........");
long original = System.currentTimeMillis();
long deliverytime = System.currentTimeMillis() + 30000;
message.putLongProperty(Message.HDR_SCHEDULED_DELIVERY_TIME, deliverytime);
System.out.println("Message Sent " + deliverytime);
senderSession.start();
producer.send(message);
receiverSession.start();
ClientConsumer consumer = receiverSession.createConsumer(queue);
ClientMessage message2 = consumer.receive(50000);
String messageBody = message2.getBodyBuffer().readString();
System.out.println("received message: " + messageBody + " after" + ((System.currentTimeMillis() - original) / 1000) + " seconds ");
assert (messageBody.equals("This is my string........"));
message2.acknowledge();
}
我刚刚在HornetQ内提出了一个功能请求。