"Server Too Busy”错误信息

我更新网站有时会出现Server Too Busy,我看看cpu 的确用了 100%。

我一定认为网站,网站重新编译需要一定的时间。

错误来自HttRuntime的RejectRequestInternal方法。

近来看到 dudu 的文章,

http://www.cnblogs.com/dudu/archive/2005/10/19/257479.html

发现可能其中一个原因是:

定义了一些错误页面是:aspx的,他在这里loop 死了。

当请求被发送到ASP.NET Worker Process时,先是由HttpRuntime的ProcessRequest方法处理,在ProcessRequest方法中,先从请求队列(RequestQueue)中获取有效的请求(GetRequestToExecute),如果有有效的请求,就调用HttpRuntime.ProcessRequestNow进行进一步的处理。而"Server Too Busy"的异常就是在GetRequestToExecute中产生的,GetRequestToExecute方法代码如下:

internal  HttpWorkerRequest GetRequestToExecute(HttpWorkerRequest wr)
{
      
int num1;
      
int num2;
      ThreadPool.GetAvailableThreads(
out num1, out num2);
      
int num3 = (num2 > num1) ? num1 : num2;
      
if ((num3 < this._minExternFreeThreads) || (this._count != 0))
      
{
            
bool flag1 = RequestQueue.IsLocal(wr);
            
if ((flag1 && (num3 >= this._minLocalFreeThreads)) && (this._count == 0))
            
{
                  
return wr;
            }

            
if (this._count >= this._queueLimit)
            
{
                  HttpRuntime.RejectRequestNow(wr);
                  
return null;
            }

            
this.QueueRequest(wr, flag1);
            
if (num3 >= this._minExternFreeThreads)
            
{
                  wr 
= this.DequeueRequest(false);
                  
return wr;
            }

            
if (num3 >= this._minLocalFreeThreads)
            
{
                  wr 
= this.DequeueRequest(true);
                  
return wr;
            }

            wr 
= null;
            
this.ScheduleMoreWorkIfNeeded();
      }

      
return wr;
}

     我们分析一下上面的代码:程序先从管理线程中获取有效线程的数目(num3)。如是num3大于minFreeThreads(该值对应于machine.config或者web.config中HttpRuntime段的minFreeThreads属性,即使执行新请求所需要的最小空闲线程数)并且请求队列中没有请求,则直接处理当前请求;如果num3小于minFreeThreads或者当前请求队列不为空("Server Too Busy"的请求就是这种情况), 从上面的代码中我们会发现当请求队列(RequestQueue)中请求数大于
_queueLimit(该值对应于machine.config或者web.config中HttpRuntime段的appRequestQueueLimit属性)时,HttpRumtime就会拒绝当前请求(RejectRequestNow),RejectRequestNow中直接调用RejectRequestInternal(HttpWorkerRequest wr), 在RejectRequestInternal中抛出了"Server_too_busy", 抛出异常后,立即捕获异常,你说怪吧,为什么不直接处理?为什么要在抛出异常后又捕获?有点多此一举?可能设计者还有其他考虑吧,比如为了代码更好的重用。

try
      
{
            
throw new HttpException(0x1f7, HttpRuntime.FormatResourceString("Server_too_busy"));
      }

      
catch  (Exception exception1)
      
{
            context1.Response.InitResponseWriter();
            
this.FinishRequest(wr, context1, exception1);
            
return;
      }

      接着就是异常的处理,向客户端浏览器显示异常信息,调用FinishRequest, 在Finish中调用context.Response.ReportRuntimeError(e, true)显示异常信息,ReportRuntimeError会根据web.config中的CustomErrors设置决定是否重定向到defaultRedirect。
     当你设置CustomErrors的defaultRedirect来定制处理异常信息时,如果遇到"Server_too_busy"就麻烦了,重定向到错误处理页面后,又被HttpRuntime拒绝,拒绝后又被重定向到defaultRedirect页面,HttpRuntime《———》HttpRuntime.....,似乎进入了一种恶性循环。原来问题有这么严重,写文章之前我还没想到,写到这我才发现。这样不停的来回,CPU岂不累死,当CPU累的不行时,就随便抛出一个其他异常:),也就是“Server Error in '/' Application.Runtime Error.”,这个异常我没找到在哪抛出的。难道在首次编译时,CPU占用很高与这个也有关系。我更新博客园服务器上的程序时,要几分钟才能恢复正常,而这时CPU基本是满负荷工作,难道也是这个问题引起,我想明天在访问高峰期测试一下就能得到证实。这似乎是设计者的一个疏忽,正确的做法应该是对于"Server_too_busy"异常,不管用户是否设置了defaultRedirect, 都不应该去重定向到defaultRedirect,而是直接向客户端发送异常信息,这是一个很特殊的情况,设计者在设计时可能没考虑到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田猿笔记

写文章不容易,希望大家小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值