NATS持久消息Java客户端

时间:2016-09-09 22:47:16

标签: java message-queue nats-streaming-server

有没有人有使用NATS Streaming Server和Java客户端的经验?具体来说,我无法弄清楚如何在订阅者离线时使用Java客户端检索消息。

我可以看到使用Go client我可以发布消息,然后添加订阅以检索所有已发布的消息。这是在NATS Streaming Getting Started文档中,它的工作方式与广告一样。

  

发布多条消息。对于每个出版物,你应该得到一个   结果

$ cd $GOPATH/src/github.com/nats-io/go-nats-streaming/examples
go run stan-pub.go foo "msg one"
Published [foo] : 'msg one'
$ go run stan-pub.go foo "msg two"
Published [foo] : 'msg two'
$ go run stan-pub.go foo "msg three"
Published [foo] : 'msg three'
  

运行订户客户端。   使用--all标志接收所有已发布的消息。

$ go run stan-sub.go --all -c test-cluster -id myID foo
Connected to nats://localhost:4222 clusterID: [test-cluster] clientID: [myID]
subscribing with DeliverAllAvailable
Listening on [foo], clientID=[myID], qgroup=[] durable=[]
[#1] Received on [foo]: 'sequence:1 subject:"foo" data:"msg one" timestamp:1465962202884478817 '
[#2] Received on [foo]: 'sequence:2 subject:"foo" data:"msg two" timestamp:1465962208545003897 '
[#3] Received on [foo]: 'sequence:3 subject:"foo" data:"msg three" timestamp:1465962215567601196

我尝试使用NATS Java client执行此操作。我无法弄清楚我是否发现了类似的方法调用,或者Java客户端中是否存在该功能。

这是我尝试过的事情

    import io.nats.client.Connection;
import io.nats.client.ConnectionFactory;
import io.nats.client.Constants;
import io.nats.client.Message;
import io.nats.client.SyncSubscription;

import java.io.IOException;
import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class NatsTest2 {

  private static final SecureRandom random = new SecureRandom();

  public static void main(String... args) throws Exception {
    final ConnectionFactory factory = new ConnectionFactory(Constants.DEFAULT_URL);
    try (final Connection conn = factory.createConnection()) {
      // Simple Async Subscriber
      final String expectMessage = "Yum, cookies " + System.currentTimeMillis();
      works(conn, expectMessage);
      broken(conn, expectMessage);
    }
  }

  private static void works(Connection conn, String expectMessage) throws IOException, TimeoutException {
    final String queue = Long.toString(random.nextLong());
    System.out.print(queue + "=>");
    try (final SyncSubscription subscription = conn.subscribeSync(queue)) {
      conn.publish(queue, expectMessage.getBytes());
      subscribe(subscription);
    }
  }

  private static void broken(Connection conn, String expectMessage) throws IOException, TimeoutException {
    final String queue = Long.toString(random.nextLong());
    System.out.print(queue + "=>");
    conn.publish(queue, expectMessage.getBytes());
    try (final SyncSubscription subscription = conn.subscribeSync(queue)) {
      subscribe(subscription);
    }
  }

  private static void subscribe(SyncSubscription subscription) throws IOException, TimeoutException {
    final Message message = subscription.nextMessage(1, TimeUnit.SECONDS);
    System.out.println(new String(message.getData()));
  }
}

这给出了输出

-8522002637987832314=>Yum, cookies 1473462495040
-3024385525006291780=>Exception in thread "main" java.util.concurrent.TimeoutException: Channel timed out waiting for items

1 个答案:

答案 0 :(得分:1)

如果您使用的是nats-streaming-server,则需要使用java-nats-streaming客户端。您正在寻找的功能(订阅历史消息)仅存在于该客户端中。

无论如何,这就是为什么你看到你对jnats客户端所做的事情:

nats-streaming-server当前嵌入了一个NATS服务器(gnatsd),因此可以为常规NATS客户端提供标准NATS功能,这就是您所看到的。

在您的示例代码中,works()恰好起作用,因为您的订阅已在您发布消息之前创建(换句话说,您的try-with-resources块确保订阅在其他任何事情发生之前已经处于活动状态) 。因此,您并没有真正收到过去发布的消息;您收到订阅开始后发布的消息。

broken()示例有效,因为它实际 在创建订阅之前发布消息,并且服务器会丢弃该消息,因为没有兴趣(还)。