Build a serious WordPress server for high traffic website with nginx

November 10, 2011 by · 1 Comment
Filed under: design, linux, server 

Deploy multiple nginx instance on 1 server for load balance

When building WordPress for high traffic website, we maintain and restart the web server frequently for better SEO  and better user experience; but we don’t want to interrupt user’s visiting.

When we get familiar with SEO, the link/site structure may change and need to update nginx configuration which need restart of nginx. When nginx new version released for fixing a dangerous security issue, we need upgrade nginx.

So we need at least 2 nginx instance for load balance, and another nginx as proxy server. Let’s build the 3 nginx instance on a single server with the same nginx installation(or use 2 nginx installation if need upgrading nginx ). Two of the instance serves WordPress with the same WordPress installation and the same database.

The architecture and network composition:

 

nginx load balance architecture on a single machine

nginx load balance architecture on a single machine

 

 

 

 

 

 

 

 

 

 

 

 

The following steps describes how to do in on Debian.

1. Deploy single wordpress server on nginx

Make sure your system is up-to-date.  Reference the following links to install php pre-requirements:

cd /opt

wget http://nginx.org/download/nginx-1.0.9.tar.gz

tar -zxvf nginx-1.0.9.tar.gz
cd /opt/nginx-1.0.9/
./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module --with-ipv6

make
make install

Create init script to manage nginx:

wget -O init-deb.sh http://library.linode.com/assets/682-init-deb.sh
mv init-deb.sh /etc/init.d/nginx
chmod +x /etc/init.d/nginx
/usr/sbin/update-rc.d -f nginx defaults
/etc/init.d/nginx start

2. Duplicate nginx configurations

cd /opt/nginx  (change directory to where nginx is installed)

cp conf/nginx.conf  conf/nginx.81.conf

cp conf/nginx.conf  conf/nginx.82.conf

mv conf/nginx.conf conf/nginx.backup.conf

And then change the listen port 80 to 81,82 respectively in nginx.81.conf and nginx.82.conf; also don’t forget to comment out the pid line and change the pid file for each instance so that each instance can be stopped normally:

pid        logs/nginx.81.pid;  ### in file nginx.81.conf

pid        logs/nginx.82.pid;  ### in file nginx.82.conf

3. Configure and deploy the proxy nginx server

vi conf/nginx.conf,

copy the following content to listen on port 80 which is balanced by two nginx instance at port 81 and 82.

#deploy multiple nginx instance for load balance on 1 server

upstream main {
        server 106.187.45.82:81;
        server 106.187.45.82:82;
}  

server {
listen 106.187.45.82:80 

location /   {
	proxy_set_header Host $host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_pass http://main;
        }
}

4. Stop your old server and start the new instance with load balance support

sbin/nginx -s stop, or kill -QUI pid

Then you can start the new instance by:

cd /opt/nginx
sbin/nginx -c conf/nginx.81.conf
sbin/nginx -c conf/nginx.82.conf
sbin/nginx -c conf/nginx.conf

In case you want to stop the instance, you can run one/all of these commands:

sbin/nginx -s stop -c conf/nginx.81.conf
sbin/nginx -s stop -c conf/nginx.82.conf
sbin/nginx -s stop -c conf/nginx.conf

Of course, you can stop the instance by executing this command too: kill -QUIT pid-of-the-nginx

5. Debug and maintenance one of the nginx instance

When you debugging on one of the nginx node, if you visit http://106.187.45.82:81, WordPress will redirect your url to the default WordPress site URL  automatically(for example http://www.beyondlinux.com/ ), and then you don’t know which instance you are visiting.

But why wordpress has automatic url redirects? You can typically visit the home page of a WordPress web site by several different URLs:

http://beyondlinux.com/,

http://www.beyondlinux.com/,

http://www.beyondlinux.com:81/

The problem with allowing all of these URLs to access a single page is that it can potentially hurt your website’s overall search engine optimization (SEO). It means search engines could index duplicate copies. So WordPress fixes this problem by employing automatic redirects known as Canonical URL Redirection, which only enables one url per page.

When debugging and testing new functions,   you don’t want to enable the redirection. You can add the following code to functions.php file. remove_filter('template_redirect','redirect_canonical');

If you don’t like editing the file, you could install the plugin: “Permalink Fix & Disable Canonical Redirects Pack“, and activate it, then redirection would be disabled.

After debugging and testing of your WordPress finished, you should deactivate the plugin to enable the Redirection for a better SEO site.

6. Redirect request to next server if error or timeout.

When in load balance mode, nginx will redirect/resend request to another server by default when server error or timeout; for more error processing, we can leverage the directive of proxy_next_upstream and  fastcgi_next_upstream

syntax: proxy_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off]; default: proxy_next_upstream error timeout;

context: http, server, location

The directive determines in what cases the request will be transmitted to the next server, here’s an example config:

proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;  

fastcgi_next_upstream error timeout invalid_header http_500 http_503 http_404;

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Why Load Balance not work in Hessian C# client calling to hessian service?

November 9, 2011 by · Comments Off on Why Load Balance not work in Hessian C# client calling to hessian service?
Filed under: design, java, troubleshooting 

When I was migrating our application from C# to Java, our Java service moved ahead of  the client application. The client application is in C#. And we export service through Hessian service. So we call java hessian service through C# hessian client.

But we met a big problem on load balance after the new application deployed. The load is never balanced on the C# hessian client’s request. The service is invoked through F5.

After digging into the code of C# hessian, I found the cause: C# Hessian Client uses HttpWebRequest with default properties to call java hessian service, while the default HttpWebRequest’s KeepAlive property is true. That means after the C# client connected to a load balance server, it will keep on calling the same back-end service and the request from this client will not routed to other back-end service.

So the solution is to change the default KeepAlive property in file CHessianMethodCaller.cs

HttpWebRequest req = webRequest as HttpWebRequest;

req.KeepAlive = false;  // newly added line to assure load balance work

 

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Noticeable Hacker news I read(2011/09-2011/11)

November 5, 2011 by · Comments Off on Noticeable Hacker news I read(2011/09-2011/11)
Filed under: tech watch 

Programming:

Signs that you’re a bad programmer

How you should go about learning NoSQL

What’s new in Cassandra 1.0: Performance | DataStax

Spark Cluster Computing Framework

Interview with Dennis Ritchie, Bjarne Stroustrup, James Gosling

Lucene Eurocon 2011: Presentation slides are now available 

What are the most learner-friendly resources for learning about algorithms? – Quora

What questions are Java Software Engineers seeing the most of on technical interviews? – Quora

Don’t Call Yourself A Programmer, And Other Career Advice | Kalzumeus Software

Building a Node.js Events App Using RabbitMQ, Websockets, and Django – James Burkhart

Scala SchoolFaceTracker

 

Productivity Tools:

Unofficial Google Advanced Search

Learn VIM Progressively

Ask HN: What programming blogs do you read daily?

9 Awesome SSH Tricks

 

Startup Lessons Learned:

Startup School notes

‘Try demo’ or ‘Buy now’: A/B testing finds which button increased clickthroughs by 47%

The Case for the Single Founder StartupIf I Launched a Startup 

5 Things a Good Product Manager Should Think About

A Few Lessons I Learned After Having Failed

What if the Secret to Success Is Failure? – NYTimes.com

10 Habits of Effective Startup Mentors « Lean Startup Machine

Notepad of Startup Ideas

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Suffered by wordpress permanent links in nginx

November 4, 2011 by · Comments Off on Suffered by wordpress permanent links in nginx
Filed under: linux, server 

I installed wordpress several month ago by default. The page links were in default format like /blog/p?101. After some posts written I realized that these format is not friendly to search engine. So I decided to change the permalinks format in wordpress. It is a suffered experience.

After I changed the permalinks to custom structure, such as “/%year%/%monthnum%/%day%/%postname%/”, then some pages, and the category, tags links, pages could not be visited correctly.

And I tried install the WP plugin “advanced permalinks”. The plugin’s feature sounds very promising, it can reserve your old pages’ permalinks in an different structure. But after activated, some of my links (like category, tags) broken too.

Then I added configurations in nginx.conf, with lots of location definitions …. :

77                 location /blog/2011 { ### for nginx redirection, 2011/06
 78                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 79                 }
 80                 location /blog/category { ### for nginx redirection, 2011/06
 81                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 82                 }
 83                 location /blog/feed{ ### for nginx redirection, 2011/06
 84                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 85                 }
 86                 location /blog/comments{ ### for nginx redirection, 2011/06
 87                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 88                 }
 89                 location /blog/sample-page{ ### for nginx redirection, 2011/06, About me
 90                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 91                 }

 95                 location /blog/index.php{ ### for nginx redirection, 2011/06
 96                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;

…. Each time a new kind of url(which has the same prefix) I added a location config, it is difficult and boring to maintenance the file.

Even more worse, when I installed a new wordpress plugin, the configuration page is in a new url, it couldn’t be accessed.

Oh my god, finally, I changed the nginx.conf like this (leave a catch-all entry in the end), then pages are shown without any colors and styles except black and white…

 77                 location /blog/2011 { ### for nginx redirection, 2011/06
 78                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 79                 }
 80                 location /blog/category { ### for nginx redirection, 2011/06
 81                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 82                 }
 83                 location /blog/feed{ ### for nginx redirection, 2011/06
 84                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 85                 }
...
 92                 location /blog/index.php/category{ ### for nginx redirection, 2011/06
 93                   try_files $uri $uri/ /blog/index.php/?q=$uri&$args;
 94                 }
 95                 location /blog/index.php{ ### for nginx redirection, 2011/06
 96                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
 97                 }
 98                 location /blog/{ ### for nginx redirection, 2011/06
 99                   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
100                 }

 

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Setup your cloud server in 3 minutes with Xen 4.1 on Ubuntu 11.10

November 2, 2011 by · 52 Comments
Filed under: cloud, linux, virtualization 

Ubuntu support xen officially since 11.10. It is really easy to install the packages. Although some issues should be fixed manually, it is a painless experience. Here’s the steps to setup your cloud server in 3 minutes with Xen 4.1 on Ubuntu 11.10.

1. Install xen hypervisor and utilities
sudo apt-get install xen-hypervisor-4.1-amd64 xen-utils-4.1 xenwatch xen-tools xen-utils-common xenstore-utils

sudo apt-get install virtinst virt-viewer virt-manager

2. Restart os, choose the xen kernel, verify xen installation
# xm info
# brctl show

3. Config your xend
$ sudo vim /etc/xen/xend-config.sxp

comment out (xend-unix-server yes) at the file, that means make sure the following line exists or been added :
(xend-unix-server yes)

#vi ~/.bashrc , add the following line:

export VIRSH_DEFAULT_CONNECT_URI="xen:///"

4. Restart, choose the xen kernel, and verify libvirt

# virsh version

Compiled against library: libvir 0.8.3
Using library: libvir 0.8.3
Using API: Xen 3.0.1
Running hypervisor: Xen 4.0.0

Conguratulations, all packages installed successfully.

5. Run virtual machine manager to manage your vms.

# virt-manager

Then you will see the screen virtual machine manager screen:

virtual machine manager for xen 4.1 in ubuntu 11.10

virtual machine manager for xen 4.1 in ubuntu 11.10

Create virtual machine in virt-manager,

error occur when finish creation, and show something like:
if ret is None:raise libvirtError(‘virDomainCreateLinux() failed’, conn=self)
….
/usr/lib64/xen/bin/qemu-dm: ….

that means qemu-dm could not be found, try to fix it:

#mkdir /usr/lib64/xen -p
#cp /usr/lib/xen-4.1/* -r /usr/lib64/xen/

then continue to finish creation of the virtual machine, still error occured, and show something like:
libvirtError: POST operation failed: xend_post: error from xen daemon: (xend.err …
or something like this:

libvirtError: POST操作失败: xend_post:来自 xen 守护进程的错误:<Fault 3: ”>

check the error log,  it will give you some clues:
# less /var/log/xen/xend.log

the log shows error occured and logged at /var/log/xen/qemu-dm-demo.log, check it:
# less /var/log/xen/qemu-dm-demo.log

it says /usr/share/qemu/keymaps/en-us could not be found, the keymaps really does not exist in my disk.
and find it at /usr/share by :
#ls /usr/share/qemu (and press Tab, it shows qemu-linaro exist)

so just copy it to fix:
#cp -r /usr/share/qemu-linaro/ /usr/share/qemu

then continue to finish the vm creation. Wow, it works!

virutal machine running at ubuntu 11.10 with xen 4.1

virutal machine running at ubuntu 11.10 with xen 4.1

Digg This
Reddit This
Stumble Now!
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)