知识分享-消息中间件详解+rabbitMQ

消息中间件

概述

消息中间件是基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统。

应用场景

异步处理

对于电商app来说,顾客下单后要扣减商品库存,还要更新订单状态等一系列操作。当并发量大的时候,服务器磁盘、IO、CPU load 会很高,因此有的时候需要一个相对较长的时间间隔才能完成上述的一系列操作。如果用户提交完订单,让用户等待几秒才能成功,对于用户来说,会很不耐烦,甚至会流失大量用户。

如果有了 MQ ,可以让系统间的通信变为异步通信,系统A 发个消息到 MQ,系统 B什么时候获取消息进行处理,系统A不用管,系统A向MQ发送完消息只需要给用户及时反馈即可,剩下的操作系统B可能会在未来的几秒、几分钟甚至几小时后才进行处理。

应用解耦★★★★★

订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。

库存系统:订阅下单的消息,获取下单消息,进行库操作。
就算库存系统出现故障,消息队列也能保证消息的可靠投递,不会导致消息丢失。

流量削峰

流量削峰一般在秒杀活动中应用广泛

消息队列优缺点

关于消息队列的优点也就是上面列举的,就是在特殊场景下有其对应的好处,解耦、异步、削峰。

缺点有以下几个:

系统可用性降低

系统引入的外部依赖越多,越容易挂掉。本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃的,你不就完了?如何保证消息队列的高可用,可以点击这里查看。

系统复杂度提高

硬生生加个 MQ 进来,你怎么[保证消息没有重复消费]?怎么[处理消息丢失的情况]?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

一致性问题

A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用,还是得用的。

常用消息中间件

AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有RabbitMQ等。

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

AMQP和JMS

MQ是消息通信的模型,并发具体实现。现在实现MQ的有两种主流方式:AMQP、JMS。

两者间的区别和联系:

  • JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
  • JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
  • JMS规定了两种消息模型;而AMQP的消息模型更加丰富

常见MQ产品

ActiveMQ:基于JMS

RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好

RocketMQ``:基于JMS,阿里巴巴产品,目前交由Apache基金会

Kafka:分布式消息系统,高吞吐量

其实现在主流的消息中间件就4种:kafka、ActiveMQ、RocketMQ、RabbitMQ

RabbitMQ详解

概述

RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。

 为什么选择RabbitMQ

1、ActiveMQ,性能不是很好,因此在高并发的场景下,直接被pass掉了。它的Api很完善,在中小型互联网公司可以去使用。

2、kafka,主要强调高性能,如果对业务需要可靠性消息的投递的时候。那么就不能够选择kafka了。但是如果做一些日志收集呢,kafka还是很好的。因为kafka的性能是十分好的。

3、RocketMQ,它的特点非常好。它高性能、满足可靠性、分布式事物、支持水平扩展、上亿级别的消息堆积、主从之间的切换等等。MQ的所有优点它基本都满足。但是它最大的缺点:商业版收费。因此它有许多功能是不对外提供的。

特点

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。

AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。

RabbitMQ的可靠性是非常好的,数据能够保证百分之百的不丢失。可以使用镜像队列,它的稳定性非常好。所以说在我们互联网的金融行业。对数据的稳定性和可靠性要求都非常高的情况下,我们都会选择RabbitMQ。当然没有kafka性能好,但是要比AvtiveMQ性能要好很多。也可以自己做一些性能的优化。

RabbitMQ可以构建异地双活架构,包括每一个节点存储方式可以采用磁盘或者内存的方式。

RabbitMQ的集群架构

非常经典的 mirror镜像模式,保证 100%数据不丢失。在实际工作中也是用得最多的,并且实现非常的简单,一般互联网大厂都会构建这种镜像集群模式。

mirror镜像队列,目的是为了保证 rabbitMQ数据的高可靠性解决方案,主要就是实现数据的同步,一般来讲是2 - 3个节点实现数据同步。对于100%数据可靠性解决方案,一般是采用 3个节点。

如上图所示,用 KeepAlived 做了 HA-Proxy 的高可用,然后有3 个节点的 MQ 服务,消息发送到主节点上,主节点通过 mirror队列把数据同步到其他的MQ节点,这样来实现其高可靠。

这就是RabbitMQ整个镜像模式的集群架构。

安装RabbitMQ

Linux安装

更新软件包和存储库

yum -y update

安装Erlang

yum -y install epel-release

yum -y update

yum -y install erlang socat

检查Erlang版本

erl -version

将得到如下输出

[root@liptan-pc ~]# erl -version Erlang (ASYNC_THREADS,HIPE) (BEAM) emulator version 5.10.4

下载RabbitMQ

Wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.10/rabbitmq-server-3.6.10-1.el7.noarch.rpm

安装RabbitMQ

rpm –import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc

运行RPM安装RPM包:

rpm -Uvh rabbitmq-server-3.6.10-1.el7.noarch.rpm

使用RabbitMQ

运行

systemctl start rabbitmq-server

开机自启

systemctl enable rabbitmq-server

检查状态

systemctl status rabbitmq-server

启动RabbitMQ Web管理控制台,方法是运行:

rabbitmq-plugins enable rabbitmq_management

通过运行以下命令,将RabbitMQ文件的所有权提供给RabbitMQ用户:

chown -R rabbitmq:rabbitmq /var/lib/rabbitmq/

将需要为RabbitMQ Web`管理控制台创建管理用户。 运行以下命令相同。

rabbitmqctl add_user admin StrongPassword

rabbitmqctl set_user_tags admin administrator

rabbitmqctl set_permissions -p / admin “.*” “.*” “.*”

Windows安装

省略

管理界面介绍

访问RabbitMQ的管理面板

http://Your_Server_IP:15672/

第一次访问需要登录,默认的账号密码为:guest/guest

主页

connections:无论生产者还是消费者,都需要与RabbitMQ建立连接后才可以完成消息的生产和消费,在这里可以查看连接情况

channels:通道,建立连接后,会形成通道,消息的投递获取依赖通道。

Exchanges:交换机,用来实现消息的路由

Queues:队列,即消息队列,消息存放在队列中,等待消费,消费后被移除队列。

Queues 队列

该栏目展示的是消息队列的信息,里面有各个队列的概要信息,也可以在此栏目添加队列Queue。

Java代码集成

依赖

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

配置

配置类

@Configuration
public class RabbitMQConfig {

    /**
     * 发送消息JSON序列化
     */
    /*@Override
    public void afterPropertiesSet() {
        //使用JSON序列化
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
    }*/
    //队列名称
    public static final String LOCK_PRECORD = "lockRrecord";

    @Bean("lockRrecord")
    public Queue itemQueue() {
        return new Queue(LOCK_PRECORD, true);
    }

    @Bean
    public MessageConverter messageConverter() {
        ContentTypeDelegatingMessageConverter messageConverter = new ContentTypeDelegatingMessageConverter();
        messageConverter.addDelegate(MediaType.APPLICATION_JSON_VALUE, new Jackson2JsonMessageConverter());
        messageConverter.addDelegate(MediaType.TEXT_PLAIN_VALUE, new SimpleMessageConverter());
        return messageConverter;
    }

}

监听

@Component
public class RabbitReceive {
    private static final Logger LOGGER = LoggerFactory.getLogger(RabbitReceive.class);
    @Resource
    private XmSjDao xmSjDao;

    @RabbitListener(queues = "xmEquipmentQueue")
    public void xmCameraQueue(String data) {
        String id = UUID.randomUUID().toString();

        JSONObject parseObject = JSONObject.parseObject(data);
        String baseValue = parseObject.get("base_value").toString();
        String stid = parseObject.get("stid").toString();
        baseValue = base64ImageUtils.uploadFile(baseValue);
        //查看该图片是否已经存过
        /*Integer count = xmSjDao.getCam(stid, baseValue);
        if (count == null || count == 0) {
            xmSjDao.insertCam(id, stid, baseValue);
        } else {
            xmSjDao.updateCam(stid, baseValue);
        }*/
        xmSjDao.insertCam(id, stid, baseValue);
    }

}

知识分享-消息中间件详解+rabbitMQ的更多相关文章

  1. Linux基础知识之挂载详解(mount,umount及开机自动挂载)

    Linux基础知识之挂载详解(mount,umount及开机自动挂载) 转载自:http://www.linuxidc.com/Linux/2016-08/134666.htm 挂载概念简述: 根文件 ...

  2. Httpd服务进阶知识-HTTP协议详解

    Httpd服务进阶知识-HTTP协议详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.WEB开发概述 1>.C/S编程 CS即客户端.服务器编程. 客户端.服务端之间需 ...

  3. [转]Vue项目全局配置微信分享思路详解

    这篇文章给大家介绍了vue项目全局配置微信分享思路讲解,使用vue作为框架,使用vux作为ui组件库,具体内容详情大家跟随脚本之家小编一起学习吧 这个项目为移动端项目,主要用于接入公众号服务.项目采用 ...

  4. Java程序员的必备知识-类加载机制详解

    类加载器的概念 类加载器是一个用来加载类文件的类. Java源代码通过javac编译器编译成类文件.然后JVM来执行类文件中的字节码来执行程序.类加载器负责加载文件系统.网络或其他来源的类文件. JV ...

  5. [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。

    一.Spring Ioc容器详解(1) 20131105 1.一切都是Bean Bean可是一个字符串或者是数字,一般是一些业务组件. 粒度一般比较粗. 2.Bean的名称 xml配置文件中,id属性 ...

  6. OpenStack基础知识-tox的详解介绍

    1.tox简介 tox是通用的虚拟环境管理和测试命令行工具.tox能够让我们在同一个Host上自定义出多套相互独立且隔离的python环境,每套虚拟环境中可能使用了不同的 Python 拦截器/环境变 ...

  7. nginx_笔记分享_php-fpm详解

    参考 http://syre.blogbus.com/logs/20092011.htmlhttp://www.mike.org.cn/articles/what-is-cgi-fastcgi-php ...

  8. 计算机基础知识和tcp详解

    计算机基础知识 作为应用软件开发程序员是写应用软件的,而应用软件必须应用在操作系统之上,调用操作系统接口,由操作系统控制硬件 比如客户端软件想要基于网络发送一条消息给服务端软件,流程是: 1.客户端软 ...

  9. OpenStack基础知识-virtualenv工具详解

    1.virtualenv介绍 virtualenv通过创建一个单独的虚拟化python运行环境,将我们所需的依赖安装进去,不同项目之间相互不干扰,从而解决不同的项目之间依赖不同,造成的冲突问题 2.安 ...

  10. 微信JSSDK分享功能详解

    本文以微信分享到朋友圈,分享给微信好友为例为参考,进行调用测试,想添加其他的功能,自行查看开发人员文档即可 工欲善其事,必先利其器,好好利用下边的帮助工具,都是腾讯给开发人员的工具 1.微信开发者说明 ...

随机推荐

  1. 编写一个应用程序,在主类Test1类中,创建两个链表List<E>对象,分别存储通过键盘输入的字符串内容

    题目1:编写一个应用程序,在主类Test1类中,创建两个链表List<E>对象,分别存储通过键盘输入的字符串内容--"chen","wang",&q ...

  2. 用 VS Code 搞Qt6:使用 PySide 6

    一般来说,用C++写 Qt 应用才是正宗的,不过,为了让小学生也能体验 Qt 的开发过程,或者官方为了增加开发者人数,推出了可用 Python 来编程的 Qt 版本.此版本命名比较奇葩,叫 PySid ...

  3. Redis高可用之主从复制原理演进分析

    Redis高可用之主从复制原理演进分析 在很久之前写过一篇 Redis 主从复制原理的简略分析,基本是一个笔记类文章. 一.什么是主从复制 1.1 什么是主从复制 主从复制,从名字可以看出,至少需要 ...

  4. 【linux】 第1回 linux运维基础

    目录 1. 运维的本质 2. 电脑与服务器 2.1 电脑的种类 2.2 服务器种类 2.3 服务器品牌 2.4 服务器尺寸 2.5 服务器内部组成 3. 磁盘阵列 4. 系统简介 5. 虚拟化 6. ...

  5. SpringBoot 2.5.5整合轻量级的分布式日志标记追踪神器TLog

    TLog能解决什么痛点 随着微服务盛行,很多公司都把系统按照业务边界拆成了很多微服务,在排错查日志的时候.因为业务链路贯穿着很多微服务节点,导致定位某个请求的日志以及上下游业务的日志会变得有些困难. ...

  6. 成功解决:snippet设置的开机自启没有效果

    1.问题描述 勾选开机启动后.没有效果.每次开机都要我重新找到对应的安装目录.双击运行开启 2.解决方法 将snipaste的快捷方式放到开机启动目录下 C:\Users\Administrator\ ...

  7. Asp.Net Core MVC传值 Asp.Net Core API 前台写法

    $("#Add_User").click(function () { var obj = { //"属性名": 传递的值, "User_Name&qu ...

  8. 【原创】All in One i.MXRT1050/RT1020 SPI Flash Algorithm for J-Flash

    2020年,这个给大家一种很漫长的恍惚感的一年,终于是过去了.这一年我们很多新的人生第一次就这么被发生了,第一次居家办公这么长时间(很多人肥膘都长了不少,我却瘦了2斤,不知是工作太积极了还是被家里小怪 ...

  9. Jupyter基本使用

    https://www.cnblogs.com/zhrb/p/12174167.html 用来取代Jupyter Notebook的一个基于Web的用户交互式用户界面.相当于增强版的Jupyter N ...

  10. dockerNginx代理本地目录

    dockerNginx代理本地目录 ssl_certificate cert/5900588_test.zk.limengkai.work.pem; ssl_certificate_key cert/ ...