Azure Web Jobs和SignalR内存泄漏 [英] Azure Web Jobs and SignalR memory leak

查看:298
本文介绍了Azure Web Jobs和SignalR内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一些偶尔连接到信号器集线器并广播消息的webjobs。下面只是一个示例,在这种情况下,它是一个用于开发的简单Web作业,其TimerTrigger属性设置为每20秒连续运行一次。如下面的代码所示。

So I have some webjobs that occasionally connect to a signalr hub and broadcast a message. Below is just an example of one, in this case its a simple web job for development with the TimerTrigger attribute that is set to run continuously every 20 seconds. Like that shown in the code below.

    public static void Main()
    {

        JobHostConfiguration config = new JobHostConfiguration();
        config.Tracing.ConsoleLevel = TraceLevel.Verbose;
        config.UseTimers();
        if (config.IsDevelopment)
        {
            config.UseDevelopmentSettings();
        }
        var host = new JobHost(config);
        host.RunAndBlock();
    }

    public static void ProcessPush([TimerTrigger("00:00:20", RunOnStartup = true)] TimerInfo timerInfo, TextWriter log)
    {
        // Send a signalr message to the Hub
        try
        {            
            SendMessageToHub(log);
        }
        catch (Exception e)
        {
            log.WriteLine($"WebJob Push Exception: {e.Message}");
        }
    }

    private static async Task SendMessageToHub(TextWriter log)
    {
            var hub = new HubConnection(CloudConfigurationManager.GetSetting("MyWebSite"));
            var proxy = _hub.CreateHubProxy("MyHub");

            log.WriteLine("WebJob Push: Sending message to SignalR Hub.");
            if (_hub.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Disconnected)
            {
                await _hub.Start();
            }
            await _proxy.Invoke("BroadcastMessage");
            log.WriteLine("WebJob Push: Sent message to SignalR Hub.");
    }

托管网站和信号中心的服务器内存总是有增量。在调查网站上的IIS日志时,似乎使用长轮询,在同一秒内涌入/批量POST消息到网站。然后等待一会儿,然后用另一批消息轰炸。顺便说一句,这也会使IIS服务器上的CPU变得疯狂。在这篇文章的底部是IIS日志条目的一个例子。

There is always an increment in memory on the server hosting the website and signalr hubs. When investigating the IIS logs on the website, it seems to have surge / batch of POST messages come to the website at the same second, using long polling. It then waits a little while and then gets bombarded with another batch of messages. By the way, this drives the CPU on the IIS Server crazy as well. At the bottom of this post is an example of the IIS log entries.

我希望能够以一致的方式从Web作业发送信号器消息有一个常规的脉冲信息(我们想扩展网络工作 - 请原谅它现在在计时器上运行的事实)。

I'd like to be able to send a signalr message from the web job in a consistent manner with a regular pulse message (we want to expand on the web job - please excuse the fact it runs on a timer for now).

亲切的问候,

Stefan

示例IIS日志条目 - 注意它们都在同一秒内进入,而不是相隔20秒:

Example IIS Log entries - notice they have all come in within the same second, instead of 20 seconds apart:

2016-11-15 23:10:35 POST / signalr / poll clientProtocol = 1.4& transport = longPolling& connectionData = [%7B%22Name%22:%22MyHub %22%7D]安培; connectionToken = TBbNVDpndk0riu8UvVzbGJrWjYIo7eMLcP4lk7ABV74OBMbZRTJrCRL1bzsPxpd1Tyle2rS3tV2JJrigninhu880ml51Xers76PPDX0Hf97dTBYR4k%2BVc2V9KAmiGt0p&安培; MESSAGEID = d-80E0087-B%2C7D%7CEz%2C0%7CE0%2C0 443 - 104.210.116.149 SignalR.Client.NET45 / 2.2.1.0 +(微软的Windows + + NT + 6.2.9200.0) - 200 0 0 5343

2016-11-15 23:10:35 POST /signalr/poll clientProtocol=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=TBbNVDpndk0riu8UvVzbGJrWjYIo7eMLcP4lk7ABV74OBMbZRTJrCRL1bzsPxpd1Tyle2rS3tV2JJrigninhu880ml51Xers76PPDX0Hf97dTBYR4k%2BVc2V9KAmiGt0p&messageId=d-80E0087-B%2C7D%7CEz%2C0%7CE0%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.0) - 200 0 0 5343

2016-11-15 23:10:35 POST / signalr / poll clientProtocol = 1.4 &安培;运输= longPolling&安培; connectionData = [%7B%22Name%22:%22MyHub%22%7D]安培; connectionToken = KYwQXpNrPIU21NXMa0So5u42EwXTcMlGyLqL3tetx4WfOtTunHLclG%2BhPd%2BcPeZPmfe6KKvQL13XIU1W5fApuTv0XN5XFPoNUmyBjhhISoqodwcZeu3QKmkbaXcpHMtE&安培; MESSAGEID = d-80E0087-B%2C7D%7Cav%2C0%7Caw%2C2 443 - 104.210.116.149 SignalR.Client.NET45 / 2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 10641

2016-11-15 23:10:35 POST /signalr/poll clientProtocol=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=KYwQXpNrPIU21NXMa0So5u42EwXTcMlGyLqL3tetx4WfOtTunHLclG%2BhPd%2BcPeZPmfe6KKvQL13XIU1W5fApuTv0XN5XFPoNUmyBjhhISoqodwcZeu3QKmkbaXcpHMtE&messageId=d-80E0087-B%2C7D%7Cav%2C0%7Caw%2C2 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.0) - 200 0 0 10641

2016-11- 15 23:10:35 POST / signalr / poll clientProtocol = 1.4& transport = longPolling& connectionData = [%7B%22Name%22:%22MyHub%22%7D]& connectionToken = nO%2BPZ8M5JJOpiobpJUV5%2FZvQyEKYjp%2FOuqQ%2F0Bkq05TKRJZfeI %2FD%2BxRyPC7EsAAjXVqJr05PksorlMWrXocGkskfVsLU2Qvtx%2Fi1O8hU5lNz4KcoSc%2Bkv%2BlDpr2AZBLv&安培; MESSAGEID = d-80E0087-B%2C7D%7CFB%2C0%7CFC%2C0 443 - 104.210.116.149 SignalR.Client.NET45 / 2.2.1.0 +(微软的Windows + + NT + 6.2.9200.0) - 200 0 0 18282

2016-11-15 23:10:35 POST /signalr/poll clientProtocol=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=nO%2BPZ8M5JJOpiobpJUV5%2FZvQyEKYjp%2FOuqQ%2F0Bkq05TKRJZfeI%2FD%2BxRyPC7EsAAjXVqJr05PksorlMWrXocGkskfVsLU2Qvtx%2Fi1O8hU5lNz4KcoSc%2Bkv%2BlDpr2AZBLv&messageId=d-80E0087-B%2C7D%7CFB%2C0%7CFC%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.0) - 200 0 0 18282

2016-11-15 23:10:35 POST / signalr / poll clientProtocol = 1.4& transport = longPolling& connectionData = [%7B%22Name%22:%22MyHub%22%7 d]安培; connectionToken = wiGSRiNHdd7crhkcAMd%2FWy%2F3qGRZ5WdBm%2BdbR3b7aTbtpB8aaBGDil%2FqAWha6Si5eEohsUmCxAU4Pkefy%2BNoxoG9fgYC4R66ErXIShyBUcsNLWo1AyH5zGDk7bFvme3E&安培; MESSAGEID = d-80E0087-B%2C7D%7CE9%2C0%7CE_%2C0 443 - 104.210.116.149 SignalR.Client.NET45 / 2.2.1.0 + (Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 11360

2016-11-15 23:10:35 POST /signalr/poll clientProtocol=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=wiGSRiNHdd7crhkcAMd%2FWy%2F3qGRZ5WdBm%2BdbR3b7aTbtpB8aaBGDil%2FqAWha6Si5eEohsUmCxAU4Pkefy%2BNoxoG9fgYC4R66ErXIShyBUcsNLWo1AyH5zGDk7bFvme3E&messageId=d-80E0087-B%2C7D%7CE9%2C0%7CE_%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.0) - 200 0 0 11360

2016-11-15 23:10:35 POST / signalr / poll clientProtocol = 1.4& ;运输= longPolling&安培; connectionData = [%7B%22Name%22:%22MyHub%22%7D]安培; connectionToken = hEJ1b0%2Bz2eeyC8IvYmOV3ffZ%2FAFQiQpEnJLUmCZTEVDLwcgOqhyQbQnu0R29sazp6BxcK4WsDhSbEdg2Sh4wMBSZjQtKMzASr2Fa2eY2HGgoVJcfDOMixQX2FCqfa%2BmP&安培; MESSAGEID = d-80E0087-B%2C7D%7CFD%2C0%7CFE% 2C0 443 - 104.210.116.149 SignalR.Client.NET45 / 2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0) - 200 0 0 15798

2016-11-15 23:10:35 POST /signalr/poll clientProtocol=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=hEJ1b0%2Bz2eeyC8IvYmOV3ffZ%2FAFQiQpEnJLUmCZTEVDLwcgOqhyQbQnu0R29sazp6BxcK4WsDhSbEdg2Sh4wMBSZjQtKMzASr2Fa2eY2HGgoVJcfDOMixQX2FCqfa%2BmP&messageId=d-80E0087-B%2C7D%7CFD%2C0%7CFE%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.0) - 200 0 0 15798

2016-11 -15 23:10:35 POST / signalr / poll clientProtocol = 1.4& transport = longPolling& connectionData = [%7B%22Name%22:%22MyHub%22%7D]& connectionToken = 2UsU63IHgaNO%2BBYmoamsKxFq7Vv3uaGigvR1NrGnntVnAbTg2C0%2BV XZnA9aT8siqpkBv%2Fo8avvvNTSBfQD77IspaO6jOnSU8rXMXDU2Vr6ojkWr%2Fwt1LFsdNy3%2BHpDGC& messageId = d-80E0087-B%2C7D%7CEv%2C0%7CEw%2C0 443 - 104.210.116.149 SignalR.Client.NET45 / 2.2.1.0 +(Microsoft + Windows + NT + 6.2.9200.0 ) - 200 0 0 11844

2016-11-15 23:10:35 POST /signalr/poll clientProtocol=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=2UsU63IHgaNO%2BBYmoamsKxFq7Vv3uaGigvR1NrGnntVnAbTg2C0%2BVXZnA9aT8siqpkBv%2Fo8avvvNTSBfQD77IspaO6jOnSU8rXMXDU2Vr6ojkWr%2Fwt1LFsdNy3%2BHpDGC&messageId=d-80E0087-B%2C7D%7CEv%2C0%7CEw%2C0 443 - 104.210.116.149 SignalR.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.0) - 200 0 0 11844

等等

更新 - 明确停止集线器连接似乎处理了孤立客户端(或同一个Web作业客户端的多余客户端)。特别是,添加_hub.Stop();在调用代理之后。

UPDATE - Explicitly stopping the hub connection seems to have dealt with the orphan clients (or superfluous clients for the same web job client). In particular, adding _hub.Stop(); after invoking the proxy.

推荐答案

所以对某些人来说,这听起来很明显,答案就是确保我们停止发送消息后的集线器连接。下面是注释包含附加行的代码。

So as obvious as it may sound to some, the answer to this was to ensure that we stop the hub connection after sending the message to it. Below is the code with the additional line surrounded by comments.

与浏览器客户端不同,客户端在一段时间不活动后会断开连接。 webjob客户端坚持不懈,并继续在网站上进行投票。因此,每次触发webjob时(通过计时器或通过读取天蓝色队列或主题的消息),它都会不断产生新客户端并保留该连接。

It would seem that unlike a browser client, whereby the client gets disconnected after a while of inactivity. The webjob client sticks around, and continues to poll the website. So each time the webjob is triggered (via a timer or via reading a message off an azure queue or topic) then it keeps spawning a new client and retaining that connection.

在webjob中,你必须明确地停止连接,否则内存和CPU将逐渐变成坚果包。

In a webjob, you must explicitly stop the connection, otherwise the memory and CPU will gradually go nutbags.

private static async Task SendMessageToHub(TextWriter log)
{
        var hub = new HubConnection(CloudConfigurationManager.GetSetting("MyWebSite"));
        var proxy = _hub.CreateHubProxy("MyHub");

        log.WriteLine("WebJob Push: Sending message to SignalR Hub.");
        if (_hub.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Disconnected)
        {
            await _hub.Start();
        }
        await _proxy.Invoke("BroadcastMessage");
        /////////////////////////////////////////////////////////////
        // Stopping the hub connection is necesssary in a web job  //
        _hub.Stop();   
        /////////////////////////////////////////////////////////////
        log.WriteLine("WebJob Push: Sent message to SignalR Hub.");
}

这篇关于Azure Web Jobs和SignalR内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆