openresty(nginx lua)统计域名状态码、平均响应时间和流量

背景

 

之前我们统计域名状态码、平均响应时间和流量的方法是:在每台机器添加一个定时脚本,来获取每个域名最近一分钟的访问日志到临时文件。然后zabbix再对这个一分钟日志临时文件作相关统计。一直运行良好,最近发现某台服务器突然负载增高。使用iotop查看发现获取最近一分钟日志的脚本占用的IO特别高。停止这个定时任务之后恢复正常。于是就打算使用nginx lua来替换目前的方法。新的方法具有统计时占用资源少,实时的特点。

 

方法介绍

 

使用nginx lua统计网站相关数据的方法为(我们以统计devops.webres.wang 404状态码为例):
记录过程:

  • 1、定义了一个共享词典access,获取当前时间戳,获取当前域名,如devops.webres.wang;
  • 2、我们定义用来存储状态码的词典key为,devops.webres.wang-404-当前时间戳;
  • 3、自增1 key(devops.webres.wang-404-当前时间戳)的值;
  • 4、循环2,3步。

 

查询过程:
提供一个接口,来累加key为devops.webres.wang-404-(前60秒时间戳-当前时间戳)的值,返回结果。

 

方法实现

 

nginx.conf设置

  1. http {
  2. […]
  3. lua_shared_dict access 10m;
  4. log_by_lua_file conf/log_acesss.lua;
  5. server {
  6. […]
  7.    location /domain_status {
  8.         default_type text/plain;
  9.         content_by_lua_file "conf/domain_status.lua";
  10.     }
  11. […]
  12. }
  13. […]
  14. }

 

log_access.lua

  1. local access = ngx.shared.access
  2. local host = ngx.var.host
  3. local status = ngx.var.status
  4. local body_bytes_sent = ngx.var.body_bytes_sent
  5. local request_time = ngx.var.request_time
  6. local timestamp = os.date("%s")
  7. local expire_time = 70
  8.  
  9. local status_key = table.concat({host,"-",status,"-",timestamp})
  10. local flow_key = table.concat({host,"-flow-",timestamp})
  11. local req_time_key = table.concat({host,"-reqt-",timestamp})
  12. local total_req_key = table.concat({host,"-total_req-",timestamp})
  13.  
  14. — count total req
  15. local total_req_sum = access:get(total_req_key) or 0
  16. total_req_sum = total_req_sum + 1
  17. access:set(total_req_key, total_req_sum, expire_time)
  18.  
  19. — count status
  20. local status_sum = access:get(status_key) or 0
  21. status_sum = status_sum + 1
  22. access:set(status_key, status_sum, expire_time)
  23.  
  24. — count flow
  25. local flow_sum = access:get(flow_key) or 0
  26. flow_sum = flow_sum + body_bytes_sent
  27. access:set(flow_key, flow_sum, expire_time)
  28.  
  29. — count request time
  30. local req_sum = access:get(req_time_key) or 0
  31. req_sum = req_sum + request_time
  32. access:set(req_time_key, req_sum, expire_time)

domain_status.lua

 

  1. local access = ngx.shared.access
  2. local args = ngx.req.get_uri_args()
  3. local count = args["count"]
  4. local host = args["host"]
  5. local status = args["status"]
  6. local one_minute_ago = tonumber(os.date("%s")) – 60
  7. local now = tonumber(os.date("%s"))
  8.  
  9. local status_total = 0
  10. local flow_total = 0
  11. local reqt_total = 0
  12. local req_total = 0
  13.  
  14. if not host then
  15.         ngx.print("host arg not found.")
  16.         ngx.exit(ngx.HTTP_OK)
  17. end
  18.  
  19. if count == "status" and not status then
  20.         ngx.print("status arg not found.")
  21.         ngx.exit(ngx.HTTP_OK)
  22. end
  23.  
  24. if not (count == "status" or count == "flow" or count == "reqt") then
  25.         ngx.print("count arg invalid.")
  26.         ngx.exit(ngx.HTTP_OK)
  27. end
  28.  
  29. for second_num=one_minute_ago,now do
  30.         local flow_key = table.concat({host,"-flow-",second_num})
  31.         local req_time_key = table.concat({host,"-reqt-",second_num})
  32.         local total_req_key = table.concat({host,"-total_req-",second_num})
  33.  
  34.         if count == "status" then
  35.                 local status_key = table.concat({host,"-",status,"-",second_num})
  36.                 local status_sum = access:get(status_key) or 0
  37.                 status_total = status_total + status_sum
  38.         elseif count == "flow" then
  39.                 local flow_sum = access:get(flow_key) or 0
  40.                 flow_total = flow_total + flow_sum
  41.         elseif count == "reqt" then
  42.                 local req_sum = access:get(total_req_key) or 0
  43.                 local req_time_sum = access:get(req_time_key) or 0
  44.                 reqt_total = reqt_total + req_time_sum
  45.                 req_total = req_total + req_sum
  46.         end
  47. end
  48.  
  49. if count == "status" then
  50.         ngx.print(status_total)
  51. elseif count == "flow" then
  52.         ngx.print(flow_total)
  53. elseif count == "reqt" then
  54.         if req_total == 0 then
  55.                 reqt_avg = 0
  56.         else
  57.                 reqt_avg = reqt_total/req_total
  58.         end
  59.         ngx.print(reqt_avg)
  60. end

使用说明

1、获取域名状态码
如请求devops.webres.wang一分钟内404状态码数量
请求接口http://$host/domain_status?count=status&host=devops.webres.wang&status=404
2、获取域名流量
请求接口http://$host/domain_status?count=flow&host=devops.webres.wang
3、获取域名一分钟内平均响应时间
请求接口http://$host/domain_status?count=reqt&host=devops.webres.wang

Nginx写IO占用高故障处理

故障现象

 

突然收到一台服务器负载过高告警,紧接着网站打开缓慢。

 

故障分析

 

  • 1、登录服务器,使用top命令看到Cpu行的iowait达到了70%以上,所以断定是IO负载过高的原因;
  • 2、接着使用iotop -o命令发现,Nginx的写IO特别大,并且在上一步的top命令看到Nginx的进程状态为D,表示Nginx在等待IO已经为僵死状态;
  • 3、这时候是清楚知道是Nginx在对文件系统进行大量的写操作导致的系统负载过高了,但还是不能知道具体Nginx在写什么文件导致的负载压力,所以我们还需要继续追查下去;
  • 4、我们找到其中一个nginx worker进程的pid,使用lsof -p pid列出来的文件发现除了一些系统库文件及日志文件,还有相当多的fastcgi_temp/xxx文件,有可能与这些文件有关联;
  • 5、再次使用strace -p pid追踪,发现nginx进程对某个fd进行大量的写操作,与lsof命令列出来的文件刚好符合;
  • 6、使用iostat 1输出的大量写io的分区也与fastcgi_temp所在分区相符合;
  • 7、猜测可能是外部正在上传大量的大文件给php-fpm,于是通过EZHTTP的小工具来查看实时流量,发现入站流量其实不大。

 

分析结果

 

根据以上的故障分析,非常有可能是本机的某些程序通过http上传大量大文件。因为对程序逻辑不熟悉,也只是猜测。为了尽快恢复服务,决定实施以下解决方案。

 

解决方案

 

既然清楚知道了fastcgi_temp io压力大,目前也无法短时间从根本上解决问题,所以决定把fastcgi_temp指向/dev/shm,也就是映射到了内存,重启nginx之后服务恢复了正常。最终原因还需要开发配合解决。

Zabbix监控Memcached PHP-FPM Tomcat Nginx MySQL 网站日志

Zabbix作为监控软件非常的灵活,支持的数据类型非常丰富,比如数字(无正负),数字(浮点),日志,文字等。我们需要做的就是使用脚本来收集好数据,然后zabbix收集并画图,设置告警线。这里我们来学习使用Zabbix监控Memcached、PHP-FPM、Tomcat、Nginx、MySQL及网站日志。

 

Memcached监控

 

自定义键值

 

  1. UserParameter=memcached.stat[*],/data/sh/memcached-status.sh "$1"

memcached-status.sh脚本内容为:

  1. #!/bin/bash
  2.  
  3. item=$1
  4. ip=127.0.0.1
  5. port=11211
  6. (echo "stats";sleep 0.5) | telnet $ip $port 2>/dev/null | grep "STAT $itemb" | awk ‘{print $3}’

 

导入模板

 

memcached zabbix模板下载

 

PHP-FPM监控

 

配置php-fpm状态页

 

打开php-fpm.conf配置文件,添加如下配置后重启php:

  1. pm.status_path = /fpm_status

 

自定义键值

 

  1. UserParameter=php-fpm[*],/data/sh/php-fpm-status.sh "$1"

php-fpm-status.sh脚本内容:

  1. #!/bin/bash
  2. ##################################
  3. # Zabbix monitoring script
  4. #
  5. # php-fpm:
  6. #  – anything available via FPM status page
  7. #
  8. ##################################
  9. # Contact:
  10. [email protected]
  11. ##################################
  12. # ChangeLog:
  13. #  20100922        VV        initial creation
  14. ##################################
  15.  
  16. # Zabbix requested parameter
  17. ZBX_REQ_DATA="$1"
  18.  
  19. # FPM defaults
  20. URL="http://localhost/fpm_status"
  21. WGET_BIN="/usr/bin/wget"
  22.  
  23. #
  24. # Error handling:
  25. #  – need to be displayable in Zabbix (avoid NOT_SUPPORTED)
  26. #  – items need to be of type "float" (allow negative + float)
  27. #
  28. ERROR_NO_ACCESS_FILE="-0.9900"
  29. ERROR_NO_ACCESS="-0.9901"
  30. ERROR_WRONG_PARAM="-0.9902"
  31. ERROR_DATA="-0.9903" # either can not connect /        bad host / bad port
  32.  
  33. # save the FPM stats in a variable for future parsing
  34. FPM_STATS=$($WGET_BIN -q $URL -O – 2> /dev/null)
  35.  
  36. # error during retrieve
  37. if [ $? -ne 0 -o -z "$FPM_STATS" ]; then
  38.   echo $ERROR_DATA
  39.   exit 1
  40. fi
  41.  
  42. #
  43. # Extract data from FPM stats
  44. #
  45. RESULT=$(echo "$FPM_STATS" | sed -n -r "s/^$ZBX_REQ_DATA: +([0-9]+)/1/p")
  46. if [ $? -ne 0 -o -z "$RESULT" ]; then
  47.     echo $ERROR_WRONG_PARAM
  48.     exit 1
  49. fi
  50.  
  51. echo $RESULT
  52.  
  53. exit 0

 

导入模板

 

php-fpm zabbix模板下载

 

Tomcat监控

 

刚开始决定监控Tomcat时,使用的是JMX,不过这货设置太复杂了,而且对防火墙要求还挺高,需要开放几个端口。只好使用Tomcat自带的状态页来监控了。

 

自定义键值

 

  1. UserParameter=tomcat.status[*],/data/sh/tomcat-status.py $1

因为需要解析到xml,所以还是决定用python实现比较方便。
/data/sh/tomcat-status.py脚本内容:

  1. #!/usr/bin/python
  2. import urllib2
  3. import xml.dom.minidom
  4. import sys
  5.  
  6. url = ‘http://127.0.0.1:8080/manager/status?XML=true’
  7. username = ‘username’
  8. password = ‘password’
  9.  
  10. passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
  11. passman.add_password(None, url, username, password)
  12. authhandler = urllib2.HTTPBasicAuthHandler(passman)
  13. opener = urllib2.build_opener(authhandler)
  14. urllib2.install_opener(opener)
  15. pagehandle = urllib2.urlopen(url)
  16. xmlData = pagehandle.read()
  17. doc = xml.dom.minidom.parseString(xmlData) 
  18.  
  19. item = sys.argv[1]
  20.  
  21. if item == "memory.free":
  22. print  doc.getElementsByTagName("memory")[0].getAttribute("free")
  23. elif item == "memory.total":
  24. print  doc.getElementsByTagName("memory")[0].getAttribute("total")
  25. elif item == "memory.max":
  26. print  doc.getElementsByTagName("memory")[0].getAttribute("max")
  27. elif item == "threadInfo.maxThreads":
  28. print  doc.getElementsByTagName("threadInfo")[0].getAttribute("maxThreads")
  29. elif item == "threadInfo.currentThreadCount":
  30. print  doc.getElementsByTagName("threadInfo")[0].getAttribute("currentThreadCount")
  31. elif item == "threadInfo.currentThreadsBusy":
  32. print  doc.getElementsByTagName("threadInfo")[0].getAttribute("currentThreadsBusy")
  33. elif item == "requestInfo.maxTime":
  34. print  doc.getElementsByTagName("requestInfo")[0].getAttribute("maxTime")
  35. elif item == "requestInfo.processingTime":
  36. print  doc.getElementsByTagName("requestInfo")[0].getAttribute("processingTime")
  37. elif item == "requestInfo.requestCount":
  38. print  doc.getElementsByTagName("requestInfo")[0].getAttribute("requestCount")
  39. elif item == "requestInfo.errorCount":
  40. print  doc.getElementsByTagName("requestInfo")[0].getAttribute("errorCount")
  41. elif item == "requestInfo.bytesReceived":
  42. print  doc.getElementsByTagName("requestInfo")[0].getAttribute("bytesReceived")
  43. elif item == "requestInfo.bytesSent":
  44. print  doc.getElementsByTagName("requestInfo")[0].getAttribute("bytesSent")
  45. else:
  46. print "unsupport item."

这个脚本是监控Tomcat7的,Tomcat6没有试过,应该区别在状态页的url以及管理页面的用户密码设置上。以上脚本可运行需要在tomcat-users.xml里添加用户,至少权限为manager-status。

 

导入模板

 

tomcat zabbix模板下载

 

Nginx监控

 

配置Nginx状态页

 

在nginx配置文件server{}中加入:

  1. location /nginx_status {
  2.     stub_status on;
  3.     access_log off;
  4. }

 

自定义键值

 

  1. UserParameter=nginx[*],/data/sh/nginx-status.sh "$1"

nginx-status.sh脚本内容:

  1. #!/bin/bash
  2. ##################################
  3. # Zabbix monitoring script
  4. #
  5. # nginx:
  6. #  – anything available via nginx stub-status module
  7. #
  8. ##################################
  9. # Contact:
  10. [email protected]
  11. ##################################
  12. # ChangeLog:
  13. #  20100922        VV        initial creation
  14. ##################################
  15.  
  16. # Zabbix requested parameter
  17. ZBX_REQ_DATA="$1"
  18. ZBX_REQ_DATA_URL="$2"
  19.  
  20. # Nginx defaults
  21. URL="http://127.0.0.1/nginx_status"
  22. WGET_BIN="/usr/bin/wget"
  23.  
  24. #
  25. # Error handling:
  26. #  – need to be displayable in Zabbix (avoid NOT_SUPPORTED)
  27. #  – items need to be of type "float" (allow negative + float)
  28. #
  29. ERROR_NO_ACCESS_FILE="-0.9900"
  30. ERROR_NO_ACCESS="-0.9901"
  31. ERROR_WRONG_PARAM="-0.9902"
  32. ERROR_DATA="-0.9903" # either can not connect /        bad host / bad port
  33.  
  34. # save the nginx stats in a variable for future parsing
  35. NGINX_STATS=$($WGET_BIN -q $URL -O – 2> /dev/null)
  36.  
  37. # error during retrieve
  38. if [ $? -ne 0 -o -z "$NGINX_STATS" ]; then
  39.   echo $ERROR_DATA
  40.   exit 1
  41. fi
  42.  
  43. #
  44. # Extract data from nginx stats
  45. #
  46. case $ZBX_REQ_DATA in
  47.   active_connections)   echo "$NGINX_STATS" | head -1             | cut -f3 -d’ ‘;;
  48.   accepted_connections) echo "$NGINX_STATS" | grep -Ev ‘[a-zA-Z]’ | cut -f2 -d’ ‘;;
  49.   handled_connections)  echo "$NGINX_STATS" | grep -Ev ‘[a-zA-Z]’ | cut -f3 -d’ ‘;;
  50.   handled_requests)     echo "$NGINX_STATS" | grep -Ev ‘[a-zA-Z]’ | cut -f4 -d’ ‘;;
  51.   reading)              echo "$NGINX_STATS" | tail -1             | cut -f2 -d’ ‘;;
  52.   writing)              echo "$NGINX_STATS" | tail -1             | cut -f4 -d’ ‘;;
  53.   waiting)              echo "$NGINX_STATS" | tail -1             | cut -f6 -d’ ‘;;
  54.   *) echo $ERROR_WRONG_PARAM; exit 1;;
  55. esac
  56.  
  57. exit 0

 

导入模板

 

nginx zabbix模板下载

 

MySQL监控

 

MySQL的监控,zabbix是默认支持的,已经有现成的模板,现成的键值,我们需要做的只是在/var/lib/zabbix里新建一个.my.cnf文件,内容如下:

  1. [client]
  2. host=127.0.0.1
  3. port=1036
  4. user=root
  5. password=root

 

网站日志监控

 

配置日志格式

 

我们假设你用的web服务器是Nginx,我们添加一个日志格式,如下:

  1. log_format withHost  ‘$remote_addrt$remote_usert$time_localt$hostt$requestt’
  2.                 ‘$statust$body_bytes_sentt$http_referert’
  3.                 ‘$http_user_agent’;

我们使用tab作分隔符,为了方便awk识别列的内容,以防出错。
然后再设置全局的日志,其它server就不需要设置日志了:

  1. access_log  /data/home/logs/nginx/$host.log withHost;

 

定时获取一分钟日志

 

设置一个定时任务:

  1. * * * * * /data/sh/get_nginx_access.sh

脚本内容为:

  1. #!/bin/bash
  2.  
  3. logDir=/data/home/logs/nginx/
  4. logNames=`ls ${logDir}/*.*.log  |awk -F"/" ‘{print $NF}’`
  5.  
  6. for $logName in $logNames;
  7. do
  8. #设置变量
  9. split_log="/tmp/split_$logName"
  10. access_log="${logDir}/$logName"
  11. status_log="/tmp/$logName"
  12.  
  13. #取出最近一分钟日志
  14. tac $access_log  | awk ‘
  15. BEGIN{
  16. FS="t"
  17. OFS="t"
  18. cmd="date -d "1 minute ago" +%H%M%S"
  19. cmd|getline oneMinuteAgo
  20. }
  21. {
  22. $3 = substr($3,13,8)
  23. gsub(":","",$3)
  24. if ($3>=oneMinuteAgo){
  25. print
  26. } else {
  27. exit;
  28. }
  29. }’ > $split_log
  30.  
  31.  
  32. #统计状态码个数
  33. awk -F’t’ ‘{
  34. status[$4" "$6]++
  35. }
  36. END{
  37. for (i in status)
  38. {
  39. print i,status[i]
  40. }
  41. }
  42. ‘ $split_log  > $status_log
  43. done

这个定时任务是每分钟执行,因为我们监控的频率是每分钟。添加这个任务是为了取得最近一分钟各域名的日志,以及统计各域名的所有状态码个数,方便zabbix来获取所需的数据。

 

自定义键值

 

  1. UserParameter=nginx.detect,/data/sh/nginx-detect.sh
  2. UserParameter=nginx.access[*],awk -v sum=0 -v domain=$1 -v code=$2 ‘{if($$1 == domain && $$2 == code ){sum+=$$3} }END{print sum}’ /tmp/$1.log
  3. UserParameter=nginx.log[*],awk -F’t’ -v domain=$1 -v code=$2 -v number=$3 -v sum=0 -v line="" ‘{if ($$4 == domain && $$6 == code ){sum++;line=line$$5"n" }}END{if (sum > number) print line}’ /tmp/split_$1.log | sort | uniq -c | sort -nr | head -10 | sed -e ‘s/^/<p>/’ -e ‘s/$/</p>/’

nginx-detect.sh脚本内容为:

  1. #!/bin/bash
  2.  
  3. function json_head {
  4.     printf "{"
  5.     printf ""data":["
  6. }
  7.  
  8. function json_end {
  9.     printf "]"
  10.     printf "}"
  11. }
  12.  
  13. function check_first_element {
  14.     if [[ $FIRST_ELEMENT -ne 1 ]]; then
  15.         printf ","
  16.     fi
  17.     FIRST_ELEMENT=0
  18. }
  19.  
  20. FIRST_ELEMENT=1
  21. json_head
  22.  
  23. logNames=`ls /data/home/logs/nginx/*.*.log |awk -F"/" ‘{print $NF}’`
  24. for logName in $logNames;
  25. do
  26. while read domain code count;do
  27.         check_first_element
  28.         printf "{"
  29.         printf ""{#DOMAIN}":"$domain","{#CODE}":"$code""
  30.         printf "}"
  31. done < /tmp/$logName
  32. done
  33. json_end

这里我们定义了三个键值,nginx.detect是为了发现所有域名及其所有状态码,nginx.access[*]是为了统计指定域名的状态码的数量,nginx.log[*]是为了测试指定域名的状态码超过指定值时输出排在前十的url。我们监控nginx访问日志用到了zabbix的自动发现功能,当我们增加域名时,不需要修改脚本,zabbix会帮助我们自动发现新增的域名并作监控。

 

配置探索规则

 

添加一个探索规则,用来发现域名及状态码,如图:
监控

 

配置监控项原型

 

监控所有的域名及状态码:
监控
域名状态码404超过200次监控:
监控
域名状态码500超过50次监控:
监控

 

配置触发器

 

404状态码超过200告警:
监控

监控
500状态码超过50告警:
监控

nginx反向代理缓存配置

这里给出示例,并详解。

  1. http {
  2. […]
  3. […]
  4.  
  5. proxy_cache_path  /data/nginx/cache/one  levels=1:2   keys_zone=one:10m max_size=10g;
  6. proxy_cache_key  "$host$request_uri";
  7.  
  8. server {
  9.     server_name devops.webres.wang webres.wang;
  10.     root /home/devops.webres.wang/web;
  11.     index index.php index.html index.htm;
  12.     location / {
  13.         proxy_pass http://127.0.0.1:8080;
  14.         proxy_set_header  Host "devops.webres.wang";
  15.         proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  16.         #开启反向代理缓存,并使用zone name为one的缓存。
  17.         proxy_cache one;
  18.         #设置状态码为200 302过期时间为10分钟
  19.         proxy_cache_valid  200 302  10m;
  20.         #设置状态码404的过期时间为1分钟
  21.         proxy_cache_valid  404      1m;
  22.     }
  23.     #清除缓存
  24.     location ~ /purge(/.*) {
  25.         #允许的IP
  26.         allow 127.0.0.1;
  27.         deny all;
  28.         proxy_cache_purge one $host$1$is_args$args;
  29.     }
  30. }
  31.  
  32. }

反向代理的缓存主要涉及以下几个命令:
proxy_cache_path proxy_cache_key proxy_cache proxy_cache_valid。

proxy_cache_path
这个是设置缓存的目录,语法如下:
proxy_cache_path path [ levels = levels ] keys_zone = name : size [ inactive = time ] [ max_size = size ] [ loader_files = number ] [ loader_sleep = time ] [ loader_threshold = time ]
可放置的上下文:
http
参数解释:
[ levels = levels ]:
设置缓存目录层数,如levels=1:2,表示创建两层目录缓存,最多创建三层。第一层目录名取proxy_cache_key md5的最后一个字符,第二层目录名取倒数2-3字符,如:
proxy_cache_key md5为b7f54b2df7773722d382f4809d65029c,则:
levels=1:2为/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
levels=1:2:3为/data/nginx/cache/c/29/650/b7f54b2df7773722d382f4809d65029c

keys_zone = name : size:
定义缓存区域名称及大小,缓存名称用于proxy_cache指令设置缓存放置在哪,如proxy_cache one,则把缓存放在zone名称为one的缓存区,即proxy_cache_path指定的具体位置。

proxy_cache_key
这个指令是设置以什么参数md5得到缓存的文件名,默认为$scheme$proxy_host$request_uri,即以协议、主机名、请求uri(包含参数)作md5得出缓存的文件名。
proxy_cache_key与下面的清缓存功能(purge cache)有很大关系。
可放置在上下文,http server location

proxy_cache
反向代理缓存设置指令,语法proxy_cache zone | off,默认为off。上下文:http server location。
可以放到指定location,这样匹配此location的url才被缓存。

proxy_cache_valid
设置指定状态码的缓存时间,语法proxy_cache_valid [ code …] time。

另外,清缓存需要安装插件ngx_cache_purge,安装方法如下:

  1. cd /tmp
  2. wget http://labs.frickle.com/files/ngx_cache_purge-2.1.tar.gz
  3. tar xzf ngx_cache_purge-2.1.tar.gz
  4. cd /tmp
  5. wget http://nginx.org/download/nginx-1.4.2.tar.gz
  6. tar xzf nginx-1.4.2.tar.gz
  7. cd nginx-1.4.2
  8. ./configure –prefix=/usr/local/nginx  –add-module=/tmp/ngx_cache_purge-2.1
  9. make && make install

参考:
http://wiki.nginx.org/HttpProxyModule
http://labs.frickle.com/nginx_ngx_cache_purge/

joomla1.5 nginx url重写规则

  1. if ( !-e $request_filename ) {
  2. rewrite (/|.php|.html|.htm|.feed|.pdf|.raw|/[^.]*)$ /index.php last;
  3. break;
  4. }
  5. #bellow are anti-attack joomla setting
  6.  
  7. if ( $args ~ "mosConfig_[a-zA-Z_]{1,21}(=|%3d)" ) {
  8. set $args "";
  9. rewrite ^.*$ http://$host/index.php last;
  10. return 403;
  11. }
  12. if ( $args ~ "base64_encode.*(.*)" ) {
  13. set $args "";
  14. rewrite ^.*$ http://$host/index.php last;
  15. return 403;
  16. }
  17. if ( $args ~ "(<|%3C).*script.*(>|%3E)" ) {
  18. set $args "";
  19. rewrite ^.*$ http://$host/index.php last;
  20. return 403;
  21. }
  22. if ( $args ~ "GLOBALS(=|[|%[0-9A-Z]{0,2})" ) {
  23. set $args "";
  24. rewrite ^.*$ http://$host/index.php last;
  25. return 403;
  26. }
  27. if ( $args ~ "_REQUEST(=|[|%[0-9A-Z]{0,2})" ) {
  28. set $args "";
  29. rewrite ^.*$ http://$host/index.php last;
  30. return 403;
  31. }