Iis Azure Web作业和信号器内存泄漏

Iis Azure Web作业和信号器内存泄漏,iis,signalr,azure-webjobs,azure-webjobssdk,Iis,Signalr,Azure Webjobs,Azure Webjobssdk,所以我有一些网络作业,偶尔会连接到信号集线器并广播消息。下面只是一个示例,在本例中,它是一个简单的web开发作业,具有TimerTrigger属性,设置为每20秒连续运行一次。如下面的代码所示 public static void Main() { JobHostConfiguration config = new JobHostConfiguration(); config.Tracing.ConsoleLevel = TraceLevel.V

所以我有一些网络作业,偶尔会连接到信号集线器并广播消息。下面只是一个示例,在本例中,它是一个简单的web开发作业,具有TimerTrigger属性,设置为每20秒连续运行一次。如下面的代码所示

    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日志条目的例子

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

亲切问候,

斯特凡

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

2016-11-15 23:10:35 POST/signalr/poll客户端协议=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=TBBNVDPNDK0RIU8UVVZBGJRWJYIO7EMLCP4LK7ABV74OBMBZRTJRCL1BZSPXPD1tyle2R3TV2JJJrIgnithU880ML51XERS76PPDX0HF97DTBYR4K%2BVc2V9KAmiGt0p&messageId=d-80E0087-B%2C7D%7CEz%2C0%2C0%2C0%2C0443-104.210.116.149信号器客户端.NET45/2.1.0+(微软+Windows+NT+6.2.9200.0.0)-200 5343

2016-11-15 23:10:35 POST/signalr/poll客户端协议=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=KYWQXPNRPIU21NXMA0SO5U42EWXTCMLGYLQL3TETX4WFOTTUNLCLCG%2BhPd%2BCPEZPMFE6KKVQL13XU1W5FAPUTV0XN5xFPONUMYBHHISOQODWCZEU3KMKBAXCPHMTE&messageId=d-80E0087-B%2C7D%7Caw%2C2443-104.210.116.149信号器客户端.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200.41)-200 1060

2016-11-15 23:10:35 POST/signalr/poll客户端协议=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=nO%2BPZ8M5JJOpiobpJUV5%2FZvQyEKYjp%2FOuqQ%2F0Bkq05TKRJZfeI%2FD%2BXRYPC7ESAJVQJR05PKSORLMWRXOCGKSKFFSLU2QVTX%2Fi1O8hU5lNz4KcoSc%2BKKV%2BR2BR2AZBLV&messageId=d-80E0087-B%2C7D%7CFB%7CFB%2C0%7CFC%2C0 443-104.210.116.149.Client.NET45/2.1.0+Windows+1820.82

2016-11-15 23:10:35 POST/signalr/poll客户端协议=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=wigsrindd7crhkcamd%2FWy%2F3qGRZ5WdBm%2BdbR3b7aTbtpB8aaBGDil%2fqahaha6si5eeohsumxau4kefy%2bnoxog9fgyc4r66erxishybucsnlwo1ayh5zgdk7fvme3e&messageId=d-80E0087-B%2C7D%7CE9%2C0%2C0-443-104.210.116.149.149 signer.Client.NET45/2.1.0+(微软+Windows+NT+1130.9200)-200

2016-11-15 23:10:35 POST/signalr/poll客户端协议=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=hEJ1b0%2Bz2eeyC8IvYmOV3ffZ%2FAFQPENJLUMCZTEVDLWCOGHYQBQNU0R29SAZP6BXCK4WSDHSBEDG2SH4WMBSZQTKMZASR2FA2EY2HGGOVJCFDOMIX2FCQFA%2BmP&messageId=d-80E0087-B%2C7D%7CFD%2C0%7CFE%2C0%2C0 443-104.210.116.149信号机客户端.NET45/2.1.0+(Microsoft+Windows+NT+6.2.9200.0)-15798

2016-11-15 23:10:35 POST/signalr/poll客户端协议=1.4&transport=longPolling&connectionData=[%7B%22Name%22:%22MyHub%22%7D]&connectionToken=2UsU63IHgaNO%2ByMoamskxfq7vv3uagigvr1nrgnntvnabtg2c0%2bxzna9at8siqpkbv%2fo8avvvvvntsbfqd77ispao6jonsu8rxmxxd2vr6ojkwr%2ft1lfsdny3%2BHpDGC&messageId=d-80E0087-B%2C7D%7CEv%2C0%7CEw%2C0 443-104.210.116.149.149 signer.Client.NET45/2.2.1.0+(Microsoft+Windows+NT+6.2.9200)-11844

等等等等


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

尽管对某些人来说这听起来很明显,但答案是确保在向集线器发送消息后停止集线器连接。下面是代码,附加的一行被注释包围

这似乎与浏览器客户端不同,浏览器客户端在一段时间不活动后会断开连接。webjob客户端会继续访问,并继续对网站进行投票。因此,每次触发webjob时(通过计时器或从azure队列或主题中读取消息),它都会不断生成一个新客户端并保留该连接

在webjob中,必须显式停止连接,否则内存和CPU将逐渐崩溃

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.");
}

轮询请求来自不同的客户端(每个客户端具有不同的connectionToken)。这只意味着服务器根据现有轮询请求向客户端发送消息,客户端必须重新建立新轮询以获取新消息(如果有)。如果您想避免这些请求,请使用更高效的传输—最好是WebSocket。(有趣的是,客户端实际上正在运行长轮询。我可以想象它没有使用WebSocket,因为默认情况下它们是禁用的,您可能忘记启用它们,但我不知道为什么它没有使用serverSentEvents)您是否尝试使触发函数异步,并将SendMessageToHub方法签名中的
异步无效更改为
异步任务
?您好,Thomas,对不起,我已在此处编辑了代码示例。实际上是:私有静态异步任务SendMessageToHub(TextWriter日志)Hi Pawel,该网站肯定启用了web套接字。我们的大多数其他信号通信都是通过ws完成的。然而,web作业客户端似乎正在进行长轮询。我开始认为,在触发消息后,我们可能需要在集线器连接上执行.Stop()方法,以停止任何长轮询,因为客户端对接收任何内容都不感兴趣,而只是触发消息。信号器服务器不能是gett