php| 初探 rabbitmq

date: 2018-09-03 21:30:23
title: php| 初探 rabbitmq
description: 零零散散折腾了 rabbitmq 几次, 归纳总结一下先

经常看到消息队列( MQ ), 实战中比较少, 说说我的一些粗线的理解:

  • 引入消息队列, 使系统之间解耦 -> 当然还有很多 小型项目 使用 重项目 的方式(系统拆分, 不存在的!); 解耦这部分的内容, 后来还会讲到
  • 通过将流程 异步化, 增加每部分的吞吐能力, 从而实现最终增加系统性能, 这一点有点类似服务器领域的 同步 -> 异步/协程, 可以参考 swoole| swoole 协程初体验

当然, 实践出真知, 还是希望能在业务中多实战, 或者参与相关的开源项目~

相关教程

老生常谈, 生命周期思维方式, 想一想消息是怎么在整个消息队列系统中流动的.

应用场景: 冗余 解耦 流量削峰 异步通信 扩展新 排序保证 -> 队列结构的中间件
队列介质: mysql redis 消息队列服务(rabbitmq kafka)
触发机制: 死循环while 定时脚本cron 守护进程daemon(fpm)
场景一 订单系统/配送系统解耦: 订单系统 -> 队列表 -> 配送系统
场景二 流量削峰: redis list类型实现定长队列, 请求先入队列, 超出队列长度后的请求丢弃
rabbitmq架构和原理: 完整实现AMQP 集群简化 持久化 跨平台

基于 AMQP(advanced message queue protocol, 高级消息队列协议)
集群模式: 表达式配置 HA模式 镜像队列模式
保证数据不丢失/高可靠/高可用

安装 rabbitmq

老生常谈, 直接上 docker:

docker-compose, 使用 rabbitmq 官方镜像:

version: '3'
services:
    rabbitmq: # https://hub.docker.com/_/rabbitmq/
        image: rabbitmq:3.7.7-management-alpine
        hostname: myrabbitmq
        ports:
            - "5672:5672" # mq
            - "15672:15672" # admin

就这么几行, rabbitmq 就配置好了, 使用 docker-compose up -d rabbit 启动, 大功告成

这里使用的 management 版本的 rabbitmq, 管理控制台地址 http://localhost:15672, 初始密码 guest/guest

进入容器内部看看:

# 进入容器
docker-compose exec rabbitmq bash 

# 查看启动的服务
bash-4.4# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
rabbitmq     1  0.0  0.0   1612  1012 ?        Ss   06:25   0:00 /bin/sh /opt/rabbitmq/sbin/rabbitmq-server
rabbitmq    90  0.0  0.0   1068   660 ?        S    06:25   0:00 /usr/lib/erlang/erts-9.3/bin/epmd -daemon
rabbitmq   158  0.5  3.9 1707624 81152 ?       Sl   06:25   0:37 /usr/lib/erlang/erts-9.3/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -s
rabbitmq   265  0.0  0.0    752   536 ?        Ss   06:25   0:00 erl_child_setup 1048576
rabbitmq   306  0.0  0.0    772     4 ?        Ss   06:25   0:00 inet_gethost 4
rabbitmq   307  0.0  0.0    772    32 ?        S    06:25   0:00 inet_gethost 4
root      3258  0.0  0.0   6364  2004 pts/0    Ss   07:25   0:00 bash
root      6813  0.0  0.0   5696   628 pts/0    R+   08:23   0:00 ps aux

# rabbitmq 相关命令行命令
bash-4.4# rabbitmq 
rabbitmq-defaults     rabbitmq-diagnostics  rabbitmq-env          rabbitmq-plugins      rabbitmq-server       rabbitmqadmin         rabbitmqctl
  • rabbitmqctl: rabbitmq control
  • rabbitmq-plugins: 也可以通过 rabbitmq-plugins 来开启管理控制台

更多配置, 可以访问 rabbitmq镜像官网 进行查看

快速开始

rabbitmq 官方文档 非常完善与清晰, 值得花时间看看

新手快速入门文档, 代码 - rabbitmq/rabbitmq-tutorials

rabbitmq 支持多种语言的 client, 这里说明支持的 php client:

  • php-amqplib: compoer package, 入门 rabbitmq 最简单的方式, composer require 即可完成安装
  • ext-amqp: PHP扩展, 需要安装 ext-amqp 扩展, 性能更优

queue-interop 按下不表, 还没进入 PSR.

官方的快速入门手册:

  • hello world

消息队列最基础的三个概念, 生产者producer + 消息队列MQ + 消费者consumer

image
  • work queues

如果 消费者的消费能力不足 怎么办? 多开几个 consumer 呗. 多个 consumer 怎么分担 MQ 中的消息呢? 所以在 消息队列MQ 和 消费者consumer 之间进行 负载均衡LB. LB并不是准去的说法, 通常的说法是消费者 订阅 消息队列的内容. 在我看来, LB 更有表现力 -- 消费能力不足导致需要多个消费者, 怎么和 web server 并发不够, 加机器加 LB 有些像呢?

这里我使用的 LB 这样的概念, 目的在于 LB 在服务器领域太常见了, 包含很多内容, 需要细细体会

image
  • pub/sub

发布订阅, 看起来像多个 hello world, 注意图里多了一个 rabbitmq 中的新概念 交换器exchange(图中简写为 X), 在 生产者producer 和 消息队列MQ 之间, 由 exchange 来决定消息 分发 到哪个 MQ 中

image
  • routing/topic

两个新的概念, 路由功能主体订阅 功能, 而这些都和 交换器exchange 有关, 涉及到的配置: 交换器类型(exchange type) + 路由key(routing key) + 绑定key(binding key). 为啥会这么复杂呢? 干嘛要这么多配置?

一言以蔽之, 决定 生产者producer 产生的消息, 投递到哪个 消息队列MQ 中, 最终又由哪个 consumer 消费

routing

topic
  • RPC

新玩法, 通过消息队列实现 远程过程调用RPC 的效果

image

我在这里并没有贴具体代码, 一则因为官方给的代码确实适合上手, 更重要是因为, 理解 rabbitmq 究竟是个什么玩意 更重要

rabbitmq 究竟是啥

  • 首先是 MQ 最基础的概念: 生产者producer + 消息队列MQ(狭义指存储消息的队列类型的数据结构) + 消费者consumer
  • consumer 怎么从 MQ 中获取消息 + consumer获取消息后确认(ack): 可以近似理解 MQ 和 consumer 之间需要一层 LB
  • producer 怎么投递消息到 MQ 中: exchange + exchange type + routing key + binding key -> 消息路由/主题订阅
  • 怎么扩展 MQ 的性能呢: 集群, 涉及到集群, 又会新增很多概念了

放几张图辅助理解:

amqp模型
  • 实际使用过程中, 还需要 tcp 连接相关的概念: connection + channel
rabbitmq模型
  • 这张图可以看到消息msg 的 生命周期
rabbitmq消息流转

写在最后

正儿八经(准确说, 这叫 专业) 的消息队列, 架构设计上确实有一定的复杂性, 而且为了满足高性能, 还会有很多性能优化的点 -- 学习消息队列, 长路漫漫, 可以好好折腾一番了~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 来源 RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。支持消息的持久化、事务、拥塞控...
    jiangmo阅读 10,266评论 2 34
  • 本文大纲 RabbitMQ 历史 RabbitMQ 应用场景 RabbitMQ 系统架构 RabbitMQ 基本概...
    Java_Explorer阅读 16,170评论 1 40
  • 1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的...
    高广超阅读 6,068评论 3 51
  • 什么叫消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂...
    lijun_m阅读 1,257评论 0 1