国外服务器低延迟网站访问springboot高防服务器整合ActiveMQ

  1. 12 月前

    国外服务器低延迟网站访问springboot高防服务器整合ActiveMQ
    服务器咨询敏敏QQ:2853898501 / 3007425289 电话微信:18316411879

    前随着微服务以及分布式的发展,消息中间件的作用越来越大了。消息中间件可以起到系统之间解耦的作用,比如用户进行购买商品,有加入购物车操作,还有下单操作以及支付操作等。在微服务的情况下,这些将是不同的服务,有可能部署在不同的容器中,因此,这个购买操作存在各个系统之间的调用关系。其中支付之后会有支付信息,以及物流等信息反馈给用户。但是如果在一个串行调用的系统中则是非常不合理的。对于用户来说支付信息和物流信息等延迟几秒基本是无感的。因此,这里会使用消息中间件,这里支付系统会生产一个支付结果的消息,然后结果反馈(短信、应用程序通知)系统和物流系统则会订阅这个消息。支付系统支付完成之后则会处理下一个订单,不在关心该订单的后续情况,结果反馈系统和物流系统则会监听到这个支付结果,并进行该订单的后续处理。从上可以看出,消息中间件解耦了支付系统和结果反馈系统以及物流系统。常见的消息中间件有:kafka、ActiveMQ、RabbitMQ。消息中间件主要有以下特点:
    电商1.png
    (1).异步处理

    (2).应用解耦

    (3).流量削峰

             本文通过介绍Springboot整合ActiveMQ的项目示例来介绍消息中间件的作用,以及ActiveMQ的特性。

    1.介绍ActiveMQ
             ActiveMQ中消息的两种角色:消息生产者和消息消费者。简而言之,消息生产者负责发送消息,而消息消费者则会处理消息。 

            ActiveMQ具有两种模式:点对点模式(Queue)和发布订阅模式(Topic)。其中点对点模式是指某一条产生的消息只能被一个消息消费者消费,即消息与消费者是一对一的关系。而发布订阅模式则有一个Topic,可以被所有监听它的消费者消费。

    2.两种模式的示例
    2.1点对点模式
            1.pom文件

    <?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.1.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.carson</groupId>
    <artifactId>activemq-producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activemq-producer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
    <java.version>1.8</java.version>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>

    <dependency>
    <groupId>org.messaginghub</groupId>
    <artifactId>pooled-jms</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
    <exclusion>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.0.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-test</artifactId>
    <version>2.2.0.RELEASE</version>
    <scope>test</scope>
    </dependency>
    </dependencies>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>
    springboot整合activemq的依赖如下所示(springboot版本为2.1及其以上)

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>

    <dependency>
    <groupId>org.messaginghub</groupId>
    <artifactId>pooled-jms</artifactId>
    </dependency>
    2.设置一个常量类,Constant

    public class Constant {

    public static final String QUEUEMESSAGE="queue";

    public static final String TOPICMESSAGE="topic";

    }
    3.消息生产类Producer

    @RestController
    public class Producer {

    @Autowired
    private JmsMessagingTemplate jmsMessageingTemplate;

    @Autowired
    private Queue queue;

    @Autowired
    private Topic topic;

    @RequestMapping(";/sendMessage/{msg}")
    public void sendMessage(@PathVariable("msg") String msg){
    this.jmsMessageingTemplate.convertAndSend(queue,msg);
    }
    @RequestMapping(";/sendMessage1/{msg}")
    public void sendMessage1(@PathVariable("msg") String msg){
    this.jmsMessageingTemplate.convertAndSend(topic,msg);
    }
    }
    其中sendMessage方法是用于验证点对点的形式,sendMessage1用于验证topic的形式。

    4.消息消费者Consumer、Consumer1
    @Component
    public class Consumer {
    @JmsListener(destination= Constant.QUEUEMESSAGE)
    public void receiveQueue(String message) throws JMSException {
    if(null!=message){
    System.out.println("我是消费者一号,接收到的queue是:"+message);
    }else{
    System.out.print("我是消费者一号,我接收到空queue");
    }
    }
    @JmsListener(destination= Constant.TOPICMESSAGE)
    public void receiveQueue1(String message) throws JMSException {
    if(null!=message){
    System.out.println("我是消费者一号,接收到的topic是:"+message);
    }else{
    System.out.print("我是消费者一号,我接收到空topic");
    }
    }
    }
    @Component
    public class Consumer1 {

    @JmsListener(destination= Constant.QUEUEMESSAGE)
    public void receiveQueue(String message) throws JMSException {
    if(null!=message){
    System.out.println("我是消费者二号,接收到的queue是:"+message);
    }else{
    System.out.print("我是消费者二号,我接收到空queue");
    }
    }
    @JmsListener(destination= Constant.TOPICMESSAGE)
    public void receiveQueue1(String message) throws JMSException {
    if(null!=message){
    System.out.println("我是消费者二号,接收到的topic是:"+message);
    }else{
    System.out.print("我是消费者二号,我接收到空topic");
    }
    }
    }
    @Component注解表示该类作为组件注入到容器中。

    5.application.properties

    server.port=8089
    spring.activemq.broker-url=tcp://127.0.0.1:61616

    # 在考虑结束之前等待的时间
    #spring.activemq.close-timeout=15s
    # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
    spring.activemq.in-memory=true
    # 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留。
    spring.activemq.non-blocking-redelivery=false
    # 等待消息发送响应的时间。设置为0等待永远。
    #spring.activemq.send-timeout=1
    #默认情况下activemq提供的是queue模式,若要使用topic模式需要配置下面配置
    #账号
    spring.activemq.user=admin
    # 密码
    spring.activemq.password=admin
    6.启动类

    @SpringBootApplication
    public class ActivemqApplication {

    @Bean
    public Queue queue(){
    return new ActiveMQQueue(Constant.QUEUEMESSAGE);
    }
    @Bean
    public Topic topic(){
    return new ActiveMQTopic(Constant.TOPICMESSAGE);
    }
    public static void main(String[] args) {
    SpringApplication.run(ActivemqApplication.class, args);
    }
    }
     queue()、topic()方法分别表示注册点对点的queue和topic。

    7.启动项目
    结果如下:

    我是消费者一号,接收到的queue是:12345
    说明queue模式生产的消息只会对应一个消费者。

    2.2发布订阅模式
    server.port=8089
    spring.activemq.broker-url=tcp://127.0.0.1:61616

    # 在考虑结束之前等待的时间
    #spring.activemq.close-timeout=15s
    # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
    spring.activemq.in-memory=true
    # 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留。
    spring.activemq.non-blocking-redelivery=false
    # 等待消息发送响应的时间。设置为0等待永远。
    #spring.activemq.send-timeout=1
    #默认情况下activemq提供的是queue模式,若要使用topic模式需要配置下面配置
    spring.jms.pub-sub-domain=true
    #账号
    spring.activemq.user=admin
    # 密码
    spring.activemq.password=admin
    发布订阅模式只需要在原有基础上将application.properties修改为如上所示,

    spring.jms.pub-sub-domain=true表示开启了topic模式。

    启动项目,并用postman调用http://127.0.0.1:8089/sendMessage1/123,结果如下:

    我是消费者一号,接收到的topic是:123
    我是消费者二号,接收到的topic是:123
    运行结果说明,两个消费者都消费topic。 说明topic模式表示一个消费对应所有的消费者。

 

或者 注册后参与话题.