{"id":199504,"date":"2013-10-29T13:27:04","date_gmt":"2013-10-29T09:27:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=199504"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=199504","title":{"rendered":"<span class=\"post_title\">Nginx \u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445 \u2014 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e LUA<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t\u0414\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b <a href=\"http:\/\/2gis.ru\">\u0432\u0441\u0435\u0445<\/a> \u043d\u0430\u0448\u0438\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 nginx. \u042d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u044d\u0442\u043e \u043d\u0430\u0434\u0435\u0436\u043d\u043e. \u041f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043d\u0438\u043c \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442. \u041d\u0430\u0448\u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0440\u044b\u0439. \u0410\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044f \u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0442\u0435\u0442. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0443\u0441\u043a\u043e\u0440\u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043d\u0430\u0448\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0420\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u201cnginx as web application\u201d. <br \/>  \u0410 \u0438\u043c\u0435\u043d\u043d\u043e, \u043e <a href=\"http:\/\/wiki.nginx.org\/3rdPartyModules\">\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445<\/a> \u043c\u043e\u0434\u0443\u043b\u044f\u0445 (\u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c LUA), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u0435\u0449\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u043e.<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage3\/f1e\/b02\/7aa\/f1eb027aa4164f226b39146ddf95092a.jpg\" alt=\"image\"\/><br \/>  <a name=\"habracut\"><\/a><\/p>\n<h5>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/h5>\n<p>  \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0443\u043c\u043a\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f. \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u043a\u0442\u043e\u0440\u044b:<br \/>   \u2014 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f,<br \/>   \u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f,<br \/>   \u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438.<br \/>  \u0421 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u0437\u044b\u0432\u0447\u0438\u0432\u044b\u043c \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c, \u0438\u043d\u043e\u0433\u0434\u0430 \u0434\u0430\u0436\u0435 \u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u043c. \u041f\u0440\u043e\u0434\u0443\u043a\u0442 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043d\u044b\u043c, \u0433\u0435\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c. \u0418 \u0438\u043c \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043b\u044e\u0434\u0435\u0439. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u043f\u043e \u043e\u0442\u0437\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0434\u043e \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u0431\u043b\u044e\u0434\u0430\u0442\u044c. <br \/>  \u041f\u0443\u0442\u0435\u0439 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e. \u041c\u043e\u0436\u043d\u043e \u0432\u0441\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u0441\u043b\u043e\u043c\u0430\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438. \u0411\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e, \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u043e \u043d\u0430\u043c \u043e\u043d \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0438 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e. \u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0431\u044b\u043b\u0430 \u0432\u0437\u044f\u0442\u0430 \u0441\u0431\u043e\u0440\u043a\u0430 <a href=\"http:\/\/openresty.org\">openresty<\/a> (nginx+LUA). \u041f\u043e\u0447\u0435\u043c\u0443 LUA. \u0411\u0435\u0437 \u043f\u043e\u043c\u043e\u0449\u0438 cgi, fastcgi \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 cgi \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 nginx \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0449\u043d\u044b\u0439, \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b. \u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e. \u041f\u0440\u0438\u0447\u0435\u043c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438, \u043d\u043e \u0438 \u0441 \u0431\u0435\u043a\u0435\u043d\u0434\u0430\u043c\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u0432\u043c\u0435\u0448\u0438\u0432\u0430\u044f\u0441\u044c \u0432 event loop \u0432\u0435\u0431\u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0431\u0435\u0437 callbacks, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043c\u0435\u044e\u0449\u0438\u0439\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b nginx. <\/p>\n<p>  \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0431\u0435\u043a\u0435\u043d\u0434\u044b:<br \/>   \u2014 Redis<br \/>   \u2014 Memcache<br \/>   \u2014 MySQL<br \/>   \u2014 PostgreSQL<br \/>  \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0449\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/github.com\/wingify\/lua-resty-rabbitmqstomp\">RabbitMQ<\/a> \u0438 <a href=\"https:\/\/github.com\/FRiCKLE\/ngx_zeromq\">0MZ<\/a>.<br \/>  \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e. \u0412\u043e \u0432\u0441\u044f\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c php-fpm )) <\/p>\n<p>  \u041b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u0432\u0441\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 C? \u041f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 LUA \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0449\u0435 \u0438 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u0418 \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u0438\u0437\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043e\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0438 nginx event loop. <\/p>\n<h5>\u041f\u0440\u0438\u043c\u0435\u0440\u044b. \u0418\u0434\u0435\u0438<\/h5>\n<p>  \u041c\u044b, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434, \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438. \u042d\u0442\u0438 \u0432\u0441\u0435 \u0448\u0442\u0443\u043a\u0438 \u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u043d\u0430 php. <\/p>\n<p>  1. \u0415\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a. \u0418\u0445 \u043d\u0430\u0434\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u043f\u0440\u0438\u0447\u0435\u043c \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, resize. \u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0432 ceph, \u044d\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433 Amazon S3. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f ImageMagick. \u041d\u0430 \u0440\u0435\u0441\u0430\u0439\u0437\u0435\u0440\u0435 \u0435\u0441\u0442\u044c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441 \u043a\u044d\u0448\u0435\u043c, \u0442\u0443\u0434\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438. <br \/>  \u041f\u0430\u0440\u0441\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u043d\u0443\u0436\u043d\u043e\u0435 \u0435\u043c\u0443 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438 \u0438\u0434\u0435\u043c \u0432 ceph, \u0437\u0430\u0442\u0435\u043c \u043d\u0430 \u043b\u0435\u0442\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c. <br \/>  serve_image.lua  <\/p>\n<pre><code class=\"lua\">require &quot;config&quot; local function return_not_found(msg)     ngx.status = ngx.HTTP_NOT_FOUND     if msg then         ngx.header[&quot;X-Message&quot;] = msg     end     ngx.exit(0) end  local name, size, ext = ngx.var.name, ngx.var.size, ngx.var.ext if not size or size == '' then     return_not_found() end if not image_scales[size] then     return_not_found('Unexpected image scale') end  local cache_dir =  static_storage_path .. '\/' .. ngx.var.first .. '\/' .. ngx.var.second .. '\/' local original_fname = cache_dir .. name .. ext local dest_fname = cache_dir .. name .. size .. ext  -- make sure the file exists local file = io.open(original_fname) if not file then     -- download file contents from ceph     ngx.req.read_body()     local data = ngx.location.capture(&quot;\/ceph_loader&quot;, {vars = { name = name .. ext }})     if data.status == ngx.HTTP_OK and data.body:len()&gt;0 then         os.execute( &quot;mkdir -p &quot; .. cache_dir )         local original = io.open(original_fname, &quot;w&quot;)         original:write(data.body)         original:close()     else         return_not_found('Original returned ' .. data.status)     end end                                                                                                                                                                                                                                   local magick = require(&quot;imagick&quot;)                                                                                                                                                                                                  magick.thumb(original_fname, image_scales[size], dest_fname)                                                                                                                                                                      ngx.exec(&quot;@after_resize&quot;) <\/code><\/pre>\n<p>  \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u0438\u043d\u0434\u0438\u043d\u0433 <a href=\"https:\/\/github.com\/leafo\/magick\">imagic.lua<\/a>. \u0414\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"http:\/\/luajit.org\/\">LuaJIT<\/a>. <\/p>\n<p>  nginx_partial_resizer.conf.template  <\/p>\n<pre><code class=\"nginx\"># Old images location ~ ^\/(small|small_wide|medium|big|mobile|scaled|original|iphone_(preview|retina_preview|big|retina_big|small|retina_small))_ {     rewrite \/([^\/]+)$ \/__CEPH_BUCKET__\/$1 break;     proxy_pass __UPSTREAM__; } # Try get image from ceph, then from local cache, then from scaled by lua original # If image test.png is original, when user wants test_30x30.png: # 1) Try get it from ceph, if not exists # 2) Try get it from \/cache\/t\/es\/test_30x30.ong, if not exists # 3) Resize original test.png and put it in \/cache\/t\/es\/test_30x30.ong location ~ ^\/(?&lt;name&gt;(?&lt;first&gt;.)(?&lt;second&gt;..)[^_]+)((?&lt;size&gt;_[^.]+)|)(?&lt;ext&gt;\\.[a-zA-Z]*)$ {     proxy_intercept_errors on;     rewrite \/([^\/]+)$ \/__CEPH_BUCKET__\/$1 break;     proxy_pass __UPSTREAM__;     error_page 404 403 = @local; } # Helper failover location for upper command cause you can't write # try_files __UPSTREAM__ \/cache\/$uri @resizer =404; location @local {     try_files \/cache\/$first\/$second\/$name$size$ext @resize; }  # If scaled file not found in local cache resize it with lua magic! location @resize { #    lua_code_cache off;     content_by_lua_file &quot;__APP_DIR__\/lua\/serve_image.lua&quot;; }  # serve scaled file, invoked in @resizer serve_image.lua location @after_resize {     try_files \/cache\/$first\/$second\/$name$size$ext =404; }  # used in @resizer serve_image.lua to download original image # $name contains original image file name location =\/ceph_loader {     internal;     rewrite ^(.+)$ \/__CEPH_BUCKET__\/$name break;     proxy_set_header Cache-Control no-cache;     proxy_set_header If-Modified-Since &quot;&quot;;     proxy_set_header If-None-Match &quot;&quot;;     proxy_pass __UPSTREAM__; }  location =\/favicon.ico {     return 404; }  location =\/robots.txt {} <\/code><\/pre>\n<p>  2. Firewall \u0434\u043b\u044f API. \u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c rps \u0438 \u0448\u043b\u0430\u0433\u0431\u0430\u0443\u043c \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d. <br \/>  Firewall.lua  <\/p>\n<pre><code class=\"lua\">module(..., package.seeall); local function ban(type, element)     CStorage.banPermanent:set(type .. '__' .. element, 1);     ngx.location.capture('\/postgres_ban', { ['vars'] = { ['type'] = type, ['value'] = element} }); end local function checkBanned(apiKey)     -- init search criteria     local searchCriteria = {};     searchCriteria['key'] = apiKey;     if ngx.var.remote_addr then         searchCriteria['ip'] = ngx.var.remote_addr;     end;     -- search in ban lists     for type, item in pairs(searchCriteria) do         local storageKey = type .. '__' .. item;         if CStorage.banPermanent:get(storageKey) then             ngx.exit(444);         elseif CStorage.banTmp:get(storageKey) then             -- calculate rps and check is our client still bad boy 8-)             local rps = CStorage.RPS:incr(storageKey, 1);             if not(rps) then                 CStorage.RPS:set(storageKey, 1, 1);                 rps=1;             end;             if rps then                 if rps &gt; config.app_params['ban_params']['rps_for_ip_to_permanent_ban'] then                     CStorage.RPS:delete(storageKey);                     ban(type, item);                     ngx.exit(444);                 elseif config.app_params['ban_params']['rps_for_ip_to_tmp_ban'] &gt; 0 and rps == config.app_params['ban_params']['rps_for_ip_to_tmp_ban'] then                     local attemptsCount = CStorage.banTmp:incr(storageKey, 1) - 1;                     if attemptsCount &gt; config.app_params['ban_params']['tmp_ban']['max_attempt_to_exceed_rps'] then                         -- permanent ban                         CStorage.banTmp:delete(storageKey);                         ban(type, item);                     end;                 end;             end;             ngx.exit(444);         end;     end; end;  local function checkTemporaryBlocked(apiKey)     local blockedData = CStorage.tmpBlockedDemoKeys:get(apiKey);     if blockedData then         --storage.tmpBlockedDemoKeys:incr(apiKey, 1); -- think about it.         return CApiException.throw('tmpDemoBlocked');     end; end;  local function checkRPS(apiKey)     local rps = nil;     -- check rps for IP and ban it if it's needed     if ngx.var.remote_addr then         local ip = 'ip__' .. tostring(ngx.var.remote_addr);         rps = CStorage.RPS:incr(ip, 1);         if not(rps) then             CStorage.RPS:set(ip, 1, 1);             rps = 1;         end;         if rps &gt; config.app_params['ban_params']['rps_for_ip_to_permanent_ban'] then             ban('ip', tostring(ngx.var.remote_addr));             ngx.exit(444);         elseif config.app_params['ban_params']['rps_for_ip_to_tmp_ban'] &gt; 0 and rps &gt; config.app_params['ban_params']['rps_for_ip_to_tmp_ban'] then             CStorage.banTmp:set(ip, 1, config.app_params['ban_params']['tmp_ban']['time']);             ngx.exit(444);         end;     end;      local apiKey_key_storage = 'key_' .. apiKey['key'];     -- check rps for key     rps = CStorage.RPS:incr(apiKey_key_storage, 1);     if not(rps) then         CStorage.RPS:set(apiKey_key_storage, 1, 1);         rps = 1;     end;     if apiKey['max_rps'] and rps &gt; tonumber(apiKey['max_rps']) then         if apiKey['mode'] == 'demo' then             CApiKey.blockTemporary(apiKey['key']);             return CApiException.throw('tmpDemoBlocked');         else             CApiKey.block(apiKey['key']);             return CApiException.throw('blocked');         end;     end;      -- similar check requests per period (RPP) for key     if apiKey['max_request_count_per_period'] and apiKey['period_length'] then         local rpp = CStorage.RPP:incr(apiKey_key_storage, 1);         if not(rpp) then             CStorage.RPP:set(apiKey_key_storage, 1, tonumber(apiKey['period_length']));             rpp = 1;         end;          if rpp &gt; tonumber(apiKey['max_request_count_per_period']) then             if apiKey['mode'] == 'demo' then                 CApiKey.blockTemporary(apiKey['key']);                 return CApiException.throw('tmpDemoBlocked');             else                 CApiKey.block(apiKey['key']);                 return CApiException.throw('blocked');             end;         end;     end; end;  function run()     local apiKey = ngx.ctx.REQUEST['key'];     if not(apiKey) then         return CApiException.throw('unauthorized');     end;     apiKey = tostring(apiKey)     -- check permanent and temporary banned     checkBanned(apiKey);     -- check api key     apiKey = CApiKey.getData(apiKey);      if not(apiKey) then         return CApiException.throw('forbidden');     end;     apiKey = JSON:decode(apiKey);     if not(apiKey['is_active']) then         return CApiException.throw('blocked');     end;      apiKey['key'] = tostring(apiKey['key']);     -- check is key in tmp blocked list     if apiKey['mode'] == 'demo' then         checkTemporaryBlocked(apiKey['key']);     end;      -- check requests count per second and per period     checkRPS(apiKey);     -- set apiKey's json to global parameter; in index.lua we send it through nginx to php application     ngx.ctx.GLOBAL['api_key'] = JSON:encode(apiKey); end; <\/code><\/pre>\n<p>  Validator.lua  <\/p>\n<pre><code class=\"lua\">module(..., package.seeall);  local function checkApiVersion()     local apiVersion = '';     if not (ngx.ctx.REQUEST['version']) then         local nginx_request = tostring(ngx.var.uri);         local version = nginx_request:sub(2,4);         if tonumber(version:sub(1,1)) and tonumber(version:sub(3,3)) then             apiVersion = version;         else             return CApiException.throw('versionIsRequired');         end;     else         apiVersion = ngx.ctx.REQUEST['version'];     end;      local isSupported = false;     for i, version in pairs(config.app_params['supported_api_version']) do         if apiVersion == version then             isSupported = true;         end;     end;      if not (isSupported) then         CApiException.throw('unsupportedVersion');     end;      ngx.ctx.GLOBAL['api_version'] = apiVersion; end;  local function checkKey()     if not (ngx.ctx.REQUEST['key']) then         CApiException.throw('unauthorized');     end; end;  function run()     checkApiVersion();     checkKey(); end; <\/code><\/pre>\n<p>  Apikey.lua  <\/p>\n<pre><code class=\"lua\">module ( ..., package.seeall )  function init()     if not(ngx.ctx.GLOBAL['CApiKey']) then         ngx.ctx.GLOBAL['CApiKey'] = {};     end end;  function flush()     CStorage.apiKey:flush_all();     CStorage.apiKey:flush_expired(); end;  function load()     local dbError = nil;     local dbData = ngx.location.capture('\/postgres_get_keys');     dbData = dbData.body;     dbData, dbError = rdsParser.parse(dbData);     if dbData ~= nil then         local rows = dbData.resultset         if rows then             for i, row in ipairs(rows) do                 local cacheKeyData = {};                 for col, val in pairs(row) do                     if val ~= rdsParser.null then                         cacheKeyData[col] = val;                     else                         cacheKeyData[col] = nil;                     end                 end                 CStorage.apiKey:set(tostring(cacheKeyData['key']),JSON:encode(cacheKeyData));             end;         end;     end; end;  function checkNotEmpty()     if not(ngx.ctx.GLOBAL['CApiKey']['loaded']) then         local cnt = CHelper.tablelength(CStorage.apiKey:get_keys(1));         if cnt == 0 then             load();         end;         ngx.ctx.GLOBAL['CApiKey']['loaded'] = 1;     end; end;  function getData(key)     checkNotEmpty();     return CStorage.apiKey:get(key); end;  function getStatus(key)         key = getData(key);         local result = '';         if key ~= nil then             key = JSON:decode(key);             if key['is_active'] ~= nil and  key['is_active'] == true then                 result = 'allowed';             else                 result = 'blocked';             end;         else             result = 'forbidden';         end;         return result; end;  function blockTemporary(apiKey)     apiKey = tostring(apiKey);     local isset = getData(apiKey);     if isset then         CStorage.tmpBlockedDemoKeys:set(apiKey, 1, config.app_params['ban_params']['time_demo_apikey_block_tmp']);     end; end;  function block(apiKey)     apiKey = tostring(apiKey);     local keyData = getData(apiKey);     if keyData then         ngx.location.capture('\/redis_get', { ['vars'] = { ['key'] = apiKey } });         keyData['is_active'] = false;         CStorage.apiKey:set(apiKey,JSON:encode(cacheKeyData));     end; end; <\/code><\/pre>\n<p>  Storages.lua  <\/p>\n<pre><code class=\"lua\">module ( ..., package.seeall )  apiKey = ngx.shared.apiKey; RPS = ngx.shared.RPS; RPP = ngx.shared.RPP; banPermanent = ngx.shared.banPermanent; banTmp = ngx.shared.banTmp; tmpBlockedDemoKeys = ngx.shared.tmpBlockedDemoKeys; <\/code><\/pre>\n<p>  3. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u0435\u0436\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 AMQP. \u041f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/github.com\/wingify\/lua-resty-rabbitmqstomp\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  4. \u041a\u0430\u043a \u044f <a href=\"http:\/\/habrahabr.ru\/company\/nordavind\/blog\/196518\/#comment_6823882\">\u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b<\/a>. \u041c\u043e\u0434\u0443\u043b\u044c \u0441\u0430\u043c\u043e\u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u201c\u0443\u043c\u043d\u043e\u0433\u043e\u201d \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 \u0431\u0435\u043a\u0435\u043d\u0434\u044b. \u0415\u0449\u0435 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435. <\/p>\n<p>  5. \u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 API. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b. \u0427\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c, <a href=\"http:\/\/tech.3scale.net\/2013\/01\/09\/augment-your-api-without-touching-it\/\">LUA \u043f\u043e\u043c\u043e\u0436\u0435\u0442<\/a>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, json&lt;-&gt;xml conversion \u043d\u0430 \u043b\u0435\u0442\u0443. <\/p>\n<p>  6\u2026. \u0438\u0434\u0435\u0439 \u0435\u0449\u0435 \u043c\u043d\u043e\u0433\u043e. <\/p>\n<p>  \u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u043e\u0432 \u043a\u0430\u043a \u0442\u0430\u043a\u043e\u0432\u044b\u0445 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u043d\u044b \u0438 \u0440\u043f\u0441 \u043f\u043e\u0441\u043b\u0435 \u0431\u0435\u043d\u0447\u0430 \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u043d\u043e\u0433\u0438\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432. \u041e\u0434\u043d\u0430\u043a\u043e, \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432, \u043c\u044b \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c 20-\u043a\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u0430 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0432\u0441\u0435 \u0441\u0442\u0430\u043b\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0434\u043e ~200 \u0440\u0430\u0437. <\/p>\n<h5>\u041f\u043b\u044e\u0441\u044b \u0438 \u043c\u0438\u043d\u0443\u0441\u044b<\/h5>\n<p>  \u041e\u0449\u0443\u0442\u0438\u043c\u044b\u0435 \u043f\u043b\u044e\u0441\u044b. \u0412\u0441\u0435, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b\u043e 5 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0430\u043c\u0438 \u043a\u043e\u0434\u0430 \u043d\u0430 php, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 100\u043a\u0431 \u0444\u0430\u0439\u043b \u043d\u0430 lua. <br \/>   \u2014 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438,<br \/>   \u2014 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f,<br \/>   \u2014 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c,<br \/>   \u2014 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0431\u0435\u043a\u0435\u043d\u0434\u0430\u043c\u0438, \u043d\u0435 \u043b\u043e\u043c\u0430\u044e\u0449\u0430\u044f \u043f\u0440\u0438 \u044d\u0442\u043e\u043c event loop nginx,<br \/>   \u2014 LUA sugar feel good! \u041a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, shared dictionary \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0444\u043e\u0440\u043a\u043e\u0432 nginx, \u0441\u0430\u0431\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u044b, \u043a\u0443\u0447\u0430 \u0431\u0438\u043d\u0434\u0438\u043d\u0433\u043e\u0432. <\/p>\n<p>  \u041d\u0435\u043e\u0449\u0443\u0442\u0438\u043c\u044b\u0435 \u043c\u0438\u043d\u0443\u0441\u044b.<br \/>   \u2014 \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0434\u043e \u0432\u0441\u0435 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0438 \u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u0440\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0438 event loop nginx.<br \/>   \u2014 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0431\u0435\u043a\u0435\u043d\u0434\u0443. \u041c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043f\u0440\u044f\u043c\u0430\u044f \u0441\u0432\u044f\u0437\u044c, \u0431\u0435\u0437 \u043f\u0440\u043e\u0441\u043b\u043e\u0435\u043a. \u042f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e 10000 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 LUA \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435 \u043f\u0440\u043e\u0436\u0443\u0435\u0442 \u043b\u0435\u0433\u043a\u043e. \u041d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u043e \u0437\u0430\u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0439\u0442\u0438 \u0432 \u0431\u0430\u0437\u0443, \u0442\u0443\u0442 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. <br \/>   \u2014 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043b\u0430\u0434\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0439\u0434\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a. <\/p>\n<p>  \u041a\u0441\u0442\u0430\u0442\u0438, \u043f\u043e\u043a\u0430 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f, \u043f\u0440\u044f\u043c\u043e \u0432 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u0448 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442 <a href=\"http:\/\/www.highload.ru\/2013\/abstracts\/934.html\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442<\/a> \u043f\u0440\u043e \u0432\u0441\u0435 \u044d\u0442\u043e \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u0445 \u043d\u0430 highload. <\/p>\n<p>  \u0421 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435\u043c \u043e\u0442\u0432\u0435\u0442\u0438\u043c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.    \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/199504\/\"> http:\/\/habrahabr.ru\/post\/199504\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t\u0414\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b <a href=\"http:\/\/2gis.ru\">\u0432\u0441\u0435\u0445<\/a> \u043d\u0430\u0448\u0438\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 nginx. \u042d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u044d\u0442\u043e \u043d\u0430\u0434\u0435\u0436\u043d\u043e. \u041f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043d\u0438\u043c \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442. \u041d\u0430\u0448\u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0440\u044b\u0439. \u0410\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044f \u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0442\u0435\u0442. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0443\u0441\u043a\u043e\u0440\u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043d\u0430\u0448\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0420\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u201cnginx as web application\u201d. <br \/>  \u0410 \u0438\u043c\u0435\u043d\u043d\u043e, \u043e <a href=\"http:\/\/wiki.nginx.org\/3rdPartyModules\">\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445<\/a> \u043c\u043e\u0434\u0443\u043b\u044f\u0445 (\u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c LUA), \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0445 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u0435\u0449\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u043e.<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage3\/f1e\/b02\/7aa\/f1eb027aa4164f226b39146ddf95092a.jpg\" alt=\"image\"\/>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-199504","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/199504","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=199504"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/199504\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=199504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=199504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=199504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}