我正在尝试使用其 NodeJS 客户端包将消息从云函数发布到云 Pub/Sub 主题。我面临以下错误:
Total timeout of API google.pubsub.v1.The publisher exceeded 60000 milliseconds before any response was received.
我尝试过的解决方案:
这是我用来发布消息的代码:
export class FeedService {
private static instance: FeedService;
private pubsubClient: PubSub;
private feedTopic: Topic;
private maxMessages = 50;
private maxMilliseconds = 10000;
private messagePromises: Promise<string>[] = [];
constructor() {
this.pubsubClient = new PubSub({
projectId: process.env.PROJECT_ID,
credentials: {
client_email: process.env.GOOGLE_CLOUD_CLIENT_EMAIL,
private_key: process.env.GOOGLE_CLOUD_CLIENT_PRIVATE_KEY,
},
});
}
public static getInstance() {
if (!FeedService.instance) {
FeedService.instance = new FeedService();
}
return FeedService.instance;
}
// provide global topic instance
private getFeedTopic() {
if (!this.feedTopic) {
this.feedTopic = this.pubsubClient.topic(process.env.FEED_TOPIC_ID, {
batching: {
maxMessages: this.maxMessages,
maxMilliseconds: this.maxMilliseconds,
},
});
}
return this.feedTopic;
}
// Calling this function to publish messages
async pushNotificationForAggregation(payload: FeedTypes.FeedQueuePayload) {
try {
const messageOptions: MessageOptions = {
json: payload,
publishTime: {
seconds: Date.now() / 1000,
},
};
// store promises
this.messagePromises.push(
this.getFeedTopic().publishMessage(messageOptions)
);
return { success: true };
} catch (error: any) {
logger.error(
`[Failed to push feed to queue] [${payload.userId}]: ${error?.message}`
);
return { success: false };
}
}
// await all promises before sending HTTP response
async processRemainingMessages() {
try {
const messages = await Promise.all(this.messagePromises);
return { success: true, messages };
} catch (error: any) {
logger.error(
`[Failed to process remaining messages] : ${error?.message}`
);
return { success: false };
}
}
}
更新
我在云运行而不是云函数中尝试了相同的代码,并且它在那里工作得很好。
所以我可以确认代码没有问题。
我已经解决了这个问题。问题出在环境变量上。 Google Cloud 函数解析从 GUI 控制台添加的每个变量以及广告转义序列。因此,我的服务帐户私有中的
\n
将转换为\\n
,导致错误的秘密。
奇怪的是,Pub/Sub SDK 没有返回正确的错误消息;它总是返回 API 超时,无论我将超时增加多少时间。
从帐户私钥中删除转义序列可以解决问题。