1

我有几个 ASP.Net 应用程序服务器,我想使用 rabbitMQ(或类似的排队工具,如 redis pub/sub)来使所有服务器上的内存缓存失效。

当应用程序服务器清除它自己的缓存时,场景很简单,将消息发送到消息队列(由 rabbitMQ 声明)并且所有其他服务器正在侦听该队列(在本例中为缓存队列)并且当它们接收到消息时(通过消费者.Received even handler)它们也使自己的内存缓存无效。

为此,我必须将侦听器放在我的 Web 应用程序中(不能放入控制台应用程序或 Windows 服务),因为每个 ASP.net Web 应用程序都有自己的内存缓存,只能从 Web 应用程序本身内部访问(不在外面)。

我在静态类中编写了一个监听方法,这是我的监听方法代码

   public static void Listen()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            channel.QueueDeclare(queue: "hello",
                                 durable: false,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
               // cache invalidation goes here
            };
            channel.BasicConsume(queue: "hello",
                                 autoAck: true,
                                 consumer: consumer);
        }
    }

我像这样在 global.asax 中的方法中调用该Listen方法Application_Start

   protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        CacheNotifier.Listen();
    }

但是,当我从其他服务器向队列发送消息时,Consumer.Received不会触发接收发送的消息。

而当我将完全相同的Listen方法放在控制台应用程序中并从 Main 方法调用它(侦听方法)时static void Main(string[] args),事件会在消息到达时正确触发,但正如我所说,我不能将侦听器放在单独的控制台应用程序或 Windows 服务中,它必须在我的网络应用程序本身中

首先,我想知道为什么我的监听器不能在 ASP.net Web 应用程序中工作,但可以在控制台应用程序中工作,RabbitMQ 的官方文档也只使用控制台应用程序

其次,我需要一个解决方案,考虑到我的听众必须在我的 asp.net web 应用程序中

任何帮助,将不胜感激

4

4 回答 4

1

我确实尝试过您的路线,但遇到了很多问题,基本上没有因为 asp.net 生命周期请求工作而留下的侦听器。

我终于把我的代码的接收部分放在了一个 Windows 服务中。当您收到消息时,您可以调用另一个 Web 服务或将您的数据写入数据库...

我的 Windows 服务现在有超过 10 个实例运行所有相同的代码,我可以将我的消息复制到我的所有站点。

于 2018-11-10T18:17:01.647 回答
1

问题是您将代码附在 using 块中,因为该语句正在处理(关闭)通道和连接,这当然会取消您的订阅。

于 2020-03-12T17:09:04.897 回答
1

我有完全相同的经历:在集成测试期间一切正常,但是当从另一个项目引用我的库代码(即使用 RabbitMQ 客户端)时,消息从队列中消耗得很好(我正在观看图表中的图表) rabbitmq admin) 但从未引发 OnReceived 回调。

发生的事情是在回调中我使用了运行时无法找到的程序集类型,它会抛出 RabbitMQ 客户端正在捕获的异常https://github.com/rabbitmq/rabbitmq-dotnet-client/blob /master/projects/client/RabbitMQ.Client/src/client/impl/ConcurrentConsumerDispatcher.cs#L89

因此,如果其他人发生这种情况,只需确保您已像这样将回调附加到您的频道,以了解发生了什么

channel.CallbackException += (chann, args) =>
{
   //check args.Exception for details
   ///...
};
于 2019-07-03T09:42:43.013 回答
0

首先,我想知道为什么我的监听器不能在 ASP.net Web 应用程序中工作但在控制台应用程序中工作,RabbitMQ 的官方文档也只使用控制台应用程序

这是一个 .NET 和 ASP.NET 编程问题,与 RabbitMQ .NET 客户端无关。我建议阅读这个 StackOverflow 线程这个线程

这些线程还讨论了您的问题的解决方案。

于 2018-07-21T15:34:53.920 回答