最近公司项目需要用到异步业务流程,和几个小伙伴讨论筛选后,最后选定使用RabbitMQ,过程中也是小坑不断,在此总结一下,供大家学习使用:
1,下载ERLANG和RabbitMQ
此处要注意版本选择,版本不同是不能互相兼容的,我选的是RabbitMQ3.7.9和ERLANG:20.0.x:参考RabbitMQ的官网,里面写的很清楚的
2,ERLANG安装
没有技术含量,一路默认安装即可,安装路径:C:\Program Files\erl10.0.1
最后配置一下环境变量:
ERLANG_HOME=C:\Program Files\erl10.0.1
path=%ERLANG_HOME%\bin
进入命令行窗口,看看版本是否正确:erl -version
3,RabbitMQ安装
安装目录:D:\RabbitMQ\rabbitmq_server-3.7.9
安装时,注意安装路径不能有空格,默认安装会有空格,需要去掉空格。
其他地方默认安装即可。
4,RabbitMQ中追加localhost以外机器访问的用户
命令行窗口进入到目录:D:\RabbitMQ\rabbitmq_server-3.7.9\sbin
新建test用户,密码root,授予administrator权限
rabbitmqctl add_user test root
rabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test ".*" ".*" ".*"
5,RabbitMQ启动
命令行窗口进入到目录:D:\RabbitMQ\rabbitmq_server-3.7.9\sbin
rabbitmq-server start
下面以JAVA程序为例子,进行开发
6,新建一个maven工程,加入一下的依赖包
<!-- rabbitmq相关依赖 -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.0.4</version>
</dependency>
<!-- 序列化相关依赖 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
7,新创建一个获取连接的类,工生产者和消费者共用
package rabbitmq;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtils {
public static Connection getConnection() throws IOException,TimeoutException {
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 设置MabbitMQ所在主机ip或者主机名 127.0.0.1即localhost
factory.setHost("192.168.40.245");
factory.setPort(5672);
//factory.setVirtualHost("/vhost_why");
factory.setUsername("test");
factory.setPassword("root");
return factory.newConnection();
}
}
8,新建生产者的类
package rabbitmq;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import org.junit.Test;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
public class Send {
private static final String QUEUE_NAME = "test_simple_queue";
@Test
public void testSendMessage() {
try {
// 打开连接和创建频道
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
// 声明一个队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 创建连接
String msg = "Hello World yaohj123!";
// String msg1 = "Hello World yaohj456!";
// 发送消息到队列中
for(int i = 0; i < 1000; i++){
msg = String.valueOf(i);
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
}
// channel.basicPublish("", QUEUE_NAME, null, msg1.getBytes());
// 关闭通道和连接
channel.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
9,新建消费者的类
package rabbitmq;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
public class receiver {
private static final String QUEUE_NAME = "test_simple_queue";
public static void main(String[] args) {
try {
// 打开连接和创建频道
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
// 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
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");
System.out.println("Customer Received:" + message);
}
};
// 自动回复队列应答 -- RabbitMQ中的消息确认机制
channel.basicConsume(QUEUE_NAME, true, consumer);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
10,运行
先运行生产者,后运行消费者,OK,大功告成!
生产的内容,消费者自动全部收到
Customer Received:0
Customer Received:1
Customer Received:2
Customer Received:3
Customer Received:4
Customer Received:5
Customer Received:6
Customer Received:7