一、浩言
我們要變的變態(tài),才能吸引更多的變態(tài)。
二、背景
最近在看消息隊(duì)列的東西,準(zhǔn)備引入到項(xiàng)目中使用,一直說(shuō)要自己先學(xué)會(huì)使用,在使用中學(xué)習(xí)。所以這算是新年的第一個(gè)周末就要加班,就在網(wǎng)上找資料自己嘗試配置下。順便紀(jì)錄下經(jīng)歷了,都是有坑要去踩的。
三、ActiveMQ 在Windows下的使用
我修改了配置文件activemq.xml,將0.0.0.0改成了127.0.0.1
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://127.0.0.1:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600000"/>
<transportConnector name="amqp" uri="amqp://127.0.0.1:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600000"/>
<transportConnector name="stomp" uri="stomp://127.0.0.1:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600000"/>
<transportConnector name="mqtt" uri="mqtt://127.0.0.1:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600000"/>
<transportConnector name="ws" uri="ws://127.0.0.1:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600000"/>
</transportConnectors>
注意點(diǎn):我在測(cè)試的時(shí)候一直報(bào)1G要大于maxFrameSize的100M,所以我在這個(gè)后面加了三個(gè)0
然后啟動(dòng)啟動(dòng)active


我們?cè)趙indows下使用這個(gè)命令查看端口netstat -ano linux下可以使用netstat -lntp查看

在瀏覽器中輸入:http://127.0.0.1:8161/admin/index.jsp會(huì)有如下顯示

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd">
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
<!-- <property name="brokerURL" value="http://127.0.0.1:61616"></property> -->
<property name="useAsyncSend" value="true"></property>
<property name="alwaysSessionAsync" value="true"></property>
<property name="useDedicatedTaskRunner" value="true"></property>
</bean>
<!-- 發(fā)送消息的目的地 -->
<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<!-- 消息隊(duì)列的名字 -->
<constructor-arg value="mahone.queue"/>
</bean>
</beans>
注意點(diǎn):我在這里面看到的我有個(gè)注釋的配置brokerURL,我剛剛開(kāi)始的時(shí)候一直配置成http...,然后怎么測(cè)試都不通,最后才發(fā)現(xiàn)是自己這里配置錯(cuò)了。

下面附上測(cè)試代碼
package com.mouse.moon.test.mq;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMq {
public static void sendWithAuto(ApplicationContext context) {
ActiveMQConnectionFactory factory = null;
Connection conn = null;
Destination destination = null;
Session session = null;
MessageProducer producer = null;
try {
destination = (Destination) context.getBean("destination");
factory = (ActiveMQConnectionFactory) context.getBean("targetConnectionFactory");
conn = factory.createConnection();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("...Hello JMS-4!");
producer.send(message);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {//關(guān)閉生產(chǎn)者
producer.close();
producer = null;
} catch (Exception e) {
}
try {//關(guān)閉session
session.close();
session = null;
}
catch (Exception e) {
}
try { //停止連接
conn.stop();
} catch (Exception e) {
}
try {//關(guān)閉連接
conn.close();
} catch (Exception e) {
}
}
}
public static void main(String[] args) {
System.out.println("-------------start--------------");
final ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/xml/activemq.xml");
sendWithAuto(context);
System.out.println("-------------end---------------");
}
}


在做測(cè)試的時(shí)候還遇到如下問(wèn)題
org.apache.activemq.ConfigurationException: There are 1 consumer options that couldn't be set on the consumer. Check the options are spelled correctly. Unknown parameters=[{perfetchSize=100}]. This consumer cannot be started.
這是在設(shè)置名字的時(shí)候附帶的參數(shù),我把這個(gè)去掉了就只能看到生產(chǎn)者的名字是"mahone.queue""
消費(fèi)端代碼:
package com.mouse.moon.test.mq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
* @author Mahone
* @description:消費(fèi)端
*
*/
public class TestConsumer extends Thread implements MessageListener{
private Connection conn = null;
private Destination destination = null ;
private Session session = null;
@Override
public void onMessage(Message message) {
try{
TextMessage tm = (TextMessage)message;
System.out.println("receive message:"+tm.getText());
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void run(){
receive();
}
public void receive(){
ConnectionFactory factory = null;
Connection conn = null ;
try{
final ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/xml/activemq.xml");
factory = (ActiveMQConnectionFactory)context.getBean("targetConnectionFactory");
conn = factory.createConnection();
conn.start();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = (Destination)context.getBean("destination");
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(this);
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String args[]){
TestConsumer mythread = new TestConsumer();
mythread.start();
}
}

上述代碼有參考該<a >博客</a>
四、消息隊(duì)列的作用
1:解耦操作
例如說(shuō)其中A更新好了之后,其他地方(B,C,D)也需要更新,那么使用消息隊(duì)列之后,A更新后,將更新通知放入消息隊(duì)列中,B,C,D中需要更新只需要訂閱這個(gè)操作就好,實(shí)現(xiàn)解耦。
2、實(shí)現(xiàn)異步操作
例如上面說(shuō)的,A更新后,其他的更新都是異步進(jìn)行處理,并不需要同步操作。
3、對(duì)流量進(jìn)行控制
有時(shí)候訪問(wèn)多了,流量就大了,忽高忽低的,如果放入隊(duì)列中,按照順序進(jìn)行操作,即是先存起來(lái),然后在按照順序進(jìn)行發(fā)送。
五:浩語(yǔ)
__
__ _ ____ __| |__ _____ ___
\ \/ \/ / | \ | \\__ \ / _ \
\ /| | / Y \/ __ \( <_> )
\/\_/ |____/|___| (____ /\____/
\/ \/
任何事情都是要靠努力和用心。