RabbitMQ解决的问题
日志处理,因为日志流量非常大,不可能直接存数据库中.所以需要使用mq
异步处理,在注册完还有发送邮箱发送短信等操作,都得执行完才能给用户回馈,这样性能很不好,也可以异步执行这些功能,但这些功能不是必须的,可以给它先存到mq然后慢慢执行,这样就大大提升了性能.
应用解耦,订单服务每下一单需要进行库存操作,在服务中直接调用的话,耦合太大,如果库存宕机,那么订单也没法工作,两个直接建立mq的话,就算库存宕机了跟订单也没关系,等库存重连上来,也可以执行先前没执行完的操作.
流量削峰,在秒杀的时候,流量是非常大的,如果都同时挤服务器的话容易支撑不住,所以使用mq的话,可以进行队列,然后筛选条件,再进行秒杀服务.
在java连接操作前先创建一个新用户.
因为账号guest具有所有的操作权限,并且又是默认账号,出于安全因素的考虑,创建一个新的用户
创建数据库virtual Hosts 一般以/开头,多个库直接互不干扰,可以测试创建一个生产创建一个
点击这个数据库
进行用户授权
获取rabbitmq的工具类
package com.buba.utils;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class ConnectionUtils {
public static Connection getConnection() throws IOException, TimeoutException {
//定义一个连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置服务地址
factory.setHost("192.168.1.66");
//端口
factory.setPort(5672);
//vhost数据库
factory.setVirtualHost("/vhost_kxj");
//用户名
factory.setUsername("user_kxj");
//密码
factory.setPassword("123456");
Connection connection = factory.newConnection();
return connection;
}
}
1.简单队列
消息发布者
package com.buba.simple;
import com.buba.utils.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Send {
private static final String QUEUE_NAME="test_simple_queue";
public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection();
//从连接中获取一个通道
Channel channel = connection.createChannel();
//创建队列声明
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
String msg = "Hello simple";
channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
System.out.println("--send msg:"+msg);
channel.close();
connection.close();
}
}
消费者 ,里面使用的是过时的api
package com.buba.simple;
import com.buba.utils.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/*
消费者
*/
public class Recv {
private static final String QUEUE_NAME="test_simple_queue";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
//定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
//监听队列
channel.basicConsume(QUEUE_NAME,true,consumer);
while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String str = new String(delivery.getBody());
System.out.println("recv msg:"+str);
}
}
}
新api
package com.buba.simple;
import com.buba.utils.ConnectionUtils;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/*
消费者
*/
public class Recv {
private static final String QUEUE_NAME="test_simple_queue";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//定义一个消费者
DefaultConsumer consumer = new DefaultConsumer(channel){
//获取到达的消息
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String str = new String(body,"utf-8");
System.out.println("recv msg:"+str);
}
};
//监听队列
channel.basicConsume(QUEUE_NAME,true,consumer);
System.out.println("123");
}
}
当发布者运行一次就发布一个消息,在这个页面就能看到total为1
点击进来后,手动点一下getMessage,就把这条消息消费了
上面的消费者代码是使用代码进行消费.
简单队列的不足
耦合性高,生产者一 一对应消费者,如果我想有多个消费者消费队列中消息,这时候就不行了,队列名更变,这时候得同时更变.