服务器内存太小,伤不起![异常与应用程序池引发的连锁命案]

最近都在写 秋色园技术原理解析 文章,今天就写一篇散文,简述一下服务器内存太小引发的命案。

 

以前写文都排版,这篇就当散文了...写完就这样了,当然加黑加红还是给加了。

 

首先,我先上2张秋色园服务器当前进程及内存的图片:

 

1:进程

 

2:物理内存剩余

 

看完这两张图片,啥感觉?内存穷紧张!!!!

 

穷紧张不打紧,打紧的是比紧张还紧张的情况发生了,什么情况?

 

出事故了,应用程序池要产生回收动作了!!!!

 

先看一下应用程序池什么情况会产生回收动作?

 

1:IIS应用程序池里的“回收”里的配置就不说了,这些是你自己定义的。

2:你手动执行“回收”,以重启应用程序池。

3:你升级dll到服务器中,新升的升级会引发应用程序池重启。

4:web应用程序产生“错误”,进程终止,引发应用程序池重启。

5:临时想不出来......

 

 

出事了,出事了,出啥事了?

 

还不是内存穷紧张那点破事,为了演示一下什么事,我决定回收一下应用程序池给大伙截图!!!

 

这里本机示例回收了,大伙知道咋回事就可以了,哈哈:

 

看到了吧,两个进程,这是什么情况?

IIS启用了新的进程来接收新的请求,同时旧的进程请求会保留继续处理之前的请求队列,直到处理完所有之前的请求才结束。

大体就是这么一回事了,问题就产生在这一瞬间:

本来就没内存了,旧的进程不回收,新的进程又出来,一出来就喊着要内存,可是系统又给不了内存,于是就卡在那里,还造成CPU百分百的情况。

就在这个小间间,网站访问就卡住了,打不开了,给人一种速度超慢的感觉。

 

什么时候你感觉打开了,估计就是旧的进程光荣退休了。

 

好了,升级时候的情况并不多,应用程序池也设置了半夜才回收一次,理论上回收也不多,这种小瞬间产生的机率并不多。

 

可是网站不稳定的情况才出现的挺频繁,似乎超出我设置的时候和升级的频率。

 

就在这些天,我发现我基础有点差:

web应用程序产生“错误”,进程终止,引发应用程序池重启。

以前都没怎么注意,现在发现了,代码写的不好,异常不处理好,应用程序池就会经常性重启,也是引发你网站慢的一个原因。

 

给大伙截一张图:

 

大伙到自己服务器上看这事件,如果看到一堆错误及警告,说明你和我一样基础差。

 

这些日志是怎么产生的?

 

其实就是系统未被捕获的异常的,然后最终一路过五关,最后就跑这来了,跑到这来,基本上你的应用程序池就变的很不稳定的说。

 

下面就随意扯扯异常这事情

首先一点就是:

在.NET 2.0中,主线程或线程的错误,都会导致进程的中止,引发应用程序池回收。

1.1版本的时候,线程的错误是不会引发主进程中止的。

 

PS:还记得我上篇文章“秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)”说到的内置线程吧,

其实隐藏说的就是这问题,线程的访问冲突,经常性的引发了主进程中止,导致应用程序池重启。

 

再说一点的就:

先把日志上的警告和异常给处理了。

 

最后一点的就是:

全局捕获未处理的异常,然后作掉它,不让它跑到这来危害应用程序池重启。[补充:作掉它并不能避免应用程序池重启]

 

基础不好,很多天了,才偶然发现这么点代码:

一:AppDomain.CurrentDomain.UnhandledException 事件

        public Window1() {
            InitializeComponent();
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        }

        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            throw new NotImplementedException();
        }

PS:在web中发现这家伙似乎不起作用,没深入纠结它,而且它阻止不了异常往上报,只能是收集信息用。

 

二:HttpApplication.Error事件

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
            context.Error += new EventHandler(context_Error);
        }

        void context_Error(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            Log.WriteLogToTxt(app.Server.GetLastError());
            app.Server.ClearError();//把错误消灭了,不让它往上抛
        }

 

这里其实要说的就是app.Server.ClearError(),为了发现这一行代码,我纠结了好多个小时,最后很偶然才发现它,[虽然发现了它,但是作用似乎不大]。

 

补充:

在楼下网友:长河落魄 的疑问声中,我测试了一下,得到以下结果:

1:主线程中产生的“错误”,只要不是致命的,系统日志中仅是“警告”级别,它不会引发应用程序重启。

2:内置线程中产生的“错误”,系统中产生的“错误”级别,它会中止进程,而且,上面的全局语句并不能捕获到异常。

 

当然,这里还有几个疑惑:

1:应用程序池是不是只遇到“错误”级别的,才会引发终止,重启?

2:主线程中一般的错误都是“警告”级别,那有没有可能会产生“错误”级别的错误呢?如果产生了,是不是一样可拦截?这上面的清除异常的代码,是不是就有效了?

3:多线程中的异常,没有全局捕获的事件了?如果有,你在哪呢?

 

 

好了,现在基本上错误都被记录,一步一步对着日志一个一个消灭了,现在基本上应用程序池很稳定不乱重启了,安稳了许多。

 

其实总结还是一句:内存太小,伤不起啊!

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:http://www.cnblogs.com/cyq1162/archive/2011/07/20/2111628.html

时间: 2024-09-22 21:51:58

服务器内存太小,伤不起![异常与应用程序池引发的连锁命案]的相关文章

求救:c# 传递给系统调用的数据区域太小。 (异常来自 HRESULT:0x8007007A)

问题描述 c中结构体定义为typedefstruct_CAM_GROUP_INFO{intnCamGroupID;//cameragroupidcharszGroupName[64];//cameragroupnameintnServerID;//belongtowhichserverintstate;//MP_CAM_StateXXXX}CAM_GROUP_INFO;我现在在c#中定义结构体[StructLayout(LayoutKind.Sequential,CharSet=CharSet.

MySQL服务器内存使用

Every so often people ask me the question how should they estimate memory consumption by MySQL Server in given configuration. What is the formula they could use. 经常有人问我配置MySQL时该如何估算内存的消耗.那么该使用什么公式来计算呢? The reasons to worry about memory usage are quit

Linux VPS服务器内存不够用的优化方案

自从把我的一个网站搬家到linode 1G 的vps上后,总感觉有些不太正常.首先dnspod监控上显示网站有时能访问,有时不行.然后wp supercache插件在执行预缓存任务时经常失败后重启,邮件内容如"[http://www.111cn.net] 预缓存可能已失去响应.预缓存已经重新启动.".还有一个情况是linode有时会发来磁盘io使用高的报警邮件. 今天抽空检查了下服务器,发现一个现象是mysql进程频繁无故重启. 150424 17:41:14 [Note] Event

Unity3D占用内存太大的解决方法

最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBundle,其实两者区别不大. Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBundle文件需要你自己创建,运行时 动态加载,可以指定路径和来源的. 其实场景里所有静态的对象也有这么一个加载过程,只是Unity3D后台替你

Erlang服务器内存耗尽bug跟踪过程

问题描述 本文描述朋友Erlang服务器内存耗尽bug的解决过程.首先说明一下问题,服务器1千多人在线,16G内存快被吃光.玩家进程占用内存偏高:接下来是解决过程.第一步:查看进程数目是否正常? erlang:**_info(process_count). 进程数目合理第二步:查看节点的内存消耗在什么地方?> erlang:memory(). 显示内存大部分消耗在进程上,由此确定是进程占用了大量内存第三步:查看哪些进程占用内存最高?> spawn(fun() -> etop:start(

解决通过Intent调用系统拍照程序,返回图片太小的问题[android]

  以下的代码可以调用系统的拍照程序, 1 2 Intent it = newIntent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(it, Activity.DEFAULT_KEYS_DIALER); 按下拍照键后,会返回到你的activity,所以你的activity要在onActivityResult方法里加一个处理, 1 2 3 4 5 6 7 8 9 10 11 12 13 protectedv

SQL服务器内存有两种基本管理方法:动态分配和静态分配

动态|服务器|静态 SQL服务器内存有两种基本管理方法:动态分配和静态分配 控制程序可使用的内存数量.动态分配允许管理员声明一块内存的大小:考虑到它的实际使用,SQL服务器可以分配给其需要占用的内存的最大值,并且(理论上)在没有使用内存的情况下将其释放.静态分配则是创建一块固定的内存空间,提供给SQL Server使用--不再进行分配. 在默认情况下,SQL Server被设置成动态分配,分配给其正在运行的计算机内所有可用的物理内存.许多管理员注意到SQL Server内存随时间的流逝被逐渐消耗

什么是服务器内存

  服务器内存也是内存(RAM),它与普通PC(个人电脑)机内存在外观和结构上没有什么明显实质性的区别,主要是在内存上引入了一些新的特有的技术,如ECC.ChipKill.热插拔技术等,具有极高的稳定性和纠错性能. 服务器内存主要技术: (1)ECC 在普通的内存上,常常使用一种技术,即Parity,同位检查码(Parity check codes)被广泛地使用在侦错码(error detectioncodes)上,它们增加一个检查位给每个资料的字元(或字节),并且能够侦测到一个字符中所有奇(偶

win8.1系统C盘可用内存越来越小如何解决

  win8.1系统C盘可用内存越来越小如何解决 1.磁盘清理:进入计算机资源管理器-右键C盘-属性-磁盘清理-清理系统文件,查看每一项资源的占用空间并且勾选清理,特别注意以前的Windows安装,也就是Windows old文件夹,安装系统时没有格式化系统盘会将以前的系统文件放入Windows old文件夹,容量很大; 2.虚拟内存:虚拟内存会将硬盘部分空间划拨作为虚拟内存使用,以页面文件形式存在,一般会占用2G-4G不等.如果你的计算机物理内存达到4G或4G以上,可以考虑取消虚拟内存的设置;