让我纠结的IIS和他的回收
本来以为项目结项,皆大欢喜,没想到到最后自动提醒居然不好使了,而且还找不到原因。
上学的时候学习global的时候没遇到这个问题,所以不知道出现在什么地方,检查代码没有发现任何问题。定时是每天的中午12点和晚上12点进行一次执行。可惜人算不如机器算。
第一天没执行。。重启IIS,执行。好吧,只能等第二天在去测试晚上12点的执行情况。第二天上班一看。。没执行。
当时的分析是,线程可能睡死了(当时怎么就没意识到睡死的概念)。剪短时间间隔。为了检测是不是代码引起的问题,1分钟执行一次。检测出来了,代码的确抛出异常。之前自己的检查的时候没有发现。好吧改掉之后。继续执行,一切OK。
改为1小时一次,坐等一小时,并且去找一些关于global的配置问题,但是无果。检查到也有不执行的,但是说的是没给权限的问题,我觉得这个东西和权限没有什么太大的关系,所以也就是做尝试的给IIS加上而已。
当然答案是肯定的,对于结果没有任何改变,本机测试1小时没问题。好吧。应该没问题了,提交上去,再次发布。第一小时,执行了一次。我觉得问题被找到了,测试人员告诉我,数据删除再次测试。结果第二次应该执行的时候没有执行。
当时百思不得其解,因为为了避免线程不好操控,是用了轻量级的timer。但是没想到这么不靠谱。执行一次就停止了。有点坑啊。
当时觉得他是消散了(还没意识到错误在眼前二次经过),那把timer定义成public的吧。我看你怎么消失,顺便在给你加个static。
好吧。加完之后测试1分钟的。没问题
测试10分钟的没问题。
测试1小时的。消失了。。。
而且是在本地消失的,不理解他的消散原因。因为压根就没执行。错误到底在哪呢?
一宿的纠结,导致失眠第二天没有什么精神并且头疼。打开电脑第一件事就是找问题。但是很可惜没有任何思绪,这个问题我也跟我的群说了,他们建议我加日志。考虑再三我加上了日志,在去执行。根据日志反馈的情况来看他是突然消失的。并没有征兆。具体来说就是当Application_Start事件执行结束后,timer的委托时间并没有执行。
那只能用笨方法来测了,调成执行时间是1分钟。一切正常。10分钟也正常。半个小时。中午休息一下,打了一盘三国杀。下午在看结果,没有运行。没想到这个破问题纠结了我一上午。这时候群里有人说可能是被IIS回收了。抱着试试看的态度在百度上搜索了一下 IIS global 回收 这三个关键字。果真搜索出答案了。
但是我不敢确信这个答案是否是正确并且针对我的程序,所以我在Application_End写了日志,如果进入这里则记录一下。程序还是半小时的。结果很明显。程序启动成功,21分钟之后程序结束。
21分钟。这能做啥呢。我把我的程序修改成15分钟执行。
执行一次。等待第二次的时候到达21分钟 程序结束。一切都被Dispose。
在去看百度的文章,大意思“Asp.Net 应用程序会不定时的关闭,这个时间间隔大约为 1~5 个小时一次。”其实这个结果并适合我,因为这个间隔是21分钟。也就是说他的应用程序池自动关闭的时间不是可以掌控的,那么现在就有几个解决方案
1.修改IIS的垃圾回收时间,并且做回收之后的Application_Start在起事件。(http://blog.csdn.net/orain/article/details/4589984)
2.修改运行时间的间隔(已经被PASS了,因为无论怎么运行最后都被回收)
3.让网站一直被访问状态。在Application_Start做手脚。
4.写windows 服务
考虑再三直接写windows服务吧。因为那篇文章也说道了对于这种长时间的自动程序写windows服务是最适合不过的。IIS的不可控因素实在太多了。
开始写windows服务,因为之前的网站代码都是封装在类库里面的,我本想把动态类库倒动过来引用调用方法就OK了。没想到。引用直接出错。我表示精神不振的我。崩溃了,三观倒塌了。但是要淡定。根据警告的信息百度了一下,原来windows服务和asp.net应用程序的默认框架集是不一样的。而是在net framework4.0上有两种(我的电脑没有没法截图)
调整框架集在生成一切都成功。但是添加到服务里面运行后停止。。自动停止。好吧在使出山寨日志写法。BLL层的引用方法的时候异常没有抛出而是直接结束了。windows服务你是有多么的脆弱。
这时候头疼的不行,把类库复制过来引用上吧。结果还是有问题。好吧三层架构的确不适合你了。一层来吧。东弄弄西弄弄。还是不行。到底是什么地方出错了。领导给我看了一个以前公司写的windows调用公司的组件项目。原来是App.Config里面还差一句话。providerName="System.Data.SqlClient" (驱动) 但是在asp.net项目中并没有用到这句话。看来我是长时间做web项目做傻了。
服务起来了。但是数据库没有变化。好吧,我忍了了,因为我知道windows服务的调试必须基于服务运行起来,或者使用windbg,但是后者没用过啊。而且还不好找他的安装包,属于windows sdk的一种。
运行成功了那就来调试下吧。。
数据库他喵的谁改什么了。。。为什么字段是必填的。。。。
最后运行成功了。心理留下了阴影反复的问不能被回收吧。。
把几个方法都写好,也到下班点了。没有做最后一次测试。星期一在去测试吧。
最后总结出来几点。
在设计项目的最初一定要考虑回收的问题,因为在.net的的世界回收是不需要人为操控的(IIS属于.net范围么?)所以不考虑内存的问题。
其次做web项目必须要考虑你做的自动是否是属于那种长时间的自动程序。要考虑IIS的回收,最后也是最重要的一点就是要设计日志,这个日志是系统日志,因为这个日志可以帮助未来的维护人员来进行科学的快速的维护,减少开发人员和维护人员不必要的时间支出。如果最初就考虑了日志的话也许问题曝光时间就会长一些解决办法会多一些。
在使用不同程序的时候发现dll的使用发生不正确,最好检查一下两个程序的框架集是不是同一个(项目类库右键属性就能看到)
因为框架集不同IDE认为你是错误的使用。其实这个问题应该大多数出在不同的IDE版本之间的dll使用,我这事偶然碰上。
最后就是关于 global的。他的编译是动态编译,应该是在IIS运行的时候才进行编译。global的编译出来的dll并不存在在任何的dll里面(我个人认为没有经过IL的检验)网上说会生成一个global.dll但是我没有发现,后来尝试按照web网站的写法写,把后置的CS代码放入到他的页面。因为在net编译的时候前置页面页面并不编译,只是把所有cs文件打包。
还有就是自己的意识和代码质量需要提高。端正心态。最初意识到消散,但是没有去寻找原因,二次消失也没有去找。只有到最后通过别人知道他的消失与垃圾回收有关。
并且更深的认识到 asp.net并不是万能的。很多东西还是需要使用CS程序来进行实现更靠谱,毕竟IIS不是我们这群人开发的,当然可以尝试开发一个IIS。。
有一个经验老道的团队是很重要的。出现问题至少能请教别人。我是自己硬生生抠出来的。
当然有写的不对的地方请各位高手指点,毕竟新手还是需要磨练的!~
我也臭不要脸的发布到首页。。。。嘿嘿。
群:59557329 希望高手进来指点一二
作者:小胖李
出处:http://www.cnblogs.com/minCS/
本文版权归作者和博客园共有,禁止转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
依旧牛逼依旧狂依旧是个小流氓