通用处理程序 (.ashx) 实现 IHttpAsyncHandler 时出现 IIS 7.0 503 错误

发布于 2024-07-14 03:39:05 字数 2817 浏览 13 评论 0原文

我在使用实现 IHttpAsyncHandler 的通用处理程序时遇到了一些性能问题。 最简单的是,处理程序接收 GET 请求,并在 20 秒后写入 '<; 后结束响应。 超时/>' 到响应。

当使用 10000-20000 个并发请求攻击 .ashx 时,在恰好 5000 个请求之后,它会失败并显示 503 服务器不可用。 当切换到同步模式并立即结束请求时,问题就消失了。

我修改了许多设置,但我唯一能实现的目标是降低发生此错误的请求阈值。

以下是我尝试过的设置的概要:

ma​​chine.config:

<configuration>
    ...
    <system.web>
        ...
        <processModel enable="true" requestQueueLimit="10000"/>
        ...

web.config:

<configuration>
    ...
    <system.web>
        ...
        <httpRuntime enable="true" appRequestQueueLimit="10000"/>
        ...

IIS Manager > 应用程序池> 高级设置

Queue Length : 65535

虽然我不能确定,但​​如果请求是同步的,这些设置似乎工作得很好,但是当异步时,在服务器开始告诉我之前,我似乎无法超过 5000 个请求走开。 如果我将设置设置得较低(无法准确记住上面的设置,但我已经尝试了所有设置),那么 503 计数会相应增加,但在严重负载下我永远无法阻止它超过 5000 。

似乎分散在无数地方的许多设置可能会影响这一点,但 5000 似乎是一成不变的。 我看到 这里说appRequestQueueLimit不能超过5000,但找不到更多信息关于这一点,并想知道这是否是错误信息。

IIS 中是否有任何类型的“洪水控制”设置可能会限制单个主机不超过 5000 个请求? 如何让 IIS 处理超过 5000 个并发异步请求?

编辑2:是否有可能超出限制的任何计数器或其他指示器,以及我将如何进一步调查?

编辑:这是负载生成器代码:

using System;
using System.Net;
using System.Threading;

namespace HammerTime
{
    class Program
    {
        private static int counter = 0;
        static void Main(string[] args)
        {
            var limit = 5000;
            ServicePointManager.DefaultConnectionLimit=limit;
            for (int i = 0; i < limit;++i )
            {
                StartWebRequest(i.ToString());

            }
            Console.ReadLine();
        }

        private static void StartWebRequest(string channelId)
        {
            string uri = "http://spender2008/test/Test.ashx?channel="+channelId;
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(uri);
            request.BeginGetResponse(responseHandler, request);
        }

        private static void responseHandler(IAsyncResult ar)
        {
            try
            {
                HttpWebRequest state = (HttpWebRequest)ar.AsyncState;
                HttpWebResponse response = (HttpWebResponse)state.EndGetResponse(ar);

            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                Console.WriteLine(Interlocked.Increment(ref counter));
            }

        }
    }
}

I'm running into some performance issues using a generic handler that implements IHttpAsyncHandler. At its simplest, the handler receives a GET request, and 20 seconds later ends the response after writing '< timeout / >' to the response.

When hammering the .ashx with 10000-20000 simultaneous requests, it fails with 503 server unavailable after precisely 5000 requests. When switching to synchronous mode, and ending the request immediately, the problem goes away.

I've tinkered with a number of settings, yet the only thing I've managed to acheive is lower the request threshold at which this error occurs.

Here's a rundown of the settings I've toyed with:

machine.config:

<configuration>
    ...
    <system.web>
        ...
        <processModel enable="true" requestQueueLimit="10000"/>
        ...

web.config:

<configuration>
    ...
    <system.web>
        ...
        <httpRuntime enable="true" appRequestQueueLimit="10000"/>
        ...

IIS Manager > ApplicationPools > Advanced Settings

Queue Length : 65535

Although I can't be sure, it seems like these settings work good and fine if the requests are synchronous, but when async, I can't seem to get beyond exactly 5000 requests before the server starts telling me to go away. If I set things lower (can't remember exactly which setting that would be from the above, but I've tried them all), then the 503 count goes up accordingly, but I can never stop it happening beyond 5000 when under serious load.

It seems that there a a number of settings scattered in a myriad of places that might affect this, but the 5000 seems fairly set in stone. I see here that appRequestQueueLimit cannot exceed 5000, but can find no further info about this, and wonder if this is misinformation.

Is there any kind of "flood-control" setting in IIS that might be limiting a single host to no more than 5000 requests? How can I get IIS to handle more that 5000 concurrent asynchronous requests?

Edit2: Are there any counters or other indicators of which limit might be being exceeded, and how would I investigate further?

Edit: Here's the loadgenerator code:

using System;
using System.Net;
using System.Threading;

namespace HammerTime
{
    class Program
    {
        private static int counter = 0;
        static void Main(string[] args)
        {
            var limit = 5000;
            ServicePointManager.DefaultConnectionLimit=limit;
            for (int i = 0; i < limit;++i )
            {
                StartWebRequest(i.ToString());

            }
            Console.ReadLine();
        }

        private static void StartWebRequest(string channelId)
        {
            string uri = "http://spender2008/test/Test.ashx?channel="+channelId;
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(uri);
            request.BeginGetResponse(responseHandler, request);
        }

        private static void responseHandler(IAsyncResult ar)
        {
            try
            {
                HttpWebRequest state = (HttpWebRequest)ar.AsyncState;
                HttpWebResponse response = (HttpWebResponse)state.EndGetResponse(ar);

            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                Console.WriteLine(Interlocked.Increment(ref counter));
            }

        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

早乙女 2024-07-21 03:39:05

好的。 已修复...非常感谢这篇帖子澄清了一些细节。

要消除 503 错误,需要进行 3 个不同的配置更改:

ma​​chine.config:

<configuration>
    ...
    <system.web>
        ...
        <processModel enable="true" requestQueueLimit="100000"/>

IIS Manager > 应用程序池> 高级设置,

Queue Length : 65535

最后(拼图中缺失的一块),命令行:

appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000

主帖中提到的 web.config 设置是无关紧要的。

10000个并发连接,没问题。 感谢帮助!

OK. Fixed... many thanks to this post for clearing up a few details.

To eliminate the 503 errors required 3 different config changes:

machine.config:

<configuration>
    ...
    <system.web>
        ...
        <processModel enable="true" requestQueueLimit="100000"/>

IIS Manager > ApplicationPools > Advanced Settings

Queue Length : 65535

and finally (the missing piece of the puzzle), the command line:

appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000

The web.config setting mentioned in the main post was irrelevant.

10000 concurrent connections, no problems. Thanks for help!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文