mq服务器与客户端消息同步,使用 ActiveMQ 实现JMS 异步调用

目录

简介

服务之间的同步调用,可以使用 HTTP 或 RPC 来完成,但并非所有的调用都需要同步,有些场景下,当客户端调用服务端时,并不需要等待服务端做出响应,此时就应该使用异步调用。异步调用的常用方式是基于 MQ (Message Queue) 来实现的。下文会以 ActiveMQ 为例进行讲解。

ActiveMQ 是 Java 世界中最为流行的开源消息中间件,它不仅功能强大,而且性能稳定。它可全面支持 JMS(Java 消息服务)技术规范,为 Java 应用程序提供标准的 JMS API。

此外 ActiveMQ 具备与 Spring 框架整合的能力,它一直都是 Spring 应用程序的消息中间件标配。同样, Spring Boot 也提供了 ActiveMQ 的开箱即用的插件,只需要几项配置,就能接入 ActiveMQ,并轻松使用 JMS API 编写异步消息通信程序。

Active MQ 官网地址如下

http://activemq.apache.org

启动 ActiveMQ 服务器

先使用 docker 安装 ActiveMQ ,目前 ActiveMQ 官方并未提供相应的 Docker 镜像,我们选择使用第三方镜像 webcenter/activemq 。

docker pull webcenter/activemq:5.14.3

接下来运行 ActiveMQ

docker run -d -p 8161:8161 -p 61616:61616 -e ACTIVEMQ_ADMIN_LOGIN=admin -e ACTIVEMQ_ADMIN_PASSWORD=admin --name activemq webcenter/activemq:5.14.3

在启动 ActiveMQ 容器时,容器对宿主机暴露了两个端口号:

8161: 表示 ActiveMQ 控制台端口号,可在浏览器中通过控制台来执行 ActiveMQ 的相关操作

61616: 表示 ActiveMQ 所监听的 TCP 端口号,应用程序可通过该端口号与 ActiveMQ 建立 TCP 连接,并完成后续的异步消息通信

此外,在启动 ActiveMQ 容器时,还提供了两个环境变量

ACTIVEMQ_ADMIN_LOGIN: 用于设置控制台管理员的用户名,默认为 admin

ACTIVEMQ_ADMIN_PASSWORD: 用于设置控制台管理员的密码,默认为 admin

查看控制台

webcenter/activemq 镜像拥有一个基于 Web 的控制台,可通过浏览器访问。容器启动完毕后,可以打开浏览器,并在地址栏中输入 http://localhost:8161

cc4d6fab385d3809899b3bfc71022f42.png

点击 Manage ActiveMQ borker 链接,浏览器将弹出一个对话框,此时输入用户名和密码,认证通过后会进入管理界面

2d4f6c152ba492f58877682c3fd37930.png

在管理界面中,包括 8 个功能菜单

Home: 基本信息

Queues: 管理的队列

Topics: 查看所管理的主题

Subscribers: 查看相关主题的订阅者

Connections: 查看客户端的连接信息

Network: 查看网络相关信息

Scheduled: 查看 ActiveMQ 内部运行的定时任务

Send: 通过表单方式查看向队列或主题发送具体消息

ActiveMQ 的消息通道

ActiveMQ 管理了两类消息通道,一类是队列(Queue),另一类叫做主题(Topic)。

Queue

Queue 用于解决消息的 点对点 通信问题,也就是说,消息从生产者(Producer) 发出后,首先进入 ActiveMQ 某个指定的 Queue 中,然后再将消息传送给其中一个消费者(Consumer)。

356be9eda46b191461a3bfbecf34d905.png

Topic

Topic 用于解决消息的发布与订阅(Publish-subscribe) 通信问题,也就是说,消息从 Producer 发出后,首先将其发布到 ActiveMQ 某个指定的 Topic 上,然后将此消息分发给每个订阅者(Subscriber) 。

087a388edfd91deaf78000b114af68f3.png

比较

在具体场合下,灵活使用以上两种通信模式来实现 Producer 与 Consumer/Subscriber 间的异步调用,从而解决调用方的耦合问题。可见,Queue 能解决调用缓冲问题,Topic 能解决消息广播问题, Queue 与 Topic 都能解决掉调用耦合问题,这些技术都为一个好的软件架构提供了有效的支撑。

开发生产者和消费者

下面就以 Queue 为例,将 ActiveMQ 与 Spring Boot 进行整合,将 Producer 作为客户端, Consumer 作为服务端,通过 Queue 实现客户端与服务端的异步调用

开发服务端(消费者)

首先创建一个名为 acitvemq-hello-server 的 spring boot 项目,如果在 eclipse 中安装了 Spring Tools ,可以在新建时选择 New Spring Starter Project 选项。或者新建 Maven 工程。对应的 maven 依赖如下

org.springframework.boot

spring-boot-starter-parent

1.5.19.RELEASE

org.springframework.boot

spring-boot-starter-activemq

在 Spring Boot 框架中已经内置了对 ActiveMQ 的支持,我们只需要依赖 spring-boot-starter-mq 就能启动 ActiveMQ,此时还需要在 application.properties 文件中添加 ActiveMQ 配置项

spring.activemq.broker-url=tcp://10.104.10.1:61616

spring.activemq.user=admin

spring.activemq.password=admin

接下来创建 HelloServer 的类,封装服务端相关代码

@Component

public class HelloServer {

@JmsListener(destination="hello-queue")

public void receive(String message) {

System.out.println(message);

}

}

使用 @Component 注解,说明它可被 Spring IoC 容器所管理。此时只需要使用 @JmsListener 注解,并将其绑定到 receive() 方法上,就能从 ActiveMQ 中接收响应的消息。

@JmsListener 注解中需要添加一个 destination 属性来指定 Queue/Topic 的名称,该名称具有唯一性。消息将以一个 String 类型参数的形式传入方法体中,也可以接收其他类型的消息,这取决于客户端发送的消息是哪种类型。Spring JMS 将消息放入 ActiveMQ 时会进行序列化,当消息从 ActiveMQ 取出时将进行反序列化,应用程序无需关注这些底层细节,只需要将精力放在业务逻辑上。

最后,编写一个 Spring Boot 应用程序启动类来启动服务端(使用 spring tools 工具会自动生成)

@SpringBootApplication

public class ActivemqHelloServerApplication {

public static void main(String[] args) {

SpringApplication.run(ActivemqHelloServerApplication.class, args);

}

}

当服务端启动完毕后,将一直监听 ActiveMQ 的 hello-queue 队列中即将到来的消息,消息由客户端来发送。

开发客户端(生产者)

创建一个名为 active-mq-client 的 Maven 项目, pom.xml 文件内容与服务端相似。application.properties 文件与服务端相同。

接下来创建一个名为 HelloClient 的类,将其作为客户端。

@Component

public class HelloClient {

@Autowired

private JmsTemplate jmsTemplate;

public void send(String message) {

jmsTemplate.convertAndSend("hello-queue", message);

}

}

这里使用了 @Autowired 注解, JmsTemplate 对象注入进来,还编写了一个 send() 方法,在该方法中调用 JmsTemplate 对象的 convertAndSend 来转换并发送消息。

最后使用 Spring Boot 应用程序启动类来启动客户端

@SpringBootApplication

public class ActivemqHelloClientApplication {

@Autowired

private HelloClient helloClient;

@PostConstruct

public void init() {

helloClient.send("hello world");

}

public static void main(String[] args) {

SpringApplication.run(ActivemqHelloClientApplication.class, args);

}

}

需要注意的是, init() 方法带有 @PostConstruct 注解,表示 Spring IoC 容器实例化 ActivemqHelloClientApplication 类后将调用该方法。

运行 main() 方法可以启动客户端应用程序,并可以在服务端应用程序控制台中看到 client 发送的消息,也可以在 ActiveMQ 控制台中查看队列的当前状态

4564b7200e9174cfed7c0f1e7b8fbf1d.png

Queue 表格中列明的含义如下

Name 表示队列名称,可在应用程序中自动创建,也可在 ActiveMQ 控制台中手动创建

Number Of Pending Messages 表示阻塞在队列中未经消费的消息条数

Number Of Consumers 表示正在与 ActiveMQ 建立连接的消费者数量

Messages Enqueued 表示进入队列的消息数量

Messages Dequeued 表示离开队列的消息数量

此外,还有下面几种操作

Browser 用于查看当前队列中消息的相关细节

Active Consumers 用于查看当前活动消费者的相关信息

Active Producers 用于查看当前活动生产者的相关信息

Send To 用于向当前队列中发送具体消息

Purge 用于清空队列中的消息

Delete 用于删除当前队列

参考

《架构探险—轻量级微服务架构》

原文:https://www.cnblogs.com/reycg-blog/p/10265139.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多个数字数组_七个问题帮助初学者深入理解Java数组

短文涨姿势,看了不白看,不关注等啥?几乎所有的高级语言当中,都提供了一种叫做”数组”的东西,Java语言当然也不例外。我们通过数组可以很方便的存储和管理一组数据。因为在Java语言当中使用数组非常的方便,…

java 异常练习题1

建立exception包,建立Bank类,类中有变量double balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数,抛出Nag…

大话设计模式读书笔记--6.原型模式

简单的复制粘贴极有可能造成重复代码的灾难, 但是java中提供了克隆的功能, 如果一个对象创建过程复杂,又要频繁使用, 在初始化信息不发生变化的情况下,应当采取克隆而不是new一个对象 定义 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 也就是说,…

Java 7#8:测试台上的NIO.2文件通道

关于新JDK 7功能的另一篇博客文章。 这次我正在写有关新的AnsynchronousFileChannel类的文章。 我将在两周内深入分析新的JDK 7功能,并决定连续编号我的帖子。 只是为了确保我不会感到困惑:-)这是我关于Java 7的第七篇文章(我承认–碰巧–这也…

5页面title样式修改_认识html:实现网站页面是这么简单的一回事

互联网时代人们通过上网浏览信息,打开浏览器上网看到丰富的图文、视频、音乐等多媒体信息,一系列信息反馈和视觉冲击之后,您有没有想过,互联网这么发达的时代,您觉得花一点点时间学会做个网站页面不真香?概…

iOS指南针

前言: 这个小项目使用到了CoreLocation框架里面的设备朝向功能,对CoreLocation感兴趣的可以翻一下之前的文章 在另一个博客站有朋友发现一个尴尬的问题(图片的东西2个方向是不对的),原谅我的大意,赶时间就直…

jq的链式调用.end();

jq的链式调用.end(); 先上code <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>li{list-style: none;width: 100px;height:20px;border:1px solid #ff0000;display: …

程序如何在两个gpu卡上并行运行_深度学习分布式训练相关介绍 - Part 1 多GPU训练...

本篇文章主要是对深度学习中运用多GPU进行训练的一些基本的知识点进行的一个梳理文章中的内容都是经过认真地分析&#xff0c;并且尽量做到有所考证抛砖引玉&#xff0c;希望可以给大家有更多的启发&#xff0c;并能有所收获介绍大多数时候&#xff0c;梯度下降算法的训练需要较…

系统英伟达gpu驱动卸载_绕过CPU,英伟达让GPU直连存储设备

英伟达最近发布了一个新的GPUDirect Storage&#xff0c;暂且叫做GPU直连存储&#xff0c;让GPU直接连到NVMe存储设备上。这一方案用到了RDMA设备来把数据从闪存存储转移到GPU本地的内存里&#xff0c;无需经过CPU还有系统内存。如果这一举措顺利的话&#xff0c;英伟达就能摆脱…

嘲弄和存根–了解Mockito的测试双打

介绍 我遇到的一件事是使用模拟框架的团队假设他们在模拟。 他们并不知道Mocks只是Gerard Meszaros在xunitpatterns.com上归类的“测试双打”之一。 重要的是要意识到每种类型的测试双精度在测试中都扮演着不同的角色。 用与您需要学习不同模式或重构的方式相同&#xff0c;您…

【代码笔记】iOS-首页3张图片变化

一&#xff0c;效果图。 二&#xff0c;工程图。 三&#xff0c;代码。 RootViewController.h #import <UIKit/UIKit.h>interface RootViewController : UIViewController {NSTimer *timer;UIImageView *imageView1;UIImageView *imageView2;UIImageView *imageView3;UIV…

使用Eclipse在Amazon Ec2中部署Java Web应用程序的完整指南

嗨&#xff0c;读者们&#xff0c; 今天&#xff0c;我将向您展示如何使用Eclipse IDE在Amazon EC2中部署简单的Java Web应用程序。 在我们开始之前&#xff0c;我们需要一些必需的东西&#xff0c; Eclipse Java EE IDE –您可以从http://www.eclipse.org/downloads/下载&…

Spring 3和Java EE 6 –不公平和不完整的比较

这篇小文章的初稿标题为“ Spring&#xff06;Java EE –比较苹果和橙子”。 在撰写本文时&#xff0c;我了解到可以比较Spring Framework和Java EE&#xff0c;但这始终是不公平且不完整的工作。 Java for Enterprise和Spring Framework的发展紧密地联系在一起。 两者相互依存…

xml配置文件推荐方式

1.XML帮助类 /// <summary>/// Xml帮助类/// </summary>public class XmlHelper{/// <summary>/// 保存xml/// </summary>/// <typeparam name"T"></typeparam>/// <param name"path"></param>/// <p…

AFNetWorking https SSL认证

一般来讲如果app用了web service , 我们需要防止数据嗅探来保证数据安全.通常的做法是用ssl来连接以防止数据抓包和嗅探 其实这么做的话还是不够的 。 我们还需要防止中间人攻击&#xff08;不明白的自己去百度&#xff09;。攻击者通过伪造的ssl证书使app连接到了伪装的假冒的…

查看环境列表_Xfce 4.14桌面环境正式发布,想要图形界面又想节省内存?就它了...

1. Xfce 4.14桌面环境正式发布&#xff0c;它有什么新特性&#xff1f;本文主要讲解Xfce 4.14桌面环境正式发布&#xff0c;它有什么新特性。Xfce已经开发了4年多&#xff0c;但是这个周末终于看到了期待已久的Xfce 4.14的发布。Xfce 4.14是这个轻量级桌面环境的最新稳定版本&a…

卷积神经网络语音识别_用于物体识别的3D卷积神经网络

本文提出了一种基于CNN的3D物体识别方法&#xff0c;能够从3D图像表示中识别3D物体&#xff0c;并在比较了不同的体素时的准确性。已有文献中&#xff0c;3D CNN使用3D点云数据集或者RGBD图像来构建3D CNNs&#xff0c;但是CNN也可以用于直接识别物体体积表示的体素。本文中&am…

#获得请求来源ip_以太网数据包TCP、IP、ICMP、UDP、ARP协议头结构详解

以太网首部目地MAC地址(8字节)源MAC地址(8字节)类型(2字节)1、IP头的结构版本(4位)头长度(4位)服务类型(8位)封包总长度(16位)封包标识(16位)标志(3位)片断偏移地址(13位)存活时间(8位)协议(8位)校验和(16位)来源IP地址(32位)目的IP地址(32位)选项(可选)填充(可选)数据(1)字节和…

c# ef报错_C# EF调用MySql出现“未将对象引用设置到对象的实例”错误解决方案

C# EF调用MySql出现“未将对象引用设置到对象的实例”错误解决方案---修改步骤---1.打开Nuget管理包&#xff0c;把Mysql.Data替换为6.10.0以下任意版本。这里选择的是6.8.82.修改完毕后&#xff0c;继续把Mysql.Data.Entity也修改为对应版本6.8.8。3.安装完成后可以看到App.Co…

ServletRequest startAsync()的有用性有限

前段时间我遇到了Servlet 3.0中AsyncContext.start&#xff08;…&#xff09;的目的是什么&#xff1f; 题。 引用上述方法的Javadoc &#xff1a; 使容器调度线程&#xff08;可能从托管线程池中&#xff09;运行指定的Runnable 。 提醒大家&#xff0c; AsyncContext是Servl…