文章出處
1-背景知識
IBM MQ支持多種語言開發,本文主要是考慮Java應用開發,MQ提供了相關的Java類庫,可以很方便集成到Java應用中。
IBM MQ Java相關類庫允許Java應用直接與隊列管理器交互,或者連接MQ服務器和客戶端進行交互。
類庫主要有兩個,一個是MQ classes for Java,另一個是支持JMS標準的MQ classes for JMS。
由于是示例學習,本文主要嘗試利用MQ classes for Java建立MQ簡單應用,從MQ 8.0開始,類庫是基于Java 7建立,因此需要Java 7以上運行時環境。
當然官方推薦使用JMS,因為最新的功能例如異步消費、自動重連等功能,都只在JMS中支持
開發有兩種通信模式連接MQ:
客戶端模式(client mode):應用作為客戶端使用TCP/IP連接MQ服務器,應用可以部署在相同機器上或者不同機器上;
綁定模式(binding mode):通過JNI(Java Native Interface)直接連接MQ服務器,避免網絡通信,性能更佳,必須和MQ服務器在相同機器上;
2-開發環境準備2.1 開發環境
VMware Workstation 11.1.4 SuSE Linux Server x64 SP4 虛擬機JDK 8.0MQ 8.0安裝包
2.2 安裝
安裝好虛擬機,SuSE Linux SP4,接下來安裝MQ本地開發環境**安裝MQ相關組件**# tar -xvf WSMQ_8.0_IFR_TRIAL_LNX_ON_X86_64_.tar.gz# cd server安裝MQ運行時組件:# rpm -ivh MQSeriesRuntime-8.0.0-2.x86_64.rpm安裝服務器組件:# rpm -ivh MQSeriesServer-8.0.0-2.x86_64.rpm安裝MQ Java庫:這里面提供MQ Java開發相關的類庫# rpm -ivh MQSeriesJava-8.0.0-2.x86_64.rpm 安裝MQ JRE:java運行時用來運行MQ Java應用# rpm -ivh MQSeriesJRE-8.0.0-2.x86_64.rpm **安裝JDK**下載JDK壓縮包,放入/home目錄下# cd /home# tar xvfz jdk-8u102-linux-x64.tar.gz # cd jdk1.8.0_102# ./java -version 出錯:Error occurred during initialization of VMCould not allocate metaspace: 1073741824 bytes很明顯內存空間不夠導致,原虛擬機只有768MB內存,增加到2GB,然后重啟虛擬機# reboot# cd /home/jdk1.8.0_102/bin# ./java -version# ./javac 提示安裝成功**配置MQ服務器**# useradd mquser1 -u 3001# passwd mquser1 設置密碼為mqtest2016# su - mqm~ cd /opt/mqm/bin設置mq環境變量~ source setmqenv -s創建隊列管理器JAVA.QUEUE.MANAGER.1,并啟動~ crtmqm JAVA.QUEUE.MANAGER.1~ strmqm JAVA.QUEUE.MANAGER.1~ dspmq 查看所有隊列管理器運行狀態啟動腳本執行器,進行設置~ runmqsc JAVA.QUEUE.MANAGER.1輸入: DEFINE QLOCAL(QUEUE1) 創建本地隊列QUEUE1 授權mquser1用戶(id為3001)使用隊列QUEUE1,其中PROFILE是對該條記錄進行命名,PRINCIPAL指定特定用戶,表明權限授權某用戶。 SET AUTHREC PROFILE(QUEUE1) OBJTYPE(QUEUE) PRINCIPAL('mquser1') AUTHADD(PUT,GET) 授權用戶mquser1可以連接隊列管理器 SET AUTHREC OBJTYPE(QMGR) PRINCIPAL('mquser1') AUTHADD(CONNECT) 定義服務器連接通道 DEFINE CHANNEL(JAVA.CLIENT.CHANNEL1) CHLTYPE(SVRCONN) TRPTYPE(TCP) 授權MQ客戶端可以連接上面定義的通道,通過ip地址和用戶名方式授權 SET CHLAUTH(JAVA.CLIENT.CHANNEL1) TYPE(ADDRESSMAP) ADDRESS('127.0.0.1') MCAUSER('mquser1') 定義監聽器,接受連接 DEFINE LISTENER(JAVA.CLIENT.LISTENER1) TRPTYPE(TCP) CONTROL(QMGR) PORT(1316) 啟動: START LISTENER(JAVA.CLIENT.LISTENER1) 結束: end**編寫Java程序**MQ Java應用主要需要包含兩個Jar包:com.ibm.mq.allclient.jar 和 com.ibm.mq.traceControl.jar在安裝目錄下/opt/mqm/java/lib# cd /opt/mqm/java/lib# java -java com.ibm.mq.allclient.jar 查看該jar詳細信息接下來可以用vim或者IDE編寫程序
3-客戶端模式進行連接
簡單應用,讀寫本機隊列,發送消息和讀取消息,以客戶端模式,利用TCP/IP進行通信
# cd /home/mq# vim MQTest.java輸入以下內容:
import java.io.IOException;import com.ibm.mq.MQEnvironment;import com.ibm.mq.MQException;import com.ibm.mq.MQGetMessageOptions;import com.ibm.mq.MQMessage;import com.ibm.mq.MQPutMessageOptions;import com.ibm.mq.MQQueue;import com.ibm.mq.MQQueueManager;import com.ibm.mq.constants.CMQC;import com.ibm.mq.constants.MQConstants;public class MQTest { public static void main(String[] args) throws MQException, IOException { //發送消息給隊列 put(); //從隊列讀取消息 get(); } static void put() throws MQException, IOException { //配置MQ服務器連接參數 MQEnvironment.hostname = "127.0.0.1"; MQEnvironment.port = 1316; MQEnvironment.channel = "JAVA.CLIENT.CHANNEL1"; //設置應用名稱,方便服務器MQ 查看應用連接 MQEnvironment.properties.put(MQConstants.APPNAME_PROPERTY, "MQ Test By Java"); //創建實例,連接隊列管理器 MQQueueManager queueManager = new MQQueueManager("JAVA.QUEUE.MANAGER.1"); //以可寫的方式訪問隊列管理器已定義的隊列QUEUE1,當然也可以創建隊列 MQQueue putQueue = queueManager.accessQueue("QUEUE1", CMQC.MQOO_OUTPUT); //新建并發送消息給隊列 MQMessage myMessage = new MQMessage(); String name = "MePlusPlus's 博客"; myMessage.writeUTF(name); //使用默認的消息選項 MQPutMessageOptions pmo = new MQPutMessageOptions(); //發送消息 putQueue.put(myMessage, pmo); putQueue.close(); //斷開連接 queueManager.disconnect(); } static void get() throws MQException, IOException { //配置MQ服務器連接參數 MQEnvironment.hostname = "127.0.0.1"; MQEnvironment.port = 1316; MQEnvironment.channel = "JAVA.CLIENT.CHANNEL1"; //設置應用名稱,方便服務器MQ 查看應用連接 MQEnvironment.properties.put(MQConstants.APPNAME_PROPERTY, "MQ Test By Java"); //創建實例,連接隊列管理器 MQQueueManager queueManager = new MQQueueManager("JAVA.QUEUE.MANAGER.1"); //以可讀的方式訪問隊列管理器已定義的隊列QUEUE1 MQQueue getQueue = queueManager.accessQueue("QUEUE1", CMQC.MQOO_INPUT_AS_Q_DEF); //從隊列讀取消息 MQMessage theMessage = new MQMessage(); MQGetMessageOptions gmo = new MQGetMessageOptions(); getQueue.get(theMessage, gmo); String name = theMessage.readUTF(); System.out.println(name); getQueue.close(); //斷開連接 queueManager.disconnect(); }}
編譯:# /home/jdk1.8.0_102/bin/javac -cp /opt/mqm/java/lib/com.ibm.mq.allclient.jar -Xlint:unchecked MQTest.java運行:# /home/jdk1.8.0_102/bin/java -cp /opt/mqm/java/lib/com.ibm.mq.allclient.jar:/home/mq MQTest**注意**路徑必須以冒號分割,windows下cp參數是分號分割,運行時必須加上MQText.class所在的目錄/home/mq,否則提示 錯誤:找不到或者無法加載主類MQTest;此外必須指明引用的jar文件完整路徑,否則提示 java.lang.ClassNotFoundException:com.ibm.mq.MQException.運行可能出錯:
com.ibm.mq.MQQueueManager.(MQQueueManager.java:675) at MQTest.put(MQTest.java:35) at MQTest.main(MQTest.java:18) Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9204: 與主機 '127.0.0.1(1316)' 的連接被拒絕。 [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2538;AMQ9213: 發生 'TCP' 的通信錯誤。
解決:明顯是和MQ服務器通信問題,可能是MQ服務器沒有啟動# telnet 127.0.0.1 1316 是否連通# su - mqm~ cd /opt/mqm/bin~ dspmq 查看隊列管理器狀態,如果沒有啟動,啟動它~ source setmqenv -s~ strmqm JAVA.QUEUE.MANAGER.1錯誤代碼:網上查明,是因為與MQ服務器連接錯誤導致,是因為用戶權限問題com.ibm.mq.MQException: MQJE001: 完成代碼為 '2',原因為 '2035'在MQTest.java文件中加入:(**以下兩句不用加,這個不是用來驗證連接的用戶,具體分析見最后小結,這個是后面實驗發現**)MQEnvironment.userID = "myuser1";MQEnvironment.password = "mqtest2016";此外在官方文檔上找到解決方法:為在隊列管理器重新增加用戶mquser1用戶的權限,MQ Java類庫用到了其它權限。 # su - mqm~ cd /opt/mqm/bin設置mq環境變量~ source setmqenv -s啟動腳本執行器,進行設置~ runmqsc JAVA.QUEUE.MANAGER.1 SET AUTHREC OBJTYPE(QMGR) PRINCIPAL('mquser1') AUTHADD(CONNECT,INQ) SET AUTHREC PROFILE('QUEUE1') OBJTYPE(QUEUE) PRINCIPAL('mquser1') AUTHADD(PUT,GET,INQ,BROWSE)其中:INQ:查詢隊列的屬性信息PUT:發送給隊列GET:從隊列讀取消息BROWSE:從隊列讀取消息,以瀏覽的選項設置CONNECT:允許應用連接MQ具體參見官網文檔 [SET AUTHREC](http://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.0.0/com.ibm.mq.ref.adm.doc/q086620_.htm)文檔中實例進行的的配置命令如下: runmqlsr -t tcp -m JAVA.QUEUE.MANAGER.1 -p 1317 (通過查看進程知道,該方式和上述方式設置效果一樣,但這樣更簡單) runmqsc JAVA.QUEUE.MANAGER.1 DEFINE CHANNEL('JAVA.CHANNEL.1') CHLTYPE(SVRCONN) TRPTYPE(TCP) DESCR('TEST FOR JAVA') SET CHLAUTH('JAVA.CHANNEL.1') TYPE(ADDRESSMAP) ADDRESS('192.168.98.1') MCAUSER('mquser1') DEFINE QLOCAL('QUEUE1') DESCR('TEST FOR QUUE') SET AUTHREC OBJTYPE(QMGR) PRINCIPAL('mquser1') AUTHADD(CONNECT,INQ) SET AUTHREC PROFILE('QUEUE1') OBJTYPE(QUEUE) PRINCIPAL('mquser1') AUTHADD(PUT,GET,INQ,BROWSE) end修改后的代碼如下:
import java.io.IOException;import com.ibm.mq.MQEnvironment;import com.ibm.mq.MQException;import com.ibm.mq.MQGetMessageOptions;import com.ibm.mq.MQMessage;import com.ibm.mq.MQPutMessageOptions;import com.ibm.mq.MQQueue;import com.ibm.mq.MQQueueManager;import com.ibm.mq.constants.CMQC;import com.ibm.mq.constants.MQConstants;public class MQTest { public static void main(String[] args) throws MQException, IOException { //發送消息給隊列 put(); //從隊列讀取消息 get(); } static void put() throws MQException, IOException { //配置MQ服務器連接參數 MQEnvironment.hostname = "127.0.0.1"; MQEnvironment.port = 1316; MQEnvironment.channel = "JAVA.CLIENT.CHANNEL1"; MQEnvironment.userID = "mquser1"; MQEnvironment.password = "mqtest2016"; //設置應用名稱,方便服務器MQ 查看應用連接 MQEnvironment.properties.put(MQConstants.APPNAME_PROPERTY, "MQ Test By Java"); //創建實例,連接隊列管理器 MQQueueManager queueManager = new MQQueueManager("JAVA.QUEUE.MANAGER.1"); //以可寫的方式訪問隊列管理器已定義的隊列QUEUE1,當然也可以創建隊列 MQQueue putQueue = queueManager.accessQueue("QUEUE1", CMQC.MQOO_OUTPUT); //新建并發送消息給隊列 MQMessage myMessage = new MQMessage(); String name = "MePlusPlus's 博客"; myMessage.writeUTF(name); //使用默認的消息選項 MQPutMessageOptions pmo = new MQPutMessageOptions(); //發送消息 putQueue.put(myMessage, pmo); putQueue.close(); //斷開連接 queueManager.disconnect(); } static void get() throws MQException, IOException { //配置MQ服務器連接參數 MQEnvironment.hostname = "127.0.0.1"; MQEnvironment.port = 1316; MQEnvironment.channel = "JAVA.CLIENT.CHANNEL1"; MQEnvironment.userID = "mquser1"; MQEnvironment.password = "mqtest2016"; //設置應用名稱,方便服務器MQ 查看應用連接 MQEnvironment.properties.put(MQConstants.APPNAME_PROPERTY, "MQ Test By Java"); //創建實例,連接隊列管理器 MQQueueManager queueManager = new MQQueueManager("JAVA.QUEUE.MANAGER.1"); //以可讀的方式訪問隊列管理器已定義的隊列QUEUE1 MQQueue getQueue = queueManager.accessQueue("QUEUE1", CMQC.MQOO_INPUT_AS_Q_DEF); //從隊列讀取消息 MQMessage theMessage = new MQMessage(); MQGetMessageOptions gmo = new MQGetMessageOptions(); getQueue.get(theMessage, gmo); String name = theMessage.readUTF(); System.out.println(name); getQueue.close(); //斷開連接 queueManager.disconnect(); }}
# /home/jdk1.8.0_102/bin/javac -cp /opt/mqm/java/lib/com.ibm.mq.allclient.jar MQTest.java# /home/jdk1.8.0_102/bin/java -cp /opt/mqm/java/lib/com.ibm.mq.allclient.jar:/home/mq MQTest
就愛閱讀www.92to.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20161206/65138.html
文章列表
全站熱搜