Maison  >  Article  >  Connexion au courtier ActiveMQ Artemis intégrée à Spring Boot

Connexion au courtier ActiveMQ Artemis intégrée à Spring Boot

WBOY
WBOYavant
2024-02-11 13:39:08817parcourir

L'éditeur php Banana vous présente la connexion proxy ActiveMQ Artemis intégrée à Spring Boot. ActiveMQ Artemis est un courtier de messages évolutif et hautes performances, souvent utilisé pour créer des systèmes de messagerie fiables. Spring Boot fournit un moyen simple et pratique d'intégrer ActiveMQ Artemis. Grâce à des connexions intégrées, nous pouvons utiliser ActiveMQ Artemis directement dans les applications Spring Boot sans configuration ni déploiement supplémentaires. Cette méthode de connexion simplifie non seulement le processus de développement, mais offre également des performances et une fiabilité supérieures, rendant la livraison des messages plus efficace et plus stable. Que vous développiez des applications en temps réel, des files d'attente de messages ou des communications asynchrones, la connexion au courtier ActiveMQ Artemis intégrée à Spring Boot est une option qui mérite d'être explorée.

Contenu de la question

J'ai une application Spring Boot 2.7.6 activemq artemis très simple qui écoute les messages.

package hello;

import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.context.annotation.bean;
import org.springframework.jms.annotation.jmslistener;
import org.springframework.jms.annotation.enablejms;
import org.springframework.jms.config.defaultjmslistenercontainerfactory;
import org.springframework.boot.autoconfigure.jms.defaultjmslistenercontainerfactoryconfigurer;
import javax.jms.connectionfactory;
import org.springframework.jms.config.jmslistenercontainerfactory;

@springbootapplication
@enablejms
public class application {

    @bean
    public jmslistenercontainerfactory<?> myfactory(connectionfactory connectionfactory,
                            defaultjmslistenercontainerfactoryconfigurer configurer) {
      defaultjmslistenercontainerfactory factory = new defaultjmslistenercontainerfactory();
      // this provides all auto-configured defaults to this factory, including the message converter
      configurer.configure(factory, connectionfactory);
      // you could still override some settings if necessary.
      return factory;
    }

    public static void main(string[] args) {
       springapplication.run(application.class, args);
    }

    @jmslistener(destination = "my-queue-1")
    public void listen(string in) {
       system.out.println(in);
    }
}

C'est le code pour configurer le proxy intégré. Je suppose juste en ajoutant plusieurs récepteurs. Différents articles ont fait référence à addconnectorconfiguration, mais jusqu'à présent aucun ne semble fonctionner.

package hello;

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.addacceptorconfiguration("remote", "tcp://0.0.0.0:61616");
    }
}

Par ce simple application.properties :

spring.artemis.mode=embedded
spring.artemis.embedded.server-id=54321
spring.artemis.embedded.queues=my-queue-1
spring.artemis.embedded.enabled=true

Ensuite, j'ai une autre application Spring Boot qui génère des messages et les envoie à l'adresse proxy.

package broker.producer;

import org.apache.activemq.artemis.jms.client.activemqconnectionfactory;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.beans.factory.annotation.value;
import org.springframework.context.annotation.bean;
import org.springframework.jms.core.jmstemplate;
import org.springframework.jms.support.destination.jndidestinationresolver;
import org.springframework.stereotype.service;

@service
public class jmsproducer {

  @value("${spring.jms.template.default-destination}")
  private string defaultdestination;

  logger log = loggerfactory.getlogger(jmsproducer.class);

  @bean
  public activemqconnectionfactory activemqconnectionfactory() {
      activemqconnectionfactory activemqconnectionfactory = new activemqconnectionfactory("tcp://localhost:61616");

      return activemqconnectionfactory;
  }

  @bean
  public jndidestinationresolver jndidestinationresolver() {
    return new jndidestinationresolver();
  }

  @bean
  public jmstemplate jmstemplate() {
    jmstemplate template = new jmstemplate();
    template.setconnectionfactory(activemqconnectionfactory());
    template.setpubsubdomain(false); // false for a queue, true for a topic
    template.setdefaultdestinationname(defaultdestination);

    return template;
  }


  public void send(string message) {
    jmstemplate jmstemplate = jmstemplate();

    log.info("sending message='{}'", message);
    jmstemplate.convertandsend(message);
    log.info("sent message='{}'", message);
  }
}

Ensuite je démarre chaque application et j'essaie d'appeler la méthode send, mais je n'arrive pas à me connecter au courtier depuis l'application productrice à cause de cette erreur :

2024-01-16 10:25:00.596 ERROR 30486 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Failed to create session factory; nested exception is ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]] with root cause

L'application producteur est capable de se connecter très bien à l'instance docker d'activemq artemis.

Actuellement, les deux applications s'exécutent sur la même machine, mais en production, j'aimerais que chaque application s'exécute dans un pod séparé.

Solution de contournement

J'ai mis en place un projet très simple comme preuve de concept pour m'assurer que ce que vous faites est possible et que tout fonctionne bien pour moi. L'agent intégré est démarré et accepte les connexions des clients distants sur le port 61616.

C'est application.java :

package hello;

import javax.jms.connectionfactory;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.boot.autoconfigure.jms.defaultjmslistenercontainerfactoryconfigurer;
import org.springframework.context.annotation.bean;
import org.springframework.jms.annotation.enablejms;
import org.springframework.jms.annotation.jmslistener;
import org.springframework.jms.config.defaultjmslistenercontainerfactory;
import org.springframework.jms.config.jmslistenercontainerfactory;

@springbootapplication
@enablejms
public class application {

    @bean
    public jmslistenercontainerfactory<?> myfactory(connectionfactory connectionfactory,
                                                                    defaultjmslistenercontainerfactoryconfigurer configurer) {
        defaultjmslistenercontainerfactory factory = new defaultjmslistenercontainerfactory();
        // this provides all auto-configured defaults to this factory, including the message converter
        configurer.configure(factory, connectionfactory);
        // you could still override some settings if necessary.
        return factory;
    }

    public static void main(string[] args) {
        springapplication.run(application.class, args);
    }

    @jmslistener(destination = "my-queue-1")
    public void listen(string in) {
        system.out.println(in);
    }
}

C'est artemisconfig.java :

package hello;

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) {
       try {
          configuration.addacceptorconfiguration("remote", "tcp://0.0.0.0:61616");
       } catch (exception e) {
          e.printstacktrace();
       }
    }
}

C'est à moi application.properties :

spring.artemis.mode=embedded
spring.artemis.embedded.server-id=54321
spring.artemis.embedded.queues=my-queue-1
spring.artemis.embedded.enabled=true

Enfin, c'est le mien pom.xml :

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelversion>4.0.0</modelversion>
   <parent>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-parent</artifactid>
      <version>2.7.6</version>
      <relativepath/>
   </parent>
   <groupid>com.example</groupid>
   <artifactid>spring-boot-customized-activemq-artemis</artifactid>
   <version>0.0.1-snapshot</version>
   <properties>
      <java.version>17</java.version>
      <spring.version>2.7.6</spring.version>
      <activemq.artemis.version>2.19.1</activemq.artemis.version>
   </properties>

   <dependencies>
      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-artemis</artifactid>
      </dependency>
      <dependency>
         <groupid>org.apache.activemq</groupid>
         <artifactid>artemis-jms-server</artifactid>
     <version>${activemq.artemis.version}</version>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-maven-plugin</artifactid>
        <version>${spring.version}</version>
         </plugin>
      </plugins>
   </build>
</project>

Je lance l'application comme ceci :

mvn spring-boot:run

Je vois des enregistrements de journal comme celui-ci :

...
... AMQ221020: Started EPOLL Acceptor at 0.0.0.0:61616 for protocols [CORE]
... AMQ221007: Server is now live
...

Je peux envoyer un message à l'agent depuis une autre application et jmslistener le message est reçu.

J'ai téléchargé le projet sur github.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer