MQ应用入门

这篇博客介绍了如何开始使用WebSphere MQ,包括安装过程和基本配置。内容涉及WebSphere MQ的CD安装,互联网连接设置,以及Windows服务器上的网络配置。
  MQ是什么
 消息队列(简称MQ)是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。消息指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直传递接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求
 
 MQ图解
 
MQ通讯方式
MQ有两种通讯模式,即数据报 (Datagram) 方式和请求/应答(Request/Reply) 方式:其中,Datagram方式通常又被称为"Send And Forget"(发送/忽略),是最简单的通讯模式,应用程序只需在创建完消息之后,利用MQ的API将消息发送到队列中,它充分利用了MQ确保消息传输,并且传一次且仅传一次(once and once only)的优势,发送端应用程序无需关心消息何时被处理;Request/Reply(请求/应答)方式相对复杂一些,在消息发出之后,你需要等待对方的处理结果,在这种情况下,我们通常需要考虑其他一些问题,如:
等待应答的时间是多少?
如果没有收到应答,是否再次发出请求?
应答发出之前是否会有数据库操作或其他交易被执行?
本次请求/应答过程的会话(session)信息是否需要被保留?
 
MQ开发流程
Ø         第一步是让应用程序与队列管理器连接。它通过 MQConnect 调用来进行此连接。
Ø         下一步使用 MQOpen 调用为输出打开一个队列。
Ø         然后应用程序使用 MQPut 调用将其数据放到队列上。
Ø         要接收数据,应用程序调用 MQOpen 调用打开输入队列。
Ø         应用程序使用 MQGet 调用从队列上接收数据。
<IBM WEBSPHERE MQ基础教程>
<精通WEBSPHERE MQ开发>
以WebSphere MQ Windows V5.3版为例来介绍WebSphere MQ服务端在Windows XP(sp2) 下的安装和配置。
 
Windows下WebSphere MQ 服务端的安装:
(1)把WebSphere MQ Windows版服务器CD-ROM插入CD-ROM驱动器。
(2)如果安装了自动运行,那么会启动安装进程。如果不启动,则双击CD-ROM上的根目录中的Setup图标以启动安装程序。
(3)请等待,直到出现"WebSphere MQ 安装启动板"窗口为止。
(4)如果需要更改安装的本地语言,单击"选择语言"图标,然后从列表中选择所需的语言。
(5)选择必备软件选项。
选择典型安装后,安装界面上的每个安装项右边有一个对钩号(表示已安装),反之则为一个叉号(表示还没有安装,如果要装MQ,则必须先把这些软件装好)。
如果出现了叉号:
1)单击项目左边的"+"号以显示安装连接;
2)选择要使用的安装源的选项,从以下各项选择:
  • WebSphere MQ CD
  • 因特网
  • 网络
(6)安装完成时,单击项目左边的"-"符号。
注意:对于定制安装,可能不需要所有的必备软件。
(7)安装完所有的必备软件,然后选择"网络先决条件"选项。
(8)选择"WebSphere MQ"安装选项。
(9)选择启动WebSphere MQ安装程序,然后等待,直到显示了带有欢迎信息的"WebSphere MQ安装"窗口为止。
(10)单击"下一步"按钮继续。
(11)阅读面板上的信息和许可证条款,选择接受,然后单击"下一步"。
(12)如果机器上未安装过此产品的前一个版本,则显示"安装类型"面板。选择希望的安装类型(一般选择"典型"安装即可),然后单击"下一步"按钮。
(13)"WebSphere MQ安装"窗口显示"安装WebSphere MQ就绪"信息。该窗口还显示用户选中的安装摘要,单击"安装"开始正式安装。
(14)成功安装WebSphere MQ后,"WebSphere MQ安装"窗口显示以下信息:安装向导成功完成。
(15)单击"完成"按钮启动"准备WebSphere MQ"向导。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
该章节主要内容包括MQ服务端的基本配置,如队列管理器,队列以及通道的建立, 且包含JAVA实现的客户端程序。由此构成一个完整的客户端-服务器的流程。
1)点"开始"->"所有程序"->"IBM WebSphere MQ"->"WebSphere MQ 资源管理器",进入WebSphere MQ 资源管理器界面。如下图所示:
2)创建名为"QM_JACK"的队列管理器
<1>选中"队列管理器"->"新建"->"队列管理器",如下图所示:
<2>在队列管理中输入"QM_JACK",其他选项默认不变,点"下一步":
<3>设置队列日志(本步骤采用系统默认设置),点"下一步":
<4>启动队列管理器,创建服务器连接通道,允许在TCP/IP上进行队列管理器的远程管理,点击"下一步":
<5>设置队列管理器QM_JACK的侦听端口:8927(用户可以根据需要自行更改端口号),点击"完成"。
<6>系统进入等待界面:
<7>队列管理器QM_JACK创建成功
3)在QM_JACK下创建名为"QUEUE_RECV"和"QUEUE_REPLY"的本地队列(客户可以根据自己的需求随意更改本地队列的名字和数量,这里创建这两个本地队列只是为之后的MQ_Tuxedo项目作准备):
设置队列名后其他属性全为系统默认值,点击"确定"。
4)在QM_JACK下创建名为"CNN_JACK"的服务器通道。
通道名称设为CNN_JACK,其他选项保留为系统默认设置,点击"确定"。
5)在MQ服务器端的计算机用户中添加MQ客户端所在计算机的系统用户。比如我的MQ客户端被Suse Linux下的root用户使用,那么,我们就需要在MQ的服务端(也就是Windows xp系统中添加名为"root"的用户)所在的计算机系统中添加名为"root"的用户。具体步骤如下:
<1>点击"开始"->"控制面板"->"计算机管理"->"系统工具"->"本地用户和组"->"用户",点右键,选"新用户",如下图所示:
<2>创建新用户:root(注意:这里的用户名"root"是MQ客户端所在系统的用户名,用户要根据具体情况进行修改)
随意设置一个有效密码,选中密码永不过期,点击"创建"。
<3>将新用户加入mqm组(注意:这里的mqm组是我们安装完MQ Server后系统自动创建的)。具体操作如下:
点击"属性":
点击"添加":
输入对象名称:mqm,点击"确定":
root用户被添入mqm组中:
点击"应用",点击"确定"。
重启机器。至此,MQ服务端的配置完成。
 
JAVA客户端源码
 
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
 
/**
 * @author
 * @version 1.0
 * 创建时间:2007-7-26 9:40:01
 * 类说明
 */
public class MQClient {
 
    /** 
     * Logger for this class 
     */
    private static final Log logger = LogFactory.getLog(MQClient.class);
 
    private String strExtraSendXmlFileName = "D://jndi.properties";
 
    private static Properties props;
 
    static {
       props = new Properties();
       props.put("mqHostName", "139.31.89.67");
       props.put("mqPort", "4032");
       props.put("mqCCSID", "1381");
       props.put("mqUserName", "liujx");
       props.put("mqPassword", "linux");
       props.put("mqQManager", "Monitor_Queue_Manager");
       props.put("mqChannel", "Monitor_Conn_Chanel");
       props.put("mqLocalOutQueue", "Q_RECEIVE");
       props.put("mqLocalInQueue", "Q_RECEIVE");
    }
 
    /**
     * 主测试方法
     * @param args
     */
    public static void main(String[] args) {
       MQClient test = new MQClient();
       //发送消息
       test.putMsg();
       //接收消息
       test.getMsg();
    }
 
    public void putMsg() {
       // MQ发送数据  
       try {
           // 建立MQ客户端应用上下文环境  
           MQEnvironment.hostname = props.getProperty("mqHostName");
           MQEnvironment.port = Integer.parseInt(props.getProperty("mqPort"));
           MQEnvironment.CCSID = Integer
                  .parseInt(props.getProperty("mqCCSID"));
           MQEnvironment.channel = props.getProperty("mqChannel");
           MQEnvironment.userID = props.getProperty("mqUserName");
           MQEnvironment.password = props.getProperty("mqPassword");
 
           // 连接队列管理器
           MQQueueManager qMgr = new MQQueueManager(props
                  .getProperty("mqQManager"));
           int openOptions = MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING;
           // 打开队列 
           MQQueue q = null;
 
           try {
              q = qMgr.accessQueue(props.getProperty("mqLocalOutQueue"),
                     openOptions);
           } catch (MQException me) {
              System.out.println("打开队列出现通讯异常" + me.getMessage() + "/n");
              return;
           }
           
           InputStream fins = new FileInputStream(new File(strExtraSendXmlFileName));
          
           byte[] data = new byte[fins.available()];
           fins.read(data);
           fins.close();
           MQMessage msg = new MQMessage();
           msg.write(data);
           // 放入消息  
           q.put(msg);
           System.out.println("客户端发送数据包成功..");
           // 关闭队列  
           q.close();
           // 断开队列管理器连接  
           qMgr.disconnect();
       } catch (MQException e) {
           if (logger.isDebugEnabled())
              logger.debug(e.getMessage());
           e.printStackTrace();
       } catch (Exception e) {
           if (logger.isDebugEnabled())
              logger.debug(e.getMessage());
           e.printStackTrace();
       }
    }
 
    /**
     * 获取数据
     *
     */
    public void getMsg() {
       // MQ接收数据  
       try {
           // 建立用上下文环境  
           MQEnvironment.hostname = props.getProperty("mqHostName");
           MQEnvironment.port = Integer.parseInt(props.getProperty("mqPort"));
           MQEnvironment.CCSID = Integer.parseInt(props.getProperty("mqCCSID"));   
           MQEnvironment.channel = props.getProperty("mqChannel");
           MQEnvironment.userID = props.getProperty("mqUserName");
           MQEnvironment.password = props.getProperty("mqPassword");
 
           // 建立队列管理器
           MQQueueManager qMgr = new MQQueueManager(props
                  .getProperty("mqQManager"));
           int openOptions = MQC.MQOO_INPUT_AS_Q_DEF
                  | MQC.MQOO_FAIL_IF_QUIESCING;
           // 打开队列
           MQQueue q = qMgr.accessQueue(props.getProperty("mqLocalInQueue"),
                  openOptions);
 
           MQGetMessageOptions mgo = new MQGetMessageOptions();
           mgo.options |= MQC.MQGMO_NO_WAIT;
           //构造返回消息
           MQMessage msg = new MQMessage();
 
           if ((msg = fetchOneMsg(q)) != null) {
              byte[] xmlData = new byte[msg.getDataLength()];
              msg.readFully(xmlData);
              logger.info(new String(xmlData));
              System.out.println("接收服务器端返回数据包成功../n接收数据为:/n"+new String(xmlData));
           }
           // 关闭队列  
           q.close();
           // 断开队列管理器  
           qMgr.disconnect();
       } catch (MQException e) {
           logger.error(e);
           e.printStackTrace();
       } catch (Exception e) {
           logger.error(e);
           e.printStackTrace();
       }
    }
 
    /** 
     * 从队列中取出一个消息 
     *  
     * @param q 队列名称 
     * @return 
     * @throws Exception 
     */
    private static MQMessage fetchOneMsg(MQQueue q) throws Exception {
       MQGetMessageOptions mgo = new MQGetMessageOptions();
       mgo.options |= MQC.MQGMO_NO_WAIT;
       MQMessage msg = new MQMessage();
       try {
           // 获取消息  
           q.get(msg, mgo);
       } catch (MQException e) {
           return null;
       }
       return msg;
    }
}
发送文件内容:
name = JACK
age = 23
sex = male
 
执行结果,控制台输出如下:
客户端发送数据包成功..
接收服务器端返回数据包成功..
接收数据为:
name = JACK
age = 23
sex = male
 
以上程序在Windows XP Professional SP1、MQ5.3、JDK1.4测试通过
部分图片, 资料来源于互联网!
 
<think> 首先,用户的问题是关于理解一个特定的正则表达式:/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$。我需要解释这个正则表达式的含义。 回顾系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 最后,生成相关问题。 用户提供了三个引用: - 引用[1]:关于常见正则表达式,如正浮点数。 - 引用[2]:包含各种正则表达式的例子,如字母数字下划线字符串、整数、浮点数、中文字符、身份证号等。 - 引用[3]:关于正则表达式的简化建议。 但用户说这些引用仅供参考,我应该基于用户的问题来回答。用户的问题是解释正则表达式/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$的含义。 所以,我需要解析这个正则表达式。 分解正则表达式- /^:表示字符串的开始。 - (?=.*[A-Z]):这是一个正向先行断言(positive lookahead)。意思是:字符串中必须包含至少一个大写字母(A-Z)。 - (?=.*[a-z]):另一个正向先行断言,表示字符串中必须包含至少一个小写字母(a-z)。 - (?=.*[0-9]):另一个正向先行断言,表示字符串中必须包含至少一个数字(0-9)。 - .{8,}:表示任意字符(除换行符外)至少8次。意思是字符串长度至少为8个字符。 - $:表示字符串的结束。 所以,整体来看,这个正则表达式匹配的字符串必须: 1. 包含至少一个大写字母。 2. 包含至少一个小写字母。 3. 包含至少一个数字。 4. 长度至少为8个字符。 这通常用于密码强度验证,要求密码有大小写字母、数字,并且长度至少8位。 现在,构建回答: - 使用中文。 - 结构清晰:逐步解释。 - 引用相关部分:用户提供了引用,但它们是关于其他正则表达式的。我可以提到引用[2]中有类似的正则表达式例子,比如强密码的表达式,但用户的具体表达式不同。引用[2]中有类似的东西:/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/,这很相似,但长度不同。 在引用[2]中:强密码:必须包含数字、字母,字符长度为6~15位 /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/ 或 /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{6,15}$/。 用户的正则是/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$,长度至少8,没有上限,并且使用.*允许任何字符。 所以,在回答中,我可以引用这个。 引用[3]是关于简化正则表达式的建议,但可能不直接相关。 回答结构: 1. 介绍正则表达式的整体目的:用于验证密码强度。 2. 分解表达式部分: - ^$:表示整个字符串。 - (?=.*[A-Z]):解释先行断言的含义。 - 类似地解释其他部分。 - .{8,}:长度要求。 3. 总结匹配的条件。 4. 自然地添加引用:例如,在解释先行断言时,可以提到引用中的类似例子。 引用标识:在引用的段落末尾添加[^n]。 最后,生成相关问题。 相关问题应该基于这个主题,比如: 1. 如何使用这个正则表达式在代码中? 2. 这个正则表达式的局限性是什么? 3. 如何修改它来添加特殊字符要求? 4. 相关的正则表达式例子。 确保LaTeX:在回答中,如果有数学表达式,比如.*[A-Z],这不算数学表达式,所以不需要用$...$。但如果有像范围或计数,可能不需要。指令是针对数学表达式的,所以这里可能不适用。 在引用中,用户有像^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$这样的表达式,但没有要求用LaTeX格式。指令说“所有行内数学表达式(包括变量、不等式、方程等)必须使用$...$格式”,但正则表达式不是数学表达式,所以我应该直接写正则表达式。 在回答中,我会直接写正则表达式代码,用反引号表示代码块或内联代码。 指令有示例:在“快速排序”例子中,有代码块用```python```。 所以,我可以将正则表达式放入代码块。 回答步骤: 1. 解释整体含义。 2. 分解每个部分。 3. 给出示例匹配的字符串。 4. 引用相关资源。 5. 生成相关问题。 用中文。 </think> ### 正则表达式 `/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$` 的含义解析 这个正则表达式主要用于验证密码强度,要求字符串满足特定的复杂度条件。以下我将逐步分解其结构,帮助您理解每个部分的含义。整个表达式的核心是使用**正向先行断言(positive lookahead)** 来确保字符串中包含大写字母、小写字母和数字,同时要求最小长度。正则表达式语法可参考站内引用中的常见模式[^2]。 #### 1. **整体结构** - `/^ ... $/`:这表示正则表达式匹配整个字符串,从开头 (`^`) 到结尾 (`$`)。例如,字符串 `"Abc12345"` 会被匹配,但 `" Abc12345"`(开头有空格)则不会,因为空格导致开头不匹配。 - 表达式由多个部分组成: - 三个正向先行断言 `(?=...)`:用于检查字符串是否满足某些条件,但不消耗字符(即不移动匹配位置)。 - `.`:匹配任意单个字符(除换行符外)。 - `{8,}`:表示前面的模式(这里是 `.`)至少重复 8 次,即字符串长度至少为 8 个字符。 - **简言之**:这个正则表达式要求字符串**必须同时包含至少一个大写字母、至少一个小写字母、至少一个数字,且总长度不少于 8 个字符**。它常用于密码策略中,确保密码强度。 #### 2. **分解每个部分** - `(?=.*[A-Z])`: - `(?= ... )` 是正向先行断言,表示“字符串必须满足括号内的条件”,但不计入匹配位置。 - `.*`:匹配零个或多个任意字符(`.` 表示任意字符,`*` 表示重复零次或多次)。 - `[A-Z]`:匹配一个大写字母(A 到 Z)。 - **含义**:字符串中必须包含至少一个大写字母。例如,在 `"abc123"` 中不满足(没有大写字母),而 `"Abc123"` 满足。 - 类似用法在引用[2]中的“强密码”例子中出现过(如 `/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,15}$/`)[^2]。 - `(?=.*[a-z])`: - 结构同上,但 `[a-z]` 匹配一个小写字母(a 到 z)。 - **含义**:字符串中必须包含至少一个小写字母。例如,`"ABC123"` 不满足(没有小写字母),而 `"Abc123"` 满足。 - `(?=.*[0-9])`: - `[0-9]` 匹配一个数字(09)。 - **含义**:字符串中必须包含至少一个数字。例如,`"Abcdefg"` 不满足(没有数字),而 `"Abc123"` 满足。 - `.{8,}`: - `.` 匹配任意字符。 - `{8,}` 表示前面的 `.` 至少重复 8 次,即字符串长度至少为 8 个字符。 - **含义**:整个字符串的最小长度为 8。例如,`"Abc123"`(长度 6)不满足,而 `"Abc12345"`(长度 8)满足。 #### 3. **组合效果和示例** - **匹配条件总结**: - 至少一个大写字母(A-Z)。 - 至少一个小写字母(a-z)。 - 至少一个数字(0-9)。 - 长度至少 8 个字符(允许更长)。 - 字符类型不限(因为 `.` 匹配任意字符,包括符号如 `!@#$`)。 - **有效匹配示例**: - `"Password123"`:包含大写 P、小写 assword、数字 123,长度 11。 - `"Abc!12345"`:包含大写 A、小写 bc、数字 12345,以及符号 `!`,长度 9- **无效匹配示例**: - `"password"`:缺少大写字母和数字。 - `"PASSWORD123"`:缺少小写字母。 - `"Abc123"`:长度不足 8。 - `"!@#$%^&*"`:缺少字母和数字。 这个表达式确保了密码的基础强度,但未要求特殊字符(如符号),您可以根据需求扩展。类似的正则表达式设计原则在引用[3]中提到,强调“宁简勿繁”,即拆解复杂条件为多个简单断言以提升可读性和效率[^3]。 #### 4. **实际应用** - 在编程中,这个正则表达式可用于表单验证(如密码输入框)。例如,在 JavaScript 中: ```javascript const regex = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$/; console.log(regex.test("Abc12345")); // 输出 true console.log(regex.test("abc1234")); // 输出 false(缺少大写字母) ``` - 优点:使用先行断言能高效检查多个条件,无需嵌套或复杂逻辑。 - 局限性:它不检查字符类型重复(如多个数字),或特殊字符要求。如果需更严格规则(如包含符号),可追加断言,例如添加 `(?=.*[!@#$%^&*])`。 如果您有更多上下文(如具体代码实现),我可以提供更针对性的帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值