• [性能测试]:关于MQ协议脚本开发


    消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过写和检索出入列队的针对应用程序的数据(消息)来通信,而无需专用连接来链接它们。

    银行脚本使用MQ通信的较多,下面介绍一个MQ的脚本:

    MQ的脚本分为SEND和RECIVE两部分

    send部分:

    import com.ibm.mq.*;
    import lrapi.lr;
    
    public class Actions
    {
        String PutQueueManagerName = "QMCPG1"; // 发送队列管理器
        String PutQueueName = "HVPSBANK"; // 发送队列名,相当于前置机的接收队列
        String QueueChannel = "xn_rcv"; // 通道名,要用服务器通道
        int PutPort = 1428; // 发送端口号,相当于前置机的接收端口
        int CCSID = 1381; // 客户端Unix用819,windows用1381
        int OpenOptions = MQC.MQOO_INPUT_AS_Q_DEF|MQC.MQOO_OUTPUT|MQC.MQOO_INQUIRE; // 连接参数
        int PutDepth = 0; // 发送队列深度
        String SndTime = ""; // 当前发送时间
    
        MQQueueManager PutQueueManager = null; // 创建发送队列管理器对象
        MQQueue PutQueue = null; // 创建发送队列对象
        MQMessage PutMessage = new MQMessage(); // 创建发送消息对象
        MQPutMessageOptions PMO = new MQPutMessageOptions(); // 创建发送消息选项队列
        
        public int init() throws Throwable
        {
            // 发送队列的参数**********************************************
            MQEnvironment.hostname = lr.eval_string("<HostIP>"); // 设置环境参数
            MQEnvironment.port = PutPort;
            MQEnvironment.CCSID = CCSID; 
            MQEnvironment.channel = QueueChannel;
            PutQueueManager = new MQQueueManager(PutQueueManagerName); // 连接发送队列管理器
            PutQueue = PutQueueManager.accessQueue(PutQueueName, OpenOptions, null, null, null); // 建立访问发送队列
            PutMessage.format = MQC.MQFMT_STRING; // 设置消息中应用数据的格式
            PutMessage.characterSet = 1381; // 设置字符集
            PutMessage.expiry = -1;    // 设置消息为不过期
    
            return 0;
        }//end of init
    
    
        public int action() throws Throwable
        {
            SndTime = String.valueOf(System.currentTimeMillis()); // 获取当前发送时间,13位
            lr.start_transaction("02_CP2I111_大额来帐_发送");
            
            PutQueueMessage("{H:" +
                            "02" +
                            "309391000011  " +
                            "HVPS" +
                            "306581000003  " +
                            "HVPS" +
                            "<Date>" + // 报文发起日期
                            "<Time>" + // 报文发起时间
                            "XML" +
                            "hvps.111.001.01     " +
                            SndTime + "<Num>" + // 通信级标识号,CNAPS2SIMU0000088212,20位,接收方根据OrigSender+OrigSendDate+MesgID唯一确定一个报文,该三项重复的报文作为通信级重复报文;
                            SndTime + "<Num>" + // 通信级参考号,CNAPS2SIMU0000030415,20位,标识本报文的关联报文,由OrigSender设置,后续节点应保持该域不变,并在通信回应报文中带回该值,以便OrigSender匹配原报文;
                            "3" +
                            "D" +
                            "         " +
                            "}
    " +
                            "{S:" + // 数字签名域起始标识
                            "2016110700130322|2016-11-07T14:25:01|1|2016110700130322|A100|CNY10.05|NORM|309391000011|309391000011|306581000003|306588000016|321|123|309391000011|306588000016|xingneng|6214620421000208396|02102|" + // 数字签名内容
                            "}
    " + // 数字签名域结束标识
                            "<?xml version="1.0" encoding="UTF-8"?>" + 
                            "<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02">" + 
                              "<FIToFICstmrCdtTrf>" + 
                            "<GrpHdr>" + 
                              "<MsgId>" + "<Date>" + "<Time>" + "<MsgNum>" + "</MsgId>" + // 报文标识号,最大35位,最好是8位日期+8位流水,否则二代后台会处理异常,2016111015130018
                            "<CreDtTm>2016-11-07T14:25:01</CreDtTm>" + 
                            "<NbOfTxs>1</NbOfTxs>" + 
                            "<SttlmInf>" + 
                            "<SttlmMtd>CLRG</SttlmMtd>" + 
                            "</SttlmInf>" + 
                            "</GrpHdr>" + 
                            "<CdtTrfTxInf>" + 
                            "<PmtId>" + 
                            "<EndToEndId>1</EndToEndId>" + 
                            "<TxId>" + SndTime + "<Num>" + "</TxId>" + // 交易标识号,最大35位,2016110700130322
                            "</PmtId>" + 
                            "<PmtTpInf>" + 
                            "<CtgyPurp>" + 
                            "<Prtry>A100</Prtry>" + 
                            "</CtgyPurp>" +
                            "</PmtTpInf>" +
                            "<IntrBkSttlmAmt Ccy="CNY">0.02</IntrBkSttlmAmt>" + // 金额
                            "<SttlmPrty>NORM</SttlmPrty>" +
                            "<ChrgBr>DEBT</ChrgBr>" +
                            "<InstgAgt>" +
                            "<FinInstnId>" +
                            "<ClrSysMmbId>" +
                            "<MmbId>309391000011</MmbId>" + // 付款清算行行号
                            "</ClrSysMmbId>" +
                            "</FinInstnId>" +
                            "<BrnchId>" +
                            "<Id>309391000011</Id>" + // 收款行行号
                            "</BrnchId>" +
                            "</InstgAgt>" +
                            "<InstdAgt>" +
                            "<FinInstnId>" +
                            "<ClrSysMmbId>" +
                            "<MmbId>306581000003</MmbId>" + // 收款清算行行号
                            "</ClrSysMmbId>" +
                            "</FinInstnId>" +
                            "<BrnchId>" +
                            "<Id>306588000016</Id>" + // 收款行行号
                            "</BrnchId>" +
                            "</InstdAgt>" +
                            "<Dbtr>" +
                            "<Nm>沈监</Nm>" + // 付款人名称
                            "</Dbtr>" +
                            "<DbtrAcct>" +
                            "<Id>" +
                            "<Othr>" +
                            "<Id>6225684352000160189</Id>" + // 付款人账号
                            "</Othr>" +
                            "</Id>" +
                            "</DbtrAcct>" +
                            "<DbtrAgt>" +
                            "<FinInstnId>" +
                            "<ClrSysMmbId>" +
                            "<MmbId>309391000011</MmbId>" + // 付款人开户行行号
                            "</ClrSysMmbId>" +
                            "</FinInstnId>" +
                            "</DbtrAgt>" +
                            "<CdtrAgt>" +
                            "<FinInstnId>" +
                            "<ClrSysMmbId>" +
                            "<MmbId>306588000016</MmbId>" + // 收款人开户行行号
                            "</ClrSysMmbId>" +
                            "</FinInstnId>" +
                            "</CdtrAgt>" +
                            "<Cdtr>" +
                            "<Nm>燕净</Nm>" + // 收款人名称
                            "</Cdtr>" +
                            "<CdtrAcct>" +
                            "<Id>" +
                            "<Othr>" +
                            "<Id>6225684341000008415</Id>" + // 收款人账号
                            "</Othr>" +
                            "</Id>" +
                            "</CdtrAcct>" +
                            "<Purp>" +
                            "<Prtry>02102</Prtry>" + // 业务种类编码
                            "</Purp>" +
                            "<RmtInf>" +
                            "<Ustrd>/C00/2016-11-07</Ustrd>" + // 备注
                            "</RmtInf>" +
                            "</CdtTrfTxInf>" +
                            "</FIToFICstmrCdtTrf>" +
                            "</Document>");
           
            lr.end_transaction("02_CP2I111_大额来帐_发送",lr.PASS);
    
            return 0;
        }//end of action
    
    
        public int end() throws Throwable
        {
            try
            {
                PutQueue.close();
                PutQueueManager.close();
                PutQueueManager.disconnect();
            }
            catch (MQException ex)
            {
                lr.error_message("02_CP2I111_大额来帐_发送退出关闭队列时出现错误,完成代码为:" + ex.completionCode + ",原因为:" + ex.reasonCode);
                ex.printStackTrace();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            
            return 0;
        }// end of end
    
        // 发送消息++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        public void PutQueueMessage(String MyStr)
        {
            try
            {
                PutMessage = new MQMessage();
                 PutMessage.write(MyStr.getBytes("UTF-8")); // 呵呵
                 PutQueue.put(PutMessage, PMO);// 将消息放入队列
                PutQueueManager.commit(); // 提交事务处理
                //PutDepth = PutQueue.getCurrentDepth(); // 获取发送队列的深度
                //System.out.println("++++++发送队列当前深度为:"+ PutDepth);
                //System.out.println("=======发送报文是:" + MyStr);
                PutMessage.clearMessage();
                PutMessage = null;
            }
            catch (MQException ex)
            {
                lr.end_transaction("02_CP2I111_大额来帐_发送",lr.FAIL);
                lr.error_message("02_CP2I111_大额来帐_发送_发送消息时出错,完成代码为:" + ex.completionCode + ",原因为:" + ex.reasonCode + "流水号为:" + SndTime);
                lr.exit(lr.EXIT_ITERATION_AND_CONTINUE, lr.FAIL);
                //System.out.println("发送消息时出现错误,完成代码为:" + ex.completionCode + ",原因为:" + ex.reasonCode);
                //ex.printStackTrace();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }    
        }
    }

    RECIVE部分:

    /*
     * LoadRunner Java script. (Build: _build_number_)
     * 
     * Script Description: 
     *                     
     */
    import java.util.Date;
    import com.ibm.mq.*;
    import lrapi.lr;
    
    public class Actions
    {
        String GetQueueManagerName = "QMCPG1"; // 接收队列管理器
        String GetQueueName = "306581000003.MBFEA.PBCTOBANK";  // 接收队列名,相当于前置机的发送队列
        String QueueChannel = "xn_rsp"; // 通道名,要用服务器通道
        //String HostName = lr.eval_string("<HostIP>"); // ip 地址
        int GetPort = 1428; // 接收端口号,相当于前置机的发送端口
        int CCSID = 1381; // 客户端Unix用819,windows用1381
        int OpenOptions = MQC.MQOO_INPUT_AS_Q_DEF|MQC.MQOO_OUTPUT|MQC.MQOO_INQUIRE; // 连接参数
        int GetDepth = 0; // 接收队列深度
    
        MQQueueManager GetQueueManager = null; // 创建接收队列管理器对象
        MQQueue GetQueue = null; // 创建接收队列对象
        MQMessage GetMessage = new MQMessage(); // 创建接收消息对象
        MQGetMessageOptions GMO = new MQGetMessageOptions(); // 创建接收消息选项对象
    
        public int init() throws Throwable
        {
            // 接收队列的参数***********************************************
            MQEnvironment.hostname = lr.eval_string("<HostIP>"); // 设置环境参数
            MQEnvironment.port = GetPort;
            MQEnvironment.CCSID = CCSID;
            MQEnvironment.channel = QueueChannel;
            GetQueueManager = new MQQueueManager(GetQueueManagerName); // 连接接收队列管理器
            GetQueue = GetQueueManager.accessQueue(GetQueueName, OpenOptions, null , null, null); // 建立访问接收队列
            GetMessage.format = MQC.MQFMT_STRING; // 设置消息体参数
            GetMessage.characterSet = 1381;
            GetMessage.expiry = -1;
            GMO.waitInterval = 20000; // 等待时间限制
            GMO.options = MQC.MQGMO_NO_WAIT; // 如果队列没有消息则立即返回
            
            return 0;
        }//end of init
    
    
        public int action() throws Throwable
        {
            String Msg = null;
            String NowTime = null;
            
            try
            {
                GetMessage = new MQMessage(); // 必须新建实例,否则无法多次迭代无法继续接收消息
                 GetDepth = GetQueue.getCurrentDepth(); // 获取接收队列的深度 
                if(GetDepth > 0) //接收队列深度不为0则打印消息
                {
                    GetQueue.get(GetMessage, GMO);
                    GetQueueManager.commit();
                    //System.out.println("======接收队列当前深度为:"+ GetDepth);
                    NowTime = String.valueOf(System.currentTimeMillis()); // 记录当前时间戳作为接收时间,13位
                    Msg = GetMessage.readString(GetMessage.getMessageLength());
                    CompResult(Msg,NowTime); // 记录接收时间、流水、交易码(所接收的交易返回信息不一定为当前程序发出的交易)
                    //System.out.println("======接收消息的内容为:
    " + Msg);
                    GetMessage.clearMessage();
                    GetMessage = null;
                }
                else
                {
                    System.out.println("++++++接收队列无消息++++++");
                }
            }
            catch(MQException ex)
            {
                if(ex.reasonCode == 2033)
                {
                    // 2033是没有消息,不做处理
                }
                else
                {  
                    lr.error_message("02_CP2I111_大额来帐_接收接收消息时出错,完成代码为:" + ex.completionCode + ",原因为:" + ex.reasonCode + ",流水号为:" + NowTime);
                    ex.printStackTrace();
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            
            return 0;
        }//end of action
    
        public int end() throws Throwable
        {
            try
            {
                GetQueue.close(); // 关闭队列
                GetQueueManager.close(); // 关闭队列管理器
                GetQueueManager.disconnect(); // 断开连接
            }
            catch (MQException ex)
            {
                lr.error_message("02_CP2I111_大额来帐_接收关闭队列时出现错误,完成代码为:" + ex.completionCode + ",原因为:" + ex.reasonCode);
                ex.printStackTrace();
            }
    
            return 0;
        }// end of end
    
        
        // 统计交易结果
        public void CompResult(String MSG, String RecTime)
        {
            boolean Result = true; // 交易是否成功
            String StartTime = null;
            double DurTime = 0; // 交易处理时间
            int FlowIndex = -1; // 位置
            String FlowNo = null;
            int ErrIndex = -1; // 错误码位置
            String ErrCode = null;
                    
            FlowIndex = MSG.indexOf("<MsgId>"); // 流水号的位置
            StartTime = MSG.substring(FlowIndex+7, FlowIndex+7+13); // 从流水号获取开始时间
            DurTime = (Double.parseDouble(RecTime) - Double.parseDouble(StartTime))/1000; // 单位秒
            //lr.error_message("======处理时间是:" + DurTime + "发送时间是:" + StartTime + "接收时间是:" + RecTime + "返回报文是:" + MSG);
            ErrIndex = MSG.indexOf("<MsgPrcCd>"); // 错误码的位置
            ErrCode = MSG.substring(ErrIndex+10, ErrIndex+10+8); // 错误码
            if(!ErrCode.equals("CU0I0000")) // 成功状态码是CU0I0000,交易失败则获取流水号
            {
                Result = false;
                   FlowNo = MSG.substring(FlowIndex+7, FlowIndex+7+13); // 流水号
                   lr.error_message("02_CP2I111_大额来帐_接收交易失败!出错流水号是:" + FlowNo + ",错误码是:" + ErrCode + ",完整出错信息是:" + MSG);
            }
            
               // 统计事务响应时间和成功率
            if(Result)
            {
                lr.set_transaction("02_CP2I111_大额来帐_接收", DurTime, lr.PASS);
                //lr.error_message("======02_CP2I111_DELZ交易事务处理时间是:" + DurTime);
            }
            else
            {
                lr.set_transaction("02_CP2I111_大额来帐_接收", DurTime, lr.FAIL);
            }
        }
    }
    
    
    // 正确返回报文:
    //{H:02306581000003  HVPS309391000011  HVPS20161110164516XMLccms.990.001.02     20161110HVPS00062057012016111016501100013U         }
    //<?xml version="1.0" encoding="UTF-8"?>
    //<Document xmlns="urn:cnaps:std:ccms:2010:tech:xsd:ccms.990.001.02"><ComConf><ConfInf><OrigSndr>309391000011</OrigSndr><OrigSndDt>20161110</OrigSndDt><MT>hvps.111.001.01</MT><MsgId>01201611101650110001</MsgId><MsgRefId>01201611101650110001</MsgRefId><MsgPrcCd>CU0I0000</MsgPrcCd></ConfInf></ComConf></Document>
  • 相关阅读:
    【258】雅思口语常用话
    【256】◀▶IEW-答案
    UITabBarController 标签栏控制器
    枚举
    HDU3631:Shortest Path(Floyd)
    让Barebox正确引导Tiny6410的linux内核
    调度子系统2_核心调度器
    12.10 公司面试总结
    X265编译中C2220错误的解决办法
    JSP元素和标签
  • 原文地址:https://www.cnblogs.com/fy--/p/8966233.html
Copyright © 2020-2023  润新知