Google cloud platform [已解决]Pubsub推送订阅未确认消息

Google cloud platform [已解决]Pubsub推送订阅未确认消息,google-cloud-platform,cloud,publish-subscribe,subscription,Google Cloud Platform,Cloud,Publish Subscribe,Subscription,这是我的设置 订阅A是向云运行部署发布消息的推送订阅 该部署公开HTTP端点,处理消息,将结果发布到主题B,并响应订阅A的POST请求。整个过程大约需要1.5秒 因此,对于订阅A中的每条消息,我应该在主题B中得到一条消息。 这就是我的代码的样子 我的应用启动了一个Express服务器 const express = require('express'); const bodyParser = require('body-parser'); const _ = require('lodash')

这是我的设置

订阅A是向云运行部署发布消息的推送订阅

该部署公开HTTP端点,处理消息,将结果发布到主题B,并响应订阅A的POST请求。整个过程大约需要1.5秒

因此,对于订阅A中的每条消息,我应该在主题B中得到一条消息。 这就是我的代码的样子

我的应用启动了一个Express服务器

const express = require('express');
const bodyParser = require('body-parser');

const _ = require('lodash');

const startBrowser = require('./startBrowser');
const tab = require('./tab');
const createMessage = require('./publishMessage');
const domain = 'https://example.com';

require('dotenv').config();

const app = express();
app.use(bodyParser.json());


const port = process.env.PORT || 8080;
app.listen(port, async () => {
  console.log('Listening on port', port);
});
所有魔法发生的终点

app.post('/', async (req, res) => {

  // Define the success and fail functions, that respond status 200 and 500 respectively
  const failed = () => res.status(500).send();
  const completed = async () => {
    const response = await res.status(200).send();
    if (response && res.writableEnded) {
      console.log('successfully responded 200');
    }
  };

  //Process the data coming from Subscription A
  let pubsubMessage = decodeBase64Json(req.body.message.data);
  let parsed =  await processor(pubsubMessage);
  
  //Post the processed data to topic B
  let messageId = await postParsedData(parsed);


  if (messageId) {
  // ACK the message once the data has been processed and posted to topic B.
    completed();

  } else {
    console.log('Didnt get a message id');
    // failed();
  }
});

//define the functions that post data to Topic B

const postParsedData = async (parsed) => {
  if (!_.isEmpty(parsed)) {
    const topicName = 'topic-B';
    const messageIdInternal = await createMessage(parsed, topicName);
  };


    return messageId;
  } else {
    console.log('Parsed is Empty');
    return null;
  }
};

function decodeBase64Json(data) {
  return JSON.parse(Buffer.from(data, 'base64').toString());
}
执行时间约为1.5秒,我可以看到记录在云上的成功响应每隔1.5秒运行一次。总计约2400条消息/小时(每个云运行实例)

主题B以约2400条消息/小时的速度接收新消息,订阅A的确认率为约200条消息/小时,这导致消息被多次重新发送

订阅A的确认截止时间为600秒。 云运行中的请求超时时间为300秒

在消息发布到topic-B之前,甚至在解析之前,我都尝试过确认消息,但我得到了相同的结果

编辑:添加了待处理消息和已处理消息的屏幕截图。处理的邮件比已确认的挂起邮件多得多。应该是1:1

谢谢你的帮助


解决方案GCP支持无法再现此错误。大量云运行的虚拟机并没有出现这种情况。解决方案只是增加工作实例的数量

您需要等待您的
完成()函数调用。像这样

....
 if (messageId) {
  // ACK the message once the data has been processed and posted to topic B.
    await completed();

  } else {
    console.log('Didnt get a message id');
    // failed();
  }

你需要等待你的
完成()函数调用。像这样

....
 if (messageId) {
  // ACK the message once the data has been processed and posted to topic B.
    await completed();

  } else {
    console.log('Didnt get a message id');
    // failed();
  }

谢谢你的回复。我已经尝试过这种方法,但我仍然看到同样的问题。实际上,“completed()”不需要是一个异步函数(我在试图找到问题时改变了这个函数)和前面的状态(200)。使用async的send()对您的响应没有影响。我已经尝试过这种方法,但我仍然看到同样的问题。实际上,“completed()”不需要是一个异步函数(我在试图找到问题时改变了这个函数)和前面的状态(200)