生命之中的最大错误在于:终日担心犯错误。— 爱尔伯特·哈伯德 (Elbert Hubbard 1856-1915),《笔记》
网上有专门的调查分析(200809):
[没有表格化,看看数据就好了]
Vendor Product Web Sites
Apache Apache 91,068,713
Microsoft IIS 62,364,634
Google GFE 10,072,687
Unknown Unknown 3,835,616
lighttpd lighttpd 3,095,928
nginx nginx 2,562,554
[没有表格化,看看数据就好了]
Vendor Product Web Sites
Apache Apache 91,068,713
Microsoft IIS 62,364,634
Google GFE 10,072,687
Unknown Unknown 3,835,616
lighttpd lighttpd 3,095,928
nginx nginx 2,562,554
最近在处理图片分布问题,问题来源是这样的:
1 把服务器B的图片定时同步到服务器A,用A来接受用户访问
2 同步有时间差,为了保证用户体验,需要在A发生404错误的时候转移到原服务器B,这样用户体会不到发生问题,否则上传图片会立刻看不到,不可能等你同步完的
我觉得这样的分布方式应该是很不错的,只要解决404错误的处理,就可以保证上面的服务正常。因为是说明问题,所以以下提及的代码都整理过,域名也做了更改。
一、最初用lighttpd来处理:
发生404错误,则交由cgi脚本来处理,取得$REQUEST_URI,location到源服务器
404.cgi脚本文件(比较简单,需要条件性的转移请自行修改):
Lighttpd下使用cgi测试:
http://test404.aslibra.com/mag/nofile
得到的是www.aslibra.com的404错误提示,说明已经转移成功
测试结果:
二、Apache安装在8080端口,尝试cgi失败了:
http://test404.aslibra.com:8080/mag/nofile
看到的是空白页面
测试结果:
琢磨了很久,才发现问题,可以看到原因,已经发出了404错误的文件头了,导致后面的location失效,但是怎么去掉404的输出呢,让我纳闷了很久。
经过查实Apache的文档:
这就找到原因了,加上一段就可以了:
测试结果:
三、Apache的PHP处理方式(安装了PHP的模块):
404.php文件内容(条件转移自行修改):
<?php
$url=$_SERVER[REQUEST_URI];
header("location: http://www.aslibra.com".$url);
?>
测试结果:
四、Nginx的配置:
因为Nginx没法使用cgi,只能使用fastcgi,所以配置了PHP的fastcgi处理404错误。
测试结果:
碰到了apache的一样的问题,于是查看官方说明的错误处理:
终于看到这个例子了:
error_page 404 =200 /.empty.gif;
也就是指定一个answer-code就正常了,修改配置:
测试结果:
这回就正常了!
以上是常见的三种web服务器的404错误处理,希望可以对解决大家的应用问题有参考价值。
五、404.cgi的条件判断(代码有点笨,sh不是专长):
转载请保留原出处:http://www.aslibra.com/blog/read.php/1115.htm
1 把服务器B的图片定时同步到服务器A,用A来接受用户访问
2 同步有时间差,为了保证用户体验,需要在A发生404错误的时候转移到原服务器B,这样用户体会不到发生问题,否则上传图片会立刻看不到,不可能等你同步完的
我觉得这样的分布方式应该是很不错的,只要解决404错误的处理,就可以保证上面的服务正常。因为是说明问题,所以以下提及的代码都整理过,域名也做了更改。
一、最初用lighttpd来处理:
发生404错误,则交由cgi脚本来处理,取得$REQUEST_URI,location到源服务器
404.cgi脚本文件(比较简单,需要条件性的转移请自行修改):
#!/bin/sh
# disable filename globbing
set -f
URI=$REQUEST_URI
## by hqlulu @ aslibra.com 2008-8-14 ##
echo "location: http://www.aslibra.com$URI"
echo
# disable filename globbing
set -f
URI=$REQUEST_URI
## by hqlulu @ aslibra.com 2008-8-14 ##
echo "location: http://www.aslibra.com$URI"
echo
Lighttpd下使用cgi测试:
#配置如下:
server.error-handler-404 = "/cgi-bin/404.cgi"
server.error-handler-404 = "/cgi-bin/404.cgi"
http://test404.aslibra.com/mag/nofile
得到的是www.aslibra.com的404错误提示,说明已经转移成功
测试结果:
引用
[root@gx ~]# curl -I http://test404.aslibra.com/mag/nofile
HTTP/1.1 302 Found
Expires: Tue, 02 Sep 2008 12:52:44 GMT
Cache-Control: max-age=864000
location: http://www.aslibra.com/mag/nofile
Date: Sat, 23 Aug 2008 12:52:44 GMT
Server: lighttpd/1.4.15
HTTP/1.1 302 Found
Expires: Tue, 02 Sep 2008 12:52:44 GMT
Cache-Control: max-age=864000
location: http://www.aslibra.com/mag/nofile
Date: Sat, 23 Aug 2008 12:52:44 GMT
Server: lighttpd/1.4.15
二、Apache安装在8080端口,尝试cgi失败了:
#配置如下:
ErrorDocument 404 "/cgi-bin/404.cgi"
ErrorDocument 404 "/cgi-bin/404.cgi"
http://test404.aslibra.com:8080/mag/nofile
看到的是空白页面
测试结果:
引用
[root@gx ~]# curl -I http://test404.aslibra.com:8080/mag/nofile
HTTP/1.1 404 Not Found
Date: Sat, 23 Aug 2008 12:55:45 GMT
Server: Apache/2.2.6 (Unix)
location: http://www.aslibra.com/mag/nofile
Connection: close
Content-Type: text/plain
HTTP/1.1 404 Not Found
Date: Sat, 23 Aug 2008 12:55:45 GMT
Server: Apache/2.2.6 (Unix)
location: http://www.aslibra.com/mag/nofile
Connection: close
Content-Type: text/plain
琢磨了很久,才发现问题,可以看到原因,已经发出了404错误的文件头了,导致后面的location失效,但是怎么去掉404的输出呢,让我纳闷了很久。
经过查实Apache的文档:
引用
如果ErrorDocument指定了一个到本地CGI脚本的重定向,该脚本应当在它的输出中包含一个"Status:"头字段以确保将导致调用它的错误条件始终返回客户端。举例来说,一个Perl ErrorDocument脚本可能包含如下内容:
print "Content-type: text/html\n";
printf "Status: %s <中断条件>\n", $ENV{"REDIRECT_STATUS"};
如果该脚本专门用于处理一个特定的错误条件,比如:404 Not Found ,它就可以使用特定的代码和错误文本进行替代。
需要注意的是如果应答包含一个"Location:"头(为了进行一个客户端重定向),脚本必须发出一个适当的"Status:"头(比如:302 Found)。否则"Location:"头可能无效。
print "Content-type: text/html\n";
printf "Status: %s <中断条件>\n", $ENV{"REDIRECT_STATUS"};
如果该脚本专门用于处理一个特定的错误条件,比如:404 Not Found ,它就可以使用特定的代码和错误文本进行替代。
需要注意的是如果应答包含一个"Location:"头(为了进行一个客户端重定向),脚本必须发出一个适当的"Status:"头(比如:302 Found)。否则"Location:"头可能无效。
这就找到原因了,加上一段就可以了:
#!/bin/sh
# disable filename globbing
set -f
URI=$REQUEST_URI
echo "Status:302 Found"
## by hqlulu @ aslibra.com 2008-8-14 ##
echo "location: http://www.aslibra.com$URI"
echo
# disable filename globbing
set -f
URI=$REQUEST_URI
echo "Status:302 Found"
## by hqlulu @ aslibra.com 2008-8-14 ##
echo "location: http://www.aslibra.com$URI"
echo
测试结果:
引用
[root@gx ~]# curl -I http://test404.aslibra.com:8080/mag/nofile
HTTP/1.1 302 Found
Date: Sat, 23 Aug 2008 13:02:54 GMT
Server: Apache/2.2.6 (Unix)
location: http://www.aslibra.com/mag/nofile
Connection: close
Content-Type: text/plain
HTTP/1.1 302 Found
Date: Sat, 23 Aug 2008 13:02:54 GMT
Server: Apache/2.2.6 (Unix)
location: http://www.aslibra.com/mag/nofile
Connection: close
Content-Type: text/plain
三、Apache的PHP处理方式(安装了PHP的模块):
ErrorDocument 404 /404.php
404.php文件内容(条件转移自行修改):
<?php
$url=$_SERVER[REQUEST_URI];
header("location: http://www.aslibra.com".$url);
?>
测试结果:
引用
[root@gx ~]# curl -I http://pic.zcom.com/mag/nofile
HTTP/1.1 302 Found
Date: Sat, 23 Aug 2008 13:10:14 GMT
Server: Apache/2.2.6 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
location: http://www.aslibra.com/mag/nofile
Content-Type: text/html
HTTP/1.1 302 Found
Date: Sat, 23 Aug 2008 13:10:14 GMT
Server: Apache/2.2.6 (Unix) PHP/5.2.6
X-Powered-By: PHP/5.2.6
location: http://www.aslibra.com/mag/nofile
Content-Type: text/html
四、Nginx的配置:
因为Nginx没法使用cgi,只能使用fastcgi,所以配置了PHP的fastcgi处理404错误。
error_page 404 /404.php;
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/www.aslibra.com$fastcgi_script_name;
include fastcgi_params;
}
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/www.aslibra.com$fastcgi_script_name;
include fastcgi_params;
}
测试结果:
引用
[root@gx ~]# curl -I http://test404.aslibra.com:88/mag/nofile
HTTP/1.1 404 Not Found
Server: nginx/0.6.31
Date: Sat, 23 Aug 2008 13:10:42 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.6
location: http://www.aslibra.com/mag/nofile
HTTP/1.1 404 Not Found
Server: nginx/0.6.31
Date: Sat, 23 Aug 2008 13:10:42 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.6
location: http://www.aslibra.com/mag/nofile
碰到了apache的一样的问题,于是查看官方说明的错误处理:
引用
error_page
syntax: error_page code [ code... ] [ = |=answer-code ] uri
default: no
context: http, server, location, if in location
The directive specifies the URI, which will be showed for the errors indicated.
Example of the use:
error_page 404 /404.html;
error_page 502 503 504 /50x.html;
error_page 403 http://example.com/forbidden.html;
Furthermore, it is possible to change the code of answer to another, for example:
error_page 404 =200 /.empty.gif;
If an erroneous answer is processed by the proxied or FastCGI server and this server can return the different answer codes, for example, 200, 302, 401 or 404, then it is possible to issue the code returned:
error_page 404 = /404.php;
syntax: error_page code [ code... ] [ = |=answer-code ] uri
default: no
context: http, server, location, if in location
The directive specifies the URI, which will be showed for the errors indicated.
Example of the use:
error_page 404 /404.html;
error_page 502 503 504 /50x.html;
error_page 403 http://example.com/forbidden.html;
Furthermore, it is possible to change the code of answer to another, for example:
error_page 404 =200 /.empty.gif;
If an erroneous answer is processed by the proxied or FastCGI server and this server can return the different answer codes, for example, 200, 302, 401 or 404, then it is possible to issue the code returned:
error_page 404 = /404.php;
终于看到这个例子了:
error_page 404 =200 /.empty.gif;
也就是指定一个answer-code就正常了,修改配置:
error_page 404 =302 /404.php;
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/www.aslibra.com$fastcgi_script_name;
include fastcgi_params;
}
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/www.aslibra.com$fastcgi_script_name;
include fastcgi_params;
}
测试结果:
引用
[root@gx ~]# curl -I http://test404.aslibra.com:88/mag/nofile
HTTP/1.1 302 Moved Temporarily
Server: nginx/0.6.31
Date: Sat, 23 Aug 2008 13:15:20 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.6
location: http://www.aslibra.com/mag/nofile
HTTP/1.1 302 Moved Temporarily
Server: nginx/0.6.31
Date: Sat, 23 Aug 2008 13:15:20 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.6
location: http://www.aslibra.com/mag/nofile
这回就正常了!
以上是常见的三种web服务器的404错误处理,希望可以对解决大家的应用问题有参考价值。
五、404.cgi的条件判断(代码有点笨,sh不是专长):
#!/bin/sh
# disable filename globbing
set -f
URI=$REQUEST_URI
echo "Status:302 Found"
if
echo $URI | grep "^/mag" >/dev/null
then
echo "location: http://www1.aslibra.com$URI"
elif
echo $URI | grep "^/op" >/dev/null
then
echo "location: http://www2.aslibra.com$URI"
else
echo
echo "file not exists!"
fi
# disable filename globbing
set -f
URI=$REQUEST_URI
echo "Status:302 Found"
if
echo $URI | grep "^/mag" >/dev/null
then
echo "location: http://www1.aslibra.com$URI"
elif
echo $URI | grep "^/op" >/dev/null
then
echo "location: http://www2.aslibra.com$URI"
else
echo
echo "file not exists!"
fi
转载请保留原出处:http://www.aslibra.com/blog/read.php/1115.htm
fast-cgi是可以使用本地服务器A,调用远程B服务器的php的fast-cgi进程,一直还没相通是把A的本地文件传输给B,B执行然后返回,还是A通知B执行某个文件?
还是自己做个测试就知道:
在[B5]上安装PHP的fastcgi,在[A5]上安装的是Nginx,加fastcgi设置
文件都分布一下:
//file @A6 //
/Data/webapps/index.htm
A6 OK
/Data/webapps/test.aslibra.com/index.php
//file @B5 //
/Data/webapps/index.htm
B5 OK
/Data/webapps/test.aslibra.com/index.php
访问两个地址:
http://test.aslibra.com/index.htm
http://test.aslibra.com/index.php
结果:
也就是说:
文件使用的是对方服务器的文件,PHP文件的路径是在主服务器设置的。
有说明是要修改 cgi.fix_pathinfo=1 ,但文件说明是默认就是1了,所以估计不用修改
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix it's paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
修改成 cgi.fix_pathinfo=0 也还没发现啥不同,不知道会发生什么现象
另外,如果指定的php文件不存在,会有这样的错误:
No input file specified.
还是自己做个测试就知道:
在[B5]上安装PHP的fastcgi,在[A5]上安装的是Nginx,加fastcgi设置
#部分设置
root /Data/webapps/;
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/pic.zcom.com$fastcgi_script_name;
include fastcgi_params;
}
root /Data/webapps/;
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/pic.zcom.com$fastcgi_script_name;
include fastcgi_params;
}
文件都分布一下:
//file @A6 //
/Data/webapps/index.htm
A6 OK
/Data/webapps/test.aslibra.com/index.php
<pre><?phpinfo();?>
//file @B5 //
/Data/webapps/index.htm
B5 OK
/Data/webapps/test.aslibra.com/index.php
<pre><? print_r($_SERVER); ?>
访问两个地址:
http://test.aslibra.com/index.htm
http://test.aslibra.com/index.php
结果:
A6 OK
(文件在A6)
[SCRIPT_FILENAME] => /Data/webapps/test.aslibra.com/index.php
[SCRIPT_NAME] => /index.php
[REQUEST_URI] => /index.php
[DOCUMENT_URI] => /index.php
[DOCUMENT_ROOT] => /Data/webapps
[SERVER_SOFTWARE] => nginx/0.6.31
[SERVER_ADDR] => X.X.X.6
[PHP_SELF] => /index.php
(文件在B5,但注意,显示的SERVER_ADDR信息是A6的IP,对外是不知道是B5在运行的)
(文件在A6)
[SCRIPT_FILENAME] => /Data/webapps/test.aslibra.com/index.php
[SCRIPT_NAME] => /index.php
[REQUEST_URI] => /index.php
[DOCUMENT_URI] => /index.php
[DOCUMENT_ROOT] => /Data/webapps
[SERVER_SOFTWARE] => nginx/0.6.31
[SERVER_ADDR] => X.X.X.6
[PHP_SELF] => /index.php
(文件在B5,但注意,显示的SERVER_ADDR信息是A6的IP,对外是不知道是B5在运行的)
也就是说:
文件使用的是对方服务器的文件,PHP文件的路径是在主服务器设置的。
有说明是要修改 cgi.fix_pathinfo=1 ,但文件说明是默认就是1了,所以估计不用修改
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix it's paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
修改成 cgi.fix_pathinfo=0 也还没发现啥不同,不知道会发生什么现象
另外,如果指定的php文件不存在,会有这样的错误:
No input file specified.
一、) 安装Nginx
1.) 安装
Nginx发音为[engine x],是由俄罗斯人Igor Sysoev建立的项目,基于BSD许可。据说他当初是F5的成员之一,英文主页:http://nginx.net。俄罗斯的一些大网站已经使用它超过两年多了,一直表现不凡。
Nginx的编译参数如下:
在这里,需要说明一下,由于Nginx的配置文件中我想用到正则,所以需要 pcre 模块的支持。我已经安装了 pcre 及 pcre-devel 的rpm包,但是 Ngxin 并不能正确找到 .h/.so/.a/.la 文件,因此我稍微变通了一下:
[root@localhost]#mkdir /usr/include/pcre/.libs/
[root@localhost]#cp /usr/lib/libpcre.a /usr/include/pcre/.libs/libpcre.a
[root@localhost]#cp /usr/lib/libpcre.a /usr/include/pcre/.libs/libpcre.la
然后,修改 objs/Makefile 大概在908行的位置上,注释掉以下内容:
./configure --disable-shared
接下来,就可以正常执行 make 及 make install 了。
2.) 修改配置文件 /usr/local/server/nginx/conf/nginx.conf
以下是我的 nginx.conf 内容,仅供参考:
如果没有报错,那么就可以开始运行Nginx了,执行以下命令即可:
备注:conf/htpasswd 文件的内容用 apache 提供的 htpasswd 工具来产生即可,内容大致如下:
3.) 查看 Nginx 运行状态
输入地址 http://192.168.8.1/NginxStatus/,输入验证帐号密码,即可看到类似如下内容:
Active connections: 328
server accepts handled requests
9309 8982 28890
Reading: 1 Writing: 3 Waiting: 324
第一行表示目前活跃的连接数
第三行的第三个数字表示Nginx运行到当前时间接受到的总请求数,如果快达到了上限,就需要加大上限值了。
第四行看不懂 :(
1.) 安装
Nginx发音为[engine x],是由俄罗斯人Igor Sysoev建立的项目,基于BSD许可。据说他当初是F5的成员之一,英文主页:http://nginx.net。俄罗斯的一些大网站已经使用它超过两年多了,一直表现不凡。
Nginx的编译参数如下:
[root@localhost]#./configure --prefix=/usr/local/server/nginx --with-openssl=/usr/include \
--with-pcre=/usr/include/pcre/ --with-http_stub_status_module --without-http_memcached_module \
--without-http_fastcgi_module --without-http_rewrite_module --without-http_map_module \
--without-http_geo_module --without-http_autoindex_module
--with-pcre=/usr/include/pcre/ --with-http_stub_status_module --without-http_memcached_module \
--without-http_fastcgi_module --without-http_rewrite_module --without-http_map_module \
--without-http_geo_module --without-http_autoindex_module
在这里,需要说明一下,由于Nginx的配置文件中我想用到正则,所以需要 pcre 模块的支持。我已经安装了 pcre 及 pcre-devel 的rpm包,但是 Ngxin 并不能正确找到 .h/.so/.a/.la 文件,因此我稍微变通了一下:
[root@localhost]#mkdir /usr/include/pcre/.libs/
[root@localhost]#cp /usr/lib/libpcre.a /usr/include/pcre/.libs/libpcre.a
[root@localhost]#cp /usr/lib/libpcre.a /usr/include/pcre/.libs/libpcre.la
然后,修改 objs/Makefile 大概在908行的位置上,注释掉以下内容:
./configure --disable-shared
接下来,就可以正常执行 make 及 make install 了。
2.) 修改配置文件 /usr/local/server/nginx/conf/nginx.conf
以下是我的 nginx.conf 内容,仅供参考:
#运行用户
user nobody nobody;
#启动进程
worker_processes 2;
#全局错误日志及PID文件
error_log logs/error.log notice;
pid logs/nginx.pid;
#工作模式及连接数上限
events {
use epoll;
worker_connections 1024;
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
#设定mime类型
include conf/mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
#设定请求缓冲
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
#开启gzip模块
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
output_buffers 1 32k;
postpone_output 1460;
#设定access log
access_log logs/access.log main;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
#设定负载均衡的服务器列表
upstream mysvr {
#weigth参数表示权值,权值越高被分配到的几率越大
#本机上的Squid开启3128端口
server 192.168.8.1:3128 weight=5;
server 192.168.8.2:80 weight=1;
server 192.168.8.3:80 weight=6;
}
#设定虚拟主机
server {
listen 80;
server_name 192.168.8.1 www.yejr.com;
charset gb2312;
#设定本虚拟主机的访问日志
access_log logs/www.yejr.com.access.log main;
#如果访问 /img/*, /js/*, /css/* 资源,则直接取本地文件,不通过squid
#如果这些文件较多,不推荐这种方式,因为通过squid的缓存效果更好
location ~ ^/(img|js|css)/ {
root /data3/Html;
expires 24h;
}
#对 "/" 启用负载均衡
location / {
proxy_pass http://mysvr;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
}
}
}
运行以下命令检测配置文件是否无误:user nobody nobody;
#启动进程
worker_processes 2;
#全局错误日志及PID文件
error_log logs/error.log notice;
pid logs/nginx.pid;
#工作模式及连接数上限
events {
use epoll;
worker_connections 1024;
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
#设定mime类型
include conf/mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
#设定请求缓冲
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
#开启gzip模块
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
output_buffers 1 32k;
postpone_output 1460;
#设定access log
access_log logs/access.log main;
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
#设定负载均衡的服务器列表
upstream mysvr {
#weigth参数表示权值,权值越高被分配到的几率越大
#本机上的Squid开启3128端口
server 192.168.8.1:3128 weight=5;
server 192.168.8.2:80 weight=1;
server 192.168.8.3:80 weight=6;
}
#设定虚拟主机
server {
listen 80;
server_name 192.168.8.1 www.yejr.com;
charset gb2312;
#设定本虚拟主机的访问日志
access_log logs/www.yejr.com.access.log main;
#如果访问 /img/*, /js/*, /css/* 资源,则直接取本地文件,不通过squid
#如果这些文件较多,不推荐这种方式,因为通过squid的缓存效果更好
location ~ ^/(img|js|css)/ {
root /data3/Html;
expires 24h;
}
#对 "/" 启用负载均衡
location / {
proxy_pass http://mysvr;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
}
}
}
如果没有报错,那么就可以开始运行Nginx了,执行以下命令即可:
备注:conf/htpasswd 文件的内容用 apache 提供的 htpasswd 工具来产生即可,内容大致如下:
3.) 查看 Nginx 运行状态
输入地址 http://192.168.8.1/NginxStatus/,输入验证帐号密码,即可看到类似如下内容:
Active connections: 328
server accepts handled requests
9309 8982 28890
Reading: 1 Writing: 3 Waiting: 324
第一行表示目前活跃的连接数
第三行的第三个数字表示Nginx运行到当前时间接受到的总请求数,如果快达到了上限,就需要加大上限值了。
第四行看不懂 :(
在把apache迁移成nginx之后,就要着手解决web日志的问题了。
由于我们分域名网站众多,以前通过cronolog将apache的log自动按照yyyy-mm-dd截断成每天的各分网站日志,然后通过bash脚本使用awstat生成所有分网站的log分析页面,以便所有网站日志的统一管理和浏览。但是nginx的配置文件中不支持cronolog的管道,只好通过手动的方式来截取生成每天的各网站日志。
在nginx.conf中定义log:
在http{}内定义log格式:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $apache_bytes_sent '
'"$http_referer" "$http_user_agent"';
log_format表示log格式,combined表示定义的格式名称,后面表示格式样式。
在server{}内定义日志文件的位置和相应的格式:
access_log /data/weblogs/www1_access.log combined;
nginx可接受的信号如下:
Signal Action
TERM, INT Terminate the server immediately
QUIT Stop the server
HUP Configuration changes, start new workers, graceful stop of old workers
USR1 Reopen log files
USR2 Upgrade the server executable
WINCH Graceful Stop (parent process advise the children to exit)
kill -HUP pid 重新应用配置文件
kill -USR1 pid 重新刷新log
通过如下方式达到日志轮询的目的:
# vi logcron.sh
log_dir="/data/weblogs"
date_dir=date +%Y/%m/%d/%H
/bin/mkdir -p ${log_dir}/${date_dir} > /dev/null 2>&1
/bin/mv ${log_dir}/access.log ${log_dir}/${date_dir}/access.log
kill -USR1 cat /opt/nginx/logs/nginx.pid
定义一个cron,在每天晚上23:59:50执行这个脚本,后面的事情就交给awstats了。
from: http://www.wp1998.cn/read.php?154
由于我们分域名网站众多,以前通过cronolog将apache的log自动按照yyyy-mm-dd截断成每天的各分网站日志,然后通过bash脚本使用awstat生成所有分网站的log分析页面,以便所有网站日志的统一管理和浏览。但是nginx的配置文件中不支持cronolog的管道,只好通过手动的方式来截取生成每天的各网站日志。
在nginx.conf中定义log:
在http{}内定义log格式:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $apache_bytes_sent '
'"$http_referer" "$http_user_agent"';
log_format表示log格式,combined表示定义的格式名称,后面表示格式样式。
在server{}内定义日志文件的位置和相应的格式:
access_log /data/weblogs/www1_access.log combined;
nginx可接受的信号如下:
Signal Action
TERM, INT Terminate the server immediately
QUIT Stop the server
HUP Configuration changes, start new workers, graceful stop of old workers
USR1 Reopen log files
USR2 Upgrade the server executable
WINCH Graceful Stop (parent process advise the children to exit)
kill -HUP pid 重新应用配置文件
kill -USR1 pid 重新刷新log
通过如下方式达到日志轮询的目的:
# vi logcron.sh
log_dir="/data/weblogs"
date_dir=date +%Y/%m/%d/%H
/bin/mkdir -p ${log_dir}/${date_dir} > /dev/null 2>&1
/bin/mv ${log_dir}/access.log ${log_dir}/${date_dir}/access.log
kill -USR1 cat /opt/nginx/logs/nginx.pid
定义一个cron,在每天晚上23:59:50执行这个脚本,后面的事情就交给awstats了。
from: http://www.wp1998.cn/read.php?154
Nginx以其良好的并发性能,目前正在逐渐取代Apache成为大家的Web server首选,但是Nginx目前的中文资料很少,需要大家努力贡献。
下面我介绍一下Nginx的Rewrite模块设置及Wordpress和Discuz的示例。Nginx的Rewrite规则比Apache的简单灵活多了,从下面介绍可见一斑。
首先,Nginx可以用if进行条件匹配,语法规则类似C,举例如下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
1、正则表达式匹配,其中:
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
2、文件及目录匹配,其中:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
如:
if (!-f $request_filename) {
proxy_pass http://127.0.0.1;
}
其次,Nginx的Rewrite规则与Apache几乎完全一致,所不同的是最后的flag标记,举例如下:
rewrite ^/feed/$ http://feed.shunz.net last;
flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite,不再匹配后面的规则
break 与last类似
redirect 返回302临时重定向
permanent 返回301永久重定向
Wordpress的重定向规则:
if (!-e $request_filename) {
rewrite ^/(index|atom|rsd)\.xml$ http://feed.shunz.net last;
rewrite ^([_0-9a-zA-Z-]+)?(/wp-.*) $2 last;
rewrite ^([_0-9a-zA-Z-]+)?(/.*\.php)$ $2 last;
rewrite ^ /index.php last;
}
Discuz!的重定向规则:
if (!-f $request_filename) {
rewrite ^/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 last;
rewrite ^/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 last;
rewrite ^/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page%3D$3&page=$2 last;
rewrite ^/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 last;
rewrite ^/tag-(.+)\.html$ /tag.php?name=$1 last;
}
下面我介绍一下Nginx的Rewrite模块设置及Wordpress和Discuz的示例。Nginx的Rewrite规则比Apache的简单灵活多了,从下面介绍可见一斑。
首先,Nginx可以用if进行条件匹配,语法规则类似C,举例如下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
1、正则表达式匹配,其中:
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
2、文件及目录匹配,其中:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
如:
if (!-f $request_filename) {
proxy_pass http://127.0.0.1;
}
其次,Nginx的Rewrite规则与Apache几乎完全一致,所不同的是最后的flag标记,举例如下:
rewrite ^/feed/$ http://feed.shunz.net last;
flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite,不再匹配后面的规则
break 与last类似
redirect 返回302临时重定向
permanent 返回301永久重定向
Wordpress的重定向规则:
if (!-e $request_filename) {
rewrite ^/(index|atom|rsd)\.xml$ http://feed.shunz.net last;
rewrite ^([_0-9a-zA-Z-]+)?(/wp-.*) $2 last;
rewrite ^([_0-9a-zA-Z-]+)?(/.*\.php)$ $2 last;
rewrite ^ /index.php last;
}
Discuz!的重定向规则:
if (!-f $request_filename) {
rewrite ^/archiver/((fid|tid)-[\w\-]+\.html)$ /archiver/index.php?$1 last;
rewrite ^/forum-([0-9]+)-([0-9]+)\.html$ /forumdisplay.php?fid=$1&page=$2 last;
rewrite ^/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /viewthread.php?tid=$1&extra=page%3D$3&page=$2 last;
rewrite ^/space-(username|uid)-(.+)\.html$ /space.php?$1=$2 last;
rewrite ^/tag-(.+)\.html$ /tag.php?name=$1 last;
}





