查看RabbitMQ的状态
[root@slave1 src]# rabbitmqctl status Status of node rabbit@slave1 ... [{pid,31613}, {running_applications,[{rabbit,"RabbitMQ","3.1.5"}, {mnesia,"MNESIA CXC 138 12","4.5"}, {os_mon,"CPO CXC 138 46","2.2.7"}, {xmerl,"XML parser","1.2.10"}, {sasl,"SASL CXC 138 11","2.1.10"}, {stdlib,"ERTS CXC 138 10","1.17.5"}, {kernel,"ERTS CXC 138 10","2.14.5"}]}, {os,{unix,linux}}, {erlang_version,"Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:16:16] [rq:16] [async-threads:30] [kernel-poll:true]\n"}, {memory,[{total,29325160}, {connection_procs,2704}, {queue_procs,42176}, {plugins,0}, {other_proc,9125504}, {mnesia,65960}, {mgmt_db,0}, {msg_index,37400}, {other_ets,806440}, {binary,754192}, {code,14419209}, {atom,1355273}, {other_system,2716302}]}, {vm_memory_high_watermark,0.4}, {vm_memory_limit,54089331507}, {disk_free_limit,1000000000}, {disk_free,19106615296}, {file_descriptors,[{total_limit,924}, {total_used,4}, {sockets_limit,829}, {sockets_used,1}]}, {processes,[{limit,1048576},{used,140}]}, {run_queue,0}, {uptime,4481727}] ...done.
基本的管理功能 stop [] #停止在erlang node上运行的rabbitmq,会使rabbitmq停止 stop_app #停止erlang node上的rabbitmq的应用,但是erlang node还是会继续运行的 start_app #启动erlan node上的rabbitmq的应用 wait #等待rabbitmq服务启动 reset #初始化node状态,会从集群中删除该节点,从管理数据库中删除所有数据,例如vhosts等等。在初始化之前rabbitmq的应用必须先停止 force_reset #无条件的初始化node状态 rotate_logs #轮转日志文件 cluster管理 join_cluster [--ram] #clusternode表示node名称,--ram表示node以ram node加入集群中。默认node以disc node加入集群,在一个node加入cluster之前,必须先停止该node的rabbitmq应用,即先执行stop_app。 cluster_status #显示cluster中的所有node change_cluster_node_type disc | ram #改变一个cluster中node的模式,该节点在转换前必须先停止,不能把一个集群中唯一的disk node转化为ram node forget_cluster_node [--offline] #远程移除cluster中的一个node,前提是该node必须处于offline状态,如果是online状态,则需要加--offline参数。 update_cluster_nodes clusternode # sync_queue queue #同步镜像队列 cancel_sync_queue queue # 用户管理 add_user #在rabbitmq的内部数据库添加用户 delete_user #删除一个用户 change_password #改变用户密码 \\改变web管理登陆密码 clear_password #清除用户密码,禁止用户登录 set_user_tags ... #设置用户tags list_users #列出用户 add_vhost #创建一个vhosts delete_vhost #删除一个vhosts list_vhosts [ ...] #列出vhosts set_permissions [-p ] #针对一个vhosts 给用户赋予相关权限 clear_permissions [-p ] #清除一个用户对vhosts的权限 list_permissions [-p ] #列出哪些用户可以访问该vhosts list_user_permissions #列出该用户的访问权限 set_parameter [-p ] # clear_parameter [-p ] # list_parameters [-p ] # policy管理,策略用来控制和修改queues和exchange在集群中的行为,策略可以应用到vhost set_policy [-p ] [--priority ] [--apply-to ] #name 策略名称,pattern 正则表达式,用来匹配资源,符合的就会应用设置的策略,apply-to 表示策略应用到什么类型的地方,一般有queues、exchange和all,默认是all。priority 是个整数优先级,definition 是json格式设置的策略。 clear_policy [-p ] #清除一个策略 list_policies [-p ] #列出已有的策略 queues && exchange状态信息 list_queues [-p ] [ ...] #返回queue的信息,如果省略了-p参数,则默认显示的是"/"vhosts的信息。 list_exchanges [-p ] [ ...] #返回exchange的信息。 list_bindings [-p ] [ ...] #返回绑定信息。 list_connections [ ...] #返回链接信息。 list_channels [ ...] #返回目前所有的channels。 list_consumers [-p ] #返回consumers, status #显示broker的状态 environment #显示环境参数的信息 report #返回一个服务状态report, eval rabbitmq支持各种插件,开启插件可以使用rabbitmq-plugins命令 插件的开启和关闭方法 rabbitmq-plugins [ ] Commands: list [-v] [-m] [-E] [-e] [ ] 显示所有的的插件。-v 显示版本 -m 显示名称 -E 显示明确已经开启的 -e显示明确的和暗中开启的 enable ... 开启一个插件 disable ... 关闭一个插件 开启:rabbitmq-plugins enable rabbitmq_management rabbitmq_management插件的用法: web http://host:15672/ api http://host:15672/api/ cli http://host:15672/cli
简单的helloworld 消费者 生产者
==》》生产者: #coding:utf-8 import sys import pika credentials=pika.PlainCredentials("guest","guest") #获取信道 conn_params=pika.ConnectionParameters("192.168.30.252",credentials=credentials) conn_broker=pika.BlockingConnection(conn_params) channel=conn_broker.channel() #声明交换器 ''' callback=None, exchange=None, #交换器名称 exchange_type='direct', #交换器的类型 passive=False, #校验是否存在 durable=False, #是否持久化 auto_delete=False,#最后一个订阅后是否删除 internal=False, nowait=False, arguments=None, type=None ''' channel.exchange_declare(exchange="hello-exchange",type="direct",passive=False,durable=True,auto_delete=False) #创建文本消息 msg=sys.argv[1] msg_props=pika.BasicProperties() msg_props.content_type='text/plain' #发布消息 channel.basic_publish(body=msg,exchange="hello-exchange",properties=msg_props,routing_key="hola") #==》》 消费者 #coding:utf-8 __author__ = 'similarface' #coding:utf-8 __author__ = 'similarface' import pika #建立到代理服务器的连接 credentials=pika.PlainCredentials('guest','guest') conn_params=pika.ConnectionParameters("192.168.30.252",credentials=credentials) conn_broker=pika.BlockingConnection(conn_params) #获取信道 channel=conn_broker.channel() #声明交换器 channel.exchange_declare(exchange="hello-exchange",type="direct",passive=False ,durable=True,auto_delete=False) #声明队列 channel.queue_declare(queue="hello-queue") #通过键hola 将队列和交换器绑定 channel.queue_bind(queue="hello-queue",exchange="hello-exchange",routing_key="hola") #用于处理传入消息的函数 def msg_consumer(channel,method,header,body): #消息确认 channel.basic_ack(delivery_tag=method.delivery_tag) if body=="quit": #停止消费并退出 channel.basic_cancel(consumer_tag="hello-consumer") channel.stop_consuming() else: print(body) return #订阅消费者 channel.basic_consume(msg_consumer,queue="hello-queue",consumer_tag="hello-consumer") #开始消费 channel.start_consuming() 带有消息跟踪的生产者 #coding:utf-8 import sys import pika from pika import spec credentials=pika.PlainCredentials("guest","guest") #获取信道 conn_params=pika.ConnectionParameters("192.168.30.252",credentials=credentials) conn_broker=pika.BlockingConnection(conn_params) channel=conn_broker.channel() #不知道高版本的pika怎么加入回调函数 使用了消息订阅的返回值来代替下面这个函数 def confirm_handler(frame): if type(frame.method)==spec.Confirm.SelectOk: print("Channel in 'confirm' mode.") #Basic.Nack 指明了消息由于RabbitMQ内部错误而丢失 elif type(frame.method)==spec.Basic.Nack: #frame.method.delivery_tag 就是信道里面消息的ID if frame.method.delivery_tag in msg_ids: print("Message lost") # elif type(frame.method)==spec.Basic.Ack: if frame.method.delivery_tag in msg_ids: print("Confirm received!") msg_ids.remove(frame.method.delivery_tag) #将信道设置成confirm模式 #channel.confirm_delivery(callback=confirm_handler) #get error 参数错误 channel.confirm_delivery() #get error 参数错误 msg=sys.argv[1] msg_props=pika.BasicProperties() msg_props.content_type="text/plain" #reset消息ID追踪器 msg_ids=[] #发布消息 if channel.basic_publish(body=msg,exchange="hello-exchange",properties=msg_props,routing_key="hola"): print("Message recived") else: print("Message lost") #将ID添加道追踪列表中 #msg_ids.append(len(msg_ids)+1) channel.close() #RabbitMQ 日志默认放在 rabbit@`hostname`.log startup_err startup_log #RabbitMQ的启动 detached守护进程模式 1.rabbitmq-server -detached 2.start_rabbitmq () { status_rabbitmq quiet ... # RABBIT_NOFILES_LIMIT from /etc/sysconfig/rabbitmq-server is not handled # automatically if [ "$RABBITMQ_NOFILES_LIMIT" ]; then ulimit -n $RABBITMQ_NOFILES_LIMIT fi ensure_pid_dir set +e RABBITMQ_PID_FILE=$PID_FILE $START_PROG $DAEMON \ > "${INIT_LOG_DIR}/startup_log" \ 2> "${INIT_LOG_DIR}/startup_err" \ 0<&- & #翻译 /usr/sbin/rabbitmqctl wait /var/run/rabbitmq/pid $CONTROL wait $PID_FILE >/dev/null 2>&1 RETVAL=$? set -e case "$RETVAL" in 0) echo SUCCESS if [ -n "$LOCK_FILE" ] ; then touch $LOCK_FILE fi ;; *) remove_pid echo FAILED - check ${INIT_LOG_DIR}/startup_\{log, _err\} RETVAL=1 ;; esac fi } #rpm 安装的可以使用 /etc/init.d/rabbitmq-server Usage: /etc/init.d/rabbitmq-server {start|stop|status|rotate-logs|restart|condrestart|try-restart|reload|force-reload} #可以学习shell启动脚本的写法 cat /etc/init.d/rabbitmq-server #关闭 CONTROL=/usr/sbin/rabbitmqctl PID_FILE=/var/run/rabbitmq/pid stop_rabbitmq () { status_rabbitmq quiet if [ $RETVAL = 0 ] ; then set +e # 还原 /usr/sbin/rabbitmqctl stop /var/run/rabbitmq/pid $CONTROL stop ${PID_FILE} > ${INIT_LOG_DIR}/shutdown_log 2> ${INIT_LOG_DIR}/shutdown_err RETVAL=$? set -e if [ $RETVAL = 0 ] ; then remove_pid if [ -n "$LOCK_FILE" ] ; then rm -f $LOCK_FILE fi else echo FAILED - check ${INIT_LOG_DIR}/shutdown_log, _err fi else echo RabbitMQ is not running RETVAL=0 fi } #重启: restart_rabbitmq() { stop_rabbitmq start_rabbitmq } #配置文件 NAME=rabbitmq-server [ -f /etc/default/${NAME} ] && . /etc/default/${NAME} [ -f /etc/sysconfig/${NAME} ] && . /etc/sysconfig/${NAME} #管理用户 #添加用户change 密码 houyi [root@slave1 ~]# rabbitmqctl add_user change houyi Creating user "change" ... ...done. #删除用户 [root@slave1 ~]# rabbitmqctl delete_user change Deleting user "change" ... ...done. #列出用户 [root@slave1 ~]# rabbitmqctl list_users Listing users ... guest [administrator] ...done. #添加虚拟host [root@slave1 ~]# rabbitmqctl add_vhost yuegong Creating vhost "yuegong" ... ...done. #添加用户 [root@slave1 ~]# rabbitmqctl add_user change houyi Creating user "change" ... ...done. #赋予权限 [root@slave1 ~]# rabbitmqctl set_permissions -p yuegong change ".*" ".*" ".*" Setting permissions for user "change" in vhost "yuegong" ... ...done. #查看权限 [root@slave1 ~]# rabbitmqctl list_user_permissions change Listing permissions for user "change" ... yuegong .* .* .* ...done. #查看vhost权限 [root@slave1 ~]# rabbitmqctl list_permissions -p yuegong Listing permissions in vhost "yuegong" ... change .* .* .* ...done. #清除权限 [root@slave1 ~]# rabbitmqctl clear_permissions -p yuegong change Clearing permissions for user "change" in vhost "yuegong" ... ...done. #查看权限 [root@slave1 ~]# rabbitmqctl list_user_permissions change Listing permissions for user "change" ... ...done. #查看消息队列 ------------ #发布消息 for i in range(10000): channel.basic_publish(body=msg,exchange="hello-exchange",properties=msg_props,routing_key="hola")= ------------ #查看队列信息 [root@slave1 ~]# rabbitmqctl list_queues Listing queues ... celery 0 hello-queue 672 hello-queue232 0 ping 0 ...done. #查看指定vhost的队列信息 [root@slave1 ~]# rabbitmqctl list_queues -p yuegong Listing queues ... hello-queue 41028 hello-queue232 0 ...done. #查看更加详细的队列信息 [root@slave1 ~]# rabbitmqctl list_queues name messages consumers memory durable auto_delete Listing queues ... celery 0 0 13952 true false hello-queue 0 1 9168 false false hello-queue232 0 0 8952 false false ping 0 0 8952 false false ...done. #查看交换器的信息 [root@slave1 ~]# rabbitmqctl list_exchanges Listing exchanges ... direct amq.direct direct amq.fanout fanout amq.headers headers amq.match headers amq.rabbitmq.log topic amq.rabbitmq.trace topic amq.topic topic celery direct celery.pidbox fanout celeryev topic hello-exchange direct reply.celery.pidbox direct rpc direct ...done. #查看绑定信息 [root@slave1 ~]# rabbitmqctl list_bindings Listing bindings ... exchange celery queue celery [] exchange hello-queue queue hello-queue [] exchange hello-queue232 queue hello-queue232 [] exchange ping queue ping [] celery exchange celery queue celery [] hello-exchange exchange hello-queue queue hola [] rpc exchange ping queue ping [] ...done. #轮换日志 rabbitmqctl rotate_logs .1 AMQP ===》目标==》 解耦 异步 ===》 扩展性 跨语言 ===》 发后即忘==》批处理 通知 #实例一: 农村下午6:00 村头的广播开始播放了 #广播通知 #coding:utf-8 import pika import sys connection=pika.BlockingConnection(pika.ConnectionParameters(host="192.168.30.252")) channel=connection.channel() channel.exchange_declare(exchange='logs',exchange_type='fanout') message=' '.join(sys.argv[1:]) or "Info:农民要种地" channel.basic_publish(exchange='logs',routing_key='',body=message) print(" [x] 通知 %r" % message) connection.close() #收听这个广播的人们 #coding:utf-8 import pika connection=pika.BlockingConnection(pika.ConnectionParameters(host='192.168.30.252')) channel=connection.channel() #交换器的类型 channel.exchange_declare(exchange='logs',exchange_type='fanout') #队列声明 result = channel.queue_declare(exclusive=True) queue_name = result.method.queue #绑定队列 channel.queue_bind(exchange='logs',queue=queue_name) print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body): print(body.decode('utf-8')) channel.basic_consume(callback,queue=queue_name,no_ack=True) channel.start_consuming() >>[root@slave1 rabbitrundir]# /usr/local/python27/bin/python emit_log.py "村长开会" [x] 通知 '\xe6\x9d\x91\xe9\x95\xbf\xe5\xbc\x80\xe4\xbc\x9a' << [*] Waiting for logs. To exit press CTRL+C 村长开会 #实例二: __author__ = 'similarface' import pika import sys connection=pika.BlockingConnection(pika.ConnectionParameters(host='192.168.30.252')) channel=connection.channel() channel.exchange_declare(exchange='topic_logs',type='topic') result=channel.queue_declare(exclusive=True) queue_name=result.method.queue binding_keys = sys.argv[1:] if not binding_keys: sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0]) sys.exit(1) for binding_key in binding_keys: channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key=binding_key) print(' [*] Waiting for logs. To exit press CTRL+C') def callback(ch, method, properties, body): print(" [x] %r:%r" % (method.routing_key, body)) channel.basic_consume(callback,queue=queue_name,no_ack=True) channel.start_consuming() ################################################## #coding:utf-8 __author__ = 'similarface' import pika import sys connection=pika.BlockingConnection(pika.ConnectionParameters(host='192.168.30.252')) channel=connection.channel() channel.exchange_declare(exchange='topic_logs',exchange_type='topic') routing_key=sys.argv[1] if len(sys.argv)> 1 else "anonymous.info" message=' '.join(sys.argv[2:]) or 'Hello World' channel.basic_publish(exchange='topic_logs',routing_key=routing_key,body=message) print(" [x] Sent %r:%r" % (routing_key, message)) connection.close() result: 示例三: #coding:utf-8 __author__ = 'similarface' import pika import uuid class FibonacciRpcClient(object): def __init__(self): self.connection=pika.BlockingConnection(pika.ConnectionParameters("192.168.30.252",credentials=pika.PlainCredentials("guest","guest"))) self.channel=self.connection.channel() result = self.channel.queue_declare(exclusive=True) self.callback_queue = result.method.queue self.channel.basic_consume(self.on_response, no_ack=True,queue=self.callback_queue) def on_response(self, ch, method, props, body): if self.corr_id == props.correlation_id: self.response = body def call(self, n): self.response = None self.corr_id = str(uuid.uuid4()) self.channel.basic_publish(exchange='', routing_key='rpc_queue', properties=pika.BasicProperties( reply_to = self.callback_queue, correlation_id = self.corr_id, ), body=str(n)) while self.response is None: self.connection.process_data_events() return int(self.response) fibonacci_rpc = FibonacciRpcClient() print(" [x] Requesting fib(300)") response = fibonacci_rpc.call(30) print(" [.] Got %r" % response) ############分割线############# #coding:utf-8 __author__ = 'similarface' import pika connection=pika.BlockingConnection(pika.ConnectionParameters("192.168.30.252",virtual_host="/",credentials=pika.PlainCredentials("guest","guest"))) channel=connection.channel() channel.queue_declare(queue='rpc_queue') def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2) def on_request(ch, method, props, body): n = int(body) print(" [.] fib(%s)" % n) response = fib(n) ch.basic_publish(exchange='', routing_key=props.reply_to, properties=pika.BasicProperties(correlation_id = props.correlation_id), body=str(response)) ch.basic_ack(delivery_tag = method.delivery_tag) channel.basic_qos(prefetch_count=1) channel.basic_consume(on_request, queue='rpc_queue') print(" [x] Awaiting RPC requests") channel.start_consuming() result: Our RPC service is now ready. We can start the server: $ python rpc_server.py [x] Awaiting RPC requests To request a fibonacci number run the client: $ python rpc_client.py [x] Requesting fib(30) |