【问题标题】:Connection Azure service bus via Java client通过 Java 客户端连接 Azure 服务总线
【发布时间】:2016-10-27 22:45:57
【问题描述】:

我正在尝试使用 AMQP 协议从 Java 客户端连接 Azure 服务总线

我按照以下链接中的说明进行操作:
http://azure.microsoft.com/en-us/documentation/articles/service-bus-java-how-to-use-jms-api-amqp/

1) 在 Azure 门户中使用名称空间“availo”和名为“queue1”的队列创建服务总线
2) 从服务总线连接信息中,我得到以下信息:

SharedAccessKeyName=RootManageSharedAccessKey
SharedAccessKey={key}

3) 为 JNDI 查找创建了“servicebus.properties”文件

   connectionfactory.SBCF = amqps://RootManageSharedAccessKey:encoded(key)@availo.servicebus.windows.net
   queue.QUEUE = queue1

4) 下面是我的简单 java 主应用程序,在类路径中包含所有必需的 jars (qpid)。

  public static void main(String[] args) {

    try {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory");
        env.put(Context.PROVIDER_URL,
                "C:\\Users\\Assaf-PC\\Documents\\GitHub\\availo\\rest-api\\src\\main\\resources\\servicebus.properties");
        Context context = new InitialContext(env);
        // Lookup ConnectionFactory and Queue
        ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF");
        Destination queue = (Destination) context.lookup("QUEUE");
        // Create Connection
        Connection connection = cf.createConnection();
        // Create sender-side Session and MessageProducer
        Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = sendSession.createProducer(queue);
    } catch (Exception e) {
        e.getLocalizedMessage();
    }

}

当我运行程序时,我在代码行中收到以下异常:

    MessageProducer producer = sendSession.createProducer(queue);

例外:

Exception in thread "main" javax.jms.JMSException: Peer did not create remote endpoint for link, target: queue1
at org.apache.qpid.amqp_1_0.jms.impl.MessageProducerImpl.<init>(MessageProducerImpl.java:98)
at org.apache.qpid.amqp_1_0.jms.impl.SessionImpl.createProducer(SessionImpl.java:390)
at org.apache.qpid.amqp_1_0.jms.impl.SessionImpl.createProducer(SessionImpl.java:59)
at availo.rest.services.ServiceBus.main(ServiceBus.java:43)
  Caused by: org.apache.qpid.amqp_1_0.client.Sender$SenderCreationException: Peer did not create    remote endpoint for link, target: queue1
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:191)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:119)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:112)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:98)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:84)
at org.apache.qpid.amqp_1_0.client.Sender.<init>(Sender.java:78)
at org.apache.qpid.amqp_1_0.client.Session$1.<init>(Session.java:90)
at org.apache.qpid.amqp_1_0.client.Session.createSender(Session.java:89)
at org.apache.qpid.amqp_1_0.jms.impl.MessageProducerImpl.<init>(MessageProducerImpl.java:86)
... 3 more

浪费了很多时间来了解我在没有成功的情况下做错了什么,有人可以帮忙吗?
非常感谢您的回答。

【问题讨论】:

  • 你能解决这个问题吗?如果可以分享,解决方案是什么??

标签: java azure jndi amqp azureservicebus


【解决方案1】:

确保您的队列没有启用分区。 ServiceBus 不支持带有分区队列的 AMQP,但是创建队列时默认启用分区。

我遇到了同样的错误,重新创建队列时未选中“启用分区”解决了它。

请参阅本文底部的分区实体限制部分:https://msdn.microsoft.com/en-us/library/azure/dn520246.aspx

分区队列和主题只能通过 SBMP 或 HTTP/HTTPS 使用。将来会添加 AMQP 支持。

【讨论】:

【解决方案2】:

此答案适用于像我这样的 Service Bus 初学者。

第一件事是为 AMQP 设置未分区队列/主题,因为不支持分区,就像其他答案所说的那样。从 Azure 门户创建队列时,我们需要取消选中“启用分区”。默认情况下,实体通过服务总线中的分区启用。

谈到这个问题,当我尝试将 Java 客户端用作队列的侦听器时,我遇到了同样的问题,它使用带有 AMQP 的 JMS 的 Qpid 实现,如 example 中所示。问题是,即使 ServiceBus 在 Azure 门户中,队列也没有配置。

如果您计划使用不同的 policyNames 来发送/收听队列(查看 this 是否有帮助),请确保您已使用正确的权限和策略名称向门户中的队列添加正确的配置。 QUEUE NOT SERVICE BUS 的 policyName 是用于 SAS 身份验证的名称,相当于 ACS 中的用户名,主/次键相当于 config(servicebus.properties) 文件中 ACS 中的密码。

先尝试使用主键。如果您收到身份验证错误,那么您可以尝试使用辅助密钥。如果键中有特殊字符,例如我转发了斜杠(/),请将其替换为相应的 UTF-8 值。所以我不得不在配置文件中使用 %2F 替换键中的 /。

这解决了我的问题。希望这会有所帮助!

PTR(PointsToRemember):

  1. 不建议像在当前用例中那样使用从代码创建来用于 AMQP。当您使用服务总线 Java API 从代码创建队列时,它是在启用分区的情况下创建的,并且没有为队列创建端点。所以,你最终会遇到两个例外,

    -- 没有创建端点,就像在这个上下文的问题中一样。

    --一旦您进入门户网站,在门户网站和配置文件中对其进行配置,然后您会得到“分区实体不支持 AMQP”(您已经知道了!)。因此,您必须返回并再次在门户中创建一个队列,禁用分区并对其进行配置。有点双重工作..所以最好使用为 AMQP 创建和配置的队列。

  2. 如果主键/辅助键中有特殊字符,请尝试重新生成它们,而不是使用它们并将特殊字符替换为配置文件中相应的 UTF-8。

【讨论】:

    【解决方案3】:

    据我所知,用户名/发行人名称不合适。

    amqps://RootManageSharedAccessKey:encoded(key)@availo.servicebus.windows.net
    

    应该是:

    amqps://owner:encoded(key)@availo.servicebus.windows.net
    

    因为来自 amqp 的用户名填充了来自 sb 端点的颁发者名称,并且默认为“所有者”(请 dbl 检查您的 azure sb 的连接信息)

    希望这会有所帮助。

    问候,

    勒内

    【讨论】:

      【解决方案4】:

      提示:使用更高版本的Qpid(qpid-jms-client-0.11.1.jar)时,connectionfactory属性不同:

      connectionfactory.myFactoryLookup = connectionfactory.myFactoryLookup = amqps://example-open-bus.servicebus.windows.net?amqp.idleTimeout=150000&jms.username=somePolicy&jms.password=aM2k3PaZY5jdIkmGKm7G%2FcH%2BUFQaFAgHIYc3dSkuiLI%3D 
      

      查看其他帖子 -> How can I Send/Receive a message from Azure Service Bus from Qpid JMS (qpid-jms-client-0.11.1.jar)?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-17
        • 2017-11-22
        • 1970-01-01
        • 1970-01-01
        • 2016-08-28
        相关资源
        最近更新 更多