待解问题:最终也没有解决 消费者ip不写localhost就不行 的问题。
已解决,放文末。
本人采用的是windows系统安装,懒得装Linux。并未用Linux+SecureCRT,但现在事后觉得还是用Linux来个远程访问比较符合实际业务场景。
一、安装与配置环境变量
1.参考https://blog.csdn.net/qq_22111417/article/details/101366703下载
亦可某盘下载:
链接:https://pan.baidu.com/s/1jSnWUrGQw8KNCl2vt31hQw
提取码:eynw
先装rmq依赖的erlang: opt_win64_22.1.exe
一路next,即可
再装rmq: rabbitmq-server-3.8.1.exe
一路next,即可
安装如qq一般简单。但和qq不同的事,我们希望在任何目录下都可以访问,那么还得有第2步:配置环境变量。
2.配置环境变量
像javaJDK一样,装完配个环境变量让我们可以即使在桌面也能敲它的命令(不然老是cd cd cd cd进去安装目录才能敲命令,码农都进累了,还怎么有精力整新活?)
环境变量配置示范:
先新建,
变量名ERLANG_HOME 变量值D:\java\rabbitMQ\erl10.5
变量名RABBITQM_SERVER 变量值D:\java\rabbitMQ\rabbitmq_server-3.8.1
再编辑变量名Path
变量值末尾新添 %ERLANG_HOME%\bin;%RABBITQM_SERVER%\sbin;
这写法多像java的封装思想啊。
二、cmd里敲命令
①
rabbitmq-plugins.bat enable rabbitmq_management – rabbitmq配置
net stop RabbitMQ && net start RabbitMQ – 开启或关闭rmq命令
这时候容易出现第一个坑:
报错:
服务名无效
解决:
我直接是开始菜单运行里搜rabbitmq 有个RabbbitMQ Service- (re)install
然后再rabbbitmq start ,就好了。。。
登录http://localhost:15672 默认账号密码 guest guest,看看能访问到不?(网页端后台图形界面新建用户更方便哦~敲命令太装逼了)
rabbitmq常用命令行汇总
https://www.cnblogs.com/potato-chip/p/9977386.html
②
查看我们的环境中安装的服务是否正确(不然等会我们cmd里新建用户的命令会使不出来,报错:unable to perform an operation on node)
参考https://www.cnblogs.com/zwgbk/p/10344678.html,若有问题,按该博文方法解决,即可
三、创建新用户并赋予权限
为什么新建用户?guest账号只能用localhost。。。如果用其他机器ip,
报错
com.rabbitmq.client.AuthenticationFailureException:
ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN.
For details see the broker logfile.
参考https://blog.csdn.net/qq_36827957/article/details/81805276
那我们还咋远程访问,远程发送信息啊,单机自娱自乐呗 。
待会的demo代码里改成
factory.setHost("localhost");
即可开启单机QQ般的自娱自乐模式。
不想自娱自乐,就新建一个其他用户:
cmd里敲命令即可
新建用户root密码123456 ——
rabbitmqctl.bat add_user root 123456
给root开权限(否则此账号做生产者时报错无权连接) ——
rabbitmqctl set_permissions -p / root “." ".” “.*”
若新建用户还有问题参照这篇博文
https://www.cnblogs.com/zwwhnly/p/10918665.html
想对RabbitMQ权限再详细了解的,参考博文
https://blog.csdn.net/qq_36827957/article/details/81805276
四、随便开一个springboot项目测试一下
package com.rabbitmq.helloworld.demo;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 生产者
*/
public class Producer {
private static final String QUEUE_NAME = "local::TFBoysqueue12:01";
private static final Logger LOGGER = LoggerFactory.getLogger(Producer.class);
public static void main(String[] args) {
try {
//连接管理器:我们的应用程序与RabbitMQ建立连接的管理器。
ConnectionFactory factory = new ConnectionFactory();
//设置你的RabbitMQ服务器ip地址
factory.setHost("192.168.10.139");
//设置帐号密码(坑:自己设置个新用户密码,不能用guest,guest只能访问localhost)
factory.setUsername("root");
factory.setPassword("123456");
//新建一个连接
Connection connection = factory.newConnection();
//再创建一个信道,这个就相当于一个邮局
//它是消息推送使用的通道。
Channel channel = connection.createChannel();
//首先在通道中申明一个队列
/**
* 第一个参数是queue:要创建的队列名
* 第二个参数是durable:是否持久化。如果为true,可以在RabbitMQ崩溃后恢复消息
* 第三个参数是exclusive:true表示一个队列只能被一个消费者占有并消费
* 第四个参数是autoDelete:true表示服务器不在使用这个队列是会自动删除它
* 第五个参数是arguments:其它参数
*/
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//创建一条消息
String message = "常博2混子,有内鬼,终止交易!";
//采用二进制流的方式传输
byte[] msg = message.getBytes("UTF-8");
//channel是一个邮局,它接收到msg数据,并将纳入到QUEUE_NAME队列中
channel.basicPublish("", QUEUE_NAME, null, msg);
LOGGER.info("发送端发送消息:{}",message);
channel.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.rabbitmq.helloworld.demo;
import com.rabbitmq.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
*消费者
*/
public class MsgConsumer {
private static final String QUEUE_NAME = "local::TFBoysqueue12:01";
private static final Logger LOGGER = LoggerFactory.getLogger(MsgConsumer.class);
public static void main(String[] args) {
try {
//连接管理器:我们的应用程序与RabbitMQ建立连接的管理器。
ConnectionFactory factory = new ConnectionFactory();
//设置RabbitMQ服务器地址
factory.setHost("localhost");//坑啊,为什么消费者还是只能设置本地,否则报错
//新建一个连接
Connection connection = factory.newConnection();
//再创建一个信道,这个就相当于一个邮局
Channel channel = connection.createChannel();
//首先在通道中申明一个队列
/**
* 第一个参数是queue:要创建的队列名
* 第二个参数是durable:是否持久化。如果为true,可以在RabbitMQ崩溃后恢复消息
* 第三个参数是exclusive:true表示一个队列只能被一个消费者占有并消费
* 第四个参数是autoDelete:true表示服务器不在使用这个队列是会自动删除它
* 第五个参数是arguments:其它参数
*/
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//创建消费者,并重写如何消费的方法(自行复习匿名内部类),我们这里仅仅就是打印一下消息
//首先从信道里面获取数据
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String message = new String(body, "UTF-8");
LOGGER.info("收件人收到消息:{}", message);
}
};
//收到了消息后,提示邮局,我已经收到消息了。可以给我发送其它消息
//第二个参数autoAck如果为false,那么消息会一直保存在RabbitMQ服务器
//消费者没有确认消息被消费,消息一直留在队列中,只有当从有新的消费者加入时,消息被分发到新的消费者。
channel.basicConsume(QUEUE_NAME, true, consumer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
pom.xml
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rabbitmq</groupId>
<artifactId>helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>helloworld</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!--支持日志框架Logback-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
</dependency>
<dependency>
<!-- 支持rabbitMQ -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
运行结果:
//坑啊,为什么消费者还是只能设置本地localhost,否则报错,是因为人家没有用Linux虚拟ip玩真的远程吗?
com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
------------------------------------古力娜扎黑魔法分割线----------------------------------
解决啦~~~,
消费者报错:
com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
解决:
灵感来源
https://www.linuxidc.com/Linux/2014-10/107917.htm
https://blog.csdn.net/qq_19734597/article/details/90042948
我的解决办法:
先关闭rmq服务。
找到rmq安装目录的ebin下的rabbit.app文件
将其中的
{loopback_users, [<<“guest”>>]},
修改为
{loopback_users, []},
即可。
然后,这么登网页版后台也行啦~~~!
Ps.
关闭服务方法大全:
法一:开始-搜索 services.msc-找到
法二:
法三:cmd敲命令组合拳
rabbitmq-service stop
rabbitmq-service install
rabbitmq-service start