[rabbitmq]RabbitMQ安装与使用

1.RabbitMQ介绍

  MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消 息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。

  • 特点 : 典型的“消费者-生产者模式”,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅队列中的消息。
  • 使用场景:在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。

2.RabbitMQ安装(CentOS 7)

3.RabbitMQ监控

  使用RabbitMQ监控的web页面首先要安装,相应的Web管理页面的组件,当前版本已经添加,这里便不需要自己动手了

1.添加配置文件

rabbitmq-env.conf
这个文件的位置是确定和不能改变的,位于:/etc/rabbitmq目录下(这个目录需要自己创建)。
文件的内容包括了RabbitMQ的一些环境变量,常用的有:
RABBITMQ_NODE_PORT= //端口号
#HOSTNAME=
#RABBITMQ_NODENAME=mq
#RABBITMQ_CONFIG_FILE= //配置文件的路径
#RABBITMQ_MNESIA_BASE=/rabbitmq/data //需要使用的MNESIA数据库的路径
#RABBITMQ_LOG_BASE=/rabbitmq/log //log的路径
#RABBITMQ_PLUGINS_DIR=/rabbitmq/plugins //插件的路径
**其实这里只需要配置端口号即可,我的配置为15672

2.打开RabbitMQ监控页面
截图

  • 打开页面:输入用户名密码(官方默认的是guest/guest,但为安全考虑仅在localhost下使用)

  • 添加用户

    rabbitmqctl add_user Username Password

  • 设置角色

    rabbitmqctl set_user_tags Username administrator

  • 使用 Username/Password即可登陆

  • 设置用户的Access visual hosts

4.常用RabbitMQ命令

1. 用户管理

用户管理包括增加用户,删除用户,查看用户列表,修改用户密码。

  • 新增一个用户

    rabbitmqctl add_user Username Password

  • 删除一个用户

    rabbitmqctl delete_user Username

  • 修改用户的密码

    rabbitmqctl change_password Username Newpassword

  • 查看当前用户列表

    rabbitmqctl list_users

2. 用户角色

按照个人理解,用户角色可分为五类,超级管理员, 监控者, 策略制定者, 普通管理者以及其他。

  • 超级管理员(administrator)

    可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。

  • 监控者(monitoring)

    可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)

  • 策略制定者(policymaker)

    可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。

    与administrator的对比,administrator能看到这些内容

  • 普通管理者(management)

    仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。

  • 其他

    无法登陆管理控制台,通常就是普通的生产者和消费者。

    了解了这些后,就可以根据需要给不同的用户设置不同的角色,以便按需管理。

  • 设置用户角色的命令为:

    rabbitmqctl set_user_tags User Tag

    User为用户名, Tag为角色名(对应于上面的administrator,monitoring,policymaker,management,或其他自定义名称)。

    也可以给同一用户设置多个角色,例如

    rabbitmqctl set_user_tags hncscwc monitoring policymaker

3. 用户权限

用户权限指的是用户对exchange,queue的操作权限,包括配置权限,读写权限。配置权限会影响到exchange,queue的声明和删除。读写权限影响到从queue里取消息,向exchange发送消息以及queue和exchange的绑定(bind)操作。

例如: 将queue绑定到某exchange上,需要具有queue的可写权限,以及exchange的可读权限;向exchange发送消息需要具有exchange的可写权限;从queue里取数据需要具有queue的可读权限。详细请参考官方文档中"How permissions work"部分。

相关命令为:

  • 设置用户权限

    rabbitmqctl set_permissions -p VHostPath User ConfP WriteP ReadP

  • 查看(指定hostpath)所有用户的权限信息

    rabbitmqctl list_permissions [-p VHostPath]

  • 查看指定用户的权限信息

    rabbitmqctl list_user_permissions User

  • 清除用户的权限信息

    rabbitmqctl clear_permissions [-p VHostPath] User

附录:RabbitMQ的配置文件

enabled_plugins

[rabbitmq_management].

rabbitmq.config

%% -*- mode: erlang -*-
%% ----------------------------------------------------------------------------
%% RabbitMQ Sample Configuration File.
%%
%% See http://www.rabbitmq.com/configure.html for details.
%% ----------------------------------------------------------------------------
[
 {rabbit,
  [%%
   %% Network Connectivity
   %% ====================
   %%

   %% By default, RabbitMQ will listen on all interfaces, using
   %% the standard (reserved) AMQP port.
   %%
   %% {tcp_listeners, [5672]},

   %% To listen on a specific interface, provide a tuple of {IpAddress, Port}.
   %% For example, to listen only on localhost for both IPv4 and IPv6:
   %%
   %% {tcp_listeners, [{"127.0.0.1", 5672},
   %%                  {"::1",       5672}]},

   %% SSL listeners are configured in the same fashion as TCP listeners,
   %% including the option to control the choice of interface.
   %%
   %% {ssl_listeners, [5671]},

   %% Maximum time for AMQP 0-8/0-9/0-9-1 handshake (after socket connection
   %% and SSL handshake), in milliseconds.
   %%
   %% {handshake_timeout, 10000},

   %% Log levels (currently just used for connection logging).
   %% One of 'debug', 'info', 'warning', 'error' or 'none', in decreasing
   %% order of verbosity. Defaults to 'info'.
   %%
   %% {log_levels, [{connection, info}, {channel, info}]},

   %% Set to 'true' to perform reverse DNS lookups when accepting a
   %% connection. Hostnames will then be shown instead of IP addresses
   %% in rabbitmqctl and the management plugin.
   %%
   %% {reverse_dns_lookups, true},

   %%
   %% Security / AAA
   %% ==============
   %%

   %% The default "guest" user is only permitted to access the server
   %% via a loopback interface (e.g. localhost).
   %% {loopback_users, [<<"guest">>]},
   %%
   %% Uncomment the following line if you want to allow access to the
   %% guest user from anywhere on the network.
   %% {loopback_users, []},

   %% Configuring SSL.
   %% See http://www.rabbitmq.com/ssl.html for full documentation.
   %%
   %% {ssl_options, [{cacertfile,           "/path/to/testca/cacert.pem"},
   %%                {certfile,             "/path/to/server/cert.pem"},
   %%                {keyfile,              "/path/to/server/key.pem"},
   %%                {verify,               verify_peer},
   %%                {fail_if_no_peer_cert, false}]},

   %% Choose the available SASL mechanism(s) to expose.
   %% The two default (built in) mechanisms are 'PLAIN' and
   %% 'AMQPLAIN'. Additional mechanisms can be added via
   %% plugins.
   %%
   %% See http://www.rabbitmq.com/authentication.html for more details.
   %%
   %% {auth_mechanisms, ['PLAIN', 'AMQPLAIN']},

   %% Select an authentication database to use. RabbitMQ comes bundled
   %% with a built-in auth-database, based on mnesia.
   %%
   %% {auth_backends, [rabbit_auth_backend_internal]},

   %% Configurations supporting the rabbitmq_auth_mechanism_ssl and
   %% rabbitmq_auth_backend_ldap plugins.
   %%
   %% NB: These options require that the relevant plugin is enabled.
   %% See http://www.rabbitmq.com/plugins.html for further details.

   %% The RabbitMQ-auth-mechanism-ssl plugin makes it possible to
   %% authenticate a user based on the client's SSL certificate.
   %%
   %% To use auth-mechanism-ssl, add to or replace the auth_mechanisms
   %% list with the entry 'EXTERNAL'.
   %%
   %% {auth_mechanisms, ['EXTERNAL']},

   %% The rabbitmq_auth_backend_ldap plugin allows the broker to
   %% perform authentication and authorisation by deferring to an
   %% external LDAP server.
   %%
   %% For more information about configuring the LDAP backend, see
   %% http://www.rabbitmq.com/ldap.html.
   %%
   %% Enable the LDAP auth backend by adding to or replacing the
   %% auth_backends entry:
   %%
   %% {auth_backends, [rabbit_auth_backend_ldap]},

   %% This pertains to both the rabbitmq_auth_mechanism_ssl plugin and
   %% STOMP ssl_cert_login configurations. See the rabbitmq_stomp
   %% configuration section later in this file and the README in
   %% https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl for further
   %% details.
   %%
   %% To use the SSL cert's CN instead of its DN as the username
   %%
   %% {ssl_cert_login_from, common_name},

   %% SSL handshake timeout, in milliseconds.
   %%
   %% {ssl_handshake_timeout, 5000},

   %%
   %% Default User / VHost
   %% ====================
   %%

   %% On first start RabbitMQ will create a vhost and a user. These
   %% config items control what gets created. See
   %% http://www.rabbitmq.com/access-control.html for further
   %% information about vhosts and access control.
   %%
   %% {default_vhost,       <<"/">>},
   %% {default_user,        <<"guest">>},
   %% {default_pass,        <<"guest">>},
   %% {default_permissions, [<<".*">>, <<".*">>, <<".*">>]},

   %% Tags for default user
   %%
   %% For more details about tags, see the documentation for the
   %% Management Plugin at http://www.rabbitmq.com/management.html.
   %%
   %% {default_user_tags, [administrator]},

   %%
   %% Additional network and protocol related configuration
   %% =====================================================
   %%

   %% Set the default AMQP heartbeat delay (in seconds).
   %%
   %% {heartbeat, 600},

   %% Set the max permissible size of an AMQP frame (in bytes).
   %%
   %% {frame_max, 131072},

   %% Set the max permissible number of channels per connection.
   %% 0 means "no limit".
   %%
   %% {channel_max, 128},

   %% Customising Socket Options.
   %%
   %% See (http://www.erlang.org/doc/man/inet.html#setopts-2) for
   %% further documentation.
   %%
   %% {tcp_listen_options, [binary,
   %%                       {packet,        raw},
   %%                       {reuseaddr,     true},
   %%                       {backlog,       128},
   %%                       {nodelay,       true},
   %%                       {exit_on_close, false}]},

   %%
   %% Resource Limits & Flow Control
   %% ==============================
   %%
   %% See http://www.rabbitmq.com/memory.html for full details.

   %% Memory-based Flow Control threshold.
   %%
   %% {vm_memory_high_watermark, 0.4},

   %% Fraction of the high watermark limit at which queues start to
   %% page message out to disc in order to free up memory.
   %%
   %% {vm_memory_high_watermark_paging_ratio, 0.5},

   %% Set disk free limit (in bytes). Once free disk space reaches this
   %% lower bound, a disk alarm will be set - see the documentation
   %% listed above for more details.
   %%
   %% {disk_free_limit, 50000000},

   %% Alternatively, we can set a limit relative to total available RAM.
   %%
   %% {disk_free_limit, {mem_relative, 1.0}},

   %%
   %% Misc/Advanced Options
   %% =====================
   %%
   %% NB: Change these only if you understand what you are doing!
   %%

   %% To announce custom properties to clients on connection:
   %%
   %% {server_properties, []},

   %% How to respond to cluster partitions.
   %% See http://www.rabbitmq.com/partitions.html for further details.
   %%
   %% {cluster_partition_handling, ignore},

   %% Make clustering happen *automatically* at startup - only applied
   %% to nodes that have just been reset or started for the first time.
   %% See http://www.rabbitmq.com/clustering.html#auto-config for
   %% further details.
   %%
   %% {cluster_nodes, {['rabbit@my.host.com'], disc}},

   %% Interval (in milliseconds) at which we send keepalive messages
   %% to other cluster members. Note that this is not the same thing
   %% as net_ticktime; missed keepalive messages will not cause nodes
   %% to be considered down.
   %%
   %% {cluster_keepalive_interval, 10000},

   %% Set (internal) statistics collection granularity.
   %%
   %% {collect_statistics, none},

   %% Statistics collection interval (in milliseconds).
   %%
   %% {collect_statistics_interval, 5000},

   %% Explicitly enable/disable hipe compilation.
   %%
   %% {hipe_compile, true},

   %% Timeout used when waiting for Mnesia tables in a cluster to
   %% become available.
   %%
   %% {mnesia_table_loading_timeout, 30000},

   %% Size in bytes below which to embed messages in the queue index. See
   %% http://www.rabbitmq.com/persistence-conf.html
   %%
   %% {queue_index_embed_msgs_below, 4096}

  ]},

 %% ----------------------------------------------------------------------------
 %% Advanced Erlang Networking/Clustering Options.
 %%
 %% See http://www.rabbitmq.com/clustering.html for details
 %% ----------------------------------------------------------------------------
 {kernel,
  [%% Sets the net_kernel tick time.
   %% Please see http://erlang.org/doc/man/kernel_app.html and
   %% http://www.rabbitmq.com/nettick.html for further details.
   %%
   %% {net_ticktime, 60}
  ]},

 %% ----------------------------------------------------------------------------
 %% RabbitMQ Management Plugin
 %%
 %% See http://www.rabbitmq.com/management.html for details
 %% ----------------------------------------------------------------------------

 {rabbitmq_management,
  [%% Pre-Load schema definitions from the following JSON file. See
   %% http://www.rabbitmq.com/management.html#load-definitions
   %%
   %% {load_definitions, "/path/to/schema.json"},

   %% Log all requests to the management HTTP API to a file.
   %%
   %% {http_log_dir, "/path/to/access.log"},

   %% Change the port on which the HTTP listener listens,
   %% specifying an interface for the web server to bind to.
   %% Also set the listener to use SSL and provide SSL options.
   %%
   %% {listener, [{port,     12345},
   %%             {ip,       "127.0.0.1"},
   %%             {ssl,      true},
   %%             {ssl_opts, [{cacertfile, "/path/to/cacert.pem"},
   %%                         {certfile,   "/path/to/cert.pem"},
   %%                         {keyfile,    "/path/to/key.pem"}]}]},

   %% One of 'basic', 'detailed' or 'none'. See
   %% http://www.rabbitmq.com/management.html#fine-stats for more details.
   %% {rates_mode, basic},

   %% Configure how long aggregated data (such as message rates and queue
   %% lengths) is retained. Please read the plugin's documentation in
   %% http://www.rabbitmq.com/management.html#configuration for more
   %% details.
   %%
   %% {sample_retention_policies,
   %%  [{global,   [{60, 5}, {3600, 60}, {86400, 1200}]},
   %%   {basic,    [{60, 5}, {3600, 60}]},
   %%   {detailed, [{10, 5}]}]}
  ]},

 %% ----------------------------------------------------------------------------
 %% RabbitMQ Shovel Plugin
 %%
 %% See http://www.rabbitmq.com/shovel.html for details
 %% ----------------------------------------------------------------------------

 {rabbitmq_shovel,
  [{shovels,
    [%% A named shovel worker.
     %% {my_first_shovel,
     %%  [

     %% List the source broker(s) from which to consume.
     %%
     %%   {sources,
     %%    [%% URI(s) and pre-declarations for all source broker(s).
     %%     {brokers, ["amqp://user:password@host.domain/my_vhost"]},
     %%     {declarations, []}
     %%    ]},

     %% List the destination broker(s) to publish to.
     %%   {destinations,
     %%    [%% A singular version of the 'brokers' element.
     %%     {broker, "amqp://"},
     %%     {declarations, []}
     %%    ]},

     %% Name of the queue to shovel messages from.
     %%
     %% {queue, <<"your-queue-name-goes-here">>},

     %% Optional prefetch count.
     %%
     %% {prefetch_count, 10},

     %% when to acknowledge messages:
     %% - no_ack: never (auto)
     %% - on_publish: after each message is republished
     %% - on_confirm: when the destination broker confirms receipt
     %%
     %% {ack_mode, on_confirm},

     %% Overwrite fields of the outbound basic.publish.
     %%
     %% {publish_fields, [{exchange,    <<"my_exchange">>},
     %%                   {routing_key, <<"from_shovel">>}]},

     %% Static list of basic.properties to set on re-publication.
     %%
     %% {publish_properties, [{delivery_mode, 2}]},

     %% The number of seconds to wait before attempting to
     %% reconnect in the event of a connection failure.
     %%
     %% {reconnect_delay, 2.5}

     %% ]} %% End of my_first_shovel
    ]}
   %% Rather than specifying some values per-shovel, you can specify
   %% them for all shovels here.
   %%
   %% {defaults, [{prefetch_count,     0},
   %%             {ack_mode,           on_confirm},
   %%             {publish_fields,     []},
   %%             {publish_properties, [{delivery_mode, 2}]},
   %%             {reconnect_delay,    2.5}]}
  ]},

 %% ----------------------------------------------------------------------------
 %% RabbitMQ Stomp Adapter
 %%
 %% See http://www.rabbitmq.com/stomp.html for details
 %% ----------------------------------------------------------------------------

 {rabbitmq_stomp,
  [%% Network Configuration - the format is generally the same as for the broker

   %% Listen only on localhost (ipv4 & ipv6) on a specific port.
   %% {tcp_listeners, [{"127.0.0.1", 61613},
   %%                  {"::1",       61613}]},

   %% Listen for SSL connections on a specific port.
   %% {ssl_listeners, [61614]},

   %% Additional SSL options

   %% Extract a name from the client's certificate when using SSL.
   %%
   %% {ssl_cert_login, true},

   %% Set a default user name and password. This is used as the default login
   %% whenever a CONNECT frame omits the login and passcode headers.
   %%
   %% Please note that setting this will allow clients to connect without
   %% authenticating!
   %%
   %% {default_user, [{login,    "guest"},
   %%                 {passcode, "guest"}]},

   %% If a default user is configured, or you have configured use SSL client
   %% certificate based authentication, you can choose to allow clients to
   %% omit the CONNECT frame entirely. If set to true, the client is
   %% automatically connected as the default user or user supplied in the
   %% SSL certificate whenever the first frame sent on a session is not a
   %% CONNECT frame.
   %%
   %% {implicit_connect, true}
  ]},

 %% ----------------------------------------------------------------------------
 %% RabbitMQ MQTT Adapter
 %%
 %% See https://github.com/rabbitmq/rabbitmq-mqtt/blob/stable/README.md
 %% for details
 %% ----------------------------------------------------------------------------

 {rabbitmq_mqtt,
  [%% Set the default user name and password. Will be used as the default login
   %% if a connecting client provides no other login details.
   %%
   %% Please note that setting this will allow clients to connect without
   %% authenticating!
   %%
   %% {default_user, <<"guest">>},
   %% {default_pass, <<"guest">>},

   %% Enable anonymous access. If this is set to false, clients MUST provide
   %% login information in order to connect. See the default_user/default_pass
   %% configuration elements for managing logins without authentication.
   %%
   %% {allow_anonymous, true},

   %% If you have multiple chosts, specify the one to which the
   %% adapter connects.
   %%
   %% {vhost, <<"/">>},

   %% Specify the exchange to which messages from MQTT clients are published.
   %%
   %% {exchange, <<"amq.topic">>},

   %% Specify TTL (time to live) to control the lifetime of non-clean sessions.
   %%
   %% {subscription_ttl, 1800000},

   %% Set the prefetch count (governing the maximum number of unacknowledged
   %% messages that will be delivered).
   %%
   %% {prefetch, 10},

   %% TCP/SSL Configuration (as per the broker configuration).
   %%
   %% {tcp_listeners, [1883]},
   %% {ssl_listeners, []},

   %% TCP/Socket options (as per the broker configuration).
   %%
   %% {tcp_listen_options, [binary,
   %%                       {packet,    raw},
   %%                       {reuseaddr, true},
   %%                       {backlog,   128},
   %%                       {nodelay,   true}]}
  ]},

 %% ----------------------------------------------------------------------------
 %% RabbitMQ AMQP 1.0 Support
 %%
 %% See https://github.com/rabbitmq/rabbitmq-amqp1.0/blob/stable/README.md
 %% for details
 %% ----------------------------------------------------------------------------

 {rabbitmq_amqp1_0,
  [%% Connections that are not authenticated with SASL will connect as this
   %% account. See the README for more information.
   %%
   %% Please note that setting this will allow clients to connect without
   %% authenticating!
   %%
   %% {default_user, "guest"},

   %% Enable protocol strict mode. See the README for more information.
   %%
   %% {protocol_strict_mode, false}
  ]},

 %% ----------------------------------------------------------------------------
 %% RabbitMQ LDAP Plugin
 %%
 %% See http://www.rabbitmq.com/ldap.html for details.
 %%
 %% ----------------------------------------------------------------------------

 {rabbitmq_auth_backend_ldap,
  [%%
   %% Connecting to the LDAP server(s)
   %% ================================
   %%

   %% Specify servers to bind to. You *must* set this in order for the plugin
   %% to work properly.
   %%
   %% {servers, ["your-server-name-goes-here"]},

   %% Connect to the LDAP server using SSL
   %%
   %% {use_ssl, false},

   %% Specify the LDAP port to connect to
   %%
   %% {port, 389},

   %% LDAP connection timeout, in milliseconds or 'infinity'
   %%
   %% {timeout, infinity},

   %% Enable logging of LDAP queries.
   %% One of
   %%   - false (no logging is performed)
   %%   - true (verbose logging of the logic used by the plugin)
   %%   - network (as true, but additionally logs LDAP network traffic)
   %%
   %% Defaults to false.
   %%
   %% {log, false},

   %%
   %% Authentication
   %% ==============
   %%

   %% Pattern to convert the username given through AMQP to a DN before
   %% binding
   %%
   %% {user_dn_pattern, "cn=${username},ou=People,dc=example,dc=com"},

   %% Alternatively, you can convert a username to a Distinguished
   %% Name via an LDAP lookup after binding. See the documentation for
   %% full details.

   %% When converting a username to a dn via a lookup, set these to
   %% the name of the attribute that represents the user name, and the
   %% base DN for the lookup query.
   %%
   %% {dn_lookup_attribute,   "userPrincipalName"},
   %% {dn_lookup_base,        "DC=gopivotal,DC=com"},

   %% Controls how to bind for authorisation queries and also to
   %% retrieve the details of users logging in without presenting a
   %% password (e.g., SASL EXTERNAL).
   %% One of
   %%  - as_user (to bind as the authenticated user - requires a password)
   %%  - anon    (to bind anonymously)
   %%  - {UserDN, Password} (to bind with a specified user name and password)
   %%
   %% Defaults to 'as_user'.
   %%
   %% {other_bind, as_user},

   %%
   %% Authorisation
   %% =============
   %%

   %% The LDAP plugin can perform a variety of queries against your
   %% LDAP server to determine questions of authorisation. See
   %% http://www.rabbitmq.com/ldap.html#authorisation for more
   %% information.

   %% Set the query to use when determining vhost access
   %%
   %% {vhost_access_query, {in_group,
   %%                       "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}},

   %% Set the query to use when determining resource (e.g., queue) access
   %%
   %% {resource_access_query, {constant, true}},

   %% Set queries to determine which tags a user has
   %%
   %% {tag_queries, []}
  ]}
].

到此为止,RabbitMQ的安装以及配置,就成功了。。。

5.系统架构

RabbitMQ Server:其实就是一种传输服务,他的角色就是维护一条从“生产者”到消费者间的一条通道,保证数据通过同一种指定的方式传输

Client A&B :“生产者”,生产者发送message(包括payload【有效载荷】,label【标签】)至队列中

Client 1,2,3 : “消费者” ,消费者是接受队列中的message信息,但是消费者接受的message信息中仅有 有效载荷 ,并没有标签信息,所以,对于消费者来说,并不知道信息来源在哪。如果有效载荷中保存了“生产者”信息,就另当别论了。

Exchanges:可以理解为数据交换类型或者是方式,也有人认为是“生产者”发布信息的地方,exchang包含以下三种方式

  • direct : 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。例如:绑定到路由的是“hello” , 则只会转发被标记为“hello”的信息
  • fanout : 不处理路邮件。这个就像广播,只需要将消息绑定到交换机上,就可随便转发
  • topic : 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
  • Queues:队列。用于生产者和消费者之间的信息传输通道
  • Bindings :是如何将消息从交换路由到特定队列。
  • Connection: 就是一个TCP的连接。Producer和Consumer都是通过TCP连接到RabbitMQ Server的。以后我们可以看到,程序的起始处就是建立这个TCP连接。

6.Java调用RabbitMQ(普通 1对1 读取)

Server

package reading.rabbitmq;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 向RabbitMQ中添加数据
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQServer {
	private final static String QUEUE_NAME = "testQueue";
	public static void main(String[] args) throws IOException, TimeoutException {
		/* 使用工厂类建立Connection和Channel,并且设置参数 */
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.1.105");// MQ的IP
		factory.setPort(5672);// MQ端口
		factory.setUsername("Username");// MQ用户名
		factory.setPassword("Password");// MQ密码
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		/* 创建消息队列,并且发送消息 */
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		for (int i = 0; i < 5; i++) {
			String message = String.valueOf(i);
			channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
			System.out.println(" [x] Sent '" + message + "'");
		}
		/* 关闭连接 */
		channel.close();
		connection.close();
	}
}

Client

package reading.rabbitmq;

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * 从RabbitMQ中取数据
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQClient {
	private final static String QUEUE_NAME = "testQueue";
	public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
	    /*建立连接*/
	      ConnectionFactory factory = new ConnectionFactory();
	      factory.setHost("192.168.1.105");//MQ的IP
	        factory.setPort(5672);//MQ端口
	        factory.setUsername("admin");//MQ用户名
	        factory.setPassword("admin");//MQ密码
	      Connection connection = factory.newConnection();
	      Channel channel = connection.createChannel();
	      /*声明要连接的队列*/
	      channel.queueDeclare(QUEUE_NAME, false, false, false, null);
	      System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
	      /*创建消费者对象,用于读取消息*/
	      QueueingConsumer consumer = new QueueingConsumer(channel);
	      channel.basicConsume(QUEUE_NAME, true, consumer);
	     /* 读取队列,并且阻塞,即在读到消息之前在这里阻塞,直到等到消息,完成消息的阅读后,继续阻塞循环*/
	      while (true) {
	        QueueingConsumer.Delivery delivery = consumer.nextDelivery();
	        String message = new String(delivery.getBody());
	        System.out.println(" [x] Received '" + message + "'");
	      }
	}
}

7.java调用RabbitMQ(绑定交换机,与队列)

server端

package reading.rabbitmq;

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 向RabbitMQ中添加数据
 * 
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQServer {
	public static void main(String[] args) throws IOException, TimeoutException {
		/* 使用工厂类建立Connection和Channel,并且设置参数 */
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.1.105");// MQ的IP
		factory.setPort(5672);// MQ端口
		factory.setUsername("admin");// MQ用户名
		factory.setPassword("admin");// MQ密码
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();

		/* 定义交换机 */
		channel.exchangeDeclare("COLOR_EXCHANGE", "direct");

		/* 创建多个消息队列 */
		channel.queueDeclare("BLACK_QUEUE", false, false, false, null);
		channel.queueDeclare("RED_QUEUE", false, false, false, null);

		/* 绑定交换机和队列 */
		channel.queueBind("BLACK_QUEUE", "COLOR_EXCHANGE", "black");
		channel.queueBind("RED_QUEUE", "COLOR_EXCHANGE", "red");

		/* 通过交换机发送不同类别的消息到不同的队列中,注意,消息是由一个交换机来根据标志发往不同的队列中去 */
		String message = "black";
		channel.basicPublish("COLOR_EXCHANGE", "black", null, message.getBytes());
		System.out.println(" [x] Sent '" + message + "'");

		message = "red";
		channel.basicPublish("COLOR_EXCHANGE", "red", null, message.getBytes());
		System.out.println(" [x] Sent '" + message + "'");

		/* 关闭连接 */
		channel.close();
		connection.close();
	}
}

Client : (接受的black队列)

package reading.rabbitmq;

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * 从RabbitMQ中取数据
 * 
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQClient {
	public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException,
			ConsumerCancelledException, InterruptedException {
		/* 建立连接 */
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.1.105");// MQ的IP
		factory.setPort(5672);// MQ端口
		factory.setUsername("admin");// MQ用户名
		factory.setPassword("admin");// MQ密码
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		/* 声明要连接的队列 */
		/* 定义交换机 */
		channel.exchangeDeclare("COLOR_EXCHANGE", "direct");
		/* 绑定交换机和队列 */
		channel.queueBind("BLACK_QUEUE", "COLOR_EXCHANGE", "black");
		/* 创建消费者对象,用于读取消息 */
		QueueingConsumer consumer = new QueueingConsumer(channel);
		channel.basicConsume("BLACK_QUEUE", true, consumer);
		/* 读取队列,并且阻塞,即在读到消息之前在这里阻塞,直到等到消息,完成消息的阅读后,继续阻塞循环 */
		while (true) {
			QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			String message = new String(delivery.getBody());
			System.out.println(" [x] Received '" + message + "'");
		}
	}
}

client (接受的red队列)

package reading.rabbitmq;

import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * 从RabbitMQ中取数据
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQClient2 {
	public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
		/* 建立连接 */
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.1.105");// MQ的IP
		factory.setPort(5672);// MQ端口
		factory.setUsername("admin");// MQ用户名
		factory.setPassword("admin");// MQ密码
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		/* 声明要连接的队列 */
		/* 定义交换机 */
		channel.exchangeDeclare("COLOR_EXCHANGE", "direct");
		/* 绑定交换机和队列 */
		channel.queueBind("RED_QUEUE", "COLOR_EXCHANGE", "black");
		/* 创建消费者对象,用于读取消息 */
		QueueingConsumer consumer = new QueueingConsumer(channel);
		channel.basicConsume("RED_QUEUE", true, consumer);
		/* 读取队列,并且阻塞,即在读到消息之前在这里阻塞,直到等到消息,完成消息的阅读后,继续阻塞循环 */
		while (true) {
			QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			String message = new String(delivery.getBody());
			System.out.println(" [x] Received '" + message + "'");
		}
	}
}

消息持久化
没有特意告诉RabbitMQ,那么在它退出或者崩溃的时候,它将会流失所有的队列和消息。为了确保信息不会丢失,有两个事情是需要注意的:我们必须把“队列”和“消息”设为持久化。

  • 设置队列持久化:

    因为我们已经定义过一个叫hello的非持久化队列。RabbitMq不允许你使用不同的参数重新定义一个队列,它会返回一个错误。但我们现在使用一个快捷的解决方法——用不同的名字,如task_queue。
    生产者(producer)和消费者(consumer)对应的代码中,queue_declare也要修改。此时就可以确保在RabbitMq重启之后queue_declare队列不会丢失。

  • 消息持久化——设置MessageProperties属性值为PERSISTENT_TEXT_PLAIN。

平均分发
使用basic.qos方法,并设置prefetch_count=1。这样是告诉RabbitMQ,再同一时刻,不要发送超过1条消息给一个工作者(worker),直到它已经处理了上一条消息并且作出了响应。这样,RabbitMQ就会把消息分发给下一个空闲的工作者(worker)。

7.RabbitMQ的RPC服务

Server

package reading.rabbitmq;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;

/**
 * 向RabbitMQ中添加数据
 * 
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQServer {
	private final static String RPC_QUEUE_NAME = "rpc_server";

	public static void main(String[] args) throws Exception {
		/* 使用工厂类建立Connection和Channel,并且设置参数 */
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.1.105");// MQ的IP
		factory.setPort(5672);// MQ端口
		factory.setUsername("admin");// MQ用户名
		factory.setPassword("admin");// MQ密码
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();

		/* 设置任务均衡,一次只领取一个任务 */
		channel.basicQos(1);

		/* 定义队列 */
		channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);

		/* 创建消费者队列 */
		QueueingConsumer consumer = new QueueingConsumer(channel);
		// 第二个参数 : 是否做出自动回应 , 如果是true 则不需绑定basicAck 作出回应, 否则 要绑定 basicAck 作出回应
		channel.basicConsume(RPC_QUEUE_NAME, true, consumer);

		System.out.println(" [x] Awaiting RPC requests");

		while (true) {
			/* 获取消费者的货物 */
			QueueingConsumer.Delivery delivery = consumer.nextDelivery();

			/* 获取消费者的返回属性,以及信息 */
			BasicProperties props = delivery.getProperties();
			BasicProperties replyProps = new BasicProperties.Builder().correlationId(props.getCorrelationId()).build();

			String message = new String(delivery.getBody());
			int n = Integer.parseInt(message);

			System.out.println(" [.] fib(" + message + ")");
			String response = "" + fib(n);
			/* 将结果返回给客户端 */
			channel.basicPublish("", props.getReplyTo(), replyProps, response.getBytes());
			// channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
		}

	}

	/**
	 * 这是一个测试接口
	 */
	private static int fib(int n) throws Exception {
		if (n == 0)
			return 0;
		if (n == 1)
			return 1;
		return fib(n - 1) + fib(n - 2);
	}
}

Client

package reading.rabbitmq;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * 从RabbitMQ中取数据
 * 
 * @author shanyepifu
 * @since 2015年8月5日09:45:18
 */
public class RabbitMQClient {
	private final static String RPC_QUEUE_NAME = "rpc_server";

	public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException,
			ConsumerCancelledException, InterruptedException {

		/* 建立连接 */
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.1.105");// MQ的IP
		factory.setPort(5672);// MQ端口
		factory.setUsername("admin");// MQ用户名
		factory.setPassword("admin");// MQ密码
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();

		/* 定义队列 */
		String replyQueueName = channel.queueDeclare().getQueue();

		/* 定义消费者队列 */
		QueueingConsumer consumer = new QueueingConsumer(channel);
		channel.basicConsume(replyQueueName, true, consumer);

		String corrId = java.util.UUID.randomUUID().toString();
		BasicProperties props = new BasicProperties.Builder().correlationId(corrId).replyTo(replyQueueName).build();

		String message = "10";

		channel.basicPublish("", RPC_QUEUE_NAME, props, message.getBytes());

		while (true) {
			QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			System.out.println("[-]" + new String(delivery.getBody()));
		}
	}
}

RabbitMQ的几种典型使用场景 http://www.cnblogs.com/luxiaoxun/p/3918054.html
RabbitMQ的使用 http://www.tuicool.com/articles/BRfEjyR

posted @ 2016-06-14 17:17  CodeLife  阅读(1009)  评论(0)    收藏  举报