目录
一、简单介绍
二、几个名词
三、四种模式
四、Springboot集成rabbitmq(确认消息返回)
五、rabbitmq延时队列使用
六、rabbitmq实现rpc调用
七、默认的guest账户只允许localhost连接,不允许使用IP
八、RabbitMQ配置文件介绍
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,可持久化。
消费者:发送消息一方。
交换机(Exchange):生产者发送消息首先到交换机上,然后根据绑定的key找到对应的队列。
绑定Key:交换机和消息队列两者之间紧紧联系的枢纽。
消息队列(Queue):消费者从消息队列取出消息。
消费者:消费者一方。
1.Direct Exchange:根据绑定key全文匹配去寻找队列 。
2.Topic Exchange:根据绑定key模糊匹配去寻找队列 。(“*”:匹配一个词;“#”:匹配多个词;举例:key.* key.#)
3.Headers Exchange:headers 也是根据规则匹配, 相较于 direct 和 topic 固定地使用 routing_key , headers 则是一个自定义匹配规则的类型。在队列与交换器绑定时, 会设定一组键值对规则, 消息中也包括一组键值对( headers 属性), 当这些键值对有一对, 或全部匹配时, 消息被投送到对应队列。
4.Fanout Exchange:广播形式,所有队列都会收到,可用于批量发送短息或邮件。
org.springframework.boot
spring-boot-starter-amqp
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
publisher-confirms: true #开启消息确认
publisher-returns: true #开启消息发送到队列失败返回
listener:
direct:
acknowledge-mode: MANUAL #开启direct模式下手动返回
simple:
acknowledge-mode: MANUAL #开启所有模式下手动返回
采用topic模式
package com.order.config;
import javax.annotation.PostConstruct;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
@Component
public class MQSenderConfig implements ConfirmCallback,ReturnCallback{
@Autowired
private RabbitTemplate rabbitTemplate;
@PostConstruct
public void init(){
rabbitTemplate.setReturnCallback(this);
rabbitTemplate.setConfirmCallback(this);
}
@Bean(name="orderCart")
public Queue queueMessage() {
return new Queue("createCart");
}
@Bean(name="productSku")
public Queue queueMessages() {
return new Queue("updateProStock");
}
@Bean
public TopicExchange exchange() {
return new TopicExchange("exchange");
}
@Bean
Binding bindingExchangeMessage(@Qualifier("orderCart") Queue queueMessage, TopicExchange exchange) {
return BindingBuilder.bind(queueMessage).to(exchange).with("createCart");
}
@Bean
Binding bindingExchangeMessages(@Qualifier("productSku") Queue queueMessages, TopicExchange exchange) {
return BindingBuilder.bind(queueMessages).to(exchange).with("updateProStock");//*表示一个词,#表示零个或多个词
}
@Override
//如果消息没有到exchange,则confirm回调,ack=false
//如果消息到达exchange,则confirm回调,ack=true
//消费者手动进行确认
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack) {
log.info("消息id:" + correlationData.getId()+"------消息发送确认成功");
} else {
log.info("消息id:" + correlationData.getId()+"------消息发送确认失败:" + cause);
}
}
@Override
//exchange到queue成功,则不回调return
//exchange到queue失败,则回调return(需设置mandatory=true,否则不回回调,消息就丢了)
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
log.info("消息主体 message : "+message);
log.info("消息主体 replyCode : "+ replyCode);
log.info("描述:"+ replyText);
log.info("消息使用的交换器 exchange : "+ exchange);
log.info("消息使用的路由键 routing : "+ routingKey);
}
}
消费者
package com.order.config;
import java.io.IOException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import com.common.util.JsonMapUtils;
import com.domain.order.OrderCart;
import com.order.service.impl.OrderCartServiceImpl;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
@Configuration
@Slf4j
public class MQReceiverConfig{
@Autowired
private OrderCartServiceImpl orderCartService;
@RabbitListener(queues = "createCart") // 监听器监听指定的Queue
public void createCart(Channel channel, Message message) {
try {
OrderCart cart =(OrderCart) JsonMapUtils.toObject(message.getBody());
orderCartService.insertSelective(cart);
log.info("执行加入购物车消息成功");
} catch (Exception e) {
log.error("执行加入购物车消息失败-----" + e.getMessage());
//丢弃这条消息
//channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
//记录日志失败原因
}finally {
//告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
try {
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
} catch (IOException e) {
log.error("回执加入购物车消息失败---" + e.getMessage());
}
}
}
}
生产者
//cart 发送内容
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
template.convertAndSend("exchange", "createCart", cart, correlationId);
不装插件会报错
connection error; protocol method: #method(reply-code=503, reply-text=COMMAND_INVALID - unknown exchange type 'x-delayed-message', class-id=40, method-id=10)
需装插件-官网:https://www.rabbitmq.com/blog/2015/04/16/scheduling-messages-with-rabbitmq/
目前最新版插件地址:https://dl.bintray.com/rabbitmq/community-plugins/3.7.x/rabbitmq_delayed_message_exchange/
放入地址
/usr/local/Cellar/rabbitmq/3.7.7_1/plugins
执行命令生效,不需要重启
/usr/local/Cellar/rabbitmq/3.7.7_1/sbin/rabbitmq-plugins enable rabbitmq_delayed_message_exchange
交换机设置类型
@Bean
public TopicExchange exchangeDelay() {
TopicExchange topicExchange = new TopicExchange("exchange-delay");
topicExchange.setDelayed(true);
return topicExchange;
}
生产者发送消息,加上延迟时间
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
//cart 转递参数内容
template.convertAndSend("exchange-delay", "updateProStock", cart, message ->{
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
message.getMessageProperties().setDelay(1 * (60*1000)); // 毫秒为单位,指定此消息的延时时长
return message;
},correlationId);
客户端发送请求(消息)时,在消息的属性(MessageProperties,在AMQP协议中定义了14中properties,这些属性会随着消息一起发送)中设置两个值replyTo(一个Queue名称,用于告诉服务器处理完成后将通知我的消息发送到这个Queue中)和correlationId(此次请求的标识号,服务器处理完成后需要将此属性返还,客户端将根据这个id了解哪条请求被成功执行了或执行失败)。
报错信息
User can only log in via localhost
在web后台管理界面或命令添加账户,记得添加权限。
也或者看这边文章:https://www.cnblogs.com/hnsongbiao/p/9100116.html
转载地址:https://www.cnblogs.com/zhen-rh/p/6884297.html
RabbitMQ支持三种配置方式:
1) 读取环境变量中配置, 这包括shell中环境变量和rabbitmq-env.conf/rabbitmq-env-conf.bat文件中配置的环境变量
可配置如端口、配置文件指定自定义位置、节点名字等信息。
2) 读取配置文件rabbitmq.config
可配置权限、集群、插件设置等高级信息, 当然也可配置端口等简单信息
3) 通过运行命令时指定参数
通常用来配置集群范围信息, 用来运行时动态传入
环境变量读取优先级
1) 读取shell中环境变量
2) 读取rabbitmq-env.conf/rabbitmq-env-conf.bat中的
3) 读取默认的
rabbitmq-env.conf/rabbitmq-env-conf.bat 详解(颜色标注的为常用配置)
变量名称 | 默认值 | 描述 |
---|---|---|
RABBITMQ_NODE_IP_ADDRESS | 默认为空字符串, 即绑定所有网络接口 | 如果想绑定到一个固定的IP可以使用此变量. 如果要绑定到两个或两个以上只能通过rabbitmq.config中的tcp_listeners来设置。 |
RABBITMQ_NODE_PORT | 5672 | 供客户端建立连接端口 |
RABBITMQ_DIST_PORT | RABBITMQ_NODE_PORT + 20000 | 用于节点和CLI工具连接的端口, 如果rabbitmq.config中配置了kernel.inet_dist_listen_min 或 kernel.inet_dist_listen_max该参数将被忽略 |
RABBITMQ_NODENAME |
|
节点名字, 必须唯一 |
RABBITMQ_CONF_ENV_FILE |
|
rabbitmq-env.conf/rabbitmq-env-conf.bat 默认位置, 不同系统不同安装方式位置也不同, 如果默认位置没找到则需在该位置手动创建一个 |
RABBITMQ_CONFIG_FILE | 同上 |
rabbitmq.config 默认位置。 如果默认位置没找到则需在该位置手动创建一个 |
RABBITMQ_USE_LONGNAME | 官网没说。。。。应该是false。。。 | 取值: true 或 false。 如果配置为true, 这将导致RabbitMQ使用完全限定的名称来标识节点 |
RABBITMQ_SERVICENAME | Windows Service: RabbitMQ | 服务名称 |
RABBITMQ_CONSOLE_LOG | 只在控制台输出日志, 日志不会持久化到文件 | 取值: new 或 reuse。 两种取值都是将控制台输出从服务器重定向到名为%rabbitmqservicename%(上面那个变量)的文件。 1)默认: 不设置, 控制台的日志不会被持久化到文件 2)new: 每次启动时都会创建一个新的文件 3)reuse: 每次启动服务器都会重用该日志文件 |
RABBITMQ_CTL_ERL_ARGS | None | 在调用rabbitmqctl时使用的erl命令的参数。应该仅用于调试目的。 |
RABBITMQ_SERVER_ERL_ARGS |
|
在调用RabbitMQ服务器时使用的erl命令的标准参数, 应该仅用于调试目的 |
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS |
|
在调用RabbitMQ服务器时使用的erl命令的附加参数。这个变量的值被附加到参数的默认列表(RABBITMQ_SERVER_ERL_ARGS). |
RABBITMQ_SERVER_START_ARGS | None | 在调用RabbitMQ服务器时使用的erl命令的额外参数。这不会覆盖RABBITMQ_SERVER_ERL_ARGS. |
HOSTNAME |
|
当前机器名称 |
COMPUTERNAME | Windows: localhost | 当前机器名称, windows使用该变量 |
ERLANG_SERVICE_MANAGER_PATH | Windows Service: %ERLANG_HOME%\erts-x.x.x\bin | erlsrv.exe的路径, erlsrv.exe这个是erlang服务的包装脚本 |
rabbitmq.config详解(核心配置)
该配置文件使用的是Erlang标准配置文件,语法请参照这里
例:
[ {rabbit, [{tcp_listeners, [5673]}]} ].
key | 描述 |
---|---|
tcp_listeners | 监听AMQP连接的端口或主机/对。 Default: [5672] |
num_tcp_acceptors | Erlang进程的数量,接受TCP监听器的连接数。 Default: 10 |
handshake_timeout | 对AMQP 0-8/0-9/0-9-1握手的最大时间(在套接字连接和SSL握手之后),以毫秒为间隔 Default: 10000 |
ssl_listeners | 如上所述,用于SSL连接。 Default: [] |
num_ssl_acceptors | 用于接受SSL监听连接的Erlang进程的数量。 Default: 1 |
ssl_options | SSL配置参数. 详情请看 SSL documentation. Default: [] |
ssl_handshake_timeout | SSL握手超时,以毫秒为间隔。 Default: 5000 |
vm_memory_high_watermark | 触发流控制的内存阈值。详情请看 memory-based flow control. Default: 0.4 |
vm_memory_high_watermark_paging_ratio | 设置当内存使用超过总内存百分比多少时,队列开始将消息持久化到磁盘以释放内存。 详情请看 memory-based flow control. Default: 0.5 |
disk_free_limit | RabbitMQ存储数据的分区的磁盘空间限制。当可用的磁盘空间低于这个限制时,就会触发流控制。值可以相对于RAM的总数设置(例如,内存比例,1.0)。该值也可以设置为整数的字节数。或者,单位(例如“50 mb”)。默认情况下,空闲磁盘空间必须超过50MB。详情请看 Disk Alarms. Default: 50000000 |
log_levels | 控制日志的粒度。该值是一个日志事件类别和日志级别对的列表。 可设置级别: 'none' 'error' 'warning' 'info' 'debug' 以上下一层级别的日志输出均包含上层级别日志输出(如: warning包含warning和error), none为不输出日志
另外,当前未分类的事件总是记录在日志中 The categories are:
Default: [{connection, info}] |
frame_max | 框架最大允许大小(以字节为单位)与消费者进行数据交换。设置为0意味着“无限”,但会在一些QPid客户端触发一个bug。 设置更大的值可能会提高吞吐量; 设置较小的值可能会提高延迟。 Default: 131072 |
channel_max | 与消费者进行谈判的最大允许数量。设置为0意味着“无限”。 使用更多的通道会增加代理的内存占用。 Default: 0 |
channel_operation_timeout | 通道操作超时为毫秒(内部使用,由于消息传递协议的差异和限制而不直接暴露于客户机)。 Default: 15000 |
heartbeat | 该值表示服务器在连接中发送的心跳延迟,在几秒钟内。优化框架。如果设置为0,则会禁用心跳。客户端可能不会遵循服务器的建议,请参阅AMQP参考以了解更多细节。 在有大量连接的情况下,禁用心跳可能改善性能,但可能会导致连接在关闭非活动连接的网络设备的出现。 Default: 60 (580 prior to release 3.5.5) |
default_vhost | 当RabbitMQ创建一个新的数据库时,创建一个虚拟主机。交换amq.rabbitmq.logwill存在于这个虚拟主机中。 Default: <<"/">> |
default_user | 当RabbitMQ从头创建一个新数据库时,要创建用户名。 Default: <<"guest">> |
default_pass | 默认用户的密码。 Default: <<"guest">> |
default_user_tags | 默认用户的标记。 Default: [administrator] |
default_permissions | 在创建时分配给默认用户的权限。 Default: [<<".*">>, <<".*">>, <<".*">>] |
loopback_users | 只允许通过环回接口连接到代理的用户列表(即localhost)。 如果您希望允许缺省的来宾用户远程连接,则需要将其更改为 []. Default: [<<"guest">>] |
cluster_nodes | 当一个节点开始第一次启动时,将它设置为使集群自动发生。元组的第一个元素是节点试图集群到的节点。第二个元素是磁盘或ram,并确定节点类型。 Default: {[], disc} |
server_properties | 键值对的列表,在连接上向客户端宣布。 Default: [] |
collect_statistics | 统计数据收集模式。主要与管理插件有关。选项有:
Default: none |
collect_statistics_interval | 统计数据收集间隔以毫秒为间隔。 主要相关插件 management plugin. Default: 5000 |
management_db_cache_multiplier | 管理插件将缓存诸如队列清单之类的代价较高的查询的时间。缓存将把最后一个查询的运行时间乘以这个值,并在此时间内缓存结果。 Default: 5 |
auth_mechanisms | SASL authentication mechanisms to offer to clients. Default: ['PLAIN', 'AMQPLAIN'] |
auth_backends | List of authentication and authorisation backends to use. Other databases than rabbit_auth_backend_internalare available through plugins. Default: [rabbit_auth_backend_internal] |
reverse_dns_lookups | 设置为true,让RabbitMQ对客户端连接执行反向DNS查找,并通过rabbitmqctl和管理插件呈现该信息。 Default: false |
delegate_count | 用于集群内部通信的委托进程的数量。当为多核CPU时可以考虑设置该值 Default: 16 |
trace_vhosts | Used internally by the tracer. 通常情况下不需要设置该参数 Default: [] |
tcp_listen_options | 默认的套接字选项。通常情况下不需要设置该参数 Default: [{backlog, 128}, {nodelay, true}, {linger, {true,0}}, {exit_on_close, false}]
|
hipe_compile | 设置为true,使用HiPE预编译RabbitMQ的部分,这是Erlang的即时编译器。这将增加服务器的吞吐量,以增加启动时间的成本。 您可能会看到,在启动时延迟几分钟,您的性能会提高20-50%。这些数据是高度工作负载和硬件依赖的。 HiPE支持可能不会编译到您的Erlang安装中。如果不是这样,启用这个选项只会导致一个警告消息被显示,而启动将照常进行。例如,Debian/Ubuntu用户需要安装erlangbase-base-hipe包。 HiPE在某些平台上是不可用的,尤其是Windows。 HiPE在17.5之前就已经知道了erlangp/otp版本的问题。HiPE推荐使用最新的erlangp/otp版本 Default: false |
cluster_partition_handling | 如何处理网络分区。可用模式:
Default: ignore |
cluster_keepalive_interval | 节点应该多频繁地将keepalive消息发送到其他节点(以毫秒为单位)。请注意,这与netticktime不一样; 错过的keepalive消息不会导致节点被认为挂机。 Default: 10000 |
queue_index_embed_msgs_below | 在消息的字节数中,消息将被直接嵌入到队列索引中。详情请看 persister tuning Default: 4096 |
msg_store_index_module | 用于队列索引的实现模块。 详情请看 persister tuning Default: rabbit_msg_store_ets_index |
backing_queue_module | 队列内容的实现模块。通常情况下不需要设置该参数 Default: rabbit_variable_queue |
msg_store_file_size_limit | Tunable value for the persister. 通常情况下不需要设置该参数 Default: 16777216 |
mnesia_table_loading_retry_limit | 在等待集群中的Mnesia tables可用时,需要重试的次数。 Default: 10 |
mnesia_table_loading_retry_timeout | 在集群中等待每个重试的时间,以便可用 Default: 30000 |
queue_index_max_ journal_entries | Tunable value for the persister. 通常情况下不需要设置该参数 Default: 65536 |
queue_master_locator | Queue master定位策略 可用策略:
Default: <<"client-local">> |
lazy_queue_explicit_gc_run_operation_threshold | 调优: 只有在内存压力下有延迟队列时。 这是触发垃圾收集器和其他内存减少活动的阈值。一个低的值可以降低性能,一个高的值可以提高性能,但是会导致更高的内存消耗。通常情况下不需要设置该参数 Default: 1000 |
queue_explicit_gc_run_operation_threshold | 调优: 在内存压力较大时。 这是触发垃圾收集器和其他内存减少活动的阈值。一个低的值可以降低性能,一个高的值可以提高性能,但是会导致更高的内存消耗。通常情况下不需要设置该参数 Default: 1000 |