nginx从其诞生不久就迅速占领市场很大份额,而且这种趋势还在增长,这说话nginx肯定有很多优秀的表现,本文就算是笔者自己一个总结文章,供以后自己参阅,也希望各位感兴趣的网友一起添加新的应用。
编译安装nginx很简单,我就从nginx编译开始
一:安装前准备
nginx编译需要在yum环境和编译环境准备好进行,yum源可以是本地源(把镜像一挂,路径一指就能用,很适合不能上网的情况)和网络源(在这我推荐使用163的源)
编译最基本环境yum  groupinstall   "Development Libraries" "Development Tools"
同时nginx编译依赖pcre-devel开发包所有野需要装一下
yum install  pcre-devel -y
下载源码包
wget http://www.nginx.org/download/nginx-1.0.14.tar.gz
(ps:如果想往xshell里直接拉东西的话需要安装这个包lrzsz,注意不是想虚拟机中拖拉东西哟)
二,编译安装
像apache一样,nginx也需要一个指定的系统用户来使用,这个系统用户如果是编译安装的时候可以自己添加指定。像我下面用的就是nginx用户和组(你完全可以改成其他你定义的系统用户)
# groupadd -r nginx
# useradd -r -g nginx -s /bin/false -M nginx
(ps,如果不添加nginx这个系统用户的话会在/usr/sbin/nginx启动的时候报错:nginx: [emerg] getpwnam("nginx") failed)
# tar xf nginx-1.0.14.tar.gz
# cd nginx-1.0.14
#./configure \
  --prefix=/usr \
  --sbin-path=/usr/sbin/nginx \
  --conf-path=/etc/nginx/nginx.conf \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx/nginx.pid  \
  --lock-path=/var/lock/nginx.lock \
  --user=nginx \
  --group=nginx \
  --with-http_ssl_module \
  --with-http_flv_module \
  --with-http_stub_status_module \
  --with-http_gzip_static_module \
  --http-client-body-temp-path=/var/tmp/nginx/client/ \
  --http-proxy-temp-path=/var/tmp/nginx/proxy/ \
  --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
  --with-pcre
#make && make install
关于配置选项的简单说明: 大部分选项对于大家来说都是一看就知道什么意思,像--with-http_gzip_static_module 这样有特殊作用的我在分析配置文件的时候给出具体解释。
刚刚编译前忘记了一件很重要的事情,就是伪装nginx的版本号,
伪装版本号需要在nginx没有被编译前修改nginx文件下的nginx-0.5.35/src/core/nginx.h这个头文件如:
/*
* Copyright (C) Igor Sysoev
*/
#ifndef _NGINX_H_INCLUDED_
#define _NGINX_H_INCLUDED_
#define NGINX_VERSION      "1.0"
#define NGINX_VER          "apache/" NGINX_VERSION
#define NGINX_VAR          "apache"
#define NGX_OLDPID_EXT     ".oldbin"
#endif /* _NGINX_H_INCLUDED_ */
(如果不在编译前修改,编译后就无法修改,最多只能隐藏nginx的版本号)
make install后一个最简答的没有经过优化的nginxweb服务器已经安装成功,可以启动服务验证下,nginx服务启动可以使用自己带的启动(ps:一定不要启动apache,不然会争用80端口)
# /usr/sbin/nginx
# netstat -tnlp | grep 80
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      27366/nginx
从上面可以看出nginx已经正常启动,打开网页http://192.168.1.103/出现了welcome to nginx!
但是这样对于习惯sv风格的管理服务的朋友来说,感觉会很不爽,还好我们有脚本,自己写个sv风格bash脚本:
# vim /etc/init.d/nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
nginx="/usr/sbin/nginx"
prog=$(basename $nginx)
 
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
 
make_dirs() {
   # make required directories
   user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
 
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
 
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
 
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
 
force_reload() {
    restart
}
 
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
 
rh_status() {
    status $prog
}
 
rh_status_q() {
    rh_status >/dev/null 2>&1
}
 
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
#chmod +x /etc/init.d/nginx
# chkconfig --add nginx
# service nginx start
验证能够正常启动关闭nginx服务,如果你编译的路径不一样的话,按照你编译的参数相对应的修改。
三:分析nginx.conf文件
# cd /etc/nginx/
# cp nginx.conf nginx.conf.bak(ps,养成好的习惯,修改前备份)
# vim nginx.conf
nginx配置文件非常简单,从整体上看nginx的配置文件分为两段
-->全局配置段:
#user  nginx;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}
--->web服务配置段:
http{
...
}
-->定义虚拟主机:
在web服务配置段,可以定义基于ip和域名的虚拟主机
server {
        listen       80;#表示监听地址和端口
        server_name  localhost;#可以改成相应的域名
        #charset koi8-r;
   #access_log  logs/host.access.log  main;
   location / {
  root   html;
  index  index.html index.htm;
   }
   #error_page  404              /404.html;
   # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
   location = /50x.html {
  root   html;
     }
   }
从上面我们发现还有location的定义,location的用法有:
1:location做uri路径匹配,匹配方式有5种:location [=|~|~*|^~|@] /uri/ { ... }
其中~(区分字符大小写)和~*(不区分字符大小写)是表示对uri进行正则表达式匹配的
^~禁止做正则表达式匹配;=表示精确匹配
2:定义别名alias,如下面的用法:
location ~ ^/download/(.*)$ {
  alias /home/website/files/$1;
}
表示在download目录下的任意文件都定义到/home/website/files目录下对应的文件。
3:定义索引;索引(在没有对应的主页的时候,把对应目录下的所有内容显示出来)
location  /  {
  autoindex  on;
}
为了网站安全,建议关闭索引。
4:定义访问控制规则:
location / {
  deny    192.168.1.1;
  allow   192.168.1.0/24;
  allow   10.1.0.0/16;
  deny    all;
}
5:错误页面重定向  以显示友好错误信息
error_page 403 404 /40x.html;
location = /40x.html {
 root /web/bbs;
}
表示:如果是根下面的40x.html都定向到 /web/bbs/目录下的40x.html页面。
6:开启Nginx状态监控的功能:需要在编译的时候--with-http_stub_status_module
location /nginx_status {
  stub_status on;
  access_log off;
}
然后在ie浏览器中输入:http://192.168.1.103/nginx_status就会出现nginx的状态信息
(nginx状态信息很重要,不能所有的主机都能访问,需要进行访问控制)
7:启用基于用户认证:基本语法如下,只需要在需要认证的目录下添加比如上面/nginx_status 这个目录
server {
 server_name www.a.com;
 . . .
 location /nginx_status  {
  auth_basic "Restricted";
  auth_basic_user_file /etc/nginx/.htpasswd;
  . . .
 }
}
/etc/nginx/.htpasswd定义用户认证文件,这个文件需要借助apache的htpasswd生成
#yum -y install httpd
# htpasswd -c -m /etc/nginx/.htpasswd test
New password:
Re-type new password:
Adding password for user test
# htpasswd  -m /etc/nginx/.htpasswd test2
New password:
Re-type new password:
Adding password for user test2
(ps:注意-c参数的意思)
# cat /etc/nginx/.htpasswd
test:$apr1$reBMM/..$CkmjFGzG0Pz3ipQHxN2id/
test2:$apr1$Gmhok/..$p2uHjdxwmROxJdwxUIiJa0
下面给个例子:
   location /nginx_status {
          stub_status on;
          access_log off;
          auth_basic "Restricted";
          auth_basic_user_file /etc/nginx/.htpasswd;
        }
通过网页访问验证:http://192.168.1.103/nginx_status
--->nginx  url地址重写功能 rewrite模块来实现
rewrite指令的语法:
rewrite regex replacement flag
常见flag有
last:完成处理当前重写指令并重新启动rewrite指令(包括重写)。
break:出现break指令,就立即跳出,不执行后面的rewrite指令。
redirect:302地址临时转向
permanent:301永久地址跳转
如把http://www.gabylinux.com/attatch.php?value=111223跳转到
http://www.gabylinux.com/111222/attatch
rewrite ^/(attatch)\.php\?value=(.*)$ /$2/$1 last;
某网站原有的论坛访问路径为/forum/,但后来根据要求需要更改为/bbs,于是,就可以通过下面的方法实现:
rewrite ^/forum/?$ /bbs/ permanent;
nginx 的条件判断+地址重写
nginx的条件判断有很多种,我直接拿来例子来说:
判断用户的浏览器类型:
if ($http_user_agent ~* MSIE) {
  rewrite  ^(.*)$  /msie/$1  break;
}
if ($http_user_agent ~* opera) {
  rewrite  ^(.*)$  /opera/$1  break;
}
上面表示如果用户的浏览器时ie时候,跳转到指定的地方,如果是opera的话跳转指定的位置。
实现域名跳转
server
{
listen 80;
server_name jump.gabylinux.com;
index index.html index.php;
root /www/htdocs;
rewrite ^/ http://www.gabylinux.com/;
}
实现域名镜像
server
{
listen 80;
server_name mirror.gabylinux.com;
index index.html index.php;
root /www/htdocs;
rewrite ^/(.*)$ http://www.gabylinux.com/$1 last;
}
防盗链配置:
location ~* \.(gif|jpg|png|swf|flv)$ {
  valid_referers none blocked www.gabylinux.com;
  if ($invalid_referer) {
    rewrite ^/ http://www.gabylinux.com/403.html;
    # return 404
  }
}

-->nginx的日志 ,和apache定义差不多,可以根据不同需要自己定义,下面给出语法格式
设定错误日志格式及级别:
http {
log_format combined '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log combined;
error_log /var/log/nginx/error.log crit;
...
}
启用日志缓存:
http {
 ...
 open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
 ...
}
--->nginx做反向代理(此时nginx不能做web服务器)
location / {
  proxy_pass        http://192.168.1.105;
  proxy_set_header  X-Real-IP  $remote_addr;
}
proxy_pass:表示所有的请求多反向代理到http://192.168.1.105这个地址上
proxy_set_header 方便后面的realserver记录真正的来源客服端ip等信息。
nginx和后端http服务器之间的连接是通过http/1.0协议进行的,因此,每连接是单独建立的;但Nginx和客户端的browser之间的会话是基于http/1.1,因此可以实现keep-alive的功能。此外,在响应用户之前,nginx把每一个用户的会话缓存至本地。
为反向代理启用缓存功能:
http {
    proxy_cache_path  /data/nginx/cache  levels=1:2    keys_zone=STATIC:10m
                                         inactive=24h  max_size=1g;
    server {
        location / {
            proxy_pass             http://1.2.3.4;
            proxy_set_header       Host $host;
            proxy_cache            STATIC;
            proxy_cache_valid      200  1d;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;
        }
    }
}
(ps:/data/nginx/cache这个目录需要自己创建
proxy_cache_valid设定对于不同类别应答的缓存时间. Example:
      proxy_cache_valid  200 302  10m;
      proxy_cache_valid  404      1m;
  Also it is possible to cache any replies with parameter "any":
  proxy_cache_valid  200 302 10m;
  proxy_cache_valid  301 1h;
  proxy_cache_valid  any 1m;)
反向代理多台服务器实现负载均衡:需要upstream backend 模块来实现
用法如下面的例子:
upstream backend {
 server www1.gabylinux.com weight=5;
 server www2.gabylinux.com max_fails=3 fail_timeout=30s;
 server www3.gabylinux.com;
}
server {
 listen 80;
 server_name example1.com;
 access_log /var/log/gabylinux.com/access.log;
 error_log /var/log/gabylinux.com/error.log debug;
 #set your default location
 location / {
  include proxy.conf;
  proxy_pass http://backend;
 }
}
weight = NUMBER - 设定权重,默认为1.
max_fails = NUMBER - 在fail_timeout指令设定的时间内发往此server的不成功的请求次数,达到此数目后,此服务器将变为不可操作状态;默认值为1;设定为0值则禁用此功能;
nginx对后端http server的健康状态检测,安装配置第三方模块。模块下载地址:https://github.com/cep21/healthcheck_nginx_upstreams;模块名称:ngx_http_healthcheck_module
这里就不在给出过程了,随后会给出反向代理多台服务器实现负载均衡的案例。