Tag: nginx

nginx-0.8.42 的一个新feature

nginx 0.8.42 有个新功能:

Feature: a text answer may be added to a “return” directive. (via nginx.org )

这个功能其实很有趣,当然自己写也不难,官方实现了就最好。

找了下,找不到相关的配置说明,只好自己摸索一下吧。一试就出来了,真神奇,哈哈。

三步走(./configure ; make ; make install)安装好 nginx 后,在配置上加一段:

location /iloveu/ {
return 200 “iloveu” ;
}
同时把
default_type  application/octet-stream;
修改为
default_type  text/plain;
如果是前者的话,不会看到字符串,而会下载的噢。
启动 nginx 后,curl -i http://127.0.0.1/iloveu/
HTTP/1.1 200 OK
Server: nginx/0.8.42
Date: Sun, 27 Jun 2010 18:44:04 GMT
Content-Type: text/plain
Content-Length: 3
Connection: keep-alive
iloveu
就这样玩玩吧。

debian 下nginx 快速搭建FCGI环境

我的想法是。。。快点,快点,再快点!!

apt-get install spawn-fcgi php5-cgi

用 spawn-fcgi 启动 fcgi ,

spawn-fcgi -a 127.0.0.1 -p 8000 -u nobody -f /usr/bin/php-cgi -C 5 ;

在 nginx 里配置加一句:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:8000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/nginx/html$fastcgi_script_name;
include fastcgi_params;
}

然后把一个 php 放在 /home/nginx/html 里,就可以使用了。

nginx 实现缓和切换新旧首页

最近首页要改版,瞎折腾,还要新首页和旧首页并行服务,只有网友点击了“新版首页”的按钮后,才会显示新版首页,否则,显示旧版首页。
灵感来自 ayou 的一段配置,我的实现原理如下:

网友点击了切换按钮以后,利用 javascript set 一个 cookie ,如 newindex=y ,首页的 / 会作判断cookie ,然后 rewrite 到相应的页面。

具体实现:
1, 网友点击 set cookie,我抄了一段最简单的东西:

<html>
<head>
<title>Welcome </title>
<script type=”text/javascript”>
function Set_Cookie( name, value, expires, path, domain, secure )
{
// set time, it’s in milliseconds
var today = new Date();
today.setTime( today.getTime() );
/*
if the expires variable is set, make the correct
expires time, the current script below will set
it for x number of days, to make it for hours,
delete * 24, for minutes, delete * 60 * 24
*/
if ( expires )
{
expires = expires * 1000 * 60 * 60 * 24;
}
var expires_date = new Date( today.getTime() + (expires) );
document.cookie = name + “=” +escape( value ) +
( ( expires ) ? “;expires=” + expires_date.toGMTString() : “” ) +
( ( path ) ? “;path=” + path : “” ) +
( ( domain ) ? “;domain=” + domain : “” ) +
( ( secure ) ? “;secure” : “” );
}
</script>
</head>
<body bgcolor=”white” text=”black”>
<center><h1>it is a test</h1></center>
<a href=”#” target=”_blank” onclick=”Set_Cookie( ‘newindex’, ‘y’, 30, ‘/’, ”, ” );window.location.href=’http://www.helosa.org/’;”>我要访问新首页</a>
</body>
</html>

2,nginx 配置:

location =/ {

root html ;
index index.html ;
if ( $cookie_newindex = “y” )
{
rewrite ^/*$ /index_new.html break;
}

}

其中 /index.html 是旧首页,/index_new.html 是新首页。
如此一来,网友访问 http://www.helosa.org/ 时, location / 就会根据cookie rewrite 到相应的首页。但是要注意的是,
http://www.helosa.org/index.html
http://www.helosa.org/index_new.html
访问的是正确的页面,因为判断 cookie 只在 / 做。

nginx 内存膨胀的一个bug

我描述一下这个 bug 。
nginx, 用作代理,proxy next upstream 里配置了 404 就next ,然后过了一段时间就发现,一些 worker 占用的内存竟然达到 几百m,通常只是几十m 而已。一不小心占满了内存,用上了 swap (有些机器把 swap 关掉的话,就直接卡死,ping 不通了),load 就上去了,如果不能及时把这个 worker kill 了,那也完蛋了。

我说说这个 bug 的触发条件吧
nginx 里配置了
proxy_next_upstream error timeout http_404;
http_404 是指,后端返回 404 的话,就把请求往下一个后端发。

upstream 的配置分以下几种情况:
upstream {
server 192.168.51.1 ;
server 192.168.51.2 ;
}
这种情况下,如果 51.1 和 51.2 都404,那么nginx 直接返回给用户 404 了。

upstream {
server 192.168.51.1 ;
server 192.168.51.2 backup ;
}
请求会卡死,负责处理这个请求的 worker 占用的内存会慢慢增大,也就是我说的那个情况了。即使这个请求取消了,这个 worker 占用的内存仍然会膨胀。
backup ,只是为了 51.1 在挂的时候,可以顶上,但想不到竟然触发了这个 bug 。。。
我测试了 0.6.39 ,0.7.65 , 0.8.32 ,这个 bug 都会存在。

upstream {
server 192.168.51.1 ;
}
如果只配置了一个后端,其实也是很快返回404 的,不会卡死。

———————————
结论:
如果配置了 proxy_next_upstream http_404,千万别配置两个后端,其中一个后端是 backup 的。

零编码 nginx + html 实现山寨版url shorten 服务

nginx 有个 memcache 的模块,可以读取 memcache 里的数据。但这个模块很简单,只能get,不能set。如果要set 就必须依靠别的方式了。

今天浏览一下nginx wiki module 的时候,发现国人写了一个功能稍多一点的模块,叫 memc_module ,几乎已经实现了 memcache 的所有tcp 协议。
路过见到,那我就玩玩啦,尝试下不用动态语言实现 url shorten 。

安装 memc module ,按照wiki 上面说的安装吧。

启动 memcache ,memcached -d 。

nginx 配置下,然后启动nginx

location / {
root   html;
index  index.html index.htm;
rewrite “^(.*)$” /hello?key=$1 last;
}

location /hello {
memc_pass 127.0.0.1:11211 ;
set $memc_key $arg_key ;
}

写html ,写个form 吧,用 post 把原始的url 提交给 nginx ,然后nginx 在对 memcache 做set 操作。这个是 value 部分,还有一个key 的部分,可以用js 生成一个随机数提交。
这里,我用curl 模拟一下这个 form 的动作,其中,就当我的随机数是 hello 吧
curl –data “<html><body><meta http-equiv=\”refresh\” content=\”0;url=http://blog.helosa.org\”></body></html>” http://127.0.0.1/hello?key=/hello

在这句话里,
key 是  /hello
value 是 <html><body><meta http-equiv=”refresh” content=”0;url=http://blog.helosa.org“></body></html>

然后,我们访问 127.0.0.1/163 是,就会跳转到我的blog首页了。

哈哈,url shorten 的服务就是这样实现了,实在有点山寨!

nginx proxy_pass 里的”/”

见配置,摘自nginx.conf 里的server 段:

server {
listen 80;
server_name abc.163.com ;
location / {
proxy_pass http://ent.163.com/ ;
}
location /star/ {
proxy_pass http://ent.163.com ;
}
}

里面有两个location,我先说第一个,/ 。其实这里有两种写法,分别是:

location / {
proxy_pass http://ent.163.com/ ;
}
location / {
proxy_pass http://ent.163.com ;
}

出来的效果都一样的。

第二个location,/star/。同样两种写法都有,都出来的结果,就不一样了。

location /star/ {
proxy_pass http://ent.163.com ;
}

当访问 http://abc.163.com/star/ 的时候,nginx 会代理访问到 http://ent.163.com/star/ ,并返回给我们。

location /star/ {
proxy_pass http://ent.163.com/ ;
}

当访问 http://abc.163.com/star/ 的时候,nginx 会代理访问到 http://ent.163.com/ ,并返回给我们。

这两段配置,分别在于, proxy_pass http://ent.163.com/ ; 这个”/”,令到出来的结果完全不同。

前者,相当于告诉nginx,我这个location,是代理访问到http://ent.163.com 这个server的,我的location是什么,nginx 就把location 加在proxy_pass 的 server 后面,这里是/star/,所以就相当于 http://ent.163.com/star/。如果是location /blog/ ,就是代理访问到 http://ent.163.com/blog/。

后者,相当于告诉nginx,我这个location,是代理访问到http://ent.163.com/的,http://abc.163.com/star/ == http://ent.163.com/ ,可以这样理解。改变location,并不能改变返回的内容,返回的内容始终是http://ent.163.com/ 。 如果是location /blog/ ,那就是 http://abc.163.com/blog/ == http://ent.163.com/ 。

这样,也可以解释了上面那个location / 的例子,/ 嘛,加在server 的后面,仍然是 / ,所以,两种写法出来的结果是一样的。

PS: 如果是 location ~* ^/start/(.*)\.html 这种正则的location,是不能写”/”上去的,nginx -t 也会报错的了。因为,路径都需要正则匹配了嘛,并不是一个相对固定的locatin了,必然要代理到一个server。

关于nginx的last-modified返回头

squid 不能缓存cache-control在65秒以下的页面,详见ayou同学的这篇文章:http://sudone.com/linux/squid_cache_65s.html

根据文章所说,如果想实现65秒以下的缓存呢,用last-modified头吧。

今天遇到了一个比较郁闷的事,就是架设在squid后的一台nginx,随意访问一个静态页面,死活不出last-modified头。也没作什么特殊的配置,我自己新装一个nginx,测试之。

$curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/0.8.32
Date: Thu, 28 Jan 2010 14:57:11 GMT
Content-Type: text/html
Content-Length: 151
Last-Modified: Thu, 28 Jan 2010 03:07:20 GMT
Connection: keep-alive
Accept-Ranges: bytes

很正常嘛,不作任何配置时默认是会有last-modified的。

后来还是经ayou同学的提醒,因为使用了ssi。。。

使用了ssi,nginx 就假设你这个页面动态的,谁知道你include的页面上次修改时间啊,当然也就不给你返回last-modified头了。

另外,使用nginx的 http_sub_module时,也不会出这个头的。在测试机上试试,加了个ssi on

$curl -I http://127.0.0.1
HTTP/1.1 200 OK
Server: nginx/0.8.32
Date: Thu, 28 Jan 2010 14:57:32 GMT
Content-Type: text/html
Connection: keep-alive

果然是ssi。。。

mark 一下,以前就试过了,今天竟然忘了!!

wordpress 上传大图爆http error

在wordpress上传一个1.1M左右size的图,竟然爆http error。。。google 了一下,竟然要配置一下apache 的 mod_security 模块,但我用的是nginx啊。。。

感觉不是wordpress的问题,难道是nginx的配置问题??查看了一下error log,发现这句

client intended to send too large body: 1134408 bytes

原来如此,我以前好像配置过这个,找了一下,作出修改如下:

在location ~ \.php$ 的标签下,加一行

client_max_body_size    8m;

然后重启nginx,我一般这样重启 killall -HUP nginx,OK,上传没问题了!!