MQ产品种类:
Kafka
RabbitMQ
RocketMQ
ActiveMQ
1 何种场景下使用了消息中间件?
工程模块相互调用频繁,且模块过多时。RPC(Dubbox架构,类似同步调用。请求(client)-》服务注册中心(dubbox或者eruka)-》响应(service)。必须一条线逐个完成。)调用存在各种问题:耦合大,性能差(同步),负载重,结构逐渐复杂(某个模块负载过多)
RPC:
RPC调用是指不同机器间的进程通讯。程序不需要关心某个远程服务是在哪台机器上执行的,远程服务调用就和调用本地服务一样。
要在不同机器间进行通讯我们需要知道通讯机器的ip和端口号。ip帮助我们定位是哪一台机器,端口号帮我们定位是机器上的哪一个进程。
RPC的出现使用得机器的进程通讯透明化,这在分布式系统中是很重要的。RPC调用架构中客户端和服务端都和一个叫服务注册中心的第三方通讯。
2 为什么要在系统中引入MQ?
MQ作用:
解耦
削锋
异步
Queue:队列,PTP
Topic:主题,pub/sub , 发布/订阅模式
ActiveMQ:
启动: ./activemq start
重启: ./activemq restart
停止: ./activemq stop
状态: ./activemq staus
默认进程端口: 61616
端口号查询:netstat -anp|grep 61616
名称查询: ps -ef|grep activemq
带日志方式启动activemq:
./activemq start > /myactiveMQ/myrunmq.log #启动消息,写入日志文件myrunmq.log
ActiveMQ:
存储数据地方:
1 队列
2 主题
点对点模式:
生成者:
public class JmsProduce {
public static final String ACTIVEMQ_URL=“tcp://192.168.0.103:61616”;
public static final String QUEUE_NAME=“queue01”;
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
Session session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue=session.createQueue(QUEUE_NAME);
MessageProducer messageProducer=session.createProducer(queue);
for(int i=1;i<=6;i++){
TextMessage textMessage=session.createTextMessage("msg---"+i);
messageProducer.send(textMessage);
}
messageProducer.close();
session.close();
connection.close();
System.out.println("消息发布到MQ完成");
}
}
消费者:
public class JmsConsumer {
public static final String ACTIVEMQ_URL=“tcp://192.168.0.103:61616”;
public static final String QUEUE_NAME=“queue01”;
public static void main(String[] args) throws Exception {
System.out.println("我是二号消费者");
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
Session session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue=session.createQueue(QUEUE_NAME);
MessageConsumer messageConsumer=session.createConsumer(queue);
/**
* 同步阻塞方式: receive()
* 订阅者或接收者调用 MessageConsumer的receive()方法来接收消息,
* receive方法在能够接收到方法之前(或者超时之前: receive(timeout)),将一直阻塞。
*/
// while(true){
// TextMessage textMessage=(TextMessage)messageConsumer.receive();
// if(null !=textMessage){
// System.out.println(“消费者接收到消息:”+textMessage.getText());
// }else {
// break;
// }
// }
// messageConsumer.close();
// session.close();
// connection.close();
/**
* 异步监听机制,实现消息消费。不会阻塞程序,当有消息时,又可以消费消息
* 订阅者或者接收者通过MessageConsumer的setMessageListener(MessageListener listener)注册一个消息监听器,
* 当消息到达之后,系统自动调用监听器MessageListener的onMessage(Message message)方法
*/
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
if(null !=message && message instanceof TextMessage){
TextMessage textMessage=(TextMessage)message;
try{
System.out.println("监听机制消费消息"+textMessage.getText());
}catch (JMSException e){
e.printStackTrace();
}
}
}
});
System.in.read(); //等待控制台输入内容,保持程序运行状态
messageConsumer.close();
session.close();
connection.close();
}
}