⬆️ ⬇️

nginx + apache. Caching

Hi% username%

Here I want to talk about how I set up caching on one server, more precisely VDS. Server characteristics: 2000MHz, 2GB RAM, 80Gb HDD, virtualization technology - OpenVZ.

It was decided to use Nginx version 0.7.64 . On the server there were about 200 sites. And a few highly loaded projects. These very projects gave tangible brakes and server load. We will consider DLE in this example.

So, the main points of caching:





0. We invent “technology”



If there are lines in urlah: index.php? Action = logout and admin.php, then we will send these requests directly to the Apache. Then, we need to teach nginx to separate logged users from guests. We will share them with the help of cookies. In my case, Cookies dle_user_id and dle_password mean that the user is logged in and we do not want to give him a page 5 minutes old. And plus, we need to send a POST request for authorization outside the cache, I think it is clear why and why (:.



1. Let's go. We write a config



Actually, I will not describe the full config, I will describe only those moments that are necessary for caching. I do not pretend to the correctness and optimality of my decision, but what is shown here works, and works well in combat conditions. Do not kick much, I recently got into the wilds of nginx, but it feels like the documentation and the example is not enough!

The main directives of the config are clickable and lead to the documentation.

')

1.1 Config itself





http {

proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=one:16m inactive=7d max_size=1024m;

proxy_temp_path /var/cache/nginx/temp; # http , .



server {

listen 127.0.0.1:80;

server_name example.com www.example.com;

proxy_temp_path /var/cache/nginx/example.com;



location @nocached {

proxy_pass 127.0.0.1:8080;

proxy_redirect example.com:8080/ /;

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Real-IP $remote_addr;

}



location / {

proxy_pass 127.0.0.1:8080;

proxy_redirect example.com:8080/ /;

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Real-IP $remote_addr;

#

if ($cookie_dle_user_id) { return 412; }

if ($cookie_dle_password) { return 412; }

if ($request_method = POST ) {

return 412;

}

error_page 412 = @nocached;

proxy_cache one;

proxy_cache_key "$request_method|$is_args|$host|$request_uri";

proxy_hide_header "Set-Cookie";

proxy_ignore_headers "Cache-Control" "Expires";

proxy_cache_valid 200 302 304 5m;

proxy_cache_valid 301 1h;

proxy_cache_valid 503 4s;

proxy_cache_valid any 1m;

proxy_cache_use_stale http_502 http_503 http_504;

}



location ~ (admin.php|index.php?action=logout) {

proxy_pass 127.0.0.1:8080;

proxy_redirect example.com:8080/ /;

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Real-IP $remote_addr;

}



location ~* ^.+\.(jpg|jpeg|gif|png|svg|htm|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {

root /var/www/example/data/www/example.com;

expires 1y;

access_log /var/www/httpd-logs/example.com.access.log;

error_page 404 = @fallback;

}

location @fallback {

proxy_pass 127.0.0.1:8080;

proxy_set_header Host $host;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Real-IP $remote_addr;

}

}

}





$ cookie_name, this variable is equal to the cookie name;



Actually, we will continue to disassemble what we namulevali here. Suggestions for improvements and revisions are welcome!



2. Debriefing





So, we had to differentiate users into 2 types, and depending on the type, give or not give him a cache.

In the @nocached location, we will let those who own two cookies - dle_user_id , dle_password , therefore these users will walk with us directly, without caching. I already wrote that for authorization POST requests are used, as well as for registration;), therefore we do not need to cache them. In this case, we simply add a check to $ request_method.

error_page 412 = @nocached actually sends the owners of cookies, or who tries to log in, directly to the Apache.

I would like to mention the directive proxy_cache_key . In it, for the key, I indicate only the “uniqueness” of the page, that is, if anyone has turned to any of our pages “Guest”, then nginx, by proxying the first answer, immediately puts it into the cache. After that, any other user who did it within the allotted page lifetime (proxy_cache_valid 200 ... 5m) gets the very page that Apache generated for the previous user, this will continue until the end of its life, in our case 200 is allocated for the answer - 5 minutes. After that, everything will continue on the same scenario.

Next, I would like to point out 2 lines: proxy_hide_header, proxy_ignore_headers which are required when caching. You don't want Vasya Pupkin to get Petya Vasechkin's cookies, and thereby do them on his behalf ... ??? The second line, proxy_ignore_headers Allows us to save Apache responses that are marked as not caching or anything else like that. After all, even for such things we have to twitch the awkward Apache, when you can cache it once, and give it away with a quick nginx.

I will not give special attention to the proxy_cache_valid parameter, everything is well described in the documentation.

proxy_cache_use_stale is a very valid directive, it allows us to give the client a cached “normal” page at the time when the Apache hanged, or died or something ... 502, and 504 errors, respectively.

In the following location ~ (admin.php | index.php? Action = logout) we say that we want to send requests that contain strings directly to Apache.

The next two locations tell nginx what statics (pictures of vidyushechka style sheets, etc.) to give to yourself. And if nginx did not find such a file on disk, then maybe it is just located in .htaccess and Apache will give it to us.



Well, I hope that everything. I really hope that my Habra topic has helped you, or will help in the future to avoid some unpleasant moments.

Thanks for attention.



PS The parser ate my http: //, and nginx needs it, how can I recover it? Otherwise, when you copy my config file, nginx may scream, and if not, then it is no longer known what will happen.

Crosspost

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



All Articles