2018-06-27-消息中间件部署及比较(rabbitMQ、a

2018-10-25  本文已影响0人  ohcomeyes

一发一存一消费,没有最好的消息队列中间件(简称消息中间件),只有最合适的消息中间件。
消息队列常用的使用场景:

消息队列的缺点
上面讲到的都是优点,这里侧重讲几个缺点。

  1. 可用性会降低:应用解耦的同时都会降低系统的可用性,包括中间件宕机所产生的影响。
  2. 复杂度增高:需要考虑更多的问题,比如消息的一致性、顺序、重复消费等问题。

消息队列是异步RPC的主要手段之一

两种模式:

  1. 点对点:每个消息只有一个消费者(Consumer),不可重复消费(一旦被消费,消息就不再在消息队列中)
  2. 发布/订阅:微信公众号(Topic),大伙(订阅者)订阅关注之后,微信公众号运营平台(发布者)发布信息后,大伙微信就都收到信息了,这里其实还分pull/push的。一个是主动推送,一个是被动拉取
    基于发布/订阅模式做扩展就是横向扩展,多个队列及消费分组订阅(提高消费能力)

实际开发中消息中间件选型基于几个方面:

  1. 功能:这个就多了,优先级队列、延迟队列(划分不同的延迟队列来避免重新排序消耗性能,缺点嘛自己悟)、死信队列(放没有推送成功的)、消费模式(pull/push)、广播消费、消息回溯(可追溯嘛,不然被卖了都不知道是谁)、消息堆积+持久化、消息追踪(链路条,方便定位)、消息过滤(根据规则过滤啊,不同类别消息发送到不同topic)、多协议支持(通用性)、跨语言支持(流行程度)、流量控制(嘿嘿嘿,上面有)、消息顺序性(还要再说一遍?)、安全机制(身份认证,权限认证(读写))、消息幂等性(承诺知道不,答应人家的事就一定要做到)、事务性消息(不想说)等
  2. 性能:一般是指其吞吐量(统一大小的消息体和不同大小的消息体生产和消耗能力),性能和功能很多时候是相悖的,鱼和熊掌不可兼得。
  3. 高可靠、高可用:先说可靠,主要在于消息的持久化这一块(消息只要写入就一定会被消费,不会因为故障导致数据丢失(这个就很好测试出来了吧))。如果是从系统的角度来看就得从整体的维度去衡量了(不能单单只靠消息中间件本身,要从生产端、服务端、消费端三个维度去保障)。
    再说可用,主要在于一个是对外部服务的依赖性(像kafka依赖zookeeper),依赖也分强依赖和弱依赖,一个在于本身的备份机制所带来的保障性(像主从复制这种备份啊,增加多个slave来加强保障同时也会存在资源浪费,大部分时候Slave可能是空闲的)。
  4. 运维:通常有审核评估啊、监控啊、报警提醒啊、容灾啊、扩容啊、升级部署等等,一方面看中间件支撑的维度,一方面就看结合自动化运维的难易度
  5. 社区力度及生态发展:这个好理解吧,使用开源框架最开始基本上愉快的奔跑,但时不时的总会掉坑里,能不能爬出来一方面看自身的实力,一方面就看社区的力度了
  6. 成本 尽量贴合团队自身的技术栈体系,让一个C栈的团队去深挖zeroMQ总比scala编写kafka要容易的多

先贴一个图(网上Q来的),一些功能支不支持主要取决于它使用的模式,看完上面详细说明应该就比较清楚

消息中间件

先从比较有代表性的两个MQ(rabbitMQ,kafka),功能对比(图还是Q来的)

中间件功能比较1
中间件功能比较2
中间件功能比较3

应用方面:

架构模型方面:

吞吐量:

可用性方面:

集群负载均衡方面:

rabbitMQ

基于erlang开发
是采用Erlang语言实现的AMQP协议的消息中间件,最初起源于金融系统,用于在分布式系统中存储转发消息。RabbitMQ发展到今天,被越来越多的人认可,这和它在可靠性、可用性、扩展性、功能丰富等方面的卓越表现是分不开的。
优点:

缺点:

activeMQ

基于java开发
是Apache出品的、采用Java语言编写的完全基于JMS1.1规范的面向消息的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。不过由于历史原因包袱太重,目前市场份额没有后面三种消息中间件多,其最新架构被命名为Apollo,(京东的消息中间件就是基于activeMQ开发的)
优点:

缺点:

zeroMQ

基于C开发
号称史上最快的消息队列,基于C语言开发。ZeroMQ是一个消息处理队列库,可在多线程、多内核和主机之间弹性伸缩,虽然大多数时候我们习惯将其归入消息队列家族之中,但是其和前面的几款有着本质的区别,ZeroMQ本身就不是一个消息队列服务器,更像是一组底层网络通讯库,对原有的Socket API上加上一层封装而已。
优点:

缺点:

rocketMQ

基于java开发(阿里消息中间件)
是阿里开源的消息中间件,目前已经捐献个Apache基金会,它是由Java语言开发的,具备高吞吐量、高可用性、适合大规模分布式系统应用等特点,经历过双11的洗礼,实力不容小觑。
优点:

缺点:

kafka

基于Scala和Java开发
起初是由LinkedIn公司采用Scala语言开发的一个分布式、多分区、多副本且基于zookeeper协调的分布式消息系统,现已捐献给Apache基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark、Flink等都支持与Kafka集成。
优点:

缺点:

redis

Redis的PUB/SUB机制,即发布-订阅模式。利用的Redis的列表(lists)数据结构。比较好的使用模式是,生产者lpush消息,消费者brpop消息,并设定超时时间,可以减少redis的压力。只有在Redis宕机且数据没有持久化的情况下丢失数据,可以根据业务通过AOF和缩短持久化间隔来保证很高的可靠性,而且也可以通过多个client来提高消费速度。但相对于专业的消息队列来说,该方案消息的状态过于简单(没有状态),且没有ack机制,消息取出后消费失败依赖于client记录日志或者重新push到队列里面。

redis不支持分组(这点很重要,在做负载均衡的时候劣势就体现出来),不过可以完全当做一个轻量级的队列使用,但redis他爹做了disque,可以去试一试。

部署安装

rabbitMQ

几个重要概念:

使用过程:

  1. 客户端连接到消息队列服务器,打开一个channel。
  2. 客户端声明一个exchange,并设置相关属性。
  3. 客户端声明一个queue,并设置相关属性。
  4. 客户端使用routing key,在exchange和queue之间建立好绑定关系。
  5. 客户端投递消息到exchange。
  6. exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。

单机
RabbitMQ 安装需要依赖 Erlang 环境
所以先安装erlang,再安装rabbitMQ,中间肯定会遇到很多问题,不同的环境问题不一样,大多数是依赖包的问题,自行补齐就行了。

rabbitmq默认创建的用户guest,密码也是guest,这个用户默认只能是本机访问,从外部访问需要添加上面的配置。建议删除guest用户

配置外部访问

# rabbitmq.config文件默认是没有的,这里是直接新建
vi rabbitmq.config
# 添加下面内容
[{rabbit, [{loopback_users, []}]}].

删除guest用户

rabbitmqctl  delete_user guest

添加用户

rabbitmqctl add_user <username> <newpassword>

给新增用户赋予超级管理员权限

rabbitmqctl set_user_tags <username> administrator

启动服务(建议后台模式运行)

service rabbitmq-server start &

开启管理UI(建议后台模式运行)

rabbitmq-plugins enable rabbitmq_management &

访问:ip:15672,用新添加的用户登陆


rabbitmq

kafka

几个重要概念:

单机
Kafka使用Zookeeper来维护集群信息,所以需要先安装zookeeper,而zookeeper是由java编写的,所以需要先安装jdk

下载地址:https://kafka.apache.org/downloads

# 下载解压
mkdir kafka && cd kafka
wget http://mirrors.shuosc.org/apache/kafka/1.0.0/kafka_2.11-1.0.0.tgz
tar -xzf kafka_2.11-1.0.0.tgz
cd kafka_2.11-1.0.1
# 启动zookeeper
bin/zookeeper-server-start.sh config/zookeeper.properties
# 启动kafka
bin/kafka-server-start.sh config/server.properties
# 创建Topic test
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
# 参数描述:
# create: 创建Topic
# zookeeper:zookeeper集群信息,多个用,分开
# replication-factor:复制因子
# partitions:分区信息
# topic:主题名

# 向topic发送消息
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
> 随便输入

# 向topic获取消息
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
# 就能看到前面输入的消息了

Kafka监控工具
kafka没有自带的web ui,这里使用KafkaOffsetMonitor, 程序一个jar包的形式运行,部署较为方便。只有监控功能,使用起来也较为安全。

KafkaOffsetMonitor托管在Github上,可以通过Github下载。
下载地址:https://github.com/Morningstar/kafka-offset-monitor/releases

# 下载好之后cd到KafkaOffsetMonitor所在目录,可以直接启动,也可以编写shell脚本来启动
java -cp KafkaOffsetMonitor-assembly-0.4.1-SNAPSHOT.jar com.quantifind.kafka.offsetapp.OffsetGetterWeb
--port 8089
--zk 127.0.0.1:2181 
--refresh 5.minutes 
--retain 1.day

编写脚本启动

mkdir kafka-monitor.sh
chmod  +x kafka-monitor.sh
vi kafka-monitor.sh
# 把之前启动的命令复制进来,如:
#! /bin/bash
java -Xms512M -Xmx512M -Xss1024K \
     -cp KafkaOffsetMonitor-assembly-0.4.1-SNAPSHOT.jar \
     com.quantifind.kafka.offsetapp.OffsetGetterWeb \
     --zk localhost:2181 \
     --port 8089 \
     --refresh 10.seconds \
     --retain 5.days
# 保存,然后就可以启动脚本了

zk :zookeeper主机地址,如果有多个,用逗号隔开
port :应用程序端口(没设置的话,日志里面会输出随机的端口号)
refresh :应用程序在数据库中刷新和存储点的频率
retain :在db中保留多长时间
dbName :保存的数据库文件名,默认为offsetapp

github上详细参数说明:

KafkaOffsetMonitor
访问:ip:端口 ui
    Topic:订阅的主题
    Partition:分区编号
    Offest:表示该parition已经消费了多少条message
    logSize:表示该partition已经写了多少条message
    Lag:表示有多少条message没有被消费。
    Owner:表示消费者
    Created:该partition创建时间
    Last Seen:消费状态刷新最新时间。

注意
本机能访问,但其它机器不能访问应该就是防火墙的问题,开放对应端口,或者关闭防火墙
如果能访问,但是没有信息显示出来,只显示了黑色的屏,是因为ui页面所依赖的ajax.googleapis.com等公共库被墙了
解决办法

结语

未完待续......。
个人博客~
简书~

上一篇 下一篇

猜你喜欢

热点阅读