本文最后更新于 707 天前,其中的信息可能已经有所发展或是发生改变。
TonglinkQ8配置SSL
1.自建生成ssl证书
生成CA私钥
cd /tmp
mkdir ca && cd ca
#创建私钥 (建议设置密码)
openssl genrsa -des3 -out myCA.key 2048
生成CA证书
# 20 年有效期
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 7300 -out myCA.crt
查看证书信息命令 openssl x509 -in myCA.crt -noout -text
创建ssl证书私钥
# 此文件夹存放待签名的证书
mkdir certs
cd certs
openssl genrsa -out localhost.key 2048
创建ssl证书CSR
openssl req -new -key localhost.key -out localhost.csr
创建域名附加配置文件cert.ext
vim cert.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.2 = 127.0.0.1
DNS.3 = test.com
DNS.4 = *.test.com
使用CA签署ssl证书
# ssl证书有效期10年,此步骤需要输入CA私钥的密码
openssl x509 -req -in localhost.csr -out localhost.crt -days 3650 \
  -CAcreateserial -CA ../myCA.crt -CAkey ../myCA.key \
  -CAserial serial -extfile cert.ext
查看签署的证书信息
openssl x509 -in localhost.crt -noout -text
使用CA验证一下证书是否通过
[tlq@harbor certs]$ openssl verify -CAfile ../myCA.crt localhost.crt
localhost.crt: OK
把服务端代码转换浏览器可以识别的PCS12格式,密码使用上面输入的密码
openssl pkcs12 -export -in localhost.crt -inkey localhost.key -out server.p12 -passout pass:123456
[tlq@harbor ca]$ tree
.
├── certs
│   ├── cert.ext
│   ├── localhost.crt
│   ├── localhost.csr
│   ├── localhost.key
│   ├── serial
│   └── server.p12
├── myCA.crt
└── myCA.key
2.部署TLQ8
省略部署,此次使用是:
Install_TLQ_Standard_Linux2.6.32_x86_64_8.1.15.2_P12_SP1.tar.gz
Install_TLQ_Standard_Linux2.6.32_x86_64_8.1.15.2_P12.tar.gz
3.配置TLQ8
执行tlqcertpwd输入密码为生成.p12文件的密码
本次是两台机器都配置了/home/tlq/TLQ8/etc/tlsys.conf
SSLCertFileName = /tmp/ca/certs/server.p12      # 节点个人证书全路径
SSLCAFileName = /tmp/ca/myCA.crt        # ca证书全路径
SSLCertPwd = 4B48494E4F4C       # p12的密码(转码保存)
配置发送节点
一台机器信息:
#
[SendConnRecord]        # 发送连接小节
ConnName = conn1        # 连接名称
SendQueName = sq        # 连接对应的发送队列名称
ConnStatus = 1      # 发送连接状态,0禁用,1正常
HostName = 192.168.111.156      # 被连接节点的IP地址
ConnPort = 11003        # 被连接节点的端口号,端口号需大于1024
ConnType = 0        # 连接类型,0为常连接,1为按需连接
SendBlockSize = 8       # 单个数据块大小,单位kbytes
SendBuff = 65536        # 连接发送缓冲区大小,单位byte
LineType = LINE1000M        # 线路类型
DiscInterval = 60       # 线路维持时间,单位为秒
BeatInterval = 20       # 线路检测时间(只适用于常连接),单位为秒
SecExitFlag =       # 出口标志 Net|Transport|ByRecv
SecExitNetData =        # 网络层出口用户数据,类型为字符串(最大长度为48字节)
SecExitTransportData =      # 传输层出口用户数据,类型为字符串(最大长度为48字节)
SSLFlag = 1 # 是否使用 SSL 安全传输
SSLProtocolVersion = 1 # SSL 协议版本 0 :GMTLSv1; 1:TLS v1.2
SSLSessionTimeout = -1 # 超时时间,单位分钟
SSLCipher = AES128-SHA256 # 协商算法(协商算法具体的列表可以参见 TongLINK /Q 手册)
配置接收进程小节
一台机器信息:
[RcvProcessRecord]      # 
RcvProcID = 10      # 接收进程编号
RcvProcStatus = 1       # 接收进程状态,0禁用,1正常
ListenPort = 11003      # 监听端口,端口号需大于1024
LocalAddr =         # 本地通信地址,如果有此项,则接收进程绑定
SSLFlag = 1 # 是否使用 SSL 安全传输
SSLProtocolVersion = 1 # SSL 协议版本 0 :GMTLSv1; 1:TLS v1.2
SSLNegoFlag = 1 # 单双向认证标志 0:单向,1:双向
SSLSessionTimeout = -1 # 超时时间,单位分钟
SSLCipher = AES128-SHA256 # 协商算法
重启节点
tlq -cstop -y
tlq
4.验证
登录控制台验证查看是否存在异常


5.Java Base 接口验证发送/消费
客户端配置
安装TLQCli8客户端
安装部署步骤省略,参考手册
客户端代理小节配置
因为是模拟发送(生产)和消费,因此两台客户代理小节的配置都要配置
注意:SSLCipher加密参数需和发送节点/接收进程节点
一致!
[ClientBroker]      # 瘦客户代理小节
#
[ClientBrokerRecord]        # 瘦客户代理
CliBrokerID = 2     # 代理进程编号
CliBrokerStatus = 1     # 启动节点时代理的启动状态,0:不启动,1:启动
ListenPort = 10261      # 代理监听的端口号,端口号需大于1024
HisRecMaxNum = 10       # 历史文件中历史记录的最大数(支持断点续传)
LocalAddr =         # 本地通信地址,如果有此项,则瘦客户代理进程绑定
Protocol = 0        # Ip协议类型 0(默认值):Ipv4; 1:Ipv4和Ipv6
SSLFlag = 1     # 是否使用SSL安全传输
SSLProtocolVersion = 1      # SSL协议版本 0 :SSL v3;  1:TLS v1
SSLNegoFlag = 1     # 单双向认证标志 0:单向,1:双向
SSLCipher = AES128-SHA256       # 协商算法(协商算法具体的列表可以参见TongLINK /Q 手册)
DebugQueName =      # 限流队列名
DebugMsgNum = 0     # 限制消息条数
DebugSleepTime = 0      # 指定队列消息数超限后的Sleep毫秒数
#
重启节点修改配置才生效
tlq -cstop -y
tlq
生产者测试代码
import com.tongtech.tlq.base.*;
import java.util.*;
import java.io.*;
public class SendMsgCli {
    private String myQcuName;
    private String myQueName;
    private String myMsgType;
    private int myCount;
    private int reConnect;
    private int SleepTime;
    private String myFileName;
    private TlqConnContext tlqConnContext = null;
    private TlqConnection tlqConnection = null;
    private TlqSSLContext tlqSSLContext = null;
    private TlqQCU tlqQcu = null;
    static int id = 0;
    public SendMsgCli(String QcuName, String QName, String MsgType,
                      String FileName) throws TlqException {
        myQcuName = QcuName;
        myQueName = QName;
        myMsgType = MsgType;
        myFileName = FileName;
        myCount = 2;
        reConnect = 200;
        SleepTime = 3000;
        tlqConnContext = new TlqConnContext();
        tlqConnContext.BrokerId = -1;
         tlqConnContext.HostName = "192.168.111.176";
         tlqConnContext.ListenPort = 10261;
         tlqSSLContext = new TlqSSLContext();
         tlqSSLContext.SSLCAFileName = "/tmp/ca/myCA.crt";
         tlqSSLContext.SSLCertFileName = "/tmp/ca/certs/server.p12";
         tlqSSLContext.SSLCertPwd = "4B48494E4F4C";
         tlqSSLContext.SSLFlag = 1;
         tlqSSLContext.SSLProtocolVersion = 1;
         tlqSSLContext.SSLCipher = "AES128-SHA256";
        tlqConnection = new TlqConnection(tlqConnContext, tlqSSLContext);
        System.out.println("qcuname="+myQcuName);
        tlqQcu = tlqConnection.openQCU(myQcuName);
    }
    public static synchronized String createID() {
        StringBuffer sb = new StringBuffer();
        sb.append(System.currentTimeMillis());
        sb.append("_");
        sb.append(id);
        ++id;
        return sb.toString();
    }
    public static byte[] createBytes(int size) { //构造Buffer消息内容
        StringBuffer sb = new StringBuffer(size);
        for (int i = 0; i < size; i++) {
            sb.append('a');
        }
        return sb.toString().getBytes();
    }
    void sendBuffMsg(int size) throws TlqException { //发送Buffer消息 size 消息大小
        TlqMessage msgInfo = new TlqMessage();
        TlqMsgOpt msgOpt = new TlqMsgOpt();
        msgInfo.MsgType = TlqMessage.BUF_MSG; //消息类型
        msgInfo.MsgSize = size; //消息大小
        byte[] msgContent = createBytes(msgInfo.MsgSize); //消息内容
        msgInfo.setMsgData(msgContent);
        msgInfo.Persistence = TlqMessage.TLQPER_Y; //持久性
        msgInfo.Priority = TlqMessage.TLQPRI_NORMAL; //优先级
        msgInfo.Expiry = 1000; //生命周期
        msgOpt.QueName = myQueName; //队列名
        tlqQcu.putMessage(msgInfo, msgOpt);
    }
    void sendFileMsg(String fName) throws TlqException { //发送文件消息
        TlqMessage msgInfo = new TlqMessage();
        TlqMsgOpt msgOpt = new TlqMsgOpt();
        msgInfo.MsgType = TlqMessage.FILE_MSG;
        fName = myFileName + " " + createID() + "_" + myFileName;
        msgInfo.MsgSize = fName.getBytes().length;
        msgInfo.setMsgData(fName.getBytes());
        msgOpt.RemoveFileFlag = TlqMsgOpt.NOTREMOVEFILE; //是否删除源文件标志
        msgInfo.Persistence = TlqMessage.TLQPER_Y;
        msgInfo.Priority = TlqMessage.TLQPRI_NORMAL;
        msgInfo.Expiry = 1000;
        msgOpt.QueName = myQueName;
        tlqQcu.putMessage(msgInfo, msgOpt);
    }
    public void sendMsg() {
        System.out.println("myMsgType is :" + myMsgType);
        try {
            for (int i = 0; i < myCount; i++) {
                if (myMsgType.equals("B") == true) {
                    sendBuffMsg(10);
                } else {
                    sendFileMsg(myFileName);
                }
            }
            System.out.println("--------------共发送消息" + myCount +
                               "条!-----------");
            System.out.println("-----------sendmsg over!!-----------");
        } catch (TlqException tlqEx) {
            tlqEx.printStackTrace();
        } finally {
            try {
                tlqQcu.close();
                tlqConnection.close();
            } catch (TlqException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] argv) throws Exception {
        String QcuName;
        String QName;
        String FileName;
        String MsgType;        
        if (argv.length < 1) {
            System.out.println("---------请输入参数!---------");
            System.out.println(
                    "---------注:如果消息类型为B,则FileName输入为no!---------");
            System.out.println(
                    "SendMsgCli QcuName QueName MsgType(B/F) FileName");
            return;
        }
        if (argv.length != 4) {
            System.out.println("---------您输入的参数格式不对,请重新输入!---------");
            System.out.println(
                    "---------注:如果消息类型为B,则FileName输入为no!---------");
            System.out.println(
                    "SendMsgCli QcuName QueName MsgType(B/F) FileName");
            return;
        } else {
            QcuName = argv[0];
            QName = argv[1];
            MsgType = argv[2];
            FileName = argv[3];
        }
        SendMsgCli sm = new SendMsgCli(QcuName, QName, MsgType, FileName);
        sm.sendMsg();
    }
}
生产者关键代码:
tlqConnContext = new TlqConnContext(); tlqConnContext.BrokerId = -1; tlqConnContext.HostName = "192.168.111.176"; tlqConnContext.ListenPort = 10261; tlqSSLContext = new TlqSSLContext(); tlqSSLContext.SSLCAFileName = "/tmp/ca/myCA.crt"; tlqSSLContext.SSLCertFileName = "/tmp/ca/certs/server.p12"; tlqSSLContext.SSLCertPwd = "4B48494E4F4C"; tlqSSLContext.SSLFlag = 1; tlqSSLContext.SSLProtocolVersion = 1; tlqSSLContext.SSLCipher = "AES128-SHA256"; tlqConnection = new TlqConnection(tlqConnContext, tlqSSLContext);
编译测试
/usr/java/jdk1.8.0_131/bin/javac SendMsgCli.java
模拟生成测试
[tlq@harbor base]$ more run.sh
#!/bin/bash
for ((i=1; i<=10000; i++))
do
    echo "这是第 $i 次循环"
    java SendMsgCli qcu1  sq  B no
    sleep 1
done

消费者测试代码
import com.tongtech.tlq.base.*;
import java.util.*;
import java.io.*;
public class GetMsgCli {
    static int MyMsgCount = 0;
    private String myQcuName;
    private String myQueName;
    private int myWaitInterval;
    private int reConnCount;
    private int sleepTime;
    private TlqConnection tlqConnection = null;
    private TlqConnContext tlqConnContext = null;
    private TlqSSLContext tlqSSLContext = null;
    private TlqQCU tlqQcu = null;
    public GetMsgCli(String QcuName, String QueName, int WaitInterval) throws
            TlqException {
        myQcuName = QcuName;
        myQueName = QueName;
        myWaitInterval = WaitInterval;
        tlqConnContext = new TlqConnContext();
        tlqConnContext.BrokerId = -1;
        tlqConnContext.HostName = "192.168.111.156";
         tlqConnContext.ListenPort = 10261;
        reConnCount = 200;
        sleepTime = 3000;
        tlqSSLContext = new TlqSSLContext();
        tlqSSLContext.SSLCAFileName = "/tmp/ca/myCA.crt";
        tlqSSLContext.SSLCertFileName = "/tmp/ca/certs/server.p12";
        tlqSSLContext.SSLCertPwd = "4B48494E4F4C";
        tlqSSLContext.SSLFlag = 1;
        tlqSSLContext.SSLProtocolVersion = 1;
        tlqSSLContext.SSLCipher = "AES128-SHA256";
        tlqConnection = new TlqConnection(tlqConnContext, tlqSSLContext);
        tlqQcu = tlqConnection.openQCU(myQcuName);
    }
    static public void printMsgInfo(TlqMessage msgInfo) {
        if ((int) msgInfo.MsgType == 1) {
            System.out.println("Received a File Msg");
            System.out.print("msgInfo.MsgId=" + new String(msgInfo.MsgId));
            System.out.println("   msgInfo.MsgSize=" + (int) msgInfo.MsgSize);
        } else {
            System.out.println("Received a Buffer Msg");
            System.out.print("msgInfo.MsgId=" + new String(msgInfo.MsgId));
            System.out.println("   msgInfo.MsgSize=" + (int) msgInfo.MsgSize);
        }
    }
    public void recvMsg() {
        int msgCount = 0;
        try {
            while (true) {
                TlqMessage msgInfo = new TlqMessage();
                TlqMsgOpt msgOpt = new TlqMsgOpt();
                msgOpt.QueName = myQueName;
                msgOpt.WaitInterval = myWaitInterval;
                /*  msgOpt.MatchOption = TlqMsgOpt.TLQMATCH_PRIORITY; //条件接收
                  msgInfo.Priority = 5;*/
                /* msgOpt.AckMode = TlqMsgOpt.TLQACK_USER;*/
                //用户确认模式
                msgOpt.OperateType = TlqMsgOpt.TLQOT_GET;
                tlqQcu.getMessage(msgInfo, msgOpt);
                msgCount = msgCount + 1;
                printMsgInfo(msgInfo);
                if (msgOpt.AckMode == TlqMsgOpt.TLQACK_USER) {
                    int acktype = TlqMsgOpt.TLQACK_COMMIT;
                    tlqQcu.ackMessage(msgInfo, msgOpt, acktype);
                }
            }
        } catch (TlqException e) {
            e.printStackTrace();
        } finally {
            MyMsgCount = msgCount;
            try {
                tlqQcu.close();
                tlqConnection.close();
            } catch (TlqException e) {
                e.printStackTrace();
            }
        }
        System.out.println("----------GetMsg is over!------------\n");
    }
    public static void main(String[] argv) throws Exception {
        String QcuName;
        String QueName;
        int WaitInterval = 0;
        if (argv.length < 1) {
            System.out.println("--------------请输入参数!--------------\n");
            System.out
                    .println("GetMsgCli QcuName QueName WaitInterval");
            return;
        }
        if (argv.length != 3) {
            System.out.println("---------您输入的参数格式不对,请重新输入!---------");
            System.out
                    .println("GetMsgCli QcuName QueName WaitInterval");
        } else {
            QcuName = argv[0];
            QueName = argv[1];
            WaitInterval = Integer.parseInt(argv[2]);
            System.out.println(
                    "--------------------receive message begin------------------");
            GetMsgCli GM = new GetMsgCli(QcuName, QueName, WaitInterval);
            GM.recvMsg();
        }
        System.out.println("-------共接收消息" + MyMsgCount + "条-------");
    }
}
消费者重点代码:
tlqConnContext = new TlqConnContext(); tlqConnContext.BrokerId = -1; tlqConnContext.HostName = "192.168.111.156"; tlqConnContext.ListenPort = 10261; reConnCount = 200; sleepTime = 3000; tlqSSLContext = new TlqSSLContext(); tlqSSLContext.SSLCAFileName = "/tmp/ca/myCA.crt"; tlqSSLContext.SSLCertFileName = "/tmp/ca/certs/server.p12"; tlqSSLContext.SSLCertPwd = "4B48494E4F4C"; tlqSSLContext.SSLFlag = 1; tlqSSLContext.SSLProtocolVersion = 1; tlqSSLContext.SSLCipher = "AES128-SHA256"; tlqConnection = new TlqConnection(tlqConnContext, tlqSSLContext);
编译测试
/usr/java/jdk1.8.0_131/bin/javac GetMsgCli.java
模拟消费测试
java GetMsgCli qcu1 lq 1000
