1 在IIS中找到这个站点所用的程序池,点击“高级设置…”
2 回收——固定时间间隔(分钟) 改为 0
3 回收——虚拟/专用内存限制(KB) 改为 0
4 进程模型——闲置超时(分钟) 改为 0 那一定是IIS的应用程序池回收的机制在作怪了。因为IIS的默认设置里面,如果一个站点所处的应用程序池超过一段时间没有被访问或者请求,IIS就会自动回收这个程序池,并且把进程杀掉。那进程里面的线程肯定也活不下来了。
但是我们可以通过设置应用程序池参数使其不会被简单的自动回收(有些情况无法避免,比如热部署的站点,错误数量超限等等)
IIS可以设置定时自动回收,默认回收是1740分钟,也就是29小时。IIS自动回收相当于服务器IIS重启,应用程序池内存清空,所有数据被清除,相当于IIS重启,在度量快速开发平台服务器端,为了减小数据库负担,内存中暂存了很多信息,不适合频繁的回收,因为回收会造成服务器端所有存在内存中的数据丢失,如果没有及时保存到数据库中,可能导致程序出现问题。而如果系统使用高峰时期,并不适合回收,回收可能导致几十秒IIS无响应,对于正在工作的人员来说,是一种很不好的体验,会以为是网络或者掉线等问题。因此,基于以上的分析,我们需要设置IIS在指定的时间内定时回收。
IIS应用程序池回收,找到相应的应用程序池并点击高级设置,就可以看到回收的相关设置(本文以windows2008R2下的IIS7为例,Windows2012类似)。
(图1)
发生配置更改时禁止回收:如果为True,应用程序池在发生配置更改时将不会回收。
固定时间间隔(分钟):超过设置的时间后,应用程序池回收,为0意味着应用程序池不会按固定间隔回收。系统默认设置的时间是1740(29小时)。
禁用重叠回收:如果为true,将发生应用程序池回收,以便在创建另一个工作进程之前退出现有工作进程。
请求限制:应用程序池在回收之前可以处理的最大请求数。如果值为0,则表示应用程序池可以处理的请求数没有限制。
生成回收事件日志条目:每发生一次指定的回收事件时便产生一个事件日志条目,里面的明细设置不一一介绍。
根据度量平台服务端配置情况看,IIS默认设置的1740分钟回收进程的策略并不合理,因为每1740分钟回收,在过程中可能就处于用户使用系统的高峰时段,为避免可能在高峰时段引起非可控问题,我们建议在每周六深夜(例如晚上1点,2点)进行IIS回收。
如果我们在IIS应用程序池的高级设置中,进行回收设置,那么只有两种方式进行,一种是固定时间间隔,一种是手动回收。固定时间间隔设置,并不太好在深夜设置,以保证每周周六深夜执行回收。我们推荐采用windows “任务计划程序”配置一个 *** 作系统定时任务执行脚本程序来实现IIS回收,设置方便,也可以灵活调整。 要通过脚本执行IIS的功能,需要在IIS安装配置的时候,勾选上管理工具中的“IIS管理脚本和工具”(见下图)。
用vbs脚本及批处理文件,结合任务计划程序,保证在每周六深夜1点执行IIS回收。
Recyclepool.vbs 文件内容:
appPoolName = WScript.Arguments(0)
Set oWebAdmin = GetObject("winmgmts:root\WebAdministration")
Set oAppPool = oWebAdmin.Get("ApplicationPool.Name='" + appPoolName + "'")
oAppPool.Recycle
set fso=createobject("scripting.filesystemobject")
if (fso.fileexists("d:\appPool\recycleIISPool.log")) then
'1-forreading,2-forwriting,8-appending
set file=fso.opentextfile("d:\appPool\recycleIISPool.log",8,ture)
else
set file=fso.createtextfile( "d:\appPool\recycleIISPool.log",8,ture)
end if
'write(x)写入x个字符,writeline写入换行,writeblanklines(n)写入N个空行
file.writeline now&" 应用程序池“"&appPoolName &"”已经回收成功。"
file.close
Recyclepool.bat文件内容:
cscript D:\appPool\recyclepool.vbs platweb
用vbs脚本及批处理文件,结合任务计划程序,保证在每周六深夜1点执行IIS回收。
成功用windows计划任务解决IIS定时回收问题。
方法一
using System
using System Data
using System Configuration
using System Collections
using System Web
using System Web Security
using System Web SessionState
using System Timers
using System Net
using System IO
using System Text
using System Threading
namespace
{
public class Global : System Web HttpApplication
{
protected void Application_Start(object sender EventArgs e)
{
//定义定时器
System Timers Timer myTimer = new System Timers Timer( )
myTimer Elapsed += new ElapsedEventHandler(myTimer_Elapsed)
myTimer Enabled = true
myTimer AutoReset = true
}
void myTimer_Elapsed(object source ElapsedEventArgs e)
{
try
{
Log SaveNote(DateTime Now ToString( yyyy MM dd HH:mm:ss ) + :AutoTask is Working! )
YourTask()
}
catch (Exception ee)
{
Log SaveException(ee)
}
}
void YourTask()
{
//在这里写你需要执行的任务
}
protected void Application_End(object sender EventArgs e)
{
Log SaveNote(DateTime Now ToString( yyyy MM dd HH:mm:ss ) + :Application End! )
//下面的代码是关键 可解决IIS应用程序池自动回收的问题
Thread Sleep( )
//这里设置你的web地址 可以随便指向你的任意一个aspx页面甚至不存在的页面 目的是要激发Application_Start
string url =
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest Create(url)
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest GetResponse()
Stream receiveStream = myHttpWebResponse GetResponseStream()//得到回写的字节流
}
}
}
原理 Global asax 可以是中应用程序或会话事件处理程序 我们用到了Application_Start(应用程序开始事件)和Application_End(应用程序结束事件) 当应用程序开始时 启动一个定时器 用来定时执行任务YourTask()方法 这个方法里面可以写上需要调用的逻辑代码 可以是单线程和多线程 当应用程序结束时 如IIS的应用程序池回收 让去访问当前的这个web地址 这里需要访问一个aspx页面 这样就可以重新激活应用程序 Log类是一个记录日志的一个类 下面是测试时生成的日志信息
================================================================
: : :AutoTask is Working!
: : :AutoTask is Working!
: : :AutoTask is Working!
: : :Application End!
: : :AutoTask is Working!
: : :AutoTask is Working!
从日志中发现 当手动回收IIS的应用程序池之后 计划任务还在执行 说明我们的目的达到了
如果将Application_End中的代码注释掉 会发现Application End之后 计划任务停止工作了 如下
================================================================
: : :AutoTask is Working!
: : :AutoTask is Working!
: : :AutoTask is Working!
: : :Application End!
局限性 可以解决应用程序池自动或者手动回收 但是无法解决IIS重启或者web服务器重启的问题 当然这种情况出现的时候不多 而且如果有人访问你的网站的时候 又会自动激活计划任务了
方案二
<%@ Application Language= C# %>
<%@ import Namespace= System IO %>
<script runat= server >
void Application_Start(object sender EventArgs e)
{
// 在应用程序启动时运行的代码
System Timers Timer myTimer = new System Timers Timer( )
myTimer Elapsed += new System Timers ElapsedEventHandler(OnTimedEvent)
myTimer Interval =
myTimer Enabled = true
}
void Application_End(object sender EventArgs e)
{
// 在应用程序关闭时运行的代码
}
void Application_Error(object sender EventArgs e)
{
// 在出现未处理的错误时运行的代码
}
void Session_Start(object sender EventArgs e)
{
// 在新会话启动时运行的代码
}
void Session_End(object sender EventArgs e)
{
// 在会话结束时运行的代码
// 注意: 只有在 nfig 文件中的 sessionstate 模式设置为
// InProc 时 才会引发 Session_End 事件 如果会话模式设置为 StateServer
// 或 SQLServer 则不会引发该事件
}
private static void OnTimedEvent(object source System Timers ElapsedEventArgs e)
{
//间隔时间执行某动作
//指定日志文件的目录
string fileLogPath = AppDomain CurrentDomain BaseDirectory + SystemLog
string fileLogName = SoftPrj_CN_ + DateTime Now ToLongDateString() + _log txt
//定义文件信息对象
FileInfo finfo = new FileInfo(fileLogPath + fileLogName)
//创建只写文件流
using (FileStream fs = finfo OpenWrite())
{
//根据上面创建的文件流创建写数据流
StreamWriter strwriter = new StreamWriter(fs)
//设置写数据流的起始位置为文件流的末尾
strwriter BaseStream Seek( SeekOrigin End)
//写入错误发生时间
strwriter WriteLine( 发生时间: + DateTime Now ToString())
//写入日志内容并换行
//strwriter WriteLine( 错误内容: + message)
strwriter WriteLine( 错误内容: )
//写入间隔符
strwriter WriteLine( )
strwriter WriteLine()
//清空缓冲区内容 并把缓冲区内容写入基础流
strwriter Flush()
//关闭写数据流
strwriter Close()
fs Close()
}
}
</script>
方案三
<%@ Application Language= C# %>
<%@ Import Namespace= System IO %>
<%@ Import Namespace= System Threading %>
<script RunAt= server >
string LogPath
Thread thread
void WriteLog()
{
while (true)
{
StreamWriter sw = new StreamWriter(LogPath true Encoding UTF )
sw WriteLine(thread Name + : + DateTime Now ToString())
sw Close()
Thread CurrentThread Join( * )//阻止 秒
}
}
void Application_Start(object sender EventArgs e)
{
LogPath = HttpContext Current Server MapPath( log txt ) //在应用程序启动时运行的代码
thread = new Thread(new ThreadStart(WriteLog))
thread Name = 写登录日志线程
thread Start()
}
void Application_End(object sender EventArgs e)
{
// 在应用程序关闭时运行的代码
}
void Application_Error(object sender EventArgs e)
{
// 在出现未处理的错误时运行的代码
}
void Session_Start(object sender EventArgs e)
{
// 在新会话启动时运行的代码
}
void Session_End(object sender EventArgs e)
{
// 在会话结束时运行的代码
// 注意: 只有在 nfig 文件中的 sessionstate 模式设置为
// InProc 时 才会引发 Session_End 事件 如果会话模式设置为 StateServer
// 或 SQLServer 则不会引发该事件
}
lishixinzhi/Article/program/net/201311/13724
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)