日期:2014-05-18  浏览次数:21009 次

如何回收IIS应用程序池?
不是使用IIS信息管理器,是用编程的方式

IIS6中的应用程序池要通过编程的方式回收,用ADSI可以吗,如何操作?这样的代码百度都搜不到啊?不要建立、删除等操作,这些都实现了,只要回收,或者设置应用程序池其他属性,如cpu占用资源控制等等。

另:Microsoft.Web.Administration类库是否只能操作IIS7而不能操作IIS6或5?
Microsoft.Web.Administration.dll是否只存在于WIN2008?我安装了vs2008+sp1,都没有找到这个文件。请大家帮忙!谢谢!


------解决方案--------------------
C# code

//添加应用程序池空间引用
using System.DirectoryServices;
using System.Text; 
using System.Text.RegularExpressions; 
using System.Diagnostics; 
using System.Management;

private void button6_Click(object sender, System.EventArgs e)
  {
   //如果应用程序池不存在,则会报错系统找不到指定路径
   string AppPoolName=this.textBox1.Text.Trim();
   string method="Start";

   try
   {    
      DirectoryEntry appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
      DirectoryEntry findPool = appPool.Children.Find(AppPoolName,"IIsApplicationPool");
      findPool.Invoke(method,null);
      appPool.CommitChanges();
      appPool.Close();
    MessageBox.Show("应用程序池名称启动成功","启动成功"); 
   }
   catch(Exception ex)
   {
    MessageBox.Show(ex.Message,"启动失败");      
   }

  }

  private void button7_Click(object sender, System.EventArgs e)
  {
   //如果应用程序池当前状态为停止,则会发生异常报错
   string AppPoolName=this.textBox1.Text.Trim();
   string method="Recycle";

   try
   {    
      DirectoryEntry appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
      DirectoryEntry findPool = appPool.Children.Find(AppPoolName,"IIsApplicationPool");
      findPool.Invoke(method,null);
      appPool.CommitChanges();
      appPool.Close();
    MessageBox.Show("应用程序池名称回收成功","回收成功"); 
   }
   catch(Exception ex)
   {
    MessageBox.Show(ex.Message,"回收失败");      
   }  
  }

  private void button8_Click(object sender, System.EventArgs e)
  {
   string AppPoolName=this.textBox1.Text.Trim();
   string method="Stop";

   try
   {    
      DirectoryEntry appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
      DirectoryEntry findPool = appPool.Children.Find(AppPoolName,"IIsApplicationPool");
      findPool.Invoke(method,null);
      appPool.CommitChanges();
      appPool.Close();
    MessageBox.Show("应用程序池名称停止成功","停止成功"); 
   }
   catch(Exception ex)
   {
    MessageBox.Show(ex.Message,"停止失败");      
   }  
  }

------解决方案--------------------
把程序对应的IIS应用程序池回收一下就好了。

可是为什么会出现这个原因呢?还有为什么回收一下就好了呢?回收做了些什么?
出现的原因
在网上搜索了一翻,发现主要是一下几个问题,当然还有其他原因
1).Framework的问题,例如1.0和2.0版本

2)aspnet_wp.exe 问题

3)安全更新程序 (KB886903)


可惜我们服务器出现的问题都不是以上几点引起的,经过我的分析认为是写的很烂很烂的程序占用了大量的资源最后导致内存泄漏,导致IIS的进程当掉了。可惜了程序我是没办法改,都是别人写的,也不会改。不过我不可能每次出现这个问题就登陆到远程服务器上去回收一次吧,所以只有让他自动回收了。

自动回收有好几种方式,也不知道那一种比较适合,而且回收工作进程是会把保存在内存里的Session清空,造成用户需要重新登陆的问题,所以自动回收要越少越好,以保证不会因为其中的一个用户使用了那个很烂的程式导致其他的用户都要重新登陆。

如果用了状态服务器或者是把Session保存到了数据库中去的程序自动回收后肯定是没有任何影响的,请求也不会中断还是一样继续运行,只是换了个工作进程继续为客户端工作,客户端是感觉不到的,当初没有为了方便没有把Session保存到数据库真是失策!

根据运行时间
系统默认是1740分钟,也就是29个小时,这个不是很好控制,建议不用,也就是去掉那个勾。

请求数目
这个要看具体的情况了。如果只有10个请求,可是有5个都在请求那个比较占资源的页面(可能是统计年度报表之类),这个时候就会出现进程当掉的情况,如果请求有1000个可是一个也没运行比较占资源的页面,这个时候进程肯定是很正常的,所以根据请求的数目来决定也不符合实际需要。

计划的时间
这个其实很好,不过具体什么时间回收好呢?通常我们都是设置上班前和下班后回收,这个时候回收是有必要的,不过针对出现随时可能出现是高内存占用并不是很适用。

内存(虚拟内存或已使用的内存)
这个针对出现内存问题引起的进程当掉实在太合适了,不过设置多大的值比较好是一个很重要的问题,我是根据每次出现问题时进程是实际占用情况决定的。我们的服务器内存是2G,通常其他的一些服务会占用掉600多M,我发现有每次进程都是到1G多的时候当掉,所以设置了最大使用内存为1000M的时候自动回收,设置后一直都没出现问题了。要查看进程的占用直接用windows任务管理器就好,值不能太小了,否则如果访问量都很大超过这个值的时候也会自动回收,这个就很没必要了。一定要多多观察进程的实际占用情况再做决定。
在IIS的配置文件里面如果配置了IIsApplicationPools节点的LogEventOnRecycle属性,每次回收的时候IIS的日志文件会根据LogEventOnRecycle属性的值纪录下相关的信息,也个也是设置自动回收时的一个重要参考,不过由于这个日志文件只能看几个小时以前的纪录,当前的纪录要几个小时后才写进去,所以看起来不方便,郁闷! 


现在暂时根据最大占用内存自动收回以前的问