• 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上的运行:

    image

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

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

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

    欢迎大家扫描下面二维码成为我的客户,为你服务和上云

  • 相关阅读:
    C# ListView应用
    C# 使用System.Speech 进行语音播报和识别
    支付宝支付-扫码支付详解
    使用git提交项目到码云
    C# byte[]数组和string的互相转化 (四种方法)
    C#中字节数组byte[]、图片image、流stream,字符串string、内存流MemoryStream、文件file,之间的转换
    C# 结构体和List<T>类型数据转Json数据保存和读取
    对 JSON 数据进行序列化和反序列化
    win10与虚拟机fedora14使用samba文件共享
    serialVersionUID, ObjectInputStream与ObjectOutputStream类,Serializable接口,serialVersionUID的作用和用法
  • 原文地址:https://www.cnblogs.com/shanyou/p/2819178.html
Copyright © 2020-2023  润新知