#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author: zengchunyun
"""
import pika class MQServer(object):
def __init__(self, host, port=5672, exchange=None, exchange_type="topic"):
"""
初始化MQ设置
:param host: MQ服务器地址
:param port: MQ端口
:param exchange: 交换器名称
:param exchange_type: 交换器类型,默认关键字类型
:return:
"""
self.host = host
self.port = port
self.exchange = exchange
self.exchange_type = exchange_type
self.queue = None
self.connection = self.connect()
self.channel = self.connect_channel()
self.create_exchange() def connect(self):
"""
连接MQ服务器
:return:
"""
return pika.BlockingConnection(pika.ConnectionParameters(host=self.host, port=self.port)) def connect_channel(self):
"""
创建频道
:return:
"""
return self.connection.channel() def create_exchange(self):
"""
定义交换器名称,防止发布时,如果交换器不存在,异常
:return:
"""
self.channel.exchange_declare(exchange=self.exchange, type=self.exchange_type) def publish(self, exchange=None, routing_key=None, body=None):
"""
创建发布者
:param exchange: 交换器名称
:param routing_key: 路由KEY
:param body:消息主体
:return:
"""
if exchange:
self.exchange = exchange
self.channel.basic_publish(exchange=self.exchange, routing_key=routing_key, body=body)
self.close() def consumer(self, exchange=None, routing_key=None, callback=None):
"""
创建消费者
:param exchange:
:param routing_key:
:param callback:
:return:
"""
if exchange:
self.exchange = exchange
self.create_queue()
self.channel.queue_bind(queue=self.queue, exchange=self.exchange, routing_key=routing_key)
self.channel.basic_consume(consumer_callback=callback, queue=self.queue, no_ack=True)
self.start() def create_queue(self):
"""
生成队列,当关闭consumer时,加上exclusive=True,queue也会被删除
:return:
"""
self.queue = self.channel.queue_declare(exclusive=True).method.queue # 为每个消费者生成不同的队列 def close(self):
"""
关闭消息连接
:return:
"""
self.connection.close() def start(self):
self.channel.start_consuming()

1.消息持久化存储

  虽然有了消息反馈机制,但如果rabbitmq自身挂掉的话,那么任务还是会丢失,所以需要将任务持久化存储起来,

durable=True  # 开启持久化设置,rabbitmq不允许使用不同的参数来重新定义存在的队列

self.queue = self.channel.queue_declare(exclusive=True,durable=True)  
self.channel.exchange_declare(exchange=self.exchange, type=self.exchange_type, durable=True)
在发送任务的时候,用delivery_mode=2来标记任务为持久化存储
 self.channel.basic_publish(exchange='',
routing_key=routing_key,
body=message,
properties=pika.BasicProperties(
delivery_mode = 2, # make message persistent
))

2.公平调度(fair dispatch)

虽然每个工作者是依次分配到任务,但是每个任务不一定一样,可能有到任务比较重,执行时间长,有的任务比较轻,执行时间短,如果能公平调度最好了,使用basic_qos设置prefetch_count=1,使得rabbitmq不会在同一时间给工作者分配多个任务,即只有工作者完成任务之后,才会再次接收到任务

 channel.basic_qos(prefetch_count=1)

完整示例代码

 #!/usr/bin/env python
import pika
import sys connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.queue_declare(queue='task_queue', durable=True) message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='',
routing_key='task_queue',
body=message,
properties=pika.BasicProperties(
delivery_mode = 2, # make message persistent
))
print (" [x] Sent %r" % (message,))
connection.close()

消费者代码

 #!/usr/bin/env python
import pika
import time connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() channel.queue_declare(queue='task_queue', durable=True)
print( ' [*] Waiting for messages. To exit press CTRL+C') def callback(ch, method, properties, body):
print (" [x] Received %r" % (body,))
time.sleep( body.count('.') )
print (" [x] Done")
ch.basic_ack(delivery_tag = method.delivery_tag) channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback,
queue='task_queue') channel.start_consuming()
 

rabbitmq应用的更多相关文章

  1. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  2. RabbitMq应用二

    在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...

  3. 如何优雅的使用RabbitMQ

    RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...

  4. RabbitMq应用一的补充(RabbitMQ的应用场景)

    直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...

  5. RabbitMq应用一

    RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...

  6. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  7. 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)

    Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...

  8. windows下 安装 rabbitMQ 及操作常用命令

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...

  9. RabbitMQ + PHP (三)案例演示

    今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...

  10. RabbitMQ + PHP (二)AMQP拓展安装

    上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...

随机推荐

  1. Centos 7最小化redis部署

    配置源 [GuGe] name=GuGe baseurl=ftp://192.168.1.82 gpgcheck= enable= 安装 sh-4.2# yum -y install gcc gcc- ...

  2. DirectX11 With Windows SDK--11 混合状态与光栅化状态

    前言 虽然这一部分的内容主要偏向于混合(Blending),但这里还需提及一下,关于渲染管线可以绑定的状态主要有如下四种: 光栅化状态(光栅化阶段) 采样器状态(像素着色阶段) 混合状态(输出合并阶段 ...

  3. HDU 1051(处理木棍 贪心)

    题意是处理一批木棍,如果当前处理的木棍长度和重量均大于前一根木棍的长度和重量,则处理当前木棍花费为 0,否则花费为 1. 用结构体存储木棍信息,将木棍按照长度从小到大排序,若长度相等则按照重量从小到大 ...

  4. MongoDB实战性能优化

    1. 性能优化分类 mongodb性能优化分为软件层面和操作系统层面. 软件层面,一般通过修改mongodb软件配置参数来达到,这个需要非常熟悉mongodb里面的各种配置参数: 而操作系统层面,相对 ...

  5. MySQL学习7 - 外键的变种 三种关系

    一 介绍 二 如何找两张表之间的关系 三 表的三种关系 1.书和出版社 2.作者和书籍的关系 3.用户和博客 本节的重点 如何找出两张表之间的关系 表的三种关系 一 介绍 因为有foreign key ...

  6. COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。最新解决方案

    检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问. (异常来自 HRE ...

  7. centos6,与centos7对于防火墙的操作

    CentOS 6.5 1.开放指定端口/sbin/iptables -I INPUT -p tcp --dport 端口号 -j ACCEPT   //写入修改/etc/init.d/iptables ...

  8. 【easy】225. Implement Stack using Queues

    用队列实现栈.这个实现方法十分的简单,就是在push这一步的时候直接变成逆序. class MyStack { private: queue<int> q; queue<int> ...

  9. linux 解决Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

    第一种: sudo vim /etc/resolv.conf 添加nameserver 8.8.8.8 第二种: /etc/apt/sources.list 的内容换成 deb http://old- ...

  10. Python-form表单标签

    语义:标记表单 #1.什么是表单? 表单就是专门用来接收用户输入或采集用户信息的 #2.表单的格式 <form> <表单元素> </form> 链接:https:/ ...