天天看點

nginx讓web更精彩

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 -eq 0 ] && rm -f $lockfile

restart() {

    configtest || return $?

    stop

    sleep 1

    start

reload() {

    echo -n $"Reloading $prog: "

    killproc $nginx -HUP

    RETVAL=$?

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

    restart|configtest)

    reload)

        rh_status_q || exit 7

    force-reload)

        force_reload

    status)

        rh_status

    condrestart|try-restart)

            ;;

    *)

        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 {

     }

從上面我們發現還有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_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

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_name mirror.gabylinux.com;

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;

啟用日志緩存:

 ...

 open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;

--->nginx做反向代理(此時nginx不能做web伺服器)

  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把每一個使用者的會話緩存至本地。

為反向代理啟用緩存功能:

    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;

 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

這裡就不在給出過程了,随後會給出反向代理多台伺服器實作負載均衡的案例。

繼續閱讀