【问题标题】:Spring boot Artemis embedded broker behaviourSpring boot Artemis 嵌入式代理行为
【发布时间】: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");
            }
        };
    }

}

【问题讨论】:

    标签: spring-boot broker activemq-artemis


    【解决方案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 将不会读取消息。

      查看此页面:stackoverflow 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 那样公开该功能是有原因的……
        • 链接失效
        猜你喜欢
        • 1970-01-01
        • 2020-08-05
        • 2021-10-30
        • 1970-01-01
        • 2016-12-09
        • 2014-10-16
        • 1970-01-01
        • 2018-05-28
        • 2013-11-23
        相关资源
        最近更新 更多