【RabbitMQ】01 简单模式
参考自腾讯云的实验课堂,减少部署时间的折腾
1、创建Erlang.Repo库
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
2、安装Erlang
yum install -y erlang
3、创建RabbitMQ-Server.Repo库
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
4、安装RabbitMQ-Server
yum install -y rabbitmq-server
5、开机自启动设置(可选)
chkconfig rabbitmq-server on
6、服务启动
service rabbitmq-server start
7、开启访问页面
rabbitmq-plugins enable rabbitmq_management
8、添加登录账号
rabbitmqctl add_user test 123456
9、账号权限设置
rabbitmqctl set_user_tags test administrator rabbitmqctl set_permissions -p "/" test ".*" ".*" ".*"
10、访问后台信息:
http://192.168.2.121:15672/ test 123456
11、服务停止
service rabbitmq-server stop
访问不了,关闭防火墙处理:
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动
参考腾讯云实验室,很多东西在这里搞安装教程贼方便
https://cloud.tencent.com/developer/labs/gallery
防止依赖缺失,还是加上这段命令:
yum install -y build-essential \ unixODBC \ unixODBC-devel \ kernel-devel \ m4 \ tk \ tc \ xz \ gcc \ gcc-c++ \ glibc-devel \ make \ ncurses-devel \ openssl \ openssl-devel \ xmlto \ perl \ wget \ gtk2-devel \ binutils-devel
草,一年前写了,算了算了,留着吧
https://www.cnblogs.com/mindzone/p/13660810.html
创建消费者和生产者两个服务:
消费者编写了简答模式,pom只放了RabbitMQ的客户端
(这里写错位置了,要放到生产者里面)
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>RabbitMQ</artifactId> <groupId>cn.dzz</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ConsumerService</artifactId> <dependencies> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.6.0</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> </project>
消息队列简单模式代码:
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.nio.charset.StandardCharsets; public class RabbitMqTest { public static void main(String[] args) throws Exception{ ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.2.121"); connectionFactory.setPort(ConnectionFactory.DEFAULT_AMQP_PORT); // 5672 connectionFactory.setVirtualHost("/dzz"); // 虚拟主机? 默认值 / connectionFactory.setUsername("guest"); // guest connectionFactory.setPassword("guest"); // guest Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); /** * public com.rabbitmq.client.AMQP.Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments) throws IOException { * com.rabbitmq.client.AMQP.Queue.DeclareOk ok = this.delegate.queueDeclare(queue, durable, exclusive, autoDelete, arguments); * this.recordQueue(ok, queue, durable, exclusive, autoDelete, arguments); * return ok; * } * String queue 队列名称? * boolean durable 是否持久化? 写入Erlang的库中,否则只存活在内存中,RabbitMQ服务重启,队列销毁 * boolean exclusive 是否独占? 只允许一个消费者服务监听这个队列? Connection对象关闭 是否删除队列 * boolean autoDelete 是否自动删除? 没有消费者服务监听时自动删除 * Map<String, Object> arguments 参数信息, 自行设置 * * 如果没有队列叫这个 hello_rabbitmq RabbitMQ会自动创建这个队列、 */ channel.queueDeclare("hello_rabbitmq", true, false, false, null); /** * public void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException { * this.delegate.basicPublish(exchange, routingKey, props, body); * } * String exchange 交换机名称,简单模式 使用默认交换机 "" * String routingKey 路由名称 (由于使用的时默认交换机,路由名称和上面的队列名称一致) * BasicProperties props 配置信息 * byte[] body 发送的消息数据 */ String body = "hello, rabbitMq !!!!"; channel.basicPublish("", "hello_rabbitmq", null, body.getBytes(StandardCharsets.UTF_8)); // 资源释放 channel.close(); connection.close(); } }
注意没开始之前,队列标签页没有任何信息:
执行代码之后:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Exception in thread "main" com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile. at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:364) at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:64) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:156) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1106) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1063) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1021) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1182) at RabbitMqTest.main(RabbitMqTest.java:19) Process finished with exit code 1
访问拒绝,是因为之前已经设置了RabbitMQ的账号信息
可以先用默认账号进行登录:
它提示这个账号仅限本机访问,由于安装在Linux上面,所以是非本机访问
使用 test 123456 再次再次执行:
"C:\Program Files (x86)\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar=59622:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\RabbitMQ\ConsumerService\target\test-classes;C:\Users\Administrator\.m2\repository\com\rabbitmq\amqp-client\5.6.0\amqp-client-5.6.0.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar" RabbitMqTest SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Exception in thread "main" java.io.IOException at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:129) at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:125) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:147) at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:403) at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:64) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:156) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1106) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1063) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1021) at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1182) at RabbitMqTest.main(RabbitMqTest.java:19) Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - vhost /dzz not found, class-id=10, method-id=40) at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36) at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502) at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:293) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:141) ... 8 more Process finished with exit code 1
虚拟主机未找到 得,还不是自动创建的,需要去面板上配置:
添加虚拟主机
没有异常了,应该是发送成功了
"C:\Program Files (x86)\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar=60801:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\RabbitMQ\ConsumerService\target\test-classes;C:\Users\Administrator\.m2\repository\com\rabbitmq\amqp-client\5.6.0\amqp-client-5.6.0.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar" RabbitMqTest SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Process finished with exit code 0
查看队列面板上面就会多出一条记录:
但是连接记录和频道记录都没有,原因是我们把资源释放掉了
现在把代码释放资源的部分注释掉,程序将不会停止
面板上面就会显示连接信息和频道信息
创建消费者,接收消息:
import com.rabbitmq.client.*; import java.io.IOException; import java.nio.charset.StandardCharsets; public class RabbitMqTest { public static void main(String[] args) throws Exception{ ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost("192.168.2.121"); connectionFactory.setPort(ConnectionFactory.DEFAULT_AMQP_PORT); // 5672 connectionFactory.setVirtualHost("/dzz"); // 虚拟主机? 默认值 / connectionFactory.setUsername("test"); // guest connectionFactory.setPassword("123456"); // guest Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); /** * public com.rabbitmq.client.AMQP.Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments) throws IOException { * com.rabbitmq.client.AMQP.Queue.DeclareOk ok = this.delegate.queueDeclare(queue, durable, exclusive, autoDelete, arguments); * this.recordQueue(ok, queue, durable, exclusive, autoDelete, arguments); * return ok; * } * String queue 队列名称? * boolean durable 是否持久化? 写入Erlang的库中,否则只存活在内存中,RabbitMQ服务重启,队列销毁 * boolean exclusive 是否独占? 只允许一个消费者服务监听这个队列? Connection对象关闭 是否删除队列 * boolean autoDelete 是否自动删除? 没有消费者服务监听时自动删除 * Map<String, Object> arguments 参数信息, 自行设置 * * 如果没有队列叫这个 hello_rabbitmq RabbitMQ会自动创建这个队列、 * * 对于消费者来说,队列声明不是必要的 */ channel.queueDeclare("hello_rabbitmq", true, false, false, null); /** * 消息接受 * public String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException { * return this.basicConsume(queue, autoAck, "", callback); * } * String queue 队列名称 * boolean autoAck 是否自动确认 * Consumer callback 回调方法 * * */ Consumer consumer = new DefaultConsumer(channel) { /** * 消息收到的回调方法(自动执行) * @param consumerTag 标识 * @param envelope RabbitMQ服务信息 * @param properties 配置信息 * @param body 收到的数据 * @throws IOException */ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("consumerTag " + consumerTag); String exchange = envelope.getExchange(); long deliveryTag = envelope.getDeliveryTag(); String routingKey = envelope.getRoutingKey(); System.out.println("exchange " + exchange); System.out.println("deliveryTag " + deliveryTag); System.out.println("routingKey " + routingKey); System.out.println("properties " + properties); System.out.println("body(message) " + new String(body, StandardCharsets.UTF_8)); System.out.println("- - - - - over - - - - -"); } }; channel.basicConsume("hello_rabbitmq", true, consumer); // 资源释放 消费者需要一直监听发送过来的消息,不能关闭资源 // channel.close(); // connection.close(); } }
执行后输出打印:
从生产者发送的三条消息全部收到
"C:\Program Files (x86)\Java\jdk1.8.0_291\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar=62981:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_291\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\RabbitMQ\ConsumerService\target\test-classes;C:\Users\Administrator\.m2\repository\com\rabbitmq\amqp-client\5.6.0\amqp-client-5.6.0.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar" RabbitMqTest SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. consumerTag amq.ctag-DEOhj99q55lb2BDUqetVaQ exchange deliveryTag 1 routingKey hello_rabbitmq properties #contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null) body(message) hello, rabbitMq !!!! - - - - - over - - - - - consumerTag amq.ctag-DEOhj99q55lb2BDUqetVaQ exchange deliveryTag 2 routingKey hello_rabbitmq properties #contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null) body(message) hello, rabbitMq !!!! - - - - - over - - - - - consumerTag amq.ctag-DEOhj99q55lb2BDUqetVaQ exchange deliveryTag 3 routingKey hello_rabbitmq properties #contentHeader<basic>(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null) body(message) hello, rabbitMq !!!! - - - - - over - - - - -
可以看到连接和频道消费者和生产者的区别了
消息存储是一个先进先出的方式,RabbitMQ像是一个缓存器,能把生产者发送的信息保存起来,等待消费者接收