2010
01.17

For those of you who don’t follow my twitter, I’ve been in the process of moving both my servers over to using nginx instead of Apache. On vps2, the switch was pretty seamless (sans SVN issues). However, vps1 proved to more of a challenge. This was partially expected, as I run multiple sites on this VPS.

“Engine X”

I began my journey by following the guide over at the Arch Linux wiki and installing nginx. After nginx was installed (not really configured, besides listening on another port), I looked into how I would get PHP working. I had heard beforehand that getting PHP working on nginx was not as simple as installing a module, I would have to use a a FastCGI. Thankfully the guide had a section on this that seemed like it would work. I settle on this command, which was simple enough.

cgi-fcgi -start -connect localhost:9000 /usr/bin/php-cgi

Now that both nginx and php-cgi were running, I headed over to the very well documented nginx wiki. After learning nginx’s way over doing vhosts, I had all the sites configured and running in no time. Here’s what a typical site configuration would look like:

server {
	listen	80;
	server_name img.compwhizii.net i.j6k.info;

	location / {
		root /srv/http/imgs;
		index index.html index.htm index.php;
	}

	location ~ \.php$ {
		root /srv/http/imgs;
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index	index.php;
		fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
		include fastcgi_params;
	}
}

For my MyBB installs that were using SEO/Pretty URLs, I found these rewrites by frostschutz. Thanks! For the Wordpress I’m just using:

if (!-e $request_filename) {
	rewrite . /index.php last;
}

I’m not entirely sure that it’s doing anything, but It’s working and that’s all I care about for now.

So everything is good for now, happy with my work I decide to go and head off to bed. Sleeping soundly I am awoken by my phone with a new email. It’s from pingdom, the GME Forums are down. The interesting bit is that I have 2 other monitoring services watching HTTP on vps1, and none of them alerted me. Since it’s obviously a false alarm, I put the phone is silent mode and get back to sleep.

Before school the next morning I log into my netbook, and I’m greeted by 2 different steam IMs about the forums being down. A quick trip to the site and I am greeted with a 502 Bad Gateway error. Not good. I check my other PHP based sites, and they are saying the same thing. With only 5 minutes till the bus arrives, it would have to wait.

Later that day I finally get around to fixing the problem, and it turns out that all that happened was php-cgi died. Odd. The simple fix was just running the command again, and life moved on.

Or did it?

Fast doesn’t mean reliable

A few hours later I got the same email, error, and fix. Something was obviously wrong. Not having the time or desire to fix the problem for good, I just started php-cgi again whenever it died. This continued for a few days, finally I decided to fix it for good.

The guide had an alternate method of using spawn-fcgi, which is used by lighttpd and part of the lighttpd package. I already had lighttpd installed so it would be a good solution. But,

[root@compwhizii-vps1 ~]# spawn-fcgi

-bash: spawn-fcgi: command not found

._.

The next 30 minutes were spent reinstalling lighttpd twice, searching through it’s folders, looking at it PKGBUILD, and a bit of crying. Finally resorting to Google I found that spawn-fcgi was split from lighttpd, and was a separate project. Since it was in the AUR I built a package for it and installed. And all was good.

For a few hours.

Again that same damn problem came back, and now I’m getting really annoyed. I remember looking at some startup scripts mentioning variables for max requests and how many processes. So I did some googling and found this, How to Stop Crashing / Hanging of php-cgi / spawn-fcgi with nginx / lighttpd.

While researching the topic across the web, it soon became apparent that php-cgi has nagging issues of stability on prolonged use. It appears the simplest way to ensure stability while using php-cgi is to recycle processes frequently. Unfortunately spawn-fcgi doesn’t provide a simple way to do it. We found out an important, but less advertised environment variable php-cgi recognizes: PHP_FCGI_MAX_REQUESTS

This variable when set, specifies the maximum number of requests served by a php-cgi process before it is killed and a new process spawned. We have set it to 1000 and it seems to be working fine in this setting, even under high loads and prolonged use. You can just set (export in bash) this environment variable before calling spawn-fcgi and that’s it. We have simplified the setup using a script and so can you.

 

Great. With that and adding the –C argument to spawn-fcgi for 4 processes, everything seems to be stable.

URL shorteners are fun

Last week godaddy had a sale on .info domains, so I went and bought 2. c-17.info and j6k.info. j6k is going to be used for shorter URLs and c-17, well, has yet to be assigned a purpose. Last week I was using just some random script I found after a Google search. It was simple as could be, with just a form to add URLs, and tracked how many times a link was used in the DB. Nowhere was that small bit of info was available publicly.

Since it only tracked 10 URLs, 6 of which were tests, I decided to just reinstall the whole thing. With the right mix of keywords I found YOURLS, the most awesome open source URL shortener. It has an info page for each link, one of my favorite features of bit.ly. So I unzipped it and configured it. One problem I ran into which caused me to hit a road block for almost 12 hours was that it has an option for Base62 encoding (That’s [a-zA-Z0-9] for you regex nerds), which for some reason stalled PHP and raped the DB server. I’m still not able to fully track where in the code it’s failing, but I don’t feel like looking now.

On the site for YOURLS there’s a link for nginx rewrites however it has 3 problems.

  1. Doesn’t support uppercase URLs
  2. Doesn’t support info page (url+)
  3. Anime shit everywhere. I nearly puked looking at the page.

I went ahead and fixed that, so here’s my modified code.

if (!-f $request_filename){
	set $rule_0 1$rule_0;
}
if (!-d $request_filename){
	set $rule_0 2$rule_0;
}
if ($rule_0 = "21"){
	rewrite ^/([0-9a-zA-Z]+)\+/?$ /yourls-infos.php?id=$1 last;
	rewrite ^/([0-9a-zA-Z]+)/?$ /yourls-go.php?id=$1 last;
}

Everything is working great now.

Thanks for reading

This is the longest blog post I’ve written to date, and I think it contains valuable information for everyone. If I’ve missed anything that you want to know about leave a comment.

Also a big thanks to whoever made sprunge.us, I love your service, it makes my life so much easier.

1 comment so far

Add Your Comment
  1. Hello everyone! I do not know where to begin but hope this place will be useful for me.
    I will be happy to get any help at the beginning.
    Thanks and good luck everyone! ;)