DevOps工作笔记:Web压力测试

前言

作为服务器管理员,一定会经常会参与服务器的抢修和排错。公司的部署在IIS上的几个Application Pool,每年总有几次宕机时刻。据描述是说,IIS的CPU占用100%,RDP都进不去,只有重启。只能猜测是软件开发里的自锁情况(dead lock),当然也不能排除是其他的程序占用导致。最近也研究了一下IIS里的限制CPU和内存的选项,先占一个坑,下一篇文章来详细介绍。今天的新任务,是要模拟IIS的CPU占用过高情况,下面是解决思路和过程。

方案一

为了让IIS里的Worker Process过载,按照尝试肯定是写一个DDoS脚本不停地访问。我的第一个方案是用PowerShell尝试的,Invoke-Webrequest命令和curl类似,可以在命令行发送访问请求。先打开PowerShell尝试一下访问谷歌:

HTTP返回的状态、内容(www.google.com)

再用上一篇在81端口映射的Node.js网站试一下:

PS C:\Users\Administrator> Invoke-Webrequest 10.1.12.182:81


StatusCode        : 200
StatusDescription : OK
Content           : <!DOCTYPE html>
                    <head>
                      <title>Employee Management Application</title>
                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
                      <style>
                      ...
RawContent        : HTTP/1.1 200 OK
                    Keep-Alive: timeout=5
                    Content-Type: text/html; charset=utf-8
                    ETag: W/"b13-SQOfsEZKVooYOG0scaiqEtSiGK4"
                    Server: Microsoft-IIS/10.0
                    X-Powered-By: Express,ASP.NET
                    Date: Thu, 22 Dec ...
Forms             : {}
Headers           : {[Keep-Alive, timeout=5], [Content-Type, text/html; charset=utf-8], [ETag, W/"b13-SQOfsEZKVooYOG0scaiqEtSiGK4"], [Server,
                    Microsoft-IIS/10.0]...}
Images            : {}
InputFields       : {}
Links             : {@{innerHTML=; innerText=; outerHTML=<A class="fa fa-angle-down" href="/desid"></A>; outerText=; tagName=A; class=fa
                    fa-angle-down; href=/desid}, @{innerHTML=; innerText=; outerHTML=<A class="fa fa-angle-up" href="/ascid"></A>; outerText=;
                    tagName=A; class=fa fa-angle-up; href=/ascid}, @{innerHTML=; innerText=; outerHTML=<A class="fa fa-angle-down"
                    href="/desFirstName"></A>; outerText=; tagName=A; class=fa fa-angle-down; href=/desFirstName}, @{innerHTML=; innerText=;
                    outerHTML=<A class="fa fa-angle-up" href="/ascFirstName"></A>; outerText=; tagName=A; class=fa fa-angle-up;
                    href=/ascFirstName}...}
ParsedHtml        : System.__ComObject
RawContentLength  : 2835

最简单的方法就是把这个命令放在一个while(1)或者while($true)里循环,然而更有效的方法则是利用Powershell的多线程实现。需要使用到RunSpacePool工具(默认自带),初始化步骤如下:

$maxConcurrentJobs = 10 #线程数量
$Runspace = [runspacefactory]::CreateRunspacePool(1,$maxConcurrentJobs) #新建线程池并指定线程数量
$Runspace.Open()

接下来就是在上面的池里添加PowerShell线程并执行之前的Invoke-Webrequest命令,十个线程同时进行的话理论上是要比我们之前的快十倍:

$content = Get-Content -Path "C:\Users\Administrator\Documents\urls.txt" #URL单独存在txt文件
while($true) {
    foreach ($url in $content) {
        $ps = [powershell]::Create()
        $ps.RunspacePool = $Runspace
        [void]$ps.AddCommand("Invoke-WebRequest").AddParameter("UseBasicParsing",$true).AddParameter("Uri",$url)
        [void]$ps.BeginInvoke() #只需要发送请求,不需要输出接收
    }
}
执行结果

可以看到执行以后Node.js和IIS进程的CPU占用确实可以提升,但是PowerShell的占用却更多,不太满足之后的测试需求。下面就要介绍第二个办法,使用开源的工具Netling。

方案二

Netling是用.Net开发的测试工具,我尝试几款之后发现这个占用CPU特别低,但是稍微用两个线程就能使IIS的CPU占用到70%。但是下载完以后得在Visual Studio里编译一下才有.exe执行文件:

在Visual Studio里右键sln文件Build编译

在CMD执行Netling.ConsoleClient.exe文件:

>Netling.ConsoleClient.exe netling <http://localhost:port/> -t <线程数> -d <持续时间>

使用两个线程占用很快超过40%

总结

本文的两个测试方法,为新手管理员们提供了不同的思路。一方面是PowerShell作为强大的自动化工具可以让Windows像Linux一样,进行许多系统层面的操作。另一方面,就是合理利用网络资源,举一反三,拒绝重复造轮子。我原本的目的是为了让IIS过载,为了增加后台的数据库调用时间而部署了Node.js(一开始占用低以为是静态网页太简单不容易过载,于是搭了一个后台)。结果思路错了,借用Netling连静态网页也能轻松到80%。

在IIS的Worker Process(W3wp 线程)过载的时候,应用程序池有哪些设置可以帮我们辅助管理、从而避免服务器资源占用过高而宕机?我们下期讨论!

发布于 2022-12-23 01:05・IP 属地加拿大