<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.iis.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Mukhtar&amp;#39;s Blog</title><subtitle type="html" /><id>http://blogs.iis.net/mukhtard/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.iis.net/mukhtard/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.iis.net/mukhtard/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2009-03-16T16:18:00Z</updated><entry><title>Webhosting Performance Tunings For IIS7</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/mukhtard/archive/2009/04/21/webhosting-performance-tunings-for-iis7.aspx" /><id>http://blogs.iis.net/mukhtard/archive/2009/04/21/webhosting-performance-tunings-for-iis7.aspx</id><published>2009-04-21T01:46:19Z</published><updated>2009-04-21T01:46:19Z</updated><content type="html">&lt;p&gt;In a webhosting environment you have hundreds of web sites on a single server. Each web site may not see a significant traffic but when you combine the traffic to all the sites on the server it is quite significant and so it is necessary to tune the server for a webhosting environment.&lt;/p&gt;  &lt;p&gt;Here are a few performance related tunings that you can make to help performance and host more sites on your IIS7 server:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Make sure your server is running a &lt;strong&gt;64-bit&lt;/strong&gt; operating system(OS) thus allowing the OS to address more than 4GB of virtual address space. Run your application pools as &lt;strong&gt;SysWow64&lt;/strong&gt; aka 32-bit on 64-bit windows OS. The advantage in running as SysWow64 is that when compared to the native 64-bit the worker process is light weight – lower memory foot print - allowing more number of worker processes to run at any given time.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Perhaps the most important feature for web hosting environment is the new &lt;strong&gt;dynamicIdleThreshold&lt;/strong&gt; feature in IIS7. In a web hosting environment you can divide all active(running) sites on a web server into two categories: hot and cold. Hot sites are the ones which are frequently visited while the cold ones see very low traffic. When hundreds of worker processes are spawned to serve these sites, available memory on the system starts running thin. At one point the system will run out of memory and the performance of the running active sites will suffer. Furthermore, new requests to new sites will not be honored. The dynamicIdleThreshold feature allows you to work around this problem. This feature keeps track of how much memory is being used on the system, and if it reaches a particular set threshold, it cuts down the idle timeout for the application pools, thus shutting down the worker processes which meet the new lower idle timeout. Let’s see in detail how the feature works:&lt;/p&gt;  &lt;p&gt;By default the feature is disabled, so the default value for dynamicIdleThreshold is 0. The value set for this attribute is interpreted as ‘% of physical memory(RAM) committed’. So, what is committed memory, it is the processes virtual memory allocations for which the OS has allocated(or committed) a page in the physical memory and/or in the page file. The dynamicIdleThreshold feature will kick in when the total committed memory reaches 80% of the value that is set for the dynamicIdleThreshold. Let’s take an example to understand this better:&lt;/p&gt;  &lt;p&gt;Let’s say we have a machine with 2GB physical memory and we set the dynamicIdleThreshold to 150. So the feature will kick in when the total committed memory reaches 80% of 3GB(150% of 2GB) which is 2.4GB. Note that the limit for the committed memory is greater than your physical memory, this limit is typically the sum of the physical memory(excluding the system memory part) and total paging files size on the machine. The following table lists, by how much the idle timeout will be cut, remember that it is windows process activation service(WAS) which is doing the idle timeout chopping:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;table border="1" cellspacing="1" cellpadding="2" width="800"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="400"&gt;&lt;strong&gt;dynamicIdleThreshold percentage reached&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="400"&gt;&lt;strong&gt;Action&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="400"&gt;80%&lt;/td&gt;        &lt;td valign="top" width="400"&gt;WAS sets idle-timeout of all worker processes to ½ of original value.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="400"&gt;85%&lt;/td&gt;        &lt;td valign="top" width="400"&gt;WAS sets idle-timeout of all worker processes to 1/4th of original value.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="400"&gt;90%&lt;/td&gt;        &lt;td valign="top" width="400"&gt;WAS sets idle-timeout of all worker processes to 1/8th of original value.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="400"&gt;95%&lt;/td&gt;        &lt;td valign="top" width="400"&gt;WAS sets idle-timeout of all worker processes to 1/16th of original value.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="400"&gt;100%&lt;/td&gt;        &lt;td valign="top" width="400"&gt;WAS sets idle-timeout of all worker processes to 1/32 of original value.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;On the other side should the committed memory usage fall below 75% of the configured dynamicIdleThreshold value WAS will restore the original idle timeout settings.&lt;/p&gt;  &lt;p&gt;In our internal testing we have seen that setting the dynamicIdleThreshold to around 130 gives optimum performance in a webhosting environment. Use trial and error to find out what will be a good value for your webhosting environment. &lt;/p&gt;  &lt;p&gt;So as you can see from the above description the feature limits the number of worker processes that can be run at any point of time by shutting down the least used processes and thus allowing new requests to be served. Compare this to Windows 2003 where in, once you have run out of memory, new request would see ‘service unavailable’ errors, you have to wait till a worker process times out and shuts down freeing up memory for a new worker processes to be launched. Thus on Windows 2008 if you enable this feature you are pretty much guaranteeing that a new request will be served even if the memory is scarce.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; The new configuration system in IIS7 now supports thousands of sites and application pools that could be used in the web hosting scenario. IIS7’s configuration system is scalable to thousands of sites. You might want to use the new API’s like &lt;strong&gt;Microsoft.Web.Administration&lt;/strong&gt; namespace, &lt;strong&gt;Microsoft.ApplicationHost.WritableAdminManager&lt;/strong&gt; or the&lt;strong&gt; appcmd&lt;/strong&gt; tool to provision hundreds of sites at a time instead of the older API’s like ADSI or WMI which are quite slow when it comes to provisioning new sites and applications.&lt;/p&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3106076" width="1" height="1"&gt;</content><author><name>mukhtard</name><uri>http://blogs.iis.net/members/mukhtard.aspx</uri></author></entry><entry><title>Sample WCAT script files</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/mukhtard/archive/2009/04/02/sample-wcat-script-files.aspx" /><id>http://blogs.iis.net/mukhtard/archive/2009/04/02/sample-wcat-script-files.aspx</id><published>2009-04-02T01:58:00Z</published><updated>2009-04-02T01:58:00Z</updated><content type="html">&lt;P&gt;At times you would want to make sure that you have the correct WCAT script files to verify that your WCAT setup is working correctly.&lt;/P&gt;
&lt;P&gt;A copy of simple client scenario file aka client.ubr requesting the default document is as follows:&lt;/P&gt;
&lt;DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px"&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;scenario
{
    name    = &lt;SPAN style="COLOR: #006080"&gt;"default_doc"&lt;/SPAN&gt;;

    warmup      = 30;
    duration    = 90;
    cooldown    = 30;

    &lt;SPAN style="COLOR: #0000ff"&gt;default&lt;/SPAN&gt;
    {
        setheader
        {
            name    = &lt;SPAN style="COLOR: #006080"&gt;"Connection"&lt;/SPAN&gt;;
            value   = &lt;SPAN style="COLOR: #006080"&gt;"keep-alive"&lt;/SPAN&gt;;
        }
        setheader
        {
            name    = &lt;SPAN style="COLOR: #006080"&gt;"Accept"&lt;/SPAN&gt;;
            value   = &lt;SPAN style="COLOR: #006080"&gt;"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, */*"&lt;/SPAN&gt;;
        }
        setheader
        {
            name    = &lt;SPAN style="COLOR: #006080"&gt;"Accept-Language"&lt;/SPAN&gt;;
            value   = &lt;SPAN style="COLOR: #006080"&gt;"en-us"&lt;/SPAN&gt;;
        }
        setheader
        {
            name    = &lt;SPAN style="COLOR: #006080"&gt;"User-Agent"&lt;/SPAN&gt;;
            value   = &lt;SPAN style="COLOR: #006080"&gt;"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0"&lt;/SPAN&gt;;
        }
        setheader
        {
            name    = &lt;SPAN style="COLOR: #006080"&gt;"Accept-Encoding"&lt;/SPAN&gt;;
            value   = &lt;SPAN style="COLOR: #006080"&gt;"gzip, deflate"&lt;/SPAN&gt;;
        }
        setheader
        {
            name    = &lt;SPAN style="COLOR: #006080"&gt;"Host"&lt;/SPAN&gt;;
            value   = server();
        }
        version     = HTTP11;
        statuscode  = 200;
        close       = ka;
    }

    transaction
    {
        id      = &lt;SPAN style="COLOR: #006080"&gt;"default_doc"&lt;/SPAN&gt;;
        weight  = 100;

        request
        {
            url = &lt;SPAN style="COLOR: #006080"&gt;"/"&lt;/SPAN&gt;;
        }
    }
}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;A very basic WCAT settings file aka settings.ubr file querying just one counter on the server would look like:&lt;/P&gt;
&lt;DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px"&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;settings
{
    counters
    {
        interval = 10;
        counter = &lt;SPAN style="COLOR: #006080"&gt;"Memory\\Available MBytes"&lt;/SPAN&gt;;
    }
}&lt;/PRE&gt;&lt;/DIV&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3056462" width="1" height="1"&gt;</content><author><name>mukhtard</name><uri>http://blogs.iis.net/members/mukhtard.aspx</uri></author><category term="WCAT SAMPLE SCRIPT" scheme="http://blogs.iis.net/mukhtard/archive/tags/WCAT+SAMPLE+SCRIPT/default.aspx" /></entry><entry><title>Troubleshooting WCAT(Web Capacity Analysis Tool) Problems</title><link rel="alternate" type="text/html" href="http://blogs.iis.net/mukhtard/archive/2009/03/16/troubleshooting-wcat-web-capacity-analysis-tool-problems.aspx" /><id>http://blogs.iis.net/mukhtard/archive/2009/03/16/troubleshooting-wcat-web-capacity-analysis-tool-problems.aspx</id><published>2009-03-16T15:18:00Z</published><updated>2009-03-16T15:18:00Z</updated><content type="html">&lt;P&gt;The best approach to figure out what is wrong with your WCAT setup and scripts is to run it manually which typically involves:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Running the WCAT controller &lt;/LI&gt;
&lt;LI&gt;Running one or more instances of WCAT client(s), the exact number is specified in the WCAT controller command in step 1 above &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The advantage with this approach is that you would see errors ,if any, in the command window(s) and not miss them because of the command window closing down which is the case when running the .wsf script provided with the download.&lt;/P&gt;
&lt;P&gt;Let's get into some details:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Running the WCAT controller&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;wcctl.exe is the WCAT controller executable, and a typical command for the controller would look as:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px"&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;wcctl.exe -t client.ubr -f settings.ubr -s mywebserver -v 10 -c 1 -o wcat_log.xml -x&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Some of the switches in the above command can also be specified in the WCAT settings file - settings.ubr. If a switch is specified in the command line it will override the one in the settings file. Let's briefly look at the arguments in the above command:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;-t&amp;nbsp;&amp;nbsp;&amp;nbsp; client scenario file containing the URL's that will be requested by the client(s), you can specify an explicit or a relative path for the file&lt;/P&gt;
&lt;P&gt;-f&amp;nbsp;&amp;nbsp;&amp;nbsp; controller settings file, typically will specify the performance counters that need to be measured on the server, can also specify client scenario file to use, server to which request are to be send etc, you can specify an explicit or a relative path for the file&lt;/P&gt;
&lt;P&gt;-s&amp;nbsp;&amp;nbsp;&amp;nbsp; web server to be stressed&lt;/P&gt;
&lt;P&gt;-v&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual clients per physical client to be used&lt;/P&gt;
&lt;P&gt;-c&amp;nbsp;&amp;nbsp;&amp;nbsp; number of physical clients used to stress the web server&lt;/P&gt;
&lt;P&gt;-o&amp;nbsp;&amp;nbsp;&amp;nbsp; output WCAT log file that gets generated at the end of the test&lt;/P&gt;
&lt;P&gt;-x&amp;nbsp;&amp;nbsp;&amp;nbsp; generate extended information, if you skip this switch the performance counters will not show up in the output log file even if you have them specified in the controller settings file, you will also miss the 'Server Information' section in the report, if you are stressing a Linux server specifying this switch will have no effect, meaning it will not collect the extended information&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Running the WCAT client&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;wcclient.exe is the WCAT client executable, its' job is to make requests that are specified in the client scenario file, typically you would run it as follows:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px"&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;wcclient.exe wcat_controller_machine_name&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As you can see wcclient.exe takes only one argument(unless you are stressing over IPV6 in which case you have to also specify the –i switch), this is the name of the WCAT controller machine.&lt;/P&gt;
&lt;P&gt;Depending on the number of physical clients you have specified for the controller command, you may have to run the above command that many times. For example if we would have specified -c 2 for the wcctl command, we would have to run wcclient command two times, ideally from two physical client machines. If you are running multiple instances of the client from individual physical client machines I would run a simple &lt;EM&gt;batch&lt;/EM&gt; script as follows on the client machines so that I don’t have to run the WCAT client from these individual machines every time I run the controller:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px"&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;:LOOP
timeout -t 5
C:\wcat6.1\wcclient.exe wcat_controller_machine_name
goto LOOP&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Make sure the path is valid on your client machines. Once your WCAT client connects to the controller, you should either see an error in both the client and controller command windows or the test should run.&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=3011496" width="1" height="1"&gt;</content><author><name>mukhtard</name><uri>http://blogs.iis.net/members/mukhtard.aspx</uri></author><category term="Troubleshooting WCAT" scheme="http://blogs.iis.net/mukhtard/archive/tags/Troubleshooting+WCAT/default.aspx" /></entry></feed>