第七章  搭建RabbitMQ解决电商促销活动高并发的问题

本节所讲内容:

7.1  RabbitMQ概述和运行机制

7.2  abbitmq使用方法

7.3  实战3-使用python调用rabbitmq服务器

 

7.1  RabbitMQ概述和运行机制

7.1.1  RabbitMQ概述

RabbitMQ概述:RabbitMQ是使用最广泛的开源消息代理。RabbitMQ轻量级,易于在集群内部和云平台中部署。它支持多种消息传递协议。 它可以满足企业高规模,高可用性的要求。RabbitMQ使用Erlang语言开发的。

MQ概述:全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。

MQ运行机制: P表示生产者,C表示消费者,红色部分为消息队列

 

 

 

MQ实战场景:

    1.我们在双11的时候,当我们凌晨大量的秒杀和抢购商品,然后去结算的时候,就会发现,界面会提醒我们,让我们稍等,以及一些友好的图片文字提醒。而不是像前几年的时代,动不动就页面卡死,报错等来呈现给用户。在这个业务场景中,我们就可以采用队列的机制来处理,因为同时结算就只能达到这么多。

    2.在我们平时的超市中购物也是一样,当我们在结算的时候,并不会一窝蜂一样涌入收银台,而是排队结算。这也是队列机制。一个接着一个的处理,不能插队。

 

RabbitMQ是AMQP服务器的一种。

AMQP简介:AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

AMQP 里主要要说两个组件:Exchange 和 Queue (在 AMQP 1.0 里还会有变动),如下图所示,绿色的 X 就是 Exchange ,红色的是 Queue ,这两者都在 Server 端,又称作 Broker ,这部分是 RabbitMQ 实现的,而蓝色的则是客户端,通常有 Producer(生产者) 和 Consumer(消费者) 两种类型:

 

 

官方网站:http://www.rabbitmq.com/

 

 

下载地址:http://www.rabbitmq.com/download.html

运行RabbitMQ监听端口号:

4369   #erlang发现口

5672   #client端通信口

15672  #管理界面ui端口

25672  #server间内部通信口

 

1、实战-搭建RabbitMQ服务器

RabbitMQ是用erlang语言编写的,所以我们先安装erlang语言环境

配置erlang语言环境

[root@xuegod63 ~]# vim /etc/yum.repos.d/rabbitmq-erlang.repo

[rabbitmq-erlang]

name=rabbitmq-erlang

baseurl=https://dl.bintray.com/rabbitmq/rpm/erlang/20/el/7

gpgcheck=1

gpgkey=https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc

enabled=1

[root@xuegod63 ~]# rpm --import  https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc

[root@xuegod63 ~]# yum install erlang -y  #安装erlang

2、安装rabbitmq服务

 下载rabbitmq地址:http://www.rabbitmq.com/download.html

 

[root@xuegod63 ~]# yum install rabbitmq-server-3.7.7-1.el7.noarch.rpm

 

启用RabbitMQ的web插件 ,方便后期管理界面:

[root@xuegod63 ~]#  rabbitmq-plugins enable rabbitmq_management

The following plugins have been configured:

  rabbitmq_management

  rabbitmq_management_agent

  rabbitmq_web_dispatch

Applying plugin configuration to rabbit@xuegod63...

The following plugins have been enabled:

  rabbitmq_management

  rabbitmq_management_agent

  rabbitmq_web_dispatch

set 3 plugins.

Offline change; changes will take effect at broker restart. #离线变更; 更改将在代理重启时生效。

 

设置开机启动

[root@xuegod63 ~]# systemctl enable rabbitmq-server.service

 

[root@xuegod63 ~]# systemctl start rabbitmq-server  #启动服务 

报错:

 

 

解决:

[root@xuegod63 ~]# ll /var/lib/rabbitmq/ -a总用量 8

drwxr-xr-x   3 rabbitmq rabbitmq   42 9月  10 15:02 .

drwxr-xr-x. 56 root     root     4096 9月  10 14:53 ..

-r--------   1 root     root       20 9月  10 00:00 .erlang.cookie

注:发现.erlang.cookie的文件拥有者是root,而rabbitmq服务是以rabbitqm普通用户运行的, 这就无法往.erlang.cookie里写入数据,所以报错了。

[root@xuegod63 ~]#  chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie  #修改文件拥有者

 

[root@xuegod63 ~]# netstat  -antup | grep 5672  #查看端口号

tcp        0      0 0.0.0.0:15672     0.0.0.0:*               LISTEN      57692/beam.smp     

tcp        0      0 0.0.0.0:25672     0.0.0.0:*               LISTEN      57692/beam.smp     

tcp6       0      0 :::5672           :::*                    LISTEN      57692/beam.smp      

 

rabbitmq配置文件位置:

[root@xuegod63 ~]# ls /var/lib/rabbitmq/

mnesia

[root@xuegod63 ~]# ls /etc/rabbitmq/enabled_plugins

/etc/rabbitmq/enabled_plugins

 

访问控制台

默认用户名和密码: guest/guest 。guest用户仅允许从在服务器以localhost或127.0.0.1作为ip登录; 

 

 

如果远程登录,如:http://192.168.1.63:15672/, 则会提示错误,登录不了。

 

 

为RabbitMQ创建用户并赋权。

[root@xuegod63 ~]# rabbitmqctl add_user root 123456  #添加用户

[root@xuegod63 ~]# rabbitmqctl set_user_tags root administrator #设置用户权限为administrator

 

测试登录,发现可以登录成功:

 

到此,已经搭建成功。

 

7.2  abbitmq使用方法

7.2.1  rabbitmq查看相关的命令

[root@xuegod63 ~]# rabbitmqctl list_connections   #用于查看当前的连接

[root@xuegod63 ~]# rabbitmqctl list_queues   #会列出所有队列名称,后边可能还会带着这个队列当前消息数

[root@xuegod63 ~]# rabbitmqctl status        #查看当前队列信息

 

7.2.2  rabbitmq的vhost管理

实战场景:当我们在创建用户时,会指定用户能访问一个虚拟机,并且该用户只能访问该虚拟机下的队列和交换机,如果没有指定,默认的是”/”;一个rabbitmq服务器上可以运行多个vhost,以便于适用不同的业务需要,这样做既可以满足权限配置的要求,也可以避免不同业务之间队列、交换机的命名冲突问题,因为不同vhost之间是隔离的。

添加xuegod-web和xuegod-bbs两个虚拟机来管理网站和论坛的队列

[root@xuegod63 ~]# rabbitmqctl add_vhost xuegod-web

[root@xuegod63 ~]# rabbitmqctl add_vhost xuegod-bbs

查看创建的虚拟主机

 

 


删除bbs虚拟机

[root@xuegod63 ~]# rabbitmqctl delete_vhost xuegod-bbs

查看虚拟机列表

[root@xuegod63 ~]# rabbitmqctl list_vhosts

Listing vhosts ...

xuegod-web

/     #“/”是rabbitmq默认的虚拟机,之前默认连接的都是它

 

7.2.3  rabbitmq用户、角色和权限管理

1、用户管理语法

添加用户:rabbitmqctl add_user {username} {password} 

删除用户:rabbitmqctl delete_user {username} 

修改密码:rabbitmqctl change_password {username} {newpassword} 

 

2、角色权限分配

  设置用户角色语法:rabbitmqctl set_user_tags {username} {tag} 

RabbitMQ的tag用户角色分类:none、management、policymaker、monitoring、administrator

tag常用角色为:administrator, monitoring, management 

 

RabbitMQ各类角色描述:

(1)、none角色权限 :不能访问 management plugin

(2)、management角色权限:

列出自己可以通过AMQP登入的virtual hosts  

查看自己的virtual hosts中的queues, exchanges 和 bindings

查看和关闭自己的channels 和 connections

查看有关自己的virtual hosts的“全局”的统计信息,包含其他用户在这些virtual hosts中的活动。

 

(3)、policymaker角色权限   #policymaker  ['pɒləsɪmeɪkə(r)]  决策者

拥有management的所有权限,还拥有查看、创建和删除自己的virtual hosts所属的policies(策略)和parameters([pəˈræmɪtə(r)] 参数 )

(4)、monitoring 角色权限

拥有management的所有权限,还拥有:

列出所有virtual hosts,包括他们不能登录的virtual hosts

查看其他用户的connections和channels

查看节点级别的数据如clustering和memory使用情况

查看真正的关于所有virtual hosts的全局的统计信息

(5)、administrator角色权限

拥有policymaker和monitoring的所有权限,还拥有:

创建和删除virtual hosts

查看、创建和删除users

查看创建和删除permissions

关闭其他用户的connections

 

3、权限设置

权限设置语法:rabbitmqctl set_permissions [-p vhostpath] {user} {conf} {write} {read} 

conf:一个正则表达式match哪些配置资源能够被该用户访问。 

write:一个正则表达式match哪些配置资源能够被该用户写。 

read:一个正则表达式match哪些配置资源能够被该用户读。

查看(指定vhost)所有用户的权限信息:rabbitmqctl list_permissions [-p vhostPath] 

查看指定用户的权限信息:rabbitmqctl list_user_permissions {username} 

清除用户的权限信息: rabbitmqctl clear_permissions [-p vhostPath] {username}

例1:创建用户root对默认虚拟主机 / 拥有所有权限

[root@xuegod63 ~]# rabbitmqctl set_permissions -p / root '.*' '.*' '.*'   #该命令使用户root对默认虚拟主机/中所有资源的拥有:配置、写、读权限

[root@xuegod63 ~]# rabbitmqctl list_user_permissions root   #查看权限

Listing permissions for user "root" ...

/       .*     .*     .*

 

例2:创建用户mk对vhost xeugod-web拥有所有权限

为RabbitMQ创建用户并赋权。

[root@xuegod63 ~]# rabbitmqctl add_user mk 123456  #添加用户

[root@xuegod63 ~]# rabbitmqctl set_user_tags mk administrator  #设置用户权限为administrator

[root@xuegod63 ~]# rabbitmqctl set_permissions -p xuegod-web mk  ".*" ".*" ".*"   #使用户mk对虚拟主机xuegod-web中所有资源的拥有:配置、写、读权限

[root@xuegod63 ~]# rabbitmqctl list_user_permissions mk  #查看权限

Listing permissions for user "mk" ...

xuegod-web   .*     .*     .*

在web界面查看权限:

 

 

 

[root@xuegod63 ~]# rabbitmqctl list_users   #查看用户列表 

Listing users ...

guest       [administrator]

root  [administrator]

[root@xuegod63 ~]# rabbitmqctl change_password mk 456789  #修改用户密码

[root@xuegod63 ~]# rabbitmqctl delete_user mk   #删除用户mk

 

7.3  实战3-使用python调用rabbitmq服务器

7.3.1  安装python实验环境

[root@xuegod63 ~]# yum install python  #安装python

[root@xuegod63 ~]# yum install epel-release -y   #安装扩展yum源

[root@xuegod63 ~]# yum install python-pip -y    #安装pip命令

[root@xuegod63 ~]# pip install --upgrade pip    #更新pip

[root@xuegod63 ~]# pip install pika    #安装pika模块。python用pika模块调用rabbitmq。

注:rabbitmq本质是一个生产者和消费者的模型结构。生产者->rabbitmq->消费者,即生产者产生消息,给到rabbitmq存储,消费者从rabbitmq中读取数据。

 

7.3.2  创建生产者代码send.py 

[root@xuegod63 ~]# vim  send.py

#!/usr/bin/env python

import pika

 

connection = pika.BlockingConnection(pika.ConnectionParameters(

        host='localhost'))

channel = connection.channel()

 

 

channel.queue_declare(queue='hello')

 

channel.basic_publish(exchange='',

                      routing_key='hello',

                      body='Hello World!')

print(" [x] Sent 'Hello World!'")

connection.close()

 

7.3.3  创建消耗者代码receive.py 

[root@xuegod63 ~]# vim receive.py

#!/usr/bin/env python

import pika

 

connection = pika.BlockingConnection(pika.ConnectionParameters(

        host='localhost'))

channel = connection.channel()

 

channel.queue_declare(queue='hello')

 

def callback(ch, method, properties, body):

    print(" [x] Received %r" % body)

 

channel.basic_consume(callback,

                      queue='hello',

                      no_ack=True)

 

print(' [*] Waiting for messages. To exit press CTRL+C')

channel.start_consuming()

7.3.4  开始测试队列

[root@xuegod63 ~]# python send.py   #此命令执行两次,产生两个名字叫hello的消息

 [x] Sent 'Hello World!'

[root@xuegod63 ~]# python send.py

 [x] Sent 'Hello World!'

 

[root@xuegod63 ~]# rabbitmqctl list_queues  #查看消息队列为2

Timeout: 60.0 seconds ...

Listing queues for vhost / ...

hello 2

 

在web界面查看消息队列,发现在2个消息队列等待处理:

 

 

 

 

[root@xuegod63 ~]# python receive.py   #消费或处理这2个消息

 [*] Waiting for messages. To exit press CTRL+C

 [x] Received 'Hello World!'   #可以看输出了消息队列中的消息内容

 [x] Received 'Hello World!'

 

[root@xuegod63 ~]# rabbitmqctl list_queues   #查看队列,已经为0

Timeout: 60.0 seconds ...

Listing queues for vhost / ...

hello 0

在web界面,查看队列,也为0了

 

 

总结:

7.1  RabbitMQ概述和运行机制

7.2  abbitmq使用方法

7.3  实战3-使用python调用rabbitmq服务器

 

posted on 2018-09-10 22:47  热巴热吧  阅读(193)  评论(0)    收藏  举报