接上篇博文,如何向 TDMQ 的 Topic 发送信息

我们上次采用了 Pulsar 作为 TDMQ 的消息列队服务,相应地,操作它的就是 pulsar-client 这个库了

由于请求只能在内网中,所以我们只能在云服务器中安装,云服务器是 Centos7.6 的系统

以下是安装记录

# 安装 pulsar-client

官方文档上介绍安装 nodejs 版的 pulsar-client 只需要如下语句

h
$ npm install pulsar-client -S

执行之后毫无意外的报错了,遂查阅了 N 多资料,最后在 pulsar-client-node github 项目里才知道原来安装它之前需要安装一系列软件与 C++ 库

# Centos 安装 Pulsar C++ 库

https://github.com/apache/pulsar-client-node

  1. yum 安装 gcc-c++,make
h
$ yum install gcc-c++ make
  1. 下载 rpm 包
h
wget https://archive.apache.org/dist/pulsar/pulsar-2.9.1/RPMS/apache-pulsar-client-2.9.1-1.x86_64.rpm
wget https://archive.apache.org/dist/pulsar/pulsar-2.9.1/RPMS/apache-pulsar-client-devel-2.9.1-1.x86_64.rpm
  1. 安装 rpm 包
h
$ rpm -ivh apache-pulsar-client*.rpm
  1. 最后再执行 npm install
h
$ npm install pulsar-client -S

# 使用 Pulsar

编写 index.js 测试

t
const Pulsar = require("pulsar-client");
(async () => {
  const client = new Pulsar.Client({
    serviceUrl: "http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5037",
    authentication: new Pulsar.AuthenticationToken({
      token: "eyJrZXlJZCI6Ixxxxxx",       // 更换为密钥
    }),
  });
 
  const producer = await client.createProducer({
    topic: 'pulsar-jm4bdxxxxx/sendmail/sendmail', // or 'my-tenant/my-namespace/my-topic' to specify topic's tenant and namespace 
  });
  let data = {
    user:"测试",
    email:"1015517471@qq.com"
  };
  await producer.send({
    data: Buffer.from(JSON.stringify(data)),
  });
 
  await client.close();
})();

根据官网文档腾讯云关于 Pulsar 文档介绍

秘钥可以从上篇文章中角色管理中获取

接下来使用 node 执行 index.js

h
➜  /home/t node index.js 
/home/t/node_modules/bindings/bindings.js:121
        throw e;
        ^
Error: libpulsar.so.2.9.1: cannot open shared object file: No such file or directory
    at Object.Module._extensions..node (node:internal/modules/cjs/loader:1183:18)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at bindings (/home/t/node_modules/bindings/bindings.js:112:48)
    at Object.<anonymous> (/home/t/node_modules/pulsar-client/index.js:20:42)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32) {
  code: 'ERR_DLOPEN_FAILED'
}

又报错了... 错误信息说明 libpulsar.so.2.9.1 找不到

经过查找本服务器是可以找到 libpulsar.so.2.9.1 的,在 /usr/lib/ 下,猜测是不是默认路径不对?也许在 /usr/lib64/ 下才是正确的?

建立一条软连接

h
$ ln -s /usr/lib/libpulsar.so.2.9.1 /usr/lib64/libpulsar.so.2.9.1

再次执行 index.js

h
$ node index.js
2022-08-31 11:40:39.043 INFO  [140338895238912] HTTPLookupService:235 | Curl Lookup Request sent for http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5039/admin/v2/persistent/pulsar-jm4bd43m2jab/sendmail/sendmail/partitions?checkAllowAutoCreation=true
2022-08-31 11:40:39.155 INFO  [140338895238912] HTTPLookupService:249 | Response received for url http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5039/admin/v2/persistent/pulsar-jm4bd43m2jab/sendmail/sendmail/partitions?checkAllowAutoCreation=true code 200
2022-08-31 11:40:39.155 INFO  [140338895238912] HTTPLookupService:293 | parsePartitionData = { LookupDataResult [brokerUrl_ = ] [brokerUrlTls_ = ] [partitions = 2] [authoritative = 0] [redirect = 0] proxyThroughServiceUrl = 0] }
2022-08-31 11:40:39.160 INFO  [140338895238912] HandlerBase:64 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0, ] Getting connection from pool
2022-08-31 11:40:39.160 INFO  [140338895238912] HandlerBase:64 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1, ] Getting connection from pool
2022-08-31 11:40:39.160 INFO  [140338895238912] HTTPLookupService:235 | Curl Lookup Request sent for http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5039/lookup/v2/topic/persistent/pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0
2022-08-31 11:40:39.187 INFO  [140338895238912] HTTPLookupService:249 | Response received for url http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5039/lookup/v2/topic/persistent/pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0 code 200
2022-08-31 11:40:39.187 INFO  [140338895238912] HTTPLookupService:328 | parseLookupData = { LookupDataResult [brokerUrl_ = pulsar://169.254.0.168:5035] [brokerUrlTls_ = ] [partitions = 0] [authoritative = 0] [redirect = 0] proxyThroughServiceUrl = 0] }
2022-08-31 11:40:39.187 INFO  [140338895238912] ClientConnection:181 | [<none> -> pulsar://169.254.0.168:5035] Create ClientConnection, timeout=10000
2022-08-31 11:40:39.187 INFO  [140338895238912] ConnectionPool:96 | Created connection for pulsar://169.254.0.168:5035
2022-08-31 11:40:39.188 INFO  [140338895238912] HTTPLookupService:235 | Curl Lookup Request sent for http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5039/lookup/v2/topic/persistent/pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1
2022-08-31 11:40:39.193 INFO  [140338876249856] ClientConnection:367 | [172.17.16.13:59602 -> 169.254.0.168:5035] Connected to broker
2022-08-31 11:40:39.201 INFO  [140338895238912] HTTPLookupService:249 | Response received for url http://pulsar-jm4bd43m2jab.tdmq-pulsar.ap-sh.qcloud.tencenttdmq.com:5039/lookup/v2/topic/persistent/pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1 code 200
2022-08-31 11:40:39.201 INFO  [140338895238912] HTTPLookupService:328 | parseLookupData = { LookupDataResult [brokerUrl_ = pulsar://169.254.0.168:10026] [brokerUrlTls_ = ] [partitions = 0] [authoritative = 0] [redirect = 0] proxyThroughServiceUrl = 0] }
2022-08-31 11:40:39.202 INFO  [140338895238912] ClientConnection:181 | [<none> -> pulsar://169.254.0.168:10026] Create ClientConnection, timeout=10000
2022-08-31 11:40:39.202 INFO  [140338895238912] ConnectionPool:96 | Created connection for pulsar://169.254.0.168:10026
2022-08-31 11:40:39.202 INFO  [140338876249856] ProducerImpl:188 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0, ] Created producer on broker [172.17.16.13:59602 -> 169.254.0.168:5035] 
2022-08-31 11:40:39.204 INFO  [140338876249856] ClientConnection:367 | [172.17.16.13:46318 -> 169.254.0.168:10026] Connected to broker
2022-08-31 11:40:39.216 INFO  [140338876249856] ProducerImpl:188 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1, ] Created producer on broker [172.17.16.13:46318 -> 169.254.0.168:10026] 
2022-08-31 11:40:39.233 INFO  [140338903631616] ClientImpl:492 | Closing Pulsar client with 1 producers and 0 consumers
2022-08-31 11:40:39.233 INFO  [140338903631616] ProducerImpl:621 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0, tdmq_sh_pulsar_release-269-8963064] Closing producer for topic persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0
2022-08-31 11:40:39.233 INFO  [140338903631616] ProducerImpl:621 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1, tdmq_sh_pulsar_release-258-12777610] Closing producer for topic persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1
2022-08-31 11:40:39.235 INFO  [140338876249856] ProducerImpl:664 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-0, tdmq_sh_pulsar_release-269-8963064] Closed producer
2022-08-31 11:40:39.236 INFO  [140338876249856] ProducerImpl:664 | [persistent://pulsar-jm4bd43m2jab/sendmail/sendmail-partition-1, tdmq_sh_pulsar_release-258-12777610] Closed producer
2022-08-31 11:40:39.236 INFO  [140338876249856] ClientConnection:1535 | [172.17.16.13:46318 -> 169.254.0.168:10026] Connection closed
2022-08-31 11:40:39.236 INFO  [140338876249856] ClientConnection:1535 | [172.17.16.13:59602 -> 169.254.0.168:5035] Connection closed

没有错误,而且打印出了很多 INFO 信息,去云函数日志查看,果然有一条调用信息,接下来我陷入深深的思考...

pulsar-client 在运行时也依赖于当前环境下的 libpulsar.so.2.9.1 , 那么如果换个环境是不是就因为无法找到该文件而报错了

# Serverless 的局限性

虽然在我的云服务器将 pulsar-client 安装成功,也成功运行起来了,但是其过程之曲折,调试之麻烦可见一斑,如果我们要把它部署到 Serverless 上呢?我没有尝试.

各个应用程序有时候会依赖一些环境本身的库,甚至是操作系统底层的一些东西,这方面 PHP 尤其明显,Nodejs 有少部分也有这种情况, pulsar-client 就是一个典型的例子

如果我们的应用程序采用 Serverless 部署,需要参考 Serverless 提供商提供的环境,例如腾讯云 Serverless 的 PHP 环境安装第三方扩展的时候就及其麻烦,如果发生实在安装不了的扩展,但是项目必须要用到的时候,需要切换回 Docker 的部署方式,那就牺牲了 Serverless 的便利性和经济性,毕竟我们选择 Serverless 的初衷是希望轻量且经济,这就是 Serverless 的局限性.

# 解决办法

好在 pulsar-client 不是唯一操作 TDMQ 消息队列的方式,还可以使用腾讯云本身的 SDK

安装 tencentcloud-sdk-nodejs

h
$ npm install tencentcloud-sdk-nodejs-tdmq --save
t
// Depends on tencentcloud-sdk-nodejs version 4.0.3 or higher
const tencentcloud = require("tencentcloud-sdk-nodejs");
const TdmqClient = tencentcloud.tdmq.v20200217.Client;
// 实例化一个认证对象,入参需要传入腾讯云账户 secretId,secretKey, 此处还需注意密钥对的保密
// 密钥可前往 https://console.cloud.tencent.com/cam/capi 网站进行获取
const clientConfig = {
  credential: {
    secretId: "SecretId",
    secretKey: "SecretKey",
  },
  region: "ap-shanghai",
  profile: {
    httpProfile: {
      endpoint: "tdmq.tencentcloudapi.com",
    },
  },
};
// 实例化要请求产品的 client 对象,clientProfile 是可选的
const client = new TdmqClient(clientConfig);
const params = {
    "Topic": "pulsar-jm4bd43m2jab/sendmail/sendmail",
    "Payload": "{\"user\":\"hello\",\"email\":\"1015517471@qq.com\"}"
};
client.SendMessages(params).then(
  (data) => {
    console.log(data);
  },
  (err) => {
    console.error("error", err);
  }
);

请我喝杯[咖啡]~( ̄▽ ̄)~*

一个放羊娃 微信支付

微信支付

一个放羊娃 支付宝

支付宝