FileSystemWatcher 导致Mono ASP.NET应用程序CPU使用率比较高

大家都知道ASP.NET 网站应用程序(WebSite)可以自动检测到你的ASP.NET应用的文件修改,其中要使用到的就是监视磁盘上的文件/目录的更改,以便应用程序可以采取它认为必要文件创建/删除/修改事件的反应中的任何步骤的FileSystemWatcher 类

Mono的 FileSystemWatcher实现尽了最大的努力适应各种环境(Linux/Windows/*BSD),在各种操作系统环境下执行其分配的任务,在Unix环境下支持以下后端的系统:

  • FAM
  • kevent (BSD*/MacOSX only)
  • gamin
  • inotify (Linux only)
  • Managed watcher

其中,假设您运行 Linux(内核2.6.13以上), inotify是一种首选的后端机制因为它需要对用户态应用程序的一部分,他不是使用轮询而是使用 Linux 内核的通知机制 (在我们的例子,Mono的运行库)。然而,它需要 Linux 内核来支持机制。

如果你的内核不支持inotify,Mono将尝试使用FAM和gamin 这样的用户态的应用程序来监测文件系统的文件/目录的更改,然后通知到Mono运行时,这样效率就大打折扣了,性能就很糟糕了。如果Mono 都无法检测到inotify,Fam以及gamin,mono将使用最后一个选项Managed watcher,此监测程序在托管代码中实现,并为监测、 轮询更改所选文件/目录上的文件系统使用一个单独的线程。由于应用程序可能 (和在 ASP.NET 的情况下有时不会)递归查看目录,它可能会非常昂贵的情况,需要检查更改为一大组的文件。每个运行的变化检测需要检查文件/目录是否存在 (以防托管观察程序这些都是两个 stat (2) 调用),然后检查更改的文件元数据 (大小、 修改时间等),生成一个事件。大约每750ms发生一次,并给服务器的 CPU 上带来大量的负载,导致CPU飙升。

解决方法也很简单,如果你可以的话的关闭文件系统监测 (这意味着您的ASP.NET应用程序将不自动重新启动修改 Web.config 时,不会重新编译文件,如果您修改代码隐藏.cs 或.aspx、.ascx 文件等)。Mono支持MONO_MANAGED_WATCHER环境变量 设置为值disable,减轻您的应用程序做上面所述的文件系统轮询事务,既然是生产环境,就不会有什么经常性更新关闭这个特性也不会有大的影响,还可以节约后台的线程资源 。

在linux上跑ASP.NET网站,有时cpu会出现占用率比较高的情况,过段时间它又正常了,在VPS中,这样情况出现的机率更大,处理方法: 1、不必管它,它自然会降下来,只是等的时间要长一点,而且有可能过段时间又出现,原因就是上述说明,如果是VPS或者云主机上出现这个问题,你一定得好好的分析下原因,是不是就是有这个特性引起的,如果是就把他关掉; 2、使用Jexus 跑ASP.NET网站,在jws.start/jws.restart两个文件中,插一句:export MONO_MANAGED_WATCHER=disable,禁止ASP.NET自动检测,当然副作用是:你修改源码后,得手工重启这个网站。

3、使用Apache的 Mod_mono 使用命令 MonoSetEnv [server_alias] MONO_MANAGED_WATCHER=disable

可以使用下面的代码检测你的Linux服务器上使用的是哪个FileSystemWatcher 实现

using System;   
using System.Collections.Generic;    
using System.Linq;    
using System.Text;    
using System.IO;    
using System.Reflection;
namespace FileWatchDetect   
{    
    class Program    
    {    
        static void Main(string[] args)    
        {    
            object watcher = new FileSystemWatcher().GetType()    
                .GetField("watcher", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);    
 
            Console.WriteLine(watcher != null ? watcher.GetType().FullName : "unknown");    
            Console.Read();    
        }    
    }    
}

下面的结果是在Windows Azure上的一台OpenSuse 12.0.4上的运行:

Inotify: 高效、实时的Linux文件系统事件监控框架

使用FAM来监视linux文件系统变化

Tip: Mono ASP.NET application burning CPU in idle state - FileSystemWatcher

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

将 .NET Core 项目打一个最简单的 NuGet 源码包,安装此包就像直接把源码放进项目一样

2018-06-20 01:22

1392
来自专栏令仔很忙

手把手教你----使用Nuget管理自己的项目库

官网上的解释:NuGet is the package manager for the Microsoft development platform in...

1621
来自专栏ASP.NETCore

.NET Core第三方开源Web框架YOYOFx

YOYOFx是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台。

4624
来自专栏编程

如何在Dynamo中创建UI

我这里说的UI指的是User Interface(用户界面),说白了就是创建窗口,让我们和Dy进行交互。效果大概是这样: ? 接下来我会教大家编写一个简单的界面...

34310
来自专栏程序员与猫

ASP.NET Core依赖注入解读&使用Autofac替代实现

标签: 依赖注入 Autofac ASPNETCore 1. 前言 关于IoC模式(控制反转)和DI技术(依赖注入),我们已经见过很多的探讨,这里就不再赘述了。...

3538
来自专栏晓晨的专栏

ASP.NET Core 使用Redis存储Session

1565
来自专栏张善友的专栏

发布基于Orchard Core的友浩达科技官网

2018.9.25 日深圳市友浩达科技有限公司发布基于Orchard Core开发的官网 http://www.weyhd.com/。 本篇文章为你介绍如何基于...

5774
来自专栏菩提树下的杨过

64位IIS(IIS6/IIS7)上跑Asp + Jet.Oledb的设置要点

由于64位操作系统不支持Microsoft OLE DB Provider for Jet驱动程序,也不支持更早的Microsoft Access Driver...

2128
来自专栏草根专栏

Identity Server 4 - Hybrid Flow - MVC客户端身份验证

2484
来自专栏FreeBuf

Office CVE-2017-8570远程代码执行漏洞复现

CVE-2017-8570漏洞是一个逻辑漏洞,利用方法简单,影响范围广。由于该漏洞和三年前的SandWorm(沙虫)漏洞非常类似,因此我们称之为“沙虫”二代漏洞...

4615

扫码关注云+社区

领取腾讯云代金券