1. 程式人生 > >WebSphere MQ Java 應用開發簡單例項(上篇:客戶端模式開發)(client mode和binding mode)

WebSphere MQ Java 應用開發簡單例項(上篇:客戶端模式開發)(client mode和binding mode)

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.0
MQ 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 VM
Could 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.<init>(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

相關推薦

WebSphere MQ Java 應用開發簡單例項客戶模式開發client modebinding mode)

1-背景知識 IBM MQ支援多種語言開發,本文主要是考慮Java應用開發,MQ提供了相關的Java類庫,可以很方便整合到Java應用中。 IBM MQ Java相關類庫允許Java應用直接與佇列管理器互動,或者連線MQ伺服器和客戶端進行互動。 類庫主要有

Java從入門到放棄》入門Struts2的常用驗證方式

java struts action validate 數據驗證 前一回,我們講完了“直接在功能方法中寫驗證代碼”這種驗證方式,接下來,我們繼續搞定後續的三種方式。二、重寫validate方法(註意這個方法會驗證該類中所有的方法) 使用重寫驗證方法的好處就是,又可以少寫一句代碼了!!

C# Socket簡單例子服務器與客戶通信

項目 回車 pop ace log () client protocol comm 這個例子只是簡單實現了如何使用 Socket 類實現面向連接的通信。 註意:此例子的目的只是為了說明用套接字寫程序的大概思路,而不是實際項目中的使用程序。在這個例子中,實際上還有很多問題

牛客網——華為機試題5進位制轉換Java

題目描述: 寫出一個程式,接受一個十六進位制的數值字串,輸出該數值的十進位制字串。(多組同時輸入 ) 輸入描述: 輸入一個十六進位制的數值字串。 輸出描述: 輸出該數值的十進位制字串。 示例1: 輸入: 0xA 輸出: 10 import java.ut

centos 6.9部署svn服務器服務器、客戶環境配置

svn svn服務器 tortoisesvn tortoisesvn使用 svn版本控制系統有很多用途,最近公司使用它加腳本實現產品補丁小更新(因為如果每次都大更新的話,每次都要重新打rpm包,更新yum源等,很麻煩)。一、服務器端安裝1、安裝svn[root@svn ~]#yum insta

華北五省機器人武術擂臺賽無差別第二從無到有的機械設計

華北五省機器人武術擂臺賽(無差別)(第二篇:從無到有的機械設計) 1. 方案設計 2. 前期材料選型(建議) 3. 加工手段(建議參賽隊自備的裝置) 4. 機械設計 5. 結束語 1. 方案設計 這裡借用東北大學ROBO

HTML5基礎加強css樣式css屬性怪異盒模型解析四十六

1.怪異盒模型和border有關: 設定border寬度可以影響其他元素的佈局:但是在IE5及以下里面只是影響其子元素; 2.可以同時設定 box-sizing屬性來使用這一特性,是其改變border寬度也不影響其他元素; 3,.box-sizing:簡單理解就是盒子大小基

java影象介面開發簡單例項-JLabel,JFileChooser,JMenu應用

import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.File;import javax.swing.ImageIcon;import javax.swing.JFileChooser;imp

java影象介面開發簡單例項-JButton及事件的簡單應用

import java.awt.BorderLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;i

Java技術_每天掌握一種設計模式002_使用場景及簡單例項建立型單例模式

1.模式描述 一個類有且僅有一個例項,並且自行例項化並向整個系統提供。 2.模式作用 保證某個類在系統中只有一個例項物件,對於特殊需求來說非常必要。 限制了例項個數有利於GC的回收。

java遞迴簡單例項

1.自己的第一篇部落格,想把自己的覺得有用的記錄下來,也可以鍛鍊自己的表達能力。內容談不上豐富,如果寫的不好,請大家多多包涵。 2.廢話不多說,就是幹,先準備下指令碼 drop TABLE IF EXISTS category; CREATE TABLE `category` ( &nb

openfire外掛開發簡單例項

網上找了半天openfire外掛開發的例子,都只是從原理上將的,並不利於菜鳥學習,所以我在這裡從動手方面將下openfire外掛的開發 1  這是我建立的目錄,請大家看清目錄結構 2  再次從包結構看下我建立的目錄結構   3  L

java網路程式設計8、基於TCP的socket程式設計簡單的socket通訊_一個客戶

宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!! 文章目錄 一、基於tcp的程式設計,就好像用電話進行交談一樣 二、在java中用於程式設計網路程式的類 三、套接字 + (輸出、輸入流) 1、伺服器程式編寫基本步驟: 2、客戶端程式

robot framework rf自動化測試例項第一啟動應用

1. 啟動手機用USB連線電腦,注意手機需要開啟開發者模式,開啟USB除錯功能(或者啟動電腦上的手機模擬器) 2. 啟動命令列cmd, 用命令檢視手機裝置名稱:adb devices (如下圖): 3. 啟動appium, 看到以下介面無報錯,則為啟動成功 4. 啟動r

javaWeb+JasperReport報表開發簡單例項

在網上搜索了很多JasperReport報表開發的例子,基本上都是說的一些理論知識,沒有一個直接用程式碼直觀表達的,想必大家想學習jasperReport報表的開始,都希望能夠直觀的看到程式碼,研究出程式碼執行後的效果是什麼,而不是一大堆的理論,說這些對於剛開始學的有毛用,

LinuxC/C++程式設計基礎(23) 使用thrift/rpc開發簡單例項(續1)

#include <vector> #include <boost/shared_ptr.hpp> #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TSimpleServer.h

java實現簡單快速的webservice客戶/資料採集器支援soap1.1soap1.2標準,支援utf-8編碼

前言: 用了cxf,axis等各種wbeservice實現庫,簡單試用了一下動態呼叫的方式,很不滿意,完全無法滿足業務的需要,所以自己實現了一個webservice採集客戶端,方便動態呼叫外部webservice介面。 一、實現的功能 1、soap1.1客戶端(soap1.

安卓APP開發簡單例項 結對程式設計心得

開始說起搞APP開發,自己和小夥伴的程式設計水平真的很低,無從下手,只有在網上找點案列,學習著怎樣開發,結對程式設計還是面臨著許多問題的,大家的水平有所差異和程式設計風格不同,我們用eclipse做了一個仿微信登入的畫面的程式,算不上APP,其中程式碼的簽入,我和他兩個仔細

Java動態代理簡單例項老闆與祕書

Java動態代理是Java中比較晦澀難懂的一個部分,雖然看了一些別人的部落格之後覺得自己大體明白了,但是事非經過不知難,自己寫的時候卻產生了諸多疑問。 本文用盡可能簡單的例子來說明Java動態代理的機制。 例子共四個部分: 1. ReadFile介面(批改檔案) 2. Bo

Eclipse+超快的模擬器Genymotion開發Android應用第一步安裝及配置Genymotion

一、安裝及配置Genymotion (1)由於Eclipse中自帶的SDK模擬器,啟動之慢,不說了 現在給大家介紹一種比較快的模擬器Genymotion (2)首先去Genymotion的官網註冊一個賬號,這個賬號是有用的 請記著你的賬號和密碼(我用的是QQ好註冊的)