Thursday, January 30, 2014

Small advice about CentOS 6 on Hyper-V

Try using the latest CentOS 5.9 or 6.4 since it has all the drivers build.
...and install the hypervkvpd package instead of the Linux Integration Services!
Just run sudo yum install hypervkvpd on the command line.

Notes from the CentOS counterpart...
Release Notes for Red Hat Enterprise Linux 5.9
Release Notes for Red Hat Enterprise Linux 6.4

...which are now close friends: CentOS Project joins forces with Red Hat :-)

IIS7 Output Cache

The wow effect...

Today while going through a performance report of a IIS7 Web server I saw a strange thing: the Network Interface Bytes/sec performance line was far apart from Web Services Bytes/sec counter.

Why is this strange? Well this particular server is just used for IIS hosting, so any incoming traffic would be HTTP traffic, which would imply that the lines should match...

The first thing checked was the traffic with a network sniffer and verified if all was really HTTP traffic coming to IIS, which it checked out: the majority of the traffic was Web.

The second thing checked was the healthiness of the performance counters. I've seen situations where performance counters just gone crazy! But this wasn't the occasion.

Without any obvious closure, I came to think of a third hypothesis: was IIS not counting the traffic made to the cached traffic on the performance counter?

Then I decided to setup a small lab on my desktop to give a try on replicating the last scenario.

The ingredients to a trial

  • Setup a virtual machine with Windows 2008 R2 and IIS 7.5 installed
  • Install HTTP request generator on the host machine: after some browsing on the Internet I went with JMeter.
  • Configure a small application with IIS Output Cache enabled: just followed the Walkthrough Guide written by Saad Laki 
After that, I only had to open Performance Monitor on the virtual server and add the counters in question (and also % Processos Time)

Right on the first try (IIS Output Cache active with Kernel mode) I've got the confirmation:
The performance traffic showed the traffic on the network interface rising, while the traffic on the Web Service just dropped to flat line. On J;Meter side, the effect was a around 3 to 4 millisecond response time:


Then I've decided to test the opposite case by removing the IIS Output Cache configuration, and the result was the recovery of the Web Service Bytes/sec line along the Network Interface performance line, and also a very big penalty on the CPU processing time...


On the JMeter side, the response time just when sky-high to the 200 miliseconds...  

My short conclusion


So why the Web Service Bytes/sec performance counter doesn't increment with IIS output cache on kernel mode?

To answer this, you must first know how the IIS architecture works: there is a kernel driver before the IIS user process called HTTP.SYS. This intercepts the request and redirects the request to the WWW service and this redirects to Worker Process (usually a ASP.Net worker process). Take a look on the diagram from IIS 7 architecture description taken from IIS.net site.


With the IIS output kernel cache active, a cached request goes from flow 1 to 8 without passing by the remaining components, and therefore reducing the overhead associated with a complete end-to-end request.

Since the Performance Monitor is attached to WWW service, this means that the last will not know about the requests directly responded by the HTTP.SYS driver.

So, got the mystery solved and some more knowledge about IIS Output Cache!
The following test will be testing IIS output cache with static contents and see if there is any gains on this configuration.

Hope I don't take one year to post a new entry on this blog! :-)
Best wishes

PS: by the way, found the tutorial to setup JMeter here.

Wednesday, May 2, 2012

Moving from Apache-Win32/PHP to IIS6/FastCGI/PHP

Recently, for performance sake, I've decided to migrate an application running on a Apache/PHP server in a Windows 2003 environment to a IIS6/PHP/FastCGI. I've read the instructions on IIS.net and PHP.net site and produced the following brief task list:

  1. Install IIS6 on the server, with the help of Windows CD
  2. Get FastCGI for IIS6 on http://www.iis.net/download/FastCGI
  3. Run FastCGI setup installation
  4. On command line, run the following command:cd \windows\system32\inetsrv
    cscript fcgiconfig.js -add -section:"PHP" -extension:php -path:"C:\PHP
    cscript fcgiconfig.js -set -section:"PHP" -InstanceMaxRequests:10000
    cscript fcgiconfig.js -set -section:"PHP" -InstanceMaxRequests:10000
    cscript fcgiconfig.js -set -section:"PHP" -ActivityTimeout:90
    cscript fcgiconfig.js -set -section:"PHP" -RequestTimeout:90

  5. Get PHP binaries with the same build used by Apache instance (5.2.17 in my case) but "VC6 x86 Non Thread Safe"version, since FastCGI doesn't need thread protection
  6. Unzipped to a new PHP directory (C:\PHP directory in this case)
  7. Copy the "php.ini" file from the old instance to the new PHP
  8. Using Notepad (or Notepad++) change the following parameters of "php.ini": fastcgi.impersonate =1
    cgi.fix_pathinfo = 1
    cgi.force_redirect = 0

  9. IIS Manager: create a new Application Pool with default settings
  10. IIS Manager: create new Website pointing to the path where your *.php files reside, and give the permissions Read and Run Scripts at the end
  11. IIS Manager: edit site properties and change the following:
    • On Home Directory tab, change the Application Pool to the one created on step 9

    • On Documents tab, change de Default Content page to index.php


Additionally, the application needs IonCube Loader extension installed on PHP, in order to decrypt their .php files. This was easily done by downloading the binaries and unzipping it to a directory (c:\php\ioncube). After that, I've need to add the following line to "php.ini":
zend_extension="c:\\php\\ioncube\\ioncube_loader_win_5.2.dll"

After this, hopefully, you'll have a new site running PHP Now, the biggest challenge with this move (like most migrations in Windows environment) was with file permissions. But thankfully to Mark Russinovich, there is a tool that help you troubleshoot this issues: PROCMON

I was able to pinpoint the problems with some security permissions and eventually give permissions to the Internet Guest Account (IUSR_[hostname] user) on the *.php files directory.

For security reasons and easier troubleshooting, I've opted for creating a dedicated user for running PHP Application Pool, and giving permission to the filesystem tree below PHP home directory (where *.php files are).

There was a problem with some images not appearing on the browser and being reported on the log files has "404 - File not found". Checking in ProcMon, I found that the application was using image files without file extension, which is them blocked by IIS since there isn't a MIME specified. The problem was solved by adding a new MIME type "*" (asterisk) with value application/octet-stream (check Microsoft KB326965).

Obrigado!