RabbitMq instance of message component implemented by cross-process call

We all know that it is impossible to complete everything in one method to complete a module. It is necessary to divide and refine the code according to various dimensions to ensure the loose coupling of the system. For example, the template pattern in the design pattern reflects this, since it is Independent modules, then you need to call the methods of other classes or interfaces to complete what you need to do.
Figure 1:

write picture description here

The above picture shows that the method of one class needs to call the method called call in another class, and it is very simple to receive the return result, because they are both in the same process space, and both classes are the same Java virtual machine instance and both help us parse it. , just call it. But what if it's not in the same process space? Can we still achieve the effect we want? Obviously not.

Figure 2:

write picture description here

Because the two classes are in different process spaces, we can't call them as easily as before, so what should we do? Many people may think of the popular microservices. Indeed, microservices can perfectly solve the problem of distributing cross-process services in different applications.

In today's Internet-dominated environment, distributed systems have been widely accepted and used, various distributed architectures are emerging one after another, and technologies supporting various microservices and SOA architectures have emerged as the times require. From the original Spring Cloud to the popular Alibaba open source framework Dubbo, it clearly illustrates the importance of distributed systems.

But what I want to say now is not a distributed service framework, but a message service component - RabbitMQ

The above problems can also be solved through the message component method. Let me combine an example to illustrate how to use rabbitMq. It is an entry, haha.

Go directly to the code to solve all problems-_-
Import the required maven dependencies, and by the way, the spring and junit packages are also introduced to run the unit test
pom.xml

<properties>
      <spring.version>3.2.8.RELEASE</spring.version>
      <logback.version>1.1.5</logback.version>
      <tomcat.version>7.0.81</tomcat.version>
</properties>
<dependencies>
       <dependency>
           <groupId>com.rabbitmq</groupId>
           <artifactId>amqp-client</artifactId>
           <version>4.0.2</version>
       </dependency>
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>fastjson</artifactId>
           <version>1.2.24</version>
       </dependency>

    <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.0.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.0.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-servlet-api</artifactId>
            <version>${tomcat.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
   </dependencies>

Because it is integrated with spring, rabbitmq.xml is introduced

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/rabbit
           http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <rabbit:connection-factory id="connectionFactory" username="test" password="test" host="192.168.xxx.xxx" port="5672"/>

    <rabbit:template id="programTemplate" connection-factory="connectionFactory" exchange="program.direct.exchange"/>

    <rabbit:admin connection-factory="connectionFactory"/>

    <rabbit:queue name="program.erland.queue" durable="true" auto-delete="false" exclusive="false">
        <rabbit:queue-arguments>
            <entry key="x-message-ttl">
                <value type="java.lang.Long">60000</value>
            </entry>
        </rabbit:queue-arguments>
    </rabbit:queue>
    <rabbit:queue name="program.java.queue" durable="true" auto-delete="false" exclusive="false">
    </rabbit:queue>

    <rabbit:direct-exchange name="program.direct.exchange" durable="true" auto-delete="false">
        <rabbit:bindings>
            <rabbit:binding queue="program.erland.queue" key="erland"></rabbit:binding>
            <rabbit:binding queue="program.java.queue" key="java"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>

    <bean id="javaListener" class="rabbitmq.spring.listener.JavaListener"></bean>
    <bean id="erlandListener" class="rabbitmq.spring.listener.ErlandListener"></bean>
    <bean id="javaProducer" class="rabbitmq.spring.producer.JavaProducer"></bean>
    <bean id="erlandProducer" class="rabbitmq.spring.producer.ErlandProducer"></bean>

    <rabbit:listener-container
            connection-factory="connectionFactory"
            acknowledge="manual"
            concurrency="20"
            max-concurrency="50"
            requeue-rejected="false">
        <rabbit:listener ref="javaListener" queue-names="program.java.queue"/>
        <rabbit:listener ref="erlandListener" queue-names="program.erland.queue"/>
    </rabbit:listener-container>


</beans>

applicationContext-test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--<context:component-scan base-package="rabbitmq.spring"></context:component-scan>-->

    <import resource="classpath*:rabbit-mq.xml"/>
</beans>

Producer
Producer

public abstract class Producer {
    @Resource(name = "programTemplate")
    AmqpTemplate amqpTemplate;

    protected abstract String routeKey();

    public void produce(Programmer log) {
        try {
            Message message = MessageBuilder.withBody(JSON.toJSONString(log).getBytes())
                    .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .setMessageId(UUID.randomUUID().toString())
                    .build();
            amqpTemplate.convertAndSend(routeKey(), message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

JavaProducer

@Component
    public class JavaProducer extends Producer {
    @Override
    protected String routeKey() {
        return "java";
    }
}

UML graphics
write picture description here

It's not enough to monitor, get it in
one go ProgramListener

public abstract class ProgramListener implements ChannelAwareMessageListener {
    final Logger logger = LoggerFactory.getLogger(this.getClass());

    public void onMessage(Message message, Channel channel) throws Exception {
        try {
            logger.info("Receive message, message body -> {}",  new String(message.getBody()));
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        } catch (Exception e) {
            logger.error("exception", e);
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
        }
    }
}

JavaListener

public class JavaListener extends ProgramListener {
}

At this point, the configuration and monitoring of rabbitmq has been completed. The configuration adopts the direct mode in rabbitmq.

Write a unit test to verify

RabbitMqMain

package com;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import rabbitmq.spring.entity.Programmer;
import rabbitmq.spring.producer.JavaProducer;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext-test.xml")
//@TestExecutionListeners({/*ServletTestExecutionListener.class, */DependencyInjectionTestExecutionListener.class/*,
//      DirtiesContextTestExecutionListener.class*/})
public class RabbitMqMain {

    @Autowired
    JavaProducer javaProducer;

    @Test
    public void testSend() {
        Programmer programmer = new Programmer();
        programmer.setMessage("i am java, do u know me?");
        javaProducer.produce(programmer);
    }
}

write picture description here

Can run normally.
Attach the rabbitmq console information:
write picture description here

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324646473&siteId=291194637