simple简单模式(下面的代码为工作模式,这里只是简单的说下简单模式):
- 消息产生者将消息放入队列
- 消息的消费者(consumer) 监听(while) 消息队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列中删除(隐患 消息可能没有被消费者正确处理,已经从队列中消失了,造成消息的丢失)应用场景:聊天(中间有一个过度的服务器;p端,c端)
3. work工作模式:
消息产生者将消息放入队列消费者可以有多个,消费者1,消费者2,同时监听同一个队列,消息被消费?C1 C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息(隐患,高并发情况下,默认会产生某一个消息被多个消费者共同使用,可以设置一个开关(syncronize,与同步锁的性能不一样) 保证一条消息只能被一个消费者使用)
应用场景:红包;大项目中的资源调度(任务分配系统不需知道哪一个任务执行系统在空闲,直接将任务扔到消息队列中,空闲的系统自动争抢)
import threading
import pika
class SingletonClass(object):
"""单例模式用来少创建连接"""
# 加锁,防止并发较高时,同时创建对象,导致创建多个对象
_singleton_lock = threading.Lock()
def __init__(self, username='baibing', password='123456', ip='ip', port=5672, data={}):
"""__init__在new出来对象后实例化对象"""
self.credentials = pika.PlainCredentials(username, password)
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=ip, port=port, credentials=self.credentials))
self.channel = self.connection.channel()
print('连接成功')
def __new__(cls):
"""__new__用来创建对象"""
if not hasattr(SingletonClass, "_instance"):
with SingletonClass._singleton_lock:
if not hasattr(SingletonClass, "_instance"):
SingletonClass._instance = super().__new__(cls)
return SingletonClass._instance
def callback(self, ch, method, properties, body):
"""订阅者的回调函数,可以在这里面做操作,比如释放库存等"""
# ch.basic_ack(delivery_tag=method.delivery_tag) # ack机制,
print("邮箱", body.decode())
def connection_close(self):
"""关闭连接"""
self.connection.close()
def consuming_start(self):
"""等待消息"""
self.channel.start_consuming()
def this_publisher(self, email, queue_name='HELLOP'):
"""发布者
email:消息
queue_name:队列名称
"""
# 1、创建一个名为HELLOP的队列
self.channel.queue_declare(queue=queue_name)
# 2、简单模式,向名为HELLOP队列中插入用户邮箱地址email
self.channel.basic_publish(exchange='',
routing_key=queue_name,
body=email
)
print("队列{}发送用户邮箱{}到MQ成功".format(queue_name, email))
# 3. 关闭连接
self.connection_close()
def this_subscriber(self, queue_name='HELLOP', prefetch_count=10):
"""订阅者
queue_name:队列名称
prefetch_count:限制未处理消息的最大值,ack未开启时生效
"""
self.channel.basic_consume(
queue_name,
self.callback, # 回调地址(函数)
auto_ack=True # True自动ack机制,告诉队列完成了,反之则需要手动告诉队列完成了
)
# 等待消息
self.consuming_start()
if __name__ == '__main__':
obj1 = SingletonClass()
print(id(obj1))
# 发布消息
obj1.this_publisher('2043232@qq.com')
obj2 = SingletonClass()
print(id(obj2))
# 发布消息
obj2.this_publisher('204323211111@qq.com')