Linux搭建RabbitMQ
1.RabbitMQ是由erlang语言编写的,导入RabbitMQ之前需要导入erlang和socat依赖
三个文件如图
2.使用工具将这三个导入系统,放在/home下,进入/home,报错点我
rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm
rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm
rpm -ivh rabbitmq-server-3.7.18-1.el7.noarch.rpm
3.rabbitmq默认会读取ls /etc/rabbitmq/下的rabbitmq.config文件,但是一开始是没有的,寻找一下
[root@localhost home]# find / -name rabbitmq.config.example
/usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example
4.得到路径后copy过来到/etc/rabbitmq下
cp /usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
5.vim /etc/rabbitmq/rabbitmq.config
修改一下配置文件打开注释,允许来宾用户,别忘了删除后面的逗号
6.启动rabbitmq的插件管理
rabbitmq-plugins enable rabbitmq_management
7.查看一下状态
systemctl status rabbitmq-server
8启动
systemctl restart rabbitmq-server
9.访问一下
http://192.168.200.130:15672
10.账号:guest
密码:guest
10.配置完成
初识mq—hello例子(点对点消费,直连)
生产者
package helloword;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;
import java.io.IOException;
public class Send {
@Test
public void getConnection() throws IOException {
//创建连接mq的连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接地址
connectionFactory.setHost("192.168.200.130");
//设置端口号
connectionFactory.setPort(5672);
//设置连接哪个虚拟主机
connectionFactory.setVirtualHost("/ems");
//设置账号
connectionFactory.setUsername("ems");
//设置密码
connectionFactory.setPassword("renliwei1");
//构建链接
Connection connection = connectionFactory.newConnection();
//获取链接中的通道
Channel channel = connection.createChannel();
/**
* 通道绑定对应消息队列
* 参数1:队列名称,如果队列不存在就自动创建
* 参数2:用来定义队列特性是否需要持久化 true持久化队列 false不持久化
* 参数3:exclusive是否独占队列 true独占队列 false不独占
* 参数4:autoDelete 是否在消费完成后自动删除队列 true自动删除 false不自动删除
* 参数5:附加参数
*/
channel.queueDeclare("hello",false,false,false,null);
//发布消息
/**
* 参数一:交换机名称
* 参数二:队列名称
* 参数三:传递消息额外名称
* 参数四:消息的具体内容
*/
channel.basicPublish("","hello",null,"hellorebbit".getBytes());
//关闭通道
channel.close();
connection.close();
}
}
消费者
package helloword;
import com.rabbitmq.client.*;
import java.io.IOException;
public class Customer {
public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.200.130");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/ems");
connectionFactory.setUsername("ems");
connectionFactory.setPassword("renliwei1");
//构建链接
Connection connection = connectionFactory.newConnection();
//获取通道
Channel channel = connection.createChannel();
//通道绑定对象
channel.queueDeclare("hello",false,false,false,null);
//消费消息
//参数1:消费哪个队列的消息,队列名称
//参数2:开始消息的自动确认机制
//参数3:消费时的回调接口
channel.basicConsume("hello",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("body:"+new String(body));
}
});
// channel.close();
// connection.close();
}
}
封装了一个工具类
省去重复的编写代码,构建连接直接调用工具类即可
package utils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
public class RabbitMQUtils {
private static ConnectionFactory connectionFactory;
static{
//创建连接mq的连接工厂,让他只new一次,类加载的时候初始化 静态代码块儿类加载的时候执行且只执行一次
connectionFactory = new ConnectionFactory();
//设置连接地址
connectionFactory.setHost("192.168.200.130");
//设置端口号
connectionFactory.setPort(5672);
//设置连接哪个虚拟主机
connectionFactory.setVirtualHost("/ems");
//设置账号
connectionFactory.setUsername("ems");
//设置密码
connectionFactory.setPassword("renliwei1");
}
public static Connection getConnection(){
try {
//构建链接
return connectionFactory.newConnection();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void getSendAndCustomerClose(Channel channel,Connection connection){
try {
if (channel!=null)channel.close();
if (connection!=null)connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
RabbitMQ持久化操作
在我们上面的例子中,当出现没有被消费的消息时,这时候突发意外情况,假如mq宕机了,这时候mq中的消息就会丢失,那么怎么来避免呢?
尝试一下
发送完消息
重启mq
刷新页面后发现消息并没有丢失
RabbitMQ消费者使用过后删除队列
Work模型
一个生产者直接对应多个消费者
生产者
package workQueue;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import utils.RabbitMQUtils;
import java.io.IOException;
public class Provider {
public static void main(String[] args) throws IOException {
//建立连接
Connection connection = RabbitMQUtils.getConnection();
//得到通道
Channel channel = connection.createChannel();
//通过通道声名队列
channel.queueDeclare("work",true,false,false,null);
for (int i=0;i<10;i++){
//发送消息
channel.basicPublish("","work",null,(i+"hello work queue").getBytes());
}
RabbitMQUtils.getSendAndCustomerClose(channel,connection);
}
}
消费者1
package workQueue;
import com.rabbitmq.client.*;
import utils.RabbitMQUtils;
import java.io.IOException;
public class Customer1 {
public static void main(String[] args)throws IOException {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("work",true,false,false,null);
channel.basicConsume("work",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("customer1"+new String(body));
}
});
}
}
消费者2
package workQueue;
import com.rabbitmq.client.*;
import utils.RabbitMQUtils;
import java.io.IOException;
public class Customer2 {
public static void main(String[] args)throws IOException {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare("work",true,false,false,null);
channel.basicConsume("work",true,new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("customer2"+new String(body));
}
});
}
}
我们会发现这个规律:在默认情况下,消费者是依次执行的(平均分配);
这里也会出现消息堆积的问题,假如消费者1,消费消息的时候比较慢,消费者2,消费消息比较快,这不是我们所希望的,我们希望消费快的多处理消息