一、RabbitMQ

1、基础概念

rabbitMQ说白了就是一个消息队列,类似于Queue,也是生产者与消费者模型.只不过做了扩展,所不同的是Queue在内存中的消息队列,而RabbitMQ是部署在机器上的;

一般而言,生成者往队列中放数据,而消费者从队列中取数据;

import Queue
import threading
message = Queue.Queue()
def producer(i): #生产者
while True:
message.put(i) def consumer(i): #消费者
while True:
msg = message.get(i) for i in range():
t=threading.Thread(target=producer,args=(i,))
t.start()
for i in range():
t=threading.Thread(target=consumer,args=(i,))
t.start()

生产者与消费者模型

RabbitMQ单独安装在一台服务器上,作为一种消息中间件,生产者和消费者都需要能够连接上这台机器;

配置安装epel源:      rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

安装erlang:           yum -y install erlang

安装rabbitmq_server并启动服务:    yum -y install rabbitmq-server                  /etc/init.d/rabbitmq-server start

客户端(生成者和消费者)需要安装API接口pika

#!/usr/bin/env python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.72.80'))
channel = connection.channel() #通道
channel.queue_declare(queue='hello') #生成队列,名为hello
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!') #往队列中插入的数据内容
print(" [x] Sent 'Hello World!'")
connection.close()

producer

#!/usr/bin/env python
# _*_ coding:utf- _*_
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='192.168.72.80'))
channel = connection.channel()
channel.queue_declare(queue='hello') #生成一个队列叫做hello,在消费者中可以省略,但前提是生成者首先运行起来,产生消息队列hello,否在在下面往hello队列中取数据的时候,会出错;队列不会重复去定义;
def callback(ch, method, properties, body): #body表示拿到的数据
print(" [x] Received %r" % body)
channel.basic_consume(callback, #从hello队列中拿数据,拿到数据就会执行callback函数;no_ack是为了防止消息丢失,如果为False,那么如果消费者没有给生成者返回ack,那么生成者就会将数据再次放入到队列中。
queue='hello',
no_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

consumer

2、RabbitMQ消息失联策略

关于no_ack=False,如果消费者将队列中的数据取走而没有给应答,那么重新启动消费者的时候依然可以看到之前的数据。

#!/usr/bin/env python
# _*_ coding:utf- _*_
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.72.80'))
channel = connection.channel()
channel.queue_declare(queue='hello')
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
import time
time.sleep()
#拿到数据之后,中断,再次执行看能否接受到数据
print 'ok'
ch.basic_ack(delivery_tag = method.delivery_tag)
channel.basic_consume(callback,
queue='hello',
no_ack=False)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

消费者失联

3、RabbitMQ服务器异常策略

如果服务器宕机,列中的数据就会丢失,解决方法是利用持久化,即将数据保存早硬盘中;

持久化是在生产者部分实现的,要实现持久化,队列和消息必须都要持久化,对于消费者,也可以不指定,取决于先启动生产者还是消费者;

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters( host='192.168.72.80'))
channel = connection.channel()
# make message persistent
channel.queue_declare(queue='hello', durable=True) channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!',
properties=pika.BasicProperties(
delivery_mode=, # make message persistent
))
print(" [x] Sent 'Hello World!'")
connection.close()

生产者

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.72.80'))
channel = connection.channel()
# make message persistent
channel.queue_declare(queue='hello', durable=True) #对于之前创建的队列,不能够实现持久化;只能对新创建的队列实现持久化
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
import time
time.sleep()
print 'ok'
ch.basic_ack(delivery_tag = method.delivery_tag)
channel.basic_consume(callback,
queue='hello',
no_ack=False)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

消费者

4、RabbitMQ消息获取顺序

假设有两个消费者,分别往队列中拿数据,一个拿奇数,一个拿偶数,奇数简单而偶数复杂,那么一个消费者永远繁忙,而另一个永远轻松,channel.basic_qos(prefetch_count=1) 表示谁来谁取,不再按照奇偶数排列;

5、RabbitMQ发布和订阅

在消息的生成者和消费者中间通过exchange消息中间件实现,发布者在消息发布到队列之前不会将数据发布到队列中,而是放置到exchange中(之前的exchange为空),exchange的名字可以是任意的,exchange可以和多个队列进行绑定,这样exchange会将数据向绑定的队列中各发送一份数据;这样就实现了订阅和发布的功能啦~~~

以下创建fanout

import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters( host='192.168.72.80'))
channel = connection.channel()
channel.exchange_declare(exchange='logs', #发布者只需绑定exchange
type='fanout') message = ' '.join(sys.argv[:]) or "info: Hello World!"
channel.basic_publish(exchange='logs',
routing_key='',
body=message)
print(" [x] Sent %r" % message)
connection.close()

发布者

import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.72.80'))
channel = connection.channel()
channel.exchange_declare(exchange='logs',
type='fanout')
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='logs', #消费者需要将队列和exchange绑定起来
queue=queue_name)
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(ch, method, properties, body):
print(" [x] %r" % body)
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
channel.start_consuming()

接受者

6、RabbitMQ实现发布订阅和关键字匹配

解释fanout类型:exchange收到消息会将数据直接发送给队列

关键字匹配:根据关键字将exchange的数据发送到不同的队列中;

#!/usr/bin/env python
# _*_ coding:utf- _*_
import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='192.168.72.80'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs',type='direct') #必须为direct类型
message ='Hello World!'
channel.basic_publish(exchange='direct_logs',
routing_key='db', #生产者发送的关键字
body=message)
print(" [x] Sent %r:%r" % ('dali', message))
connection.close()

生产者

#!/usr/bin/env python
# _*_ coding:utf- _*_
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.72.80'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs',
type='direct')
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key="dali")
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key="db") #匹配到的关键字
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(ch, method, properties, body):
print(" [x] %r" % body)
channel.basic_consume(callback,queue=queue_name,no_ack=True)
channel.start_consuming()

消费者1

#!/usr/bin/env python
# _*_ coding:utf- _*_
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.72.80'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs',
type='direct')
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key="erbi")
channel.queue_bind(exchange='direct_logs',
queue=queue_name,
routing_key="db") #匹配到的关键字
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(ch, method, properties, body):
print(" [x] %r" % body)
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
channel.start_consuming()

消费者2

关键字模糊匹配:

#匹配0和或多个单词

*只能匹配一个单词

监控作业内容:

、使用Redis实现配置信息和数据的传输与存储。
、执行命令采集指标
、机器分类、实现监控模板
如:{ 'CPU':{'cmd',}}
机器根据主机名取模板,key为主机名,value为模板;
课可以通过反射类实现:
def cpu():
return 'CPU指标'
s='hi'
func=getattr(api,"hi")
result = func() 其中api.py最少的监控指标为两项
、某个指标超过多长时间内n次报警; 、使用线程:
a、每隔几秒,去取自己的模板
b、使用自己的模板 、运行程序获取监控指标,通过Redis的订阅和发布功能实现;

需求

二、Memcached

1、基础概念

将经常访问的内容放在缓存中,Memcache是一种缓存的机制,是管理内存的; Memcached不同于Redis,只有一种数据类型,即key-value;

安装memcached:

wget http://memcached.org/latest

tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install
PS:依赖libevent
       yum install libevent-devel
       apt-get install libevent-dev
 
使用python操作memcached需要安装相关模块:
https://pypi.python.org/pypi/python-memcached
 
启动memcached:   memcached -d -m 128 -u root -p 12000
成功启动之后,可以使用telnet连接memcached操作了.
 
2、set和set
import memcache
mc = memcache.Client(['192.168.72.80:12000'], debug=True) #debug表示在执行的时候,如果出错,信息就会以debug的模式输出
mc.set("foo", "bar")
ret = mc.get('foo')
print ret

set和get

set还具有修改键值对的功能

3、Memcached集群

memcached集群主机中后面会追加权重值,在memcached server内存中会维护一个memcached主机列表,主机列表中主机的重复此处与权重值相关

假如要执行mc.set("foo", "bar")
、将foo转换为一个数字
import binascii
print memcache.cmemcache_hash('foo') #将字符串foo转换为数字 、将该数字和主机列表长度求余数,将余数作为索引,以此来找到列表中主机的IP,将该KEY_VALUE值存入主机中;

原理

4、add

增加键值对,如果已经存在该键,报错.

5、replace

修改某个键的值,如果该键不存在,报错/异常

6、set和set_multi

import memcache
mc = memcache.Client([('192.168.72.80:12000',)], debug=True)
mc.set_multi({'key1': 'val1', 'key2': 'val2'})
print mc.get('key1')

set_multi

7、delete和delete_multi

如果存在该键,删除,不存在,不出异常

import memcache
mc = memcache.Client([('192.168.72.80:12000',)], debug=True)
mc.set_multi({'key1': 'val1', 'key2': 'val2'})
print mc.get('key1')
mc.delete_multi(['key1','key2']) #键值存在,删除,不存在,报异常

delete_multi

8、get和get_multi
import memcache
mc = memcache.Client([('192.168.72.80:12000',)], debug=True)
mc.set_multi({'key1': 'val1', 'key2': 'val2'})
print mc.get('key1')
#mc.delete_multi(['key1','key2'])
item_dict = mc.get_multi(["key1","key2"])
print item_dict #获取结果为字典

get_multi

9、append和prepend

append:指定key的值,在该key后面追加内容

prepend:指定key的值,在该key的值前面追加内容

import memcache
mc = memcache.Client([('192.168.72.80:12000',)], debug=True)
mc.set_multi({'k1': 'val1', 'key2': 'val2'})
print mc.get('k1')
mc.append('k1','after') #如果K1的值之前不存在,报异常
print mc.get('k1')
mc.prepend('k1','before')
print mc.get('k1')

append和prepend

10、desr和incr

incr:自增,默认自增1

decr:自减,默认自减1

import memcache
mc = memcache.Client(['192.168.72.80:12000'], debug=True)
mc.set('k1','')
mc.incr('k1')
print mc.get('k1')
mc.incr('k1',)
mc.decr('k1')
print mc.get('k1')
mc.decr('k1',)
print mc.get('k1')

decr和incr

11、gets和cas

具体查看

具体查看memcache.py源代码,本质上是利用socket来send和Recv来实现上述功能的;
 
 
 
redis文档:http://doc.redisfans.com/
 
 
 
 
三、SQLALchemy
参考地址:
          http://www.cnblogs.com/alex3714/articles/5978329.html
 
sqlarchemy是一款著名的python ORM框架,可以让对数据库小白的用户或者开发者不必写蛋疼的SQL,而直接通过程序语言对数据库进行操作,sqlarchemy提供的程序语言方法,可以先转换为SQL,再通过SQL对数据库进行相关操作;
可以有四种方式+sqlarchemy进行连接数据库操作,我这里采用的是pymysql,因为windows上安装mysql-python之类的包,会出现各种问题,并且python3目前还不支持mysql-python;
 
1、创建表;
sqlarchemy创建数据库表有两种方式:MetaData和declarative_base
 
使用MetaData
from sqlalchemy import create_engine,select, Table, Column, Integer, String, MetaData, ForeignKey

metadata = MetaData()

user = Table('user', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(20)),
) color = Table('color', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(20)),
)
engine = create_engine("mysql+pymysql://root:@192.168.74.20:3306/test", max_overflow=5) metadata.create_all(engine)

declarative_base

from sqlalchemy import create_engine,and_,or_,func,Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String,ForeignKey
from sqlalchemy.orm import sessionmaker,relationship Base = declarative_base() #生成一个SqlORM 基类 Host2Group = Table('host_2_group',Base.metadata,
Column('host_id',ForeignKey('host.id'),primary_key=True),
Column('group_id',ForeignKey('group.id'),primary_key=True),
) engine = create_engine("mysql+pymysql://root:@192.168.74.20:3306/test",echo=True) #echo=True表示打印出创建过程 class Host(Base):
__tablename__ = 'host'
id = Column(Integer,primary_key=True,autoincrement=True)
hostname = Column(String(64),unique=True,nullable=False)
ip_addr = Column(String(128),unique=True,nullable=False)
port = Column(Integer,default=22)
#group_id = Column(Integer, ForeignKey('group.id'))
groups = relationship('Group',
secondary=Host2Group,
backref='host_list') #group =relationship("Group",backref='host_list')
#group =relationship("Group",back_populates='host_list')
def __repr__(self):
return "<id=%s,hostname=%s, ip_addr=%s>" %(self.id,
self.hostname,
self.ip_addr)
class Group(Base):
__tablename__ = 'group'
id = Column(Integer,primary_key=True)
name = Column(String(64),unique=True,nullable=False)
#host_id = Column(Integer,ForeignKey('hosts.id'))
#host_list =relationship("Host", back_populates="group")
#hosts =relationship("Host")
def __repr__(self):
return "<id=%s,name=%s>" %(self.id,self.name) Base.metadata.create_all(engine) #创建所有表结构

2、增删改查

#!/usr/bin/env python
# -*- coding:utf-8 -*- from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey metadata = MetaData() user = Table('user', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(20)),
) color = Table('color', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(20)),
)
engine = create_engine("mysql+mysqldb://root:123@127.0.0.1:3306/s11", max_overflow=5) conn = engine.connect() # 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)
conn.execute(user.insert(),{'id':7,'name':'seven'})
conn.close() # sql = user.insert().values(id=123, name='wu')
# conn.execute(sql)
# conn.close() # sql = user.delete().where(user.c.id > 1) # sql = user.update().values(fullname=user.c.name)
# sql = user.update().where(user.c.name == 'jack').values(name='ed') # sql = select([user, ])
# sql = select([user.c.id, ])
# sql = select([user.c.name, color.c.name]).where(user.c.id==color.c.id)
# sql = select([user.c.name]).order_by(user.c.name)
# sql = select([user]).group_by(user.c.name) # result = conn.execute(sql)
# print result.fetchall()
# conn.close()

  

 

RabbitMQ、Memcached、SQLAlchemy的更多相关文章

  1. eAccelerator、memcached、xcache、APC 等四个加速扩展的区别

    折腾VPS的朋友,在安装好LNMP等Web运行环境后都会选择一些缓存扩展安装以提高PHP运行速度,常被人介绍的有eAccelerator.memcached.xcache.Alternative PH ...

  2. redis、memcached、mongoDB 对比与安装

    一.redis.memcached.mongoDB 对比 Memcached 和 Redis都是内存型数据库,数据保存在内存中,通过tcp直接存取,速度快,并发高.Mongodb是文档型的非关系型数据 ...

  3. 数据库应用(Mysql、Mongodb、Redis、Memcached、CouchDB、Cassandra)

    目前,主流数据库包括关系型(SQL)和非关系型(NoSQL)两种. 关系数据库是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据,支持复杂的事物处理和结构化查询.代表实 ...

  4. Docker部署Django项目+Nginx+Fluend日志收集 和redis、memcached、RabbitMQ、Celery

    前言 一.docker 1.docker是什么? Docker的英文本意是“搬运工”,Docker搬运的是集装箱(Container)可以成为容器,我可以把写的Django的WEB应用以及Python ...

  5. S1_搭建分布式OpenStack集群_03 Mysql、MQ、Memcached、ETCD安装配置

    一.安装mysql(contorller)controller ~]# yum -y install mariadb mariadb-server python2-PyMySQL 配置my.cnf文件 ...

  6. PHP 安装 redis、memcached、openssl、pdo_mysql等

        PHP openssl 扩展的安装 这些插件可以通过在 php.ini 中添加 extension 的方式来加载所需要的插件,其实在 php 的安装包里就已经有相关的插件代码包了,在 php7 ...

  7. redis、memcached、mongoDB 对比

    Mongodb和Memcached不是一个范畴内的东西.Mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据.Mongodb 和 Memcached不存在谁替换谁的问题. ...

  8. redis、Memcached、MongoDb使用心得

    最近在思考数据库以及缓存的问题,发现这些知识点其实是有一点关联的,于是这篇文章通过一个连环提问的方式将这些知识点串联起来. 问:为什么要用 Memcached.Redis,直接用 MySQL 这些数据 ...

  9. 网站缓存技术(Redis、Memcached、Ehcache)

    Redis 是什么? 通常而言目前的数据库分类有几种,包括 SQL/NSQL,,关系数据库,键值数据库等等等. 分类的标准也不一,Redis本质上也是一种键值数据库的,但它在保持键值数据库简单快捷特点 ...

随机推荐

  1. virt-install vs qemu-kvm创建guest主机

    virt-install是rpm包python-virtinst里的一个工具 -- 其实就是一个python写的脚本 .基本可以理解为virsh-install是qemu-kvm工具的人性化实现.可以 ...

  2. Solr——Windows下部署Solr6.6.0至Tomcat8.5.28(一)

    一.window 环境 solr 6.6.3 下载地址 http://archive.apache.org/dist/lucene/solr/ jdk 1.8    tomcat 8.5 本机tomc ...

  3. DOM常用的属性和方法

    之前一直傻傻分不清DOM和JavaScript究竟有什么区别,随着相关工作时间的增长,开始逐渐区分DOM和JavaScript了,最近,也一直在复习有关DOM方面的知识,<JavaScript ...

  4. OraOLEDB.Oracle找不到驱动问题

    如果安装Oracle的时候没有把Oracle Provider for OLE DB,这个组件安装上,那么就会导致在使用程序的时候无法使用Oracle客户端驱动问题,弥补的办法就是重新下载客户端程序. ...

  5. gentoo rt-thread scons --menuconfig libs/lxdialog/util.o: undefined reference to symbol 'nodelay'

    今天在另外一台电脑上面使用 rt-thread 的 env 工具,scons --menuconfig 出现错误,提示如下: scons: Reading SConscript files ... s ...

  6. linux常用命令总结-updating

    Linux 命令总结 启动终端: ctr+alt+t终端字体放大: ctr+shift+'+',终端字体缩小: ctr+'-'ls: 查看当前目录下的文件信息pwd: 查看目录所在的路径touch: ...

  7. 33.纯 CSS 创作牛奶文字变换效果

    原文地址:https://segmentfault.com/a/1190000015037234 感想:transform: translateY(50% & -50%);  animatio ...

  8. Python学习笔记_week3_函数

    一.介绍 1.面向对象(华山派)--->类(独门秘籍)--->class(定义的关键字) 2.面向过程(少林派)--->过程--->def 3.函数式编程(逍遥派)---> ...

  9. Maven概念模型

    两个核心 1.依懒管理:对jar包管理 2.项目构建管理:通过命令进行项目构建管理

  10. spring 之 factory-bean & factory-method

    这两者常常是一起出现的,或者说他们经常是一起被使用的.但是其实是分为了两种情况: 1 同时使用factory-bean 和 factory-method 如果,我们在一个bean 元素上同时配置 fa ...