Nginx पर कैशिंग प्रॉक्सी। मुश्किल विन्यास

Habré पर पहले से ही Nginx के कई विवरण हैं, लेकिन, मुझे लगता है, मेरा कॉन्फ़िगरेशन भी दिलचस्प होगा।
स्थिति इस प्रकार है: एक वेबसाइट (एक ऑनलाइन स्टोर) कई आईआईएस सर्वरों पर होस्ट की जाती है, इसके सामने एक बैलेंसर है। उनके बीच, IIS पर लोड को कम करने के लिए nginx स्थापित करने का निर्णय लिया गया था।

डायनेमिक कंटेंट का बड़ा हिस्सा अजाक्स द्वारा प्रदर्शित किया गया है, इसलिए उत्पाद कैटलॉग के पृष्ठों को कैशिंग करना काफी सुरक्षित है। हालांकि, उनके पास उत्पाद के बारे में समीक्षाएं हो सकती हैं, जिसके लिए आप वोट कर सकते हैं - ठीक उसी तरह जैसे हब्रे पर, जिसे भी ध्यान में रखना होगा।

इसके अलावा, मैं कैश में लोकप्रिय पृष्ठों की वैधता को स्वचालित रूप से बनाए रखना चाहता हूं।

इसलिए, सबसे पहले हम नए सिरे से स्थापित करते हैं - इसके बिना, यह काम नहीं करेगा। हम भी wget और कर्ल की आवश्यकता होगी।
मैं स्वयं प्रॉक्सी के विन्यास का विस्तार से वर्णन नहीं करूंगा, लेकिन कैश को बनाए रखने के तरीकों पर ध्यान केंद्रित करूंगा।

स्वयं नग्नेक्स का विन्यास:


worker_processes 4; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #    . proxy_cache_path /var/cache/nginx levels=2:2 keys_zone=STATIC:512m inactive=24h max_size=32g; sendfile on; keepalive_timeout 65; gzip on; gzip_proxied any; gzip_min_length 1100; gzip_http_version 1.0; gzip_buffers 4 8k; gzip_comp_level 9; gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json; server { server_name 127.0.0.1; listen 80; set $backend 127.0.0.2; #   .   .   - | log_format cache '$remote_addr|$time_local|$request_uri|$request_method|$status|$http_referer|$cookie___sortOrder|$IsAuth|$sent_http_content_type|$http_user_agent'; access_log /var/log/nginx/proxy_access.log cache; error_log off; #       location ~* /(basket.aspx|visitedgoods.aspx|users/|sale/order.aspx|sale/posted.aspx) { proxy_pass http://$backend; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass_header Set-Cookie; proxy_redirect off; set $IsAuth 1; if ($cookie_AUTH = "") { set $IsAuth 0; } } location / { #     | -     ,   -   ,     if ($args ~* (.*)\|(.*)) { set $brand $1$2; rewrite ^(.*) $1?$brand? redirect; } if ($args ~* (.*)\%7C(.*)) { set $brand $1$2; rewrite ^(.*) $1?$brand? redirect; } rewrite ([a-zA-Z0-9]+)\|([a-zA-Z0-9]+) $1$2? permanent; rewrite ([a-zA-Z0-9]+)\%7C([a-zA-Z0-9]+) $1$2? permanent; rewrite (.*)\%7C$ $1? permanent; rewrite (.*)\| $1? permanent; proxy_pass http://$backend; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass_header Set-Cookie; proxy_ignore_headers "Expires" "Cache-Control" "Set-Cookie"; # ,   .      ,      . set $IsAuth 1; if ($cookie_AUTH = "") { set $IsAuth 0; } # ,      -       set $DoBypass 0; if ($http_user_agent = "WGET-POST-daemon") { set $DoBypass 1; } #  __sortOrder          proxy_cache STATIC; proxy_cache_key "$host$uri$is_args$args $cookie___sortOrder $IsAuth"; proxy_cache_valid 200 301 302 304 30m; proxy_cache_bypass $DoBypass; proxy_cache_use_stale error timeout invalid_header updating; proxy_connect_timeout 100ms; proxy_redirect off; } } } 


तो, प्रॉक्सी तैयार है। अब मजा हिस्सा है।

हम पिछले 24 घंटों के लिए कैश में TOP-20,000 पेज रखना चाहते हैं। लॉग इस तरह दिखता है:

127.0.0.3|20/Oct/2011:15:45:43 +0400|/catalog/25/women.aspx|GET|200|http://127.0.0.1/|-|0|text/html; charset=windows-1251|Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.9.168 Version/11.51


लॉग हर घंटे एक्सेस किए जाते हैं और दैनिक रूप से संग्रहीत किए जाते हैं। दुर्भाग्य से, लॉगरोट को पता नहीं है कि लॉग को दिन में एक बार से कम में कैसे परिवर्तित किया जाए, इसलिए यह औसत गंदे हैक का उपयोग करता है: कॉन्फ़िगरेशन फ़ाइल का आकार 1 और प्रति घंटे एक बार मुकुट पर लॉगोटेट -f /etc/nginx.rotate।

सबसे अधिक देखे गए पृष्ठों की सूची बनाने के लिए स्क्रिप्ट:

 #!/bin/bash #   IP,        ourIP=$(ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}') #       ,    curl -H "Cookie: BasketID=KYKY-B-PYKY" -H "Content-Type: application/json" -d "{\"login\":\"USERNAME\",\"password\":\"PASS\",\"remeberMe\":\"true\"}" -c /var/log/nginx/cookies1.txt http://127.0.0.1/Resources/Services/SystemService.asmx/SignIn line=$(tail -n 1 /var/log/nginx/cookies1.txt) AUTH=$(echo $line | awk '{wild=$7; print wild}') #   :      . cp /var/log/nginx/proxy_access.log /var/log/nginx/overall_proxy FILES=/var/log/nginx/*.gz for f in $FILES do cat $f | gunzip>> /var/log/nginx/overall_proxy done #     wget- rm -f /var/log/nginx/wget/* #         (   - text/html),          ,  20000       wget-. awk -v ourIP="$ourIP" '{ FS="|"; ip = $1; url = $3; code = $5; catsrt=$7; isauth=$8; ct=$9; if (ip != ourIP) if (url !~ "basket.aspx" && url !~ "visitedgoods.aspx" && url !~ "users/" && url !~ "sale/order.aspx" && url !~ "sale/posted.aspx") if (code = "200") if (ct ~ "text/html;") print "http://" ourIP url "|" catsrt "|" isauth}' /var/log/nginx/overall_proxy | sort | uniq -c | sort -n -k1,6 | tail -n20000 | awk '{print $2}' | awk -v AUTH="$AUTH" '{FS="|"}$2=="-"{$2=""} $3=="0"{$3=""} $3=="1"{$3=AUTH}{print "-b --header=\"Cookie: __sortOrder="$2"; AUTH="$3"\" -o /dev/null -O /dev/null "$1 }'> /var/log/nginx/cache.dat rm -f /var/log/nginx/overall_proxy cd /var/log/nginx/wget #     10  -   10  . split -l 2000 /var/log/nginx/cache.dat rm -f /var/log/nginx/cache.dat 


इसलिए, आउटपुट पर हमें कमांड के साथ फाइल मिलती है:
-b --header="Cookie: __sortOrder=; AUTH=" -o /dev/null -O /dev/null 127.0.0.1/catalog/25/women.aspx

फिर, प्रत्येक 20 मिनट में, हमें इस सूची में जाना चाहिए और कैश को मान्य करने के लिए सर्वर से प्रत्येक पृष्ठ का अनुरोध करना चाहिए।

 #!/bin/bash FILES=/var/log/nginx/wget/* #      wget- if [ -s /var/log/nginx/wgets.pid ] then cat /var/log/nginx/wgets.pid | xargs kill rm -f /var/log/nginx/wgets.pid fi #   . for f in $FILES do cat $f | xargs wget & echo $! >> /var/log/nginx/wgets.pid done 


अब यह केवल टिप्पणी के लिए मतदान करते समय पृष्ठ कैश को अपडेट करने के लिए रहता है। यह वही है जो दानव कर रहा है, मतदान के लिए लॉग की लगातार निगरानी कर रहा है।

 #!/bin/bash #    curl -H "Cookie: BasketID=KYKY-B-PYKY-U-ATAC" -H "Content-Type: application/json" -d "{\"login\":\"USERNAME\",\"password\":\"PASS\",\"remeberMe\":\"true\"}" -c /var/log/nginx/cookies.txt http://127.0.0.1/Resources/Services/SystemService.asmx/SignIn line=$(tail -n 1 /var/log/nginx/cookies.txt) AUTH=$(echo $line | awk '{wild=$7; print wild}') # ,      if [ -f /var/log/nginx/post-daemon.pid ] ; then echo "POST-daemon already running!" exit fi #     nginx-    (/usr/bin/tail -f /var/log/nginx/proxy_access.log & echo $! >/var/log/nginx/post-daemon.pid) | while read -r line do if [[ $line =~ '/Resources/Services/SystemService.asmx/VoteToComment|POST|200' ]]; then #    wget -   . ref=$(echo $line | awk -F"|" '{ FS="|"; ref=$6; print ref}') sortOrder=$(echo $line | awk -F"|" '{ FS="|"; co=$7; print co}') IsAuth=$(echo $line | awk -F"|" '{ FS="|"; IsAuth=$8; print IsAuth}') if [[ $sortOrder == "-" ]]; then sortOrder="" fi # ,    -     ,  . UserAgent   nginx-,         . if [[ $IsAuth == "0" ]]; then wget --user-agent="WGET-POST-daemon" --header="Cookie: __sortOrder=$sortOrder" -o /dev/null -O /dev/null $ref else wget --user-agent="WGET-POST-daemon" --header="Cookie: __sortOrder=$sortOrder; AUTH=$AUTH" -o /dev/null -O /dev/null $ref fi fi done exit 


लॉगरोट के लिए कॉन्फ़िगरेशन:

 /var/log/nginx/*log { daily rotate 24 size 1 missingok notifempty compress postrotate /etc/init.d/nginx reload /etc/init.d/nginx-POSTcache restart endscript } 


हमारे डेमॉन के लिए init स्क्रिप्ट:

 #!/bin/sh # # This script starts and stops the nginx cache updater daemon # # chkconfig: - 85 15 # # processname: post-daemon # pidfile: /var/log/nginx/post-daemon.pid . /etc/rc.d/init.d/functions daemon="/usr/local/sbin/post-daemon.sh" pidfile="/var/log/nginx/post-daemon.pid" prog=$(basename $daemon) start() { [ -x $daemon ] || exit 5 echo -n $"Starting POST-daemon: " ($daemon &) & retval=$? echo [ $retval -eq 0 ] return $retval } stop() { echo -n $"Stopping POST-daemon: " pid=$(cat $pidfile) kill $pid rm -f $pidfile retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { stop start } rh_status() { status $prog } case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) rh_status ;; *) echo $"Usage: $0 {start|stop|status|restart}" exit 2 esac 


समाधान थोड़ा बैसाखी जैसा है, लेकिन काम कर रहा है। IIS पर लोड गिर गया है; क्लाइंट को पेज डिलीवरी की गति बढ़ गई है। मैं ध्यान देता हूं कि साइट पर सभी चित्र एक अलग सर्वर पर हैं और कैशिंग के अधीन नहीं हैं।

Source: https://habr.com/ru/post/In131146/


All Articles