Showing posts with label Virtual Server. Show all posts
Showing posts with label Virtual Server. Show all posts

Wednesday, 10 July 2013

Apache Performance Tuning BASH Script

BASH Script to tune Apache Configuration Settings

As you might know a lot of the time I think the LAMP / Wordpress combo is a big bag of shite.

There are so many configuration options, at so many different levels that need tuning to get optimal performance, it is a nightmare to find the right information. There is also too many people offering various solutions for Wordpress / Linux / Apache / MySQL configuration.

Different people recommend different sizes for your config values and just trying to link up server load with page/URL/script requests to find out the cause of any performance issue is a nightmare in itself.

I would have thought there would have been a basic tool out there that could log server load, memory, disk swapping over time and then link that up with the MySQL slow query log, Apache error AND access logs so that you could easily tell when you had issues what processes were running, which URL's were being hit and how much activity was going on to identify culprits for tuning. I have even thought of learning PERL just to write one - not that I want to!

Even with all the MySQL tuning possible, caching plugins installed and memory limits on potentially intensive tasks it can be a nightmare to get the best out of a 1GB RAM, 40GB Virtual Server that is constantly hammered by BOTS, Crawlers and humans. I ban over 50% of my traffic and I still get performance issues at various times of the day - why? I have no FXXING idea!

Without throwing RAM at the problem you can try and set your APACHE values in the config file to appropriate values for your server and MPM fork type.

For older versions of Apache the Multi-Processing Module, non-threaded, pre-forking webserver is well suited as long as the configuration is correct. However it can consume lots of memory if not configured correctly.

For newer versions (2+) the Worker MPM is better as each thread handles a connection at a time and this is considered better for high traffic servers due to the smaller memory footprint. However to get PHP working on this setting apparently needs a lot of configuration and you should read up about this before considering a change.

Read about Apache performance tuning here Apache Performance Tuning.

To find out your current apache version from the console run

apache2 -v OR httpd -v (depending on your server type, if you run top and see apache2 threads then use apache2 otherwise use httpd)

You will get something like this.

Server version: Apache/2.2.9 (Debian) Server built: Feb 5 2012 21:40:20

To find out your current module configuration from the console run

apache2 -V OR httdp -V

Server version: Apache/2.2.9 (Debian)
Server built: Feb 5 2012 21:40:20
Server's Module Magic Number: 20051115:15
Server loaded: APR 1.2.12, APR-Util 1.2.12
Compiled using: APR 1.2.12, APR-Util 1.2.12
Architecture: 64-bit Server
MPM: Prefork threaded: no forked: yes (variable process count)
etc etc etc...

There are lots of people giving "suitable" configuration settings for the various apache settings but one thing you need to do if you run TOP and notice high memory usage and especially high virtual memory usage is try and reduce disk swapping.

I have noticed that when Apache is consuming a lot of memory that your virtual memory (disk based) will be high and you will often experience either high server loads and long wait times for pages to load OR very small server loads e.g 0.01-0.05, an unresponsive website and lots of MySQL Server Gone Away messages in your error log file.

You need to optimise your settings so that disk swapping is minimal which means trying to optimise your MySQL settings using the various MySQL tuning tools I have wrote about as well as working out the right size for your Apache configuration values.

One problem is that if you use up your memory by allowing MySQL to have enough room to cache everything it needs then you can find yourself with little left for Apache. Depending on how much memory each process consumes you can easily find that a sudden spike in concurrent hits uses up all available memory and starts disk swapping.

Therefore apart from MySQL using the disk to carry out OR caching large queries you need to find the right number of clients to allow at any one time. If you allow too many and don't have enough memory to contain them all then the server load will go up, people will wait and the amount of disk swapping will increase and increase until you enter a spiral of doom that only a restart fixes.

It is far better to allow fewer connections and serve them up quickly with a small queue and less waiting than open too many for your server to handle and create a massive queue with no hope of ending.

One of the things you should watch out for is Twitter Rushes caused by automatically tweeting your posts to twitter accounts as this can cause 30-50 BOTS to hit your site at once. If they all consume your memory up then it can cause a problem that I have wrote about before.

Working out your MaxClients value

To work out the correct number of clients to allow you need to do some maths and to help you I have created a little bash script to do this.

What it does is find out the average size of an Apache thread then restarts Apache so that the correct "free size" value can be obtained.

It then divides the remainder by the Apache process size. The value you get should be roughly the right value for your MaxClients.

It will also show you how much disk swapped or virtual memory you are using as well as the size of your MySQL process.

I noticed on my own server that when it was under-performing I was using twice as much disk space as RAM. However when I re-configured my options and gave the system enough RAM to accommodate all the SQL / APACHE processes then it worked fine with low swapping.

Therefore if your virtual memory is greater than the size of your total RAM e.g if you are using 1.5GB of hard disk space as virtual memory and only have 1GB of RAM then it will show an error message.

Also as a number of Apache tuners claim that your MinSpareServers should be 10-25% of your MaxClients value and your MaxSpareServers value 25-50% of your MaxClientsValue I have also included the calculations for these settings as well.


#!/bin/bash
echo "Calculate MaxClients by dividing biggest Apache thread by free memory"
if [ -e /etc/debian_version ]; then
 APACHE="apache2"
elif [ -e /etc/redhat-release ]; then
 APACHE="httpd"
fi
APACHEMEM=$(ps -aylC $APACHE |grep "$APACHE" |awk '{print $8'} |sort -n |tail -n 1)
APACHEMEM=$(expr $APACHEMEM / 1024)
SQLMEM=$(ps -aylC mysqld |grep "mysqld" |awk '{print $8'} |sort -n |tail -n 1)
SQLMEM=$(expr $SQLMEM / 1024)
echo "Stopping $APACHE to calculate the amount of free memory"
/etc/init.d/$APACHE stop &> /dev/null
TOTALFREEMEM=$(free -m |head -n 2 |tail -n 1 |awk '{free=($4); print free}')
TOTALMEM=$(free -m |head -n 2 |tail -n 1 |awk '{total=($2); print total}')
SWAP=$(free -m |head -n 4 |tail -n 1 |awk '{swap=($3); print swap}')
MAXCLIENTS=$(expr $TOTALFREEMEM / $APACHEMEM)
MINSPARESERVERS=$(expr $MAXCLIENTS / 4)
MAXSPARESERVERS=$(expr $MAXCLIENTS / 2)
echo "Starting $APACHE again"
/etc/init.d/$APACHE start &> /dev/null
echo "Total memory $TOTALMEM"
echo "Free memory $TOTALFREEMEM"
echo "Amount of virtual memory being used $SWAP"
echo "Largest Apache Thread size $APACHEMEM"
echo "Amount of memory taking up by MySQL $SQLMEM"
if [[ SWAP > TOTALMEM ]]; then
      ERR="Virtual memory is too high"
else
      ERR="Virtual memory is ok"
fi
echo "$ERR"
echo "Total Free Memory $TOTALFREEMEM"
echo "MaxClients should be around $MAXCLIENTS"
echo "MinSpareServers should be around $MINSPARESERVERS"
echo "MaxSpareServers should be around $MAXSPARESERVERS"


If you get 0 for either of the last two values then consider increasing your memory or working out what is causing your memory issues. Either that or set your MinSpareServers to 2 and MaxSpareServers to 4.

There are many other settings which you can find appropriate values for but adding indexes to your database tables and ensuring your database table/query caches can fit in memory rather than swapped to disk is a good way to improve performance without having to resort to more caching at all the various levels Wordpress/Apache/Linux users love doing.

If you do use a caching plugin for Wordpress then I would recommend tuning it so that it doesn't cause you problems.

At first I thought WP SuperCache was a solution and pre-caching all my files would speed things up due to static HTML being served quicker than PHP.

However I found that the pre-cache stalled often, caused lots of background queries to rebuild the files which consumed memory and also took up lots of disk space.

If you are going to pre-cache everything then hold the files as long as possible as if they don't change there seems little point in deleting and rebuilding them every hour or so and using up SQL/IO etc.

I have also turned off gzip compression in the plugin and enabled it at Apache level. It seems pointless doing it twice and PHP will use more resources than the server.

The only settings I have enabled in WP-Super-Cache at the moment are:


  • Don’t cache pages with GET parameters. (?x=y at the end of a url) 
  • Cache rebuild.
  • Serve a supercache file to anonymous users while a new file is being generated. 
  • Extra homepage checks. (Very occasionally stops homepage caching)
  • Only refresh current page when comments made. 
  • Cache Timeout is set to 100000 seconds (why rebuild constantly?)
  • Pre-Load - disabled.

Also in the Rejected User Agents box I have left it blank as I see no reason NOT to let BOTS like googlebot create cached pages for other people to use. As bots will most likely be your biggest visitor it seems odd to not let these BOTS create cached files.

So far this has given me some extra performance.

Hopefully the tuning I have done tonight will help the issue I am getting of very low server loads, MySQL gone away errors and high disk swapping. I will have to wait and see!

Monday, 27 February 2012

How to delete a Virtual Server using Virtualmin

Deleting a Virtual Server from your server  - Replacing the default site domain on a server with an IP address


The other day I talked about how you can setup a website for testing on your LINUX server using host headers so that you can test it before purchasing a domain name.

Now I did this on one PC and gave the virtual server a particular name in the hosts file so I could access it but because I was at work and behind a proxy it wouldn't allow me to access the website by the desired hostname. Therefore to get to the site I just put in my servers IP address e.g http://174.34.34.114.

However on my home laptop I changed my mind about the name I wanted to use for the new site and instead of editing the existing virtual server I created a new one with a new domain name (again one I hadn't purchased yet).

However because I wasn't behind an office proxy my local hosts file allowed me to access the website by the domain name I had given it in my file with a command like so e.g:

174.34.34.114 www.robsnewblog.com

However now I am back in the office and want to access the new site but due to the proxy issue when I enter the IP address I am met with the old site as that is the default site for the server. Changing the host file has no effect due to the issue with the Proxy. Therefore I cannot access my new domain www.robsnewblog.com either by the IP address OR the hosts file command.

Therefore the solution is to delete the old Virtual Server from my host in Virtualmin and reset the new site as the default server so that I can access it by the hosts IP address alone.

To do this you need to do the following:

1. Login to your host e.g https://myhostname.blah.com:10000/
2. Choose the virtual server you want to delete from the drop down box on the left e.g robstestdomain.
3. Extend the "Disable and Delete" menu option on the left menu and choose "Delete Virtual Server"
4. The main section will list all the services and files that will be deleted. Confirm that you want to delete the server.
5. You will be given an output like the following:


Delete Server
In domain robstestdomain.com
Deleting mail aliases ..
.. done
Deleting AWstats configuration file and Cron job ..
.. done

Removing password protection for AWstats ..
.. done

Deleting MySQL database robstestdomain ..
.. done

Deleting MySQL login ..
.. done

Disabling log file rotation ..
.. done

Deleting scheduled Webalizer reporting ..
.. done

Deleting virtual website ..
.. done

Deleting Apache log files ..
.. done

Removing from email domains list ..
.. done

Deleting home directory ..
.. done

Deleting administration user ..
.. done

Deleting administration group ..
.. done

Deleting server details for robstestdomain.com ..
.. done

Applying web server configuration ..
.. done

6. The virtual server will now have been deleted. A quick test by going to the domain or IP will show you the site cannot be accessed anymore and if you try to FTP to the site you will get an error trying to connect.

7. As you haven't bought a domain for the new site and if like me you are behind a proxy that is preventing you from using your hosts file to access the new domain then you will want to access the site from the IP address alone.

If this is the case and your hosts file is not working (after editing, and re-starting your browser) then you need to ensure that the Virtual Server you want to use is set as the default by going into VirtualMin, editing the Server, choosing "Server Configuration" from the menu and then "Website Options" and then making sure the "Default website for IP address?" radio button is ticked if it isn't already. This will ensure all requests to the IP address are forwarded to the Virtual Server in question.

7. Restart Apache - From WebMin (which you should have installed when you setup the server if you prefer graphical interfaces to using the SSH console) you can do this by going to System > Bootup and Shutdown. Tick the Apache2 box and then at the bottom hit the "Restart" button. Either that or use the command line and this command: /etc/init.d/apache2 restart.

8. If you have any problems go to System Settings and choose the "Re-Check Configuration" option to see if any errors appear or run apache2ctl configtest from the command line to ensure all configuration files are correct.


9. Go to the IP address of your site and hopefully it will now load up. Obviously if you are using an IP address to access the site but the website is set-up with a non existent domain name then paths to scripts and CSS files will not load correctly as they will be pointing to places that don't exist.


To fix this you will need to edit your database either in VirtualMin or through a MySQL management tool like PHPMyAdmin or Navicat and go through the wp_options table editing every row that currently points to your domain name to your IP address. The main ones will be:

  • siteurl
  • home
  • dashboard_widget_options



Obviously if you have custom plugins that have added their own data into the database you might need to change those as well. A quick SQL query will help you hunt any rows down


SELECT  *
FROM    wp_options
WHERE  option_value = 'http://www.robstestdomain.com';


Where you would obviously replace the URL with the domain you want to replace with your IP address.


This should now let you see the website on your PC even a proxy is blocking your hosts file commands.

How to install WebMin on LINUX

How to install WebMin on LINUX

If you are from a Windows background and used to graphical interfaces then moving to a LINUX system can be quite a challenge due to the fact that most techies like to use commands from the console to carry out their work.

Whilst it is a good opportunity to learn some of the commands when you first rent a virtual server from Rackspace or buy your own box then you want to get your sites up and running quickly without having to read a lot of information first.

Therefore if you don't have the time to learn all the LINUX commands installing WebMin on your system is a quick way of providing you with a graphical interface to allow you to edit files and stop and start services like the Apache webserver or MySQL database server, as well as managing these services and configuring settings through a visual interface. You will need to have Java installed to use parts of WebMin.

If you want to learn how to use the console for carrying out your work then a good list of Linux applications and commands can be found here: Linux Commands and you should read some of the following articles I have written specifically about performance turning and managing a system such as Wordpress on a LINUX based system.

The Wordpress Survival Guide Part 1
The Wordpress Survival Guide Part 2
Performance Tuning Tools for MySQL
Using Host Headers to setup a test site on LINUX
Problems with LINUX Apache and PHP
Debugging Memory Issues on Wordpress

A quick cheat sheet of the most popular commands I find myself constantly using from the command line through a tool like PUTTY are below. Make a copy and save them to your desktop for quick and easy access.


CommandDetails
dateShow the current date and time on the server
cdchange drive e.g cd /var (go to the var directory)
cd ../go back up one directory
cd ../../go back up two directories
lslist out the contents of a directory
whoamisee who you are logged in as
su - [username]Assume the permissions of the specified user
sudo [command]Run a command as root but stay as the user you are logged in as
topShow the current running processes and server load
top -d .2Show the current running processes with .2 second refresh
tail -f access_logView the most current entries in the sites access log
grep "61.252.14.247" access_log | tailView the most current entries in the sites access log for a certain IP address
netstat -taShow all current connections to the server
grep "27/Feb/2012:" access_log | sed 's/ - -.*//' | sort | uniq -c | sort -nr | lessView the IP's that appear in your access log the most for a certain date ordered by the most frequent first.
/etc/init.d/apache2 restartRestart Apache
apache2ctl configtestTest the Apache configuration for configuration errors
/etc/init.d/mysql restartRestart MySQL
wget [URL]Remotely access, load and save a file to the current directory
chmod 777 [filepath]Grant full read/write/delete permission to everyone to a file or folder
chmod +x [filepath]Grant execute permission to a script
rebootReboot the server


How to install WebMin on a LINUX

Back to WebMin, to install WebMin on a LINUX based server you should do the following.

1. Install PUTTY if you haven't already.
2. Connect to your server through SSH using PUTTY.
3. Download the WebMin file with the following command:
wget http://prdownloads.sourceforge.net/webadmin/webmin_1.580_all.deb
4. Run the following command: dpkg --install webmin_1.580_all.deb

You should have now installed WebMin to /usr/share/webmin.

The administration username will be set to root and the password will be set to your current root password.

You should now be able to login to Webmin by accessing your hostname/IP on the port 10000.

For example e.g if your hostname is myhost.some-site.com then use http://myhost.some-site.com:10000/.

If you server is running in SSL mode (which it should) then it will initially give you a "Bad Request" error and ask you to try a secure URL instead e.g https://myhost.some-site.com:10000/

The WebMin options will appear as a tab to the right of the VirtualMin tab in the top left of the screen.

Saturday, 25 February 2012

Using Host Headers on a Virtual Server and creating a new site before buying a domain name

How to create and test a website before buying the domain name


Sometimes you may want to create a new website but don't have a domain name to point it at but still want to test everything is working.

Today I wanted to do this and there were a number of issues I had to work through so I thought I would list them for all the Windows developers who are new to LINUX and APACHE.

The site was a basic Wordpress site which was going to run on a Rackspace Virtual Server which already hosted a number of sites.

If you have installed VirtualMin and WebMin it's very easy to manage your server with a graphical interface otherwise you will need to do everything through a SSH client like PUTTY terminal serviced into your server.

1. Create a new virtual site
  • Login into your webserver which will be your hostname on port 1000 e.g: https://myhostname.blah.com:10000/
  • If you login as root you won't need to create Webmin logins for each virtual host.
  • Choose the "Create Virtual Server" option on the left menu.
  • Complete the form entering the name of the domain you want to use e.g  robstestdomain  I tend to use the domain name as the description field as well.
  • Enter a password - this will be used for your FTP and Database password unless you change it later - make it secure by using a mixture of letters and numbers both lower and uppercase. If you cannot remember a complex string use a combination of words or a sentence and add numbers or symbols between each word and at the beginning and end e.g 77Strictly2012Software1984
  • Under the Enabled features I ticked the following options:

Setup website for domain?
Accept mail for domain?
Setup Webalizer for web logs?
Create MySQL database?
Enable AWstats reporting?


  • Click the "Create Server" button and the system will generate everything it needs with an output like so

Setting Up Virtual Server

In domain robstestdomain.com
Creating administration group robstestdomain ..
.. done
Creating administration user robstestdomain ..
.. done
Creating aliases for administration user ..
.. done
Adding administration user to groups ..
.. done
Creating home directory ..
.. done
Creating mailbox for administration user ..
.. done
Adding to email domains list ..
.. done
Adding default mail aliases ..
.. done
Adding new virtual website ..
.. done
Adding webserver user www-data to server's group ..
.. done
Performing other Apache configuration ..
.. done
Setting up scheduled Webalizer reporting ..
.. done
Setting up log file rotation ..
.. done
Creating MySQL login ..
.. done
Creating MySQL database robstestdomain ..
.. done
Setting up AWstats reporting ..
.. done
Setting up password protection for AWstats ..
.. done
Applying web server configuration ..
.. done
Saving server details ..
.. done

Once you have done this open up your favourite FTP client like FileZilla and add the new domains details to the Site Manager. For example if you were creating a secure FTP site you would use these settings.

  1. Click "New Site" give it the name of your domain > "robstestdomain"
  2. On the right fill out the form with
  3. Host: myhostname.blah.com
  4. Protocol: SFTP - SSH File Transfer Protocol (secure FTP) you can choose FTP if your hosts firewall is setup to allow traffic through ports 20 and 21.
  5. Logon type: Normal
  6. User: robstestdomain
  7. Password: [the same password you entered when creating the Virtual Server] e,g 77Strictly2012Software1984
  8. Click "Connect" your FTP client should now connect to the new folder on your server which will be empty apart from some default folders like cgi-bin, homes, logs, public_html etc.


Download the latest version of Wordpress from their site: http://wordpress.org/download/

Extract the files and copy them up to the public_html folder on your server e.g: /home/robstestdomain/public_html

You will now have extra folders like wp-content, wp-includes and wp-admin under /public_html as well as a number of files including wp-config-sample.php.

You need to edit this file and replace the main database connection settings at the top of the file. These will be the same settings you used when creating the site unless you have manually gone in and changed them.


// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'robstestdomain');

/** MySQL database username */
define('DB_USER', 'robstestdomain');

/** MySQL database password */
define('DB_PASSWORD', '77Strictly2012Software1984');

/** MySQL hostname */
define('DB_HOST', 'localhost');

One thing I found earlier is that if you created a domain with a hyphen in it like "My-Domain" then when you create the username you should replace the hyphen with an underscore otherwise it won't be able to connect to the database.

You should also add in sentences for all the security keys to make your site more secure. The longer the words the better.


define('AUTH_KEY',         'some phrase or two');
define('SECURE_AUTH_KEY',  'another unique phrase 100003433');

....

define('NONCE_SALT',       'something else 23423423');

Once complete save the file as wp-config.php and upload to the root folder e.g /public-html/wp-config.php

Now that you have a virtual server setup you need to make sure that you can access it from your own computer as it currently isn't visible online as there is no DNS record setup pointing a domain to your site.

To do this you can edit your hosts file which is located om your computer (windows 7) under
c:\windows\System32\drivers\etc\hosts.

You need to add the following line to the host file that points the IP address of your webserver to the domain you have just created.

If you don't know the IP address of your host just open a command prompt and type "PING [hostname]" e.g PING myhostname.blah.com

Reply from 179.202.123.19: bytes=32 time=105ms TTL=49

In your host file at the bottom of any exiting list put the IP address of your host and the domain you want it to point to e.g

179.202.123.19 www.robstestdomain.com

If you have problems editing the file such as it saying that the file is "Read Only" even when it's not set as Read Only, or you don't have sufficient administrator privileges to edit the file then do the following:

1. Right click on Notepad and choose "Run as administrator"
2. Use the File > Open option to open the hosts file
3. Add the line in and then choose File > Save.

Make sure you shut down your browser after editing the host file before re-opening it and then typing in the domain name in the address bar e.g http://www.robstestdomain.com.

If everything has gone okay you should be taken to the Wordpress configuration page e.g http://www.robstestdomain.com /wp-admin/install.php where you can complete the setup by entering details of your sitename, email and password.

Once the form is completed click on the "Install Wordpress" button it will build all the tables in your database and activate your site. You can check the database has been build from within VirtualMin or by using a MySQL database management system like Navicat.

Remember if you have other sites on the same server that have DNS records setup they should still work by entering their domain names into the address bar but because you have told your computer to always take the domain and point it at your server in the host file you should be able to see your new site even if no-one else can.

You could enter your IP address alone instead of the domain name but either should bring you to the new site.

If you don't want people to access your new site during development by hitting your IP address (not that many real users would do) you should setup some htaccess or deny hosts rules so that only traffic from your own PC can directly use the IP address or your new test domain name and return a 403 status code to everybody else.

Once you have set your site up, installed your themes and plugins and read my Wordpress Survival Guides, one and two on the best plugins to use for performance and the best Apache config for your site you will be ready to rumble. Go and buy a domain from http://www.123-reg.co.uk/ and point it to your new virtual server.

If you have any problems you should also check your new sites Apache config file e.g /etc/apache2/sites-available/robstestdomain.com.conf and make sure its setup like you want. Open an existing config file for one of your other working sites and copy and paste the data changing the names to your new site.


Always restart your server after changing your conflig files but only after running a test for any syntax errors in any of your config files. You can do this in your console with the following lines.


myhost:~:# apache2ctl configtest
Syntax OK
myhost:~:# /etc/init.d/apache2 restart

You can also restart Apache through WebMin which is located under the System > Bootup and Shutdown menu option.

And that my friends is how you do it.

Update: 27-FEB-2012

If you change your mind about the domain name you want to use for your site you will need to delete the existing virtual server and set-up a new one. This might cause problems if you are behind a proxy at work that doesn't allow your hosts file to work. Therefore you should read this article on deleting a site in VirtualMin and accessing a Wordpress site by IP address alone.