DevOps工作笔记:Web压力测试
前言
作为服务器管理员,一定会经常会参与服务器的抢修和排错。公司的部署在IIS上的几个Application Pool,每年总有几次宕机时刻。据描述是说,IIS的CPU占用100%,RDP都进不去,只有重启。只能猜测是软件开发里的自锁情况(dead lock),当然也不能排除是其他的程序占用导致。最近也研究了一下IIS里的限制CPU和内存的选项,先占一个坑,下一篇文章来详细介绍。今天的新任务,是要模拟IIS的CPU占用过高情况,下面是解决思路和过程。
方案一
为了让IIS里的Worker Process过载,按照尝试肯定是写一个DDoS脚本不停地访问。我的第一个方案是用PowerShell尝试的,Invoke-Webrequest命令和curl类似,可以在命令行发送访问请求。先打开PowerShell尝试一下访问谷歌:
再用上一篇在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执行文件:
在CMD执行Netling.ConsoleClient.exe文件:
>Netling.ConsoleClient.exe netling <http://localhost:port/> -t <线程数> -d <持续时间>
总结
本文的两个测试方法,为新手管理员们提供了不同的思路。一方面是PowerShell作为强大的自动化工具可以让Windows像Linux一样,进行许多系统层面的操作。另一方面,就是合理利用网络资源,举一反三,拒绝重复造轮子。我原本的目的是为了让IIS过载,为了增加后台的数据库调用时间而部署了Node.js(一开始占用低以为是静态网页太简单不容易过载,于是搭了一个后台)。结果思路错了,借用Netling连静态网页也能轻松到80%。
在IIS的Worker Process(W3wp 线程)过载的时候,应用程序池有哪些设置可以帮我们辅助管理、从而避免服务器资源占用过高而宕机?我们下期讨论!