如何在Rabbitmqrascal.js上按请求管理发布连接

问题描述

我正在使用Rascal.Js(它使用amqplib)通过node.js应用程序上的RabbitMq进行消息传递逻辑。

我在项目启动时使用的示例与其示例类似,该示例创建一个永久实例并“注册”我的所有订阅者,并在消息到达队列时(在后台重定向消息。

我的问题是出版商。有来自外部的http请求应该触发我的发布者。用户单击各种创建按钮,从而导致一定的操作流程。到了某个时候,我需要使用发布者。

在这里,我不确定正确的方法。每次需要发布消息时都需要打开一个新的连接吗?并在结束后将其关闭?还是我应该以使其对所有发布者都保持相同连接打开的方式来实现它? (实际上我不太确定如何以可以从我的应用程序的其他部分访问它的方式创建它。)

此刻我正在使用以下内容

async publishMessage(publisherName,message) {
        const dynamicSettings = setupDynamicVariablesFromConfigFiles(minimalPublishSettings);
        const broker = await Rascal.brokerAsPromised.create(Rascal.withDefaultConfig(dynamicSettings.Rascal));

        broker.on('error',async function(err) {
            loggerUtil.writetoLog('error','publishMessage() broker_error_event: ' + publisherName + err + err.stack);
            await broker.shutdown();
        })
   
        const publication = await broker.publish(publisherName,message);
        try {
            publication.on('error',async function(err) {
                loggerUtil.writetoLog('error','publishMessage() publish_error_event: ' + err + err.stack);
                await broker.shutdown();
            }).on("success",async (messageId) => {
                await broker.shutdown();
            }).on("return",async (message) => {
                loggerUtil.writetoLog('error','publishMessage() publish_return_event: ' + err + err.stack);
                await broker.shutdown();
            })
        }
        catch(err) {
            loggerUtil.writetoLog('error','Something went wrong ' + err + err.stack);
            await broker.shutdown();
        }

    }

当我需要发布消息时,可以在应用程序的不同部分使用此功能。 我以为只是为所有端点添加broker.shutdown(),但是在发生错误后的某个时刻,我遇到了关闭关闭的连接的异常情况,这让我担心关闭方法(可能不会这样做)一个好)。我认为这与此有关- 我尝试这样做(注释的代码),但是我认为在某些情况下它不能很好地工作。如果一切正常,则转到“成功”,然后我可以将其关闭。 但是有一次我遇到了一个错误而不是成功,当我尝试使用broker.shutdown()时,它给了我另一个异常,使应用程序崩溃了。我认为这与此有关- https://github.com/squaremo/amqp.node/issues/111

我不确定最安全的方法是什么?

编辑:

实际上,现在我想到了,这个异常可能与我试图关闭catch {}区域中的经纪人有关。我将继续调查。

解决方法

Rascal旨在在应用程序启动时启动一次,而不是针对每个HTTP请求创建。如果以这种方式使用应用程序,它将非常慢,并且根据需要处理的并发请求数,很可能会超过您可以与代理建立的最大连接数。此外,您将无法获得Rascal提供的任何好处,例如连接恢复失败。

如果可以预先确定需要发布到的队列或交换,请在应用程序启动时(在HTTP服务器之前)配置Rascal,并在请求之间共享发布者。如果在收到http请求之前无法确定队列或进行交换,则Rascal是不适当的选择。相反,最好直接使用amqplib,但仍应建立共享连接和通道。不过,您将必须手动处理连接和通道错误,否则它们将使您的应用程序崩溃。