记录
Rabbitmq的pika库实现了对消息队列的完美管理,但是假设我现在有n个服务(consumer),我如何能够看到哪个服务健康的存在呢?我之前的方法是写个监控服务的,每个服务写好后,会定期给监控服务发送个1,表示“我还活着”。如果监控挂了,那就没辙了。当然你可以通过http://ip:15672来查看所有服务的状态,然而不巧的是,这个管理页面不是很好,至少UI不够美观。通过官网,我们可以看到MQ有一套自己的http/api,所以我们就可以自己搞个管理网站了。这里是观察rabbitmq-management的发包请求来写的!!!使用了urllib库。
实现http-api
下面的代码,我都是经过测试的,还没有写全。也算是抛砖引玉吧
import urllib,urllib2
import simplejson
import base64
# 类
class MQManage(object):
def __init__(self):
self._conn = None
self._host = None
self._username = None
self._password = None
self._vhost = '/'
#创建一个连接
def create_connection(self,host,username,password):
try:
self._username = username
self._password = password
url = "http://"+host + ":15672/api/whoami"
self._host = "http://"+host
userInfo = "%s:%s" % (username, password)
userInfo = base64.b64encode(userInfo.encode('UTF-8'))
auth = 'Basic ' + userInfo#必须的
request = urllib2.Request(url)
request.add_header('content-type', 'application/json')
request.add_header('authorization', auth)
response = urllib2.urlopen(request)
self._conn = auth
except Exception, e:
return None
#设置用户权限
def set_user_vhost(self, vhost='/', configure='.*', write='.*', read='.*'):
try:
url = self._host + ':15672/api/permissions/%2F/'
url += self._username
body = {}
body['username'] = self._username
body['vhost'] = vhost
body['configure'] = configure
body['write'] = write
body['read'] = read
data = simplejson.dumps(body)
request = urllib2.Request(url, data)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
request.get_method = lambda: "PUT"
opener = urllib2.build_opener(urllib2.HTTPHandler)
response = urllib2.urlopen(request)
res = response.read()
return res
except Exception, e:
# print str(e)
return None
#列出所有用户
def list_users(self):
try:
url = self._host + ":15672/api/users"
request = urllib2.Request(url)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
response = urllib2.urlopen(request)
return response.read()
except Exception, e:
return None
#列出所有队列
def list_queues(self):
try:
url = self._host + ":15672/api/queues"
request = urllib2.Request(url)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
response = urllib2.urlopen(request)
return response.read()
except Exception, e:
return None
#列出所有交换机
def list_exchanges(self):
try:
url = self._host + ":15672/api/exchanges"
request = urllib2.Request(url)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
response = urllib2.urlopen(request)
exchanges = response.read()
return exchanges
except Exception, e:
return None
#列出所有连接
def list_connections(self):
try:
url = self._host + ":15672/api/connections"
request = urllib2.Request(url)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
response = urllib2.urlopen(request)
exchanges = response.read()
return exchanges
except Exception, e:
return None
#显示每个连接的详细信息
def show_connection_detail(self,connection):
#10.0.0.245%3A44104%20-%3E%2010.0.0.158%3A5672%20(1)
try:
con = urllib.quote_plus( connection,safe='(,),' )
url = self._host + ':15672/api/channels/'+ con
url = url.replace('+','%20')
# url = 'http://10.0.0.158:15672/api/connections/10.0.0.245%3A30078%20-%3E%2010.0.0.158%3A5672/channels'
request = urllib2.Request( url )
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
response = urllib2.urlopen(request)
detail = response.read()
return detail
except Exception, e:
print str(e)
return None
def clear_exchanges(self):
exchanges = self.list_exchanges()
for exchange in exchanges:
self.del_exchange(exchange_name=exchange['name'])
def clear_queues(self):
queues = self.list_queues()
for queue in queues:
self.del_queue(queue_name=queue['name'])
def del_exchange(self, exchange_name):
try:
url = self._host + ':15672/api/exchanges/%2F/'
url += exchange_name
body = {}
body['vhost'] = self._vhost
body['name'] = exchange_name
data = simplejson.dumps(body)
request = urllib2.Request(url, data)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
request.get_method = lambda: "PUT"
opener = urllib2.build_opener(urllib2.HTTPHandler)
response = urllib2.urlopen(request)
res = response.read()
return res
except Exception, e:
return None
def del_queue(self, queue_name ):
try:
url = self._host + ':15672/api/queues/%2F/'
url += queue_name
body = {}
body['vhost'] = self._vhost
body['name'] = queue_name
data = simplejson.dumps(body)
request = urllib2.Request(url, data)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
request.get_method = lambda: "DELETE"
opener = urllib2.build_opener(urllib2.HTTPHandler)
response = urllib2.urlopen(request)
res = response.read()
return res
except Exception, e:
return None
def add_vhost(self, vhost_name):
try:
url = self._host + ":15672/api/vhosts/"
url = url + vhost_name
body = {}
body['name'] = vhost_name
data = simplejson.dumps(body)
request = urllib2.Request(url, data)
request.add_header('content-type', 'application/json')
request.add_header('authorization', self._conn)
request.get_method = lambda: "PUT"
urllib2.build_opener(urllib2.HTTPHandler)
response = urllib2.urlopen(request)
res = response.read()
return None
except Exception, e:
print str(e)
return None
例如,使用show_connection_detail 后,可以得到类似这样的数据结果
{“connection_details”:{“name”:“10.0.0.245:33728 -> 10.0.0.158:5672”,“peer_port”:33728,“peer_host”:“10.0.0.245”},
“publishes”:[],“deliveries”:[],“consumer_details”:[{“channel_details”:{“name”:“10.0.0.245:33728 -> 10.0.0.158:5672 (1)”,“number”:1,“connection_name”:“10.0.0.245:33728 -> 10.0.0.158:5672”,“peer_port”:33728,“peer_host”:“10.0.0.245”},“queue”:“name”:“standard3”,“vhost”:"/"},“consumer_tag”:“ctag1.ccad2f1905964f1ca6c1d8134ed6e167”,“exclusive”:false,“ack_required”:true,“arguments”:{}}],“idle_since”:“2017-01-19 13:15:25”,“transactional”:false,“confirm”:false,“consumer_count”:1,“messages_unacknowledged”:0,“messages_unconfirmed”:0,“messages_uncommitted”:0,“acks_uncommitted”:0,“prefetch_count”:1,“client_flow_blocked”:false,“node”:“rabbit@ubuntu”,“name”:“10.0.0.245:33728 -> 10.0.0.158:5672 (1)”,“number”:1,“user”:“guest”,“vhost”:"/"}
具体的过程可以自己尝试
使用
mq = MQManage()
mq.create_connection("10.0.0.158",'guest','guest')
queuelist = mq.list_queues()
print queuelist
exchangelist = mq.list_exchanges()
print exchangelist
connections = mq.list_connections()
print connections
details = mq.show_connection_detail("10.0.0.245:33728 -> 10.0.0.158:5672 (1)")
print details
这里只是记录一下,客官也可以观察rabbitmq-management的数据包,自己分析,丰富完善。这种方法比较笨,但是对获取结果的分析,我们就可以观察到每个队列的详细信息,状态,数据包大小等等,不需要通过curl 在Linux下执行一条条命令(个人感觉,在linux下执行http/api请求,是效率最低下的)