Spring boot Artemis 嵌入式代理行为

Posted

技术标签:

【中文标题】Spring boot Artemis 嵌入式代理行为【英文标题】:Spring boot Artemis embedded broker behaviour 【发布时间】:2017-02-08 23:54:24 【问题描述】:

早上好,

我最近一直在努力使用 spring-boot-artemis-starter。 我对其 spring-boot 支持的理解如下:

设置spring.artemis.mode=embedded 和tomcat 一样,spring-boot 将实例化一个可通过tcp(服务器模式)访问的代理。以下命令应该成功:nc -zv localhost 61616 设置spring.artmis.mode=native,spring-boot只会根据spring.artemis.*属性(客户端模式)配置jms模板。

客户端模式与我机器上的独立 artemis 服务器一起工作得很好。 不幸的是,我无法在服务器模式下访问 tcp 端口。

如果有人确认我对嵌入式模式的理解,我将不胜感激。

感谢您的游览帮助

经过一番挖掘,我注意到 spring-boot-starter-artemis 提供的开箱即用的实现使用org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory 接受器。我想知道这是否不是根本原因(同样我绝不是专家)。 但似乎有一种方法可以自定义 artemis 配置。 因此,我尝试了以下配置,但没有任何运气:

@SpringBootApplication
public class MyBroker 

    public static void main(String[] args) throws Exception 
        SpringApplication.run(MyBroker.class, args);
    

    @Autowired
    private ArtemisProperties artemisProperties;

    @Bean
    public ArtemisConfigurationCustomizer artemisConfigurationCustomizer() 
        return configuration -> 
            try 
               configuration.addAcceptorConfiguration("netty", "tcp://localhost:" + artemisProperties.getPort());
             catch (Exception e) 
                throw new RuntimeException("Failed to add netty transport acceptor to artemis instance");
            
        ;
    


【问题讨论】:

【参考方案1】:

您只需在 Artemis 配置中添加一个连接器和一个接受器。使用 Spring Boot Artemis 启动器,Spring 创建了一个配置 bean,它将用于 EmbeddedJMS 配置。您可以在 ArtemisEmbeddedConfigurationFactory 类中看到这一点,其中将为配置设置 InVMAcceptorFactory。您可以编辑此 bean 并通过自定义 ArtemisConfigurationCustomizer bean 更改 Artemis 行为,该 bean 将被 Spring autoconfig 吸收并应用于配置。

Spring Boot 应用程序的示例配置类:

import org.apache.activemq.artemis.api.core.TransportConfiguration;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConfigurationCustomizer;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ArtemisConfig implements ArtemisConfigurationCustomizer 
    @Override
    public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) 
        configuration.addConnectorConfiguration("nettyConnector", new TransportConfiguration(NettyConnectorFactory.class.getName()));
        configuration.addAcceptorConfiguration(new TransportConfiguration(NettyAcceptorFactory.class.getName()));
    

【讨论】:

【参考方案2】:

我和我的同事遇到了与 this link (chapter Artemis Support) 上的文档完全相同的问题,没有提及添加单独的 ArtemisConfigurationCustomizer - 这很可悲,因为我们意识到如果没有这个定制器,我们的 Spring Boot 应用程序将启动并表现得好像一切正​​常但实际上它不会做任何事情。

我们还意识到,如果没有定制器,application.properties 文件将不会被加载,因此无论您在此处提到的主机或端口是什么,它都不会计算在内。

按照两个示例所述添加定制器后,它可以正常工作。

以下是我们得出的一些结果:

仅在配置 ArtemisConfigurationCustomizer 后才加载 application.properties

您不再需要使用嵌入式 Spring Boot Artemis 客户端的 broker.xml

许多使用 Artemis 的示例使用“in-vm”协议,而我们只想使用 netty tcp 协议,因此我们需要将其添加到配置中

对我来说最重要的参数是 pub-sub-domain,因为我使用的是主题而不是队列。如果您使用主题,则需要将此参数设置为 true,否则 JMSListener 将不会读取消息。

查看此页面:*** jmslistener-usage-for-publish-subscribe-topic

当使用 @JmsListener 时,它使用 DefaultMessageListenerContainer 它扩展了 JmsDestinationAccessor 默认情况下具有 pubSubDomain 设置为 false。当此属性为 false 时 在队列上操作。如果你想使用主题,你必须设置这个 属性值为 true。

In Application.properties:
spring.jms.pub-sub-domain=true

如果有人对完整示例感兴趣,我已将其上传到我的 github: https://github.com/CorDharel/SpringBootArtemisServerExample

【讨论】:

【参考方案3】:

嵌入模式将代理作为应用程序的一部分启动。这种设置没有可用的网络协议,只允许 InVM 调用。自动配置exposes the necessary pieces you can tune 虽然我不确定你是否真的可以在嵌入式模式下拥有一个 TCP/IP 通道。

【讨论】:

谢谢@Sephane Nicoll。这一定是有原因的。它不能解决我的用例,但我会处理它。 明确地说,我是 Spring Boot 团队的成员,如果有意义的话,我很高兴重新审视这个用例。我只是不确定现在是否可以。如果您想从外部(通过 TCP/IP)访问代理,则不应将其嵌入 IMO。 对我来说,它与 Web 容器的用例相同。我选择 spring-boot 是因为它为 Web 容器提供了生产就绪功能。如果我想为我的代理提供相同的功能怎么办:我用 spring-boot 封装它,瞧。我受益于所有不错的功能,包括 linux 服务支持、健康检查等。此外,无需开发人员在其机器上安装和配置它,它已经提供。无论如何,我回滚到 activemq,它提供了一种启动 tcp 代理并在我的 IT 测试中用 spring boot 封装它的方法。现在所有 IT 组件都以相同的方式启动:java -jar ... 我不同意。您是否正在使用 H2 嵌入式数据库进行生产? JMS 代理旨在由生产中具有高可用性的多个组件访问。我想 Artemis 没有像 ActiveMQ 那样公开该功能是有原因的…… 链接失效

以上是关于Spring boot Artemis 嵌入式代理行为的主要内容,如果未能解决你的问题,请参考以下文章

如何使用嵌入式 ActiveMQ Artemis 为 Spring Boot 配置 max-delivery-attempts?

使用 Spring Boot 对 Artemis Cluster 进行持久订阅

ActiveMQ Artemis 前缀为“jms.topic”。到 Spring Boot Client 上定义的所有主题名称

如何使用 Spring Boot 配置嵌入式 ActiveMQ 代理 URL

在 Apache SSL 代理后面嵌入 Tomcat 的 Spring Boot

Apache ActiveMQ Artemis简介