第十一篇:消息队列、缓存
一、消息队列简绍
二、RabbitMQ基本实列:
三、RabbitMQ消息分发轮询
四、消息持久化
五、Fanout广播模式
六、Direct广播模式
七、Redis基本操作
八、Redis Hash操作
九、Redis发布订阅
回顾:
epoll linux 底层:libevent.so
gevent linux 底层: libevent.so
一、RabbitMQ 消息队列
python中的队列:
threading QUEUE,线程间进行交互
进程QUEUE,用于父进程与子进程进行交互,或同属同一父进程下的多个子进程;
RabbitMQ arlang语言开发;
模块:pika,celery
默认端口5672
生产者:
import pika
connection = pika.BlockingConnection(
pika.ConnectionParameters('localhost')
)
channel = connection.channel() #声明一个管道
channel.queue_declare(queue='hello', durable=True)
channel.basic_publish(
exchange='',
routing_key='hello',
body='Hello World!',
properties=pika.BasicProperties(
delivery_mode=2,
)
)
print('[x] Sent "Hello World!"')
connection.close()
消费者:
import pika
connection = pika.BlockingConnection(
pika.ConnectionParameters('localhost')
)
channel = connection.channel() #声明一个管道
channel.queue_declare(queue='hello',durable=True)
#再次申明是因为不确定是否已经声明;
def callback(ch,method,properties,body):
#ch,管道的内存对象,
print('[X] Received %r' % body)
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_consume(
callback, #如果收到消息就调用callback函数处理消息;
queue='hello',
no_ack=True)#消息处理完了不确认;
print('[*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming() #开始收消息;
消息分发轮询
一个生产者对多个消费者模式,去掉no_ack=True,消费者没处理完的消息会自动分发给下一个;
二、消息队列持久化
服务重启后消息队列丢失;队列存储在内存中;
每次申明队列的时候添加 durable=True 用来持久化队列,没有持久化消息;
持久化消息:生成消息时加:
properties=pika.BasicProperties(
delivery_mode=2,
)
消费者端加:
channel.basic_qos(prefetch_count=1)
当前客户端接收消息大于一时不再接收新的消息;
三、消息广播
exchange类型:
fanout:所以
direct:
topic:
headers:
随机生成queue_name
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
定义queue类型:
channel.exchange_declare(exchange='logs',type='fanout')
绑定某个转发器:
channel.queue_bind(exchange='logs',queue=queue_name)
消息订阅发布模式;
direct广播模式
分类广播
更细致的消息过滤:
正则匹配过滤
topic广播模式
rpc
双队列,既是生产者又是消费者;
四、缓存:
Redis
每秒写8万、读10万
redis基本操作:
redis-cli
set key value
keys * #查看所有key
get key #获取value
set key ex 3 #设置过期时间秒
set key px 3 #设置过期时间毫秒
set key value nx #key不存在时当前set操作执行
set key value xx #key存在时当前set操作执行
mset n1 aa n2 bb #批量设置
mget n1 n2 #批量获取
getset #设置新值并返回原来的值
getrange n1 1 2 #获取值切片
setrange n1 1 AC #指定字符串索引设置值
setbit n1 1 0 #指定二进制位修改
bitcount
incr aa #自增
decr aa #自减
append key xxxxx #追加
select 15 切换db
hash存储
hset info name alex
hget info name
hkeys info
hvals info
hgetall info
hmset
hmget key k1 k2
hlen
hexists
hdel
hincrby
hscan #过滤
列表:
lpush names alex jack bob 先入后出
lrange names 0 -1
rpush 先入先出
linsert 插入
import redis
r = redis.Redis(host='192.168.209.128',port=6379)
r.set("foo","Bar")
print(r.get("foo"))
pool = redis.ConnectionPool(host='192.168.209.128',port=6379)
r = redis.Redis(connection_pool=pool)