{"id":318189,"date":"2021-02-17T21:01:07","date_gmt":"2021-02-17T21:01:07","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=318189"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=318189","title":{"rendered":"\u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430: \u0434\u043e\u043a\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f, \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u0442\u0435\u0441\u0442\u044b"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u044f php \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u042f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439, \u043a\u0430\u043a \u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043b \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u0432\u043e\u0438\u0445 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437 \u043f\u043e\u0434\u0435\u043b\u043a\u0438 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435 \u0441\u0442\u0430\u043b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0441 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c 1000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u043e\u0447\u0435\u043d\u044c \u0443\u0437\u043a\u043e\u0439 \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438. <\/p>\n<h2>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h2>\n<p>\u041f\u0430\u0440\u0443 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u044f \u0440\u0435\u0448\u0438\u043b \u0442\u0440\u044f\u0445\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u0438\u043d\u043e\u0439 \u0438 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0432 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Lineage_II\" rel=\"noopener noreferrer nofollow\">LineAge II <\/a>\u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043f\u0438\u0440\u0430\u0442\u0441\u043a\u0438\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0438\u0433\u0440\u0435 \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f &#171;\u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c&#187; \u0441 \u044f\u0449\u0438\u043a\u0430\u043c\u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 4 \u0431\u043e\u0441\u0441\u043e\u0432. \u042f\u0449\u0438\u043a \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 2 \u043c\u0438\u043d\u0443\u0442\u044b. \u0421\u0430\u043c\u0438 \u0431\u043e\u0441\u0441\u044b \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u044f 24 +\/- 6\u0447, \u0442\u043e \u0435\u0441\u0442\u044c \u0448\u0430\u043d\u0441 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0435\u0441\u0442\u044c \u043a\u0430\u043a \u0447\u0435\u0440\u0435\u0437 18\u0447, \u0442\u0430\u043a \u0438 \u0447\u0435\u0440\u0435\u0437 30\u0447. \u0423 \u043c\u0435\u043d\u044f \u043d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u044b\u043b\u0430 \u0444\u0443\u043b\u043b\u0442\u0430\u0439\u043c \u0440\u0430\u0431\u043e\u0442\u0430, \u0434\u0430 \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0436\u0434\u0430\u0442\u044c \u044d\u0442\u0438 \u044f\u0449\u0438\u043a\u0438. \u041d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043c\u043e\u0438\u043c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u044d\u0442\u043e\u0442 \u043a\u0432\u0435\u0441\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b &#171;\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c&#187; \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0435\u0441\u0442\u044c RSS \u0444\u0438\u0434 \u0432 \u0444\u043e\u0440\u043c\u0435\u0442 XML, \u0433\u0434\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u044e\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u043c\u0435\u0440\u0442\u0438 \u0431\u043e\u0441\u0441\u0430.<\/p>\n<p>\u0417\u0430\u0434\u0443\u043c\u043a\u0430 \u0431\u044b\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 RSS<\/p>\n<\/li>\n<li>\n<p>\u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0435\u0439 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043a\u0430\u043d\u0430\u043b<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u0431\u043e\u0441\u0441\u0430 \u043d\u0435 \u0443\u0431\u0438\u043b\u0438 \u0437\u0430 \u043f\u0435\u0440\u0432\u044b\u0435 9\u0447 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c &#171;\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c 3\u0447&#187;, \u0438 &#171;\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c 1,5\u0447&#187;. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0432\u0435\u0447\u0435\u0440\u043e\u043c \u043f\u0440\u0438\u0448\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c 3\u0447, \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043c\u0435\u0440\u0442\u044c \u0431\u043e\u0441\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044f \u043f\u043e\u0439\u0434\u0443 \u0441\u043f\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0434 \u043d\u0430 php \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e 3 php \u0444\u0430\u0439\u043b\u0430. \u041e\u0434\u0438\u043d \u0431\u044b\u043b \u0441 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%91%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82\" rel=\"noopener noreferrer nofollow\">god object <\/a>\u043a\u043b\u0430\u0441\u0441\u043e\u043c, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432 \u0434\u0432\u0443\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 &#8212; \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u043e\u0432\u044b\u0445, \u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0435\u0441\u0442\u044c \u043b\u0438 \u0431\u043e\u0441\u0441\u044b \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c &#171;\u0440\u0435\u0441\u043f\u0435&#187;. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u043b \u044f \u0438\u0445 \u043a\u0440\u043e\u043d \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438. \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0438 \u0440\u0435\u0448\u0430\u043b\u043e \u043c\u043e\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443.<\/p>\n<p>\u0414\u0440\u0443\u0433\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043b\u0438, \u0447\u0442\u043e \u044f \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0441\u044c \u0432 \u0438\u0433\u0440\u0435 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 \u0431\u043e\u0441\u0441\u043e\u0432, \u0438 \u0447\u0435\u0440\u0435\u0437 10 \u0434\u043d\u0435\u0439 \u0443 \u043c\u0435\u043d\u044f \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 \u0431\u044b\u043b\u043e \u043e\u043a\u043e\u043b\u043e 50 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432. \u0422\u0430\u043a \u0436\u0435 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0434\u043b\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430\u0442\u0441\u043a\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0417\u0430\u0434\u0430\u0447\u0443 \u044f \u0442\u043e\u0436\u0435 \u0440\u0435\u0448\u0438\u043b \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u043e\u0439. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0443 \u043c\u0435\u043d\u044f \u0443\u0436\u0435 4 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043f\u043e\u0447\u0442\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0438 \u0444\u0430\u0439\u043b \u0441 god object. \u041f\u043e\u0442\u043e\u043c \u043c\u0435\u043d\u044f \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043b\u044f \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430\u0442\u0441\u043a\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0418 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0443 \u043c\u0435\u043d\u044f \u0441\u043f\u0443\u0441\u0442\u044f \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u0443 \u043c\u0435\u043d\u044f 6 \u0444\u0430\u0439\u043b\u043e\u0432, \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0442 \u0441\u0435\u0431\u044f \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e (\u043f\u043e 2 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440)<\/p>\n<\/li>\n<li>\n<p>\u043e\u0434\u0438\u043d god object \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0442\u0435\u043d \u0441\u0442\u0440\u043e\u043a<\/p>\n<\/li>\n<li>\n<p>MySQL \u0438 Redis \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0433\u0434\u0435 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043b \u043a\u043e\u0434<\/p>\n<\/li>\n<li>\n<p>cron \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0444\u0430\u0439\u043b\u044b<\/p>\n<\/li>\n<li>\n<p>~1400 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043b \u043c\u0435\u0441\u044f\u0446\u0430\u043c\u0438 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f &#171;\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 &#8212; \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0439&#187;. \u041d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0432 \u043f\u043e\u0440\u044f\u0434\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0449\u0435 \u0431\u044b\u043b\u043e \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043b\u0435\u0433\u0447\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0438 \u0442\u0434. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0437\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435, \u0432 \u0441\u0432\u043e\u0435 \u043b\u0438\u0447\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<h2>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0441\u043b\u0435 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430<\/h2>\n<ol>\n<li>\n<p>\u041e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0433\u0447\u0435 \u0431\u044b\u043b\u043e \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 &#8212; \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438, \u043f\u043e \u0441\u0443\u0442\u0438 \u0440\u0430\u0441\u043a\u0438\u0434\u0430\u0442\u044c god object \u043f\u043e \u0444\u0430\u0439\u043b\u0430\u043c, \u0441\u0430\u043c \u043a\u043e\u0434 \u043d\u0435 \u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u0438\u043d\u0430\u0447\u0435 \u044d\u0442\u043e \u0437\u0430\u0442\u044f\u043d\u0435\u0442 \u0441\u0440\u043e\u043a\u0438. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c PSR-12.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 supervisor<\/p>\n<\/li>\n<li>\n<p>\u0412\u043d\u0435\u0434\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Codeception<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c MySQL \u0438 Redis<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Github Actions \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 code style<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u043d\u044f\u0442\u044c Prometheus, Grafana \u0434\u043b\u044f \u043c\u0435\u0442\u0440\u0438\u043a \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \/metrics \u0434\u043b\u044f Prometheus<\/p>\n<\/li>\n<li>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u0435\u0440 \u043e\u0431\u0440\u0430\u0437 \u0434\u043b\u044f \u0431\u043e\u0442\u0430 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0440\u0435\u0437 \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c 4 \u0431\u043e\u0441\u0441\u043e\u0432 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u0431\u043e\u0442\u0443 \u0432 \u043b\u0438\u0447\u043a\u0443<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0430\u0436\u043d\u043e\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u0412\u0441\u0435 \u044d\u0442\u0438 \u0448\u0430\u0433\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0432 \u0442\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043a\u0430\u043a \u044f \u0438\u0445 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e \u0432 \u044d\u0442\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435. \u0421\u0434\u0435\u043b\u0430\u043b \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0435 \u0437\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u043b\u044e\u0441 \u043f\u0430\u0440\u0430 \u0432\u0435\u0447\u0435\u0440\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u0422\u0430\u043a \u0436\u0435 \u0432 \u0446\u0435\u043b\u044f\u0445 \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 &#171;\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u043c&#187;, \u043d\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c &#171;\u0440\u0435\u0432\u043e\u043b\u044e\u0446\u0438\u0438&#187;, \u0430 \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043f\u043b\u0430\u0432\u043d\u043e \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u0438\u0437 \u043f\u043b\u0430\u043d\u0430 \u0434\u0430\u0432\u0430\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<h2>\u0428\u0430\u0433 1. \u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u0431\u044b\u043b\u043e \u043d\u0435 \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u043e \u043d\u0435\u0434\u0435\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430\u043c\u0438 Singleton<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace AsteriosBot\\Core\\Support;  use AsteriosBot\\Core\\Exception\\DeserializeException; use AsteriosBot\\Core\\Exception\\SerializeException;  class Singleton {     protected static $instances = [];      \/**      * Singleton constructor.      *\/     protected function __construct()     {         \/\/ do nothing     }      \/**      * Disable clone object.      *\/     protected function __clone()     {         \/\/ do nothing     }      \/**      * Disable serialize object.      *      * @throws SerializeException      *\/     public function __sleep()     {         throw new SerializeException(\"Cannot serialize singleton\");     }      \/**      * Disable deserialize object.      *      * @throws DeserializeException      *\/     public function __wakeup()     {         throw new DeserializeException(\"Cannot deserialize singleton\");     }      \/**      * @return static      *\/     public static function getInstance(): Singleton     {         $subclass = static::class;         if (!isset(self::$instances[$subclass])) {             self::$instances[$subclass] = new static();         }         return self::$instances[$subclass];     } }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b\u0437\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442 \u043d\u0435\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>getInstance()<\/code><\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace AsteriosBot\\Core\\Connection;  use AsteriosBot\\Core\\App; use AsteriosBot\\Core\\Support\\Config; use AsteriosBot\\Core\\Support\\Singleton; use FaaPz\\PDO\\Database as DB;  class Database extends Singleton {     \/**      * @var DB      *\/     protected DB $connection;      \/**      * @var Config      *\/     protected Config $config;      \/**      * Database constructor.      *\/     protected function __construct()     {         $this-&gt;config = App::getInstance()-&gt;getConfig();         $dto = $this-&gt;config-&gt;getDatabaseDTO();         $this-&gt;connection = new DB($dto-&gt;getDsn(), $dto-&gt;getUser(), $dto-&gt;getPassword());     }      \/**      * @return DB      *\/     public function getConnection(): DB     {         return $this-&gt;connection;     } }<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u044f \u043d\u0435 \u043c\u0435\u043d\u044f\u043b \u0441\u0430\u043c\u0443 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443, \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0432\u0441\u0435 &#171;\u043a\u0430\u043a \u0431\u044b\u043b\u043e&#187;. \u0426\u0435\u043b\u044c \u0431\u044b\u043b\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u0435\u0441\u0442\u0438 \u043f\u043e \u0444\u0430\u0439\u043b\u0430\u043c \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u043e\u043a, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0434\u043b\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u0441\u0442\u0430\u043c\u0438.<\/p>\n<h2>\u0428\u0430\u0433 2: \u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432<\/h2>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0447\u0435\u0440\u0435\u0437 <code>docker-compose.yml<\/code><\/p>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043b\u044f \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"markdown\">  worker:     build:       context: .       dockerfile: docker\/worker\/Dockerfile     container_name: 'asterios-bot-worker'     restart: always     volumes:       - .:\/app\/     networks:       - tier<\/code><\/pre>\n<p>\u0410 \u0441\u0430\u043c  <code>docker\/worker\/Dockerfile<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>FROM php:7.4.3-alpine3.11  # Copy the application code COPY . \/app  RUN apk update &amp;&amp; apk add --no-cache \\     build-base shadow vim curl supervisor \\     php7 \\     php7-fpm \\     php7-common \\     php7-pdo \\     php7-pdo_mysql \\     php7-mysqli \\     php7-mcrypt \\     php7-mbstring \\     php7-xml \\     php7-simplexml \\     php7-openssl \\     php7-json \\     php7-phar \\     php7-zip \\     php7-gd \\     php7-dom \\     php7-session \\     php7-zlib \\     php7-redis \\     php7-session   # Add and Enable PHP-PDO Extenstions RUN docker-php-ext-install pdo pdo_mysql RUN docker-php-ext-enable pdo_mysql  # Redis RUN apk add --no-cache pcre-dev $PHPIZE_DEPS \\         &amp;&amp; pecl install redis \\         &amp;&amp; docker-php-ext-enable redis.so  # Install PHP Composer RUN curl -sS https:\/\/getcomposer.org\/installer | php -- --install-dir=\/usr\/local\/bin --filename=composer  # Remove Cache RUN rm -rf \/var\/cache\/apk\/*  # setup supervisor ADD docker\/supervisor\/asterios.conf \/etc\/supervisor\/conf.d\/asterios.conf ADD docker\/supervisor\/supervisord.conf \/etc\/supervisord.conf  VOLUME [\"\/app\"]  WORKDIR \/app  RUN composer install  CMD [\"\/usr\/bin\/supervisord\", \"-c\", \"\/etc\/supervisord.conf\"] <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 Dockerfile, \u0442\u0430\u043c \u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e supervisord, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432.<\/p>\n<h2>\u0428\u0430\u0433 3: \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 supervisor<\/h2>\n<p>\u0412\u0430\u0436\u043d\u044b\u0439 \u0434\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440 \u043f\u043e supervisor. \u041e\u043d \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0434\u043e\u043b\u0433\u043e, \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0433\u043e &#171;\u043f\u0430\u0434\u0435\u043d\u0438\u044f&#187; &#8212; \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c. \u041c\u043e\u0438 \u0436\u0435 php \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u043b\u0438\u0441\u044c. supervisor \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0438\u0445 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u0430\u043b \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0441\u043d\u043e\u0432\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u0430\u043c \u043a\u043e\u0434 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430 1 \u043c\u0438\u043d\u0443\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0441  supervisor. <\/p>\n<p>\u041a\u043e\u0434 \u0444\u0430\u0439\u043b\u0430 worker.php<\/p>\n<pre><code class=\"php\">&lt;?php  require __DIR__ . '\/vendor\/autoload.php';  use AsteriosBot\\Channel\\Checker; use AsteriosBot\\Channel\\Parser; use AsteriosBot\\Core\\App; use AsteriosBot\\Core\\Connection\\Log;  $app = App::getInstance(); $checker = new Checker(); $parser = new Parser(); $servers = $app-&gt;getConfig()-&gt;getEnableServers(); $logger = Log::getInstance()-&gt;getLogger(); $expectedTime = time() + 60; \/\/ +1 min in seconds $oneSecond = time(); while (true) {     $now = time();     if ($now &gt;= $oneSecond) {         $oneSecond = $now + 1;         try {             foreach ($servers as $server) {                 $parser-&gt;execute($server);                 $checker-&gt;execute($server);             }         } catch (\\Throwable $e) {             $logger-&gt;error($e-&gt;getMessage(), $e-&gt;getTrace());         }     }     if ($expectedTime &lt; $now) {         die(0);     } }<\/code><\/pre>\n<p>\u0423 RSS \u0435\u0441\u0442\u044c \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0441\u043f\u0430\u043c\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0438 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 1\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0439 \u0432\u043e\u0440\u043a\u0435\u0440 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 2 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 rss, \u0430 \u0437\u0430\u0442\u0435\u043c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0431\u043e\u0441\u0441\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e \u0441\u0442\u0430\u0440\u0442\u0435 \u0438\u043b\u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0435\u0441\u043f\u0430\u0443\u043d\u0430 \u0431\u043e\u0441\u0441\u043e\u0432. \u041f\u043e\u0441\u043b\u0435 1 \u043c\u0438\u043d\u0443\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u043e\u0440\u043a\u0435\u0440 \u0443\u043c\u0438\u0440\u0430\u0435\u0442, \u0438 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 supervisor<\/p>\n<p>\u0421\u0430\u043c \u043a\u043e\u043d\u0444\u0438\u0433 supervisor \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"markdown\">[program:worker] command = php \/app\/worker.php stderr_logfile=\/app\/logs\/supervisor\/worker.log numprocs = 1 user = root startsecs = 3 startretries = 10 exitcodes = 0,2 stopsignal = SIGINT reloadsignal = SIGHUP stopwaitsecs = 10 autostart = true autorestart = true stdout_logfile = \/dev\/stdout stdout_logfile_maxbytes = 0 redirect_stderr = true<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0441\u0443\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 &#8212; \u0432 \u0444\u0430\u0439\u043b\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430 <code>\/etc\/supervisord.conf<\/code>\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0435\u043c\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0438\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432<\/p>\n<pre><code>[supervisord] nodaemon=true  [include] files = \/etc\/supervisor\/conf.d\/*.conf<\/code><\/pre>\n<p>\u041d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 supervisorctl:<\/p>\n<pre><code>supervisorctl status       # \u0441\u0442\u0430\u0442\u0443\u0441 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 supervisorctl stop all     # \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 supervisorctl start all    # \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 supervisorctl start worker # \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0434\u0438\u043d \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0430, \u0431\u043b\u043e\u043a [program:worker]<\/code><\/pre>\n<h3>\u0428\u0430\u0433 4: \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Codeception <\/h3>\n<p>\u042f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e \u0447\u0443\u0442\u044c-\u0447\u0443\u0442\u044c \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0442\u044c <code>unit<\/code> \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434, \u0430 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0449\u0435 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435. \u041f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u044e\u043d\u0438\u0442 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043f\u0430\u0440\u0443 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u043e\u0441\u043e\u0431\u043e \u0432\u0430\u0436\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0431\u044b\u043b\u0430 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439, \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u043b\u043e\u0441\u044c \u0441 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432 \u043a\u043e\u043d\u0444\u0438\u0433 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b<\/p>\n<pre><code># Codeception Test Suite Configuration # # Suite for unit or integration tests.  actor: UnitTester modules:     enabled:         - Asserts         - \\Helper\\Unit         - Db:               dsn: 'mysql:host=mysql;port=3306;dbname=test_db;'               user: 'root'               password: 'password'               dump: 'tests\/_data\/dump.sql'               populate: true               cleanup: true               reconnect: true               waitlock: 10               initial_queries:                 - 'CREATE DATABASE IF NOT EXISTS test_db;'                 - 'USE test_db;'                 - 'SET NAMES utf8;'     step_decorators: ~<\/code><\/pre>\n<h3>\u0428\u0430\u0433 5: \u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f MySQL \u0438 Redis<\/h3>\n<p>\u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0433\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e \u0435\u0449\u0435 \u043f\u0430\u0440\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043e\u0442\u043e\u0432. \u0412\u0441\u0435 \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0435\u0440 MySQL \u0438 \u043e\u0434\u0438\u043d Redis \u0434\u043b\u044f \u043a\u0435\u0448\u0430. \u042f \u0440\u0435\u0448\u0438\u043b \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c \u0432 \u043e\u0442\u0435\u043b\u044c\u043d\u044b\u0439 docker-compose.yml, \u0430 \u0441\u0430\u043c\u0438\u0445 \u0431\u043e\u0442\u043e\u0432 \u0437\u0430\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 docker network<\/p>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>version: '3'  services:   mysql:     image: mysql:5.7.22     container_name: 'telegram-bots-mysql'     restart: always     ports:       - \"3306:3306\"     environment:       MYSQL_ROOT_PASSWORD: \"${DB_PASSWORD}\"       MYSQL_ROOT_HOST: '%'     volumes:       - .\/docker\/sql\/dump.sql:\/docker-entrypoint-initdb.d\/dump.sql     networks:       - tier    redis:     container_name: 'telegram-bots-redis'     image: redis:3.2     restart: always     ports:       - \"127.0.0.1:6379:6379\/tcp\"     networks:       - tier    pma:     image: phpmyadmin\/phpmyadmin     container_name: 'telegram-bots-pma'     environment:       PMA_HOST: mysql       PMA_PORT: 3306       MYSQL_ROOT_PASSWORD: \"${DB_PASSWORD}\"     ports:       - '8006:80'     networks:       - tier  networks:   tier:     external:       name: telegram-bots-network<\/code><\/pre>\n<p>DB_PASSWORD \u044f \u0445\u0440\u0430\u043d\u044e \u0432 .env \u0444\u0430\u0439\u043b\u0435, \u0430 .\/docker\/sql\/dump.sql \u0443 \u043c\u0435\u043d\u044f \u043b\u0435\u0436\u0438\u0442 \u0431\u0435\u043a\u0430\u043f \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0430\u043a \u0436\u0435 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b external network \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0435 &#8212; \u0432 \u043a\u0430\u0436\u0434\u043e\u043c docker-compose.yml \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043e\u0442\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u043d\u0438 \u0432\u0441\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0438\u0435 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0440\u0435\u0434\u0438\u0441.<\/p>\n<h3>\u0428\u0430\u0433 6: \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Github Actions<\/h3>\n<p>\u0412 \u0448\u0430\u0433\u0435 4 \u044d\u0442\u043e\u0433\u043e \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0444\u043e\u0440\u043a Codeception, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u0441\u0430\u043c\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0435\u0442 \u0431\u0430\u0437\u044b, \u0432 \u0448\u0430\u0433\u0435 5 \u044f \u0435\u0435 \u0432\u044b\u043d\u0435\u0441 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0438 \u0437\u0430\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u043b \u0447\u0435\u0440\u0435\u0437 external docker network. \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 Github Actions \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u043d\u0430 \u043b\u0435\u0442\u0443 \u0442\u0430\u043a \u0436\u0435 \u0447\u0435\u0440\u0435\u0437 docker-compose.<\/p>\n<pre><code class=\"xml\">name: Actions  on:   pull_request:     branches: [master]   push:     branches: [master]  jobs:   build:     runs-on: ubuntu-latest     steps:       - name: Checkout         uses: actions\/checkout@v2        - name: Get Composer Cache Directory         id: composer-cache         run: |           echo \"::set-output name=dir::$(composer config cache-files-dir)\"       - uses: actions\/cache@v1         with:           path: ${{ steps.composer-cache.outputs.dir }}           key: ${{ runner.os }}-composer-${{ hashFiles('**\/composer.lock') }}           restore-keys: |             ${{ runner.os }}-composer-       - name: Composer validate         run: composer validate       - name: Composer Install         run: composer install --dev --no-interaction --no-ansi --prefer-dist --no-suggest --ignore-platform-reqs       - name: PHPCS check         run: php vendor\/bin\/phpcs --standard=psr12 app\/ -n       - name: Create env file         run: |           cp .env.github.actions .env       - name: Build the docker-compose stack         run: docker-compose -f docker-compose.github.actions.yml -p asterios-tests up -d       - name: Sleep         uses: jakejarvis\/wait-action@master         with:           time: '30s'       - name: Run test suite         run: docker-compose -f docker-compose.github.actions.yml -p asterios-tests exec -T php vendor\/bin\/codecept run unit<\/code><\/pre>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>on<\/code>\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u0433\u0434\u0430 \u0431\u0438\u043b\u0434 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u0451\u0442\u0441\u044f. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0443\u043b\u043b \u0440\u0435\u043a\u0432\u0435\u0441\u0442\u0430 \u0438\u043b\u0438 \u043f\u0440\u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u0435 \u0432 \u043c\u0430\u0441\u0442\u0435\u0440.<\/p>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>uses: actions\/checkout@v2<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043a \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044e. <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u0435\u0448\u0430 \u043a\u043e\u043c\u043f\u043e\u0437\u0435\u0440\u0430, \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0435\u0441\u043b\u0438 \u0432 \u043a\u0435\u0448\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 run: <code>php vendor\/bin\/phpcs --standard=psr12 app\/ -n<\/code>\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043a\u043e\u0434\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 <a href=\"https:\/\/www.php-fig.org\/psr\/psr-12\/\" rel=\"noopener noreferrer nofollow\">PSR-12<\/a> \u0432 \u043f\u0430\u043f\u043a\u0435 <code>.\/app<\/code>  <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0442\u0443\u0442 \u0443 \u043c\u0435\u043d\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0444\u0430\u0439\u043b <code>.env.github.actions<\/code>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 <code>.env<\/code> C\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 <code>.env.github.actions<\/code><\/p>\n<pre><code>SERVICE_ROLE=test TG_API=XXXXX TG_ADMIN_ID=123 TG_NAME=AsteriosRBbot DB_HOST=mysql DB_NAME=root DB_PORT=3306 DB_CHARSET=utf8 DB_USERNAME=root DB_PASSWORD=password LOG_PATH=.\/logs\/ DB_NAME_TEST=test_db REDIS_HOST=redis REDIS_PORT=6379 REDIS_DB=0 SILENT_MODE=true FILLER_MODE=true<\/code><\/pre>\n<p>\u0418\u0437 \u0432\u0430\u0436\u043d\u043e\u0433\u043e \u0442\u0443\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0431\u0430\u0437\u044b \u0432 \u044d\u0442\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u044e \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>docker-compose.github.actions.yml<\/code>\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u0438 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 <code>docker-compose.github.actions.yml<\/code>:<\/p>\n<pre><code class=\"xml\">version: '3'  services:    php:     build:       context: .       dockerfile: docker\/php\/Dockerfile     container_name: 'asterios-tests-php'     volumes:       - .:\/app\/     networks:       - asterios-tests-network    mysql:     image: mysql:5.7.22     container_name: 'asterios-tests-mysql'     restart: always     ports:       - \"3306:3306\"     environment:       MYSQL_DATABASE: asterios       MYSQL_ROOT_PASSWORD: password     volumes:       - .\/tests\/_data\/dump.sql:\/docker-entrypoint-initdb.d\/dump.sql     networks:       - asterios-tests-network # #  redis: #    container_name: 'asterios-tests-redis' #    image: redis:3.2 #    ports: #      - \"127.0.0.1:6379:6379\/tcp\" #    networks: #      - asterios-tests-network  networks:   asterios-tests-network:     driver: bridge<\/code><\/pre>\n<p>\u042f \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 Redis, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u0421\u0431\u043e\u0440\u043a\u0430 \u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c docker-compose \u0444\u0430\u0439\u043b\u043e\u043c, \u0430 \u0437\u0430\u0442\u0435\u043c \u0442\u0435\u0441\u0442\u044b &#8212; \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a<\/p>\n<pre><code>docker-compose -f docker-compose.github.actions.yml -p asterios-tests up -d docker-compose -f docker-compose.github.actions.yml -p asterios-tests exec -T php vendor\/bin\/codecept run unit<\/code><\/pre>\n<p>\u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u043e\u0431\u0440\u0430\u0442\u0438\u0442 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0430\u0440\u0442\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432. \u042d\u0442\u043e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0441\u043f\u0435\u043b\u0430 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<h3>\u0428\u0430\u0433 7: \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Prometheus \u0438 Grafana<\/h3>\n<p>\u0412 \u0448\u0430\u0433\u0435 5 \u044f \u0432\u044b\u043d\u0435\u0441 MySQL \u0438 Redis \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 docker-compose.yml. \u0422\u0430\u043a \u043a\u0430\u043a Prometheus \u0438 Grafana \u0442\u043e\u0436\u0435 \u043e\u0431\u0449\u0438\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043c\u043e\u0438\u0445 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u043e\u0432, \u044f \u0438\u0445 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0442\u0443\u0434\u0430 \u0436\u0435. \u0421\u0430\u043c \u043a\u043e\u043d\u0444\u0438\u0433 \u044d\u0442\u0438\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>  prometheus:     image: prom\/prometheus:v2.0.0     command:       - '--config.file=\/etc\/prometheus\/prometheus.yml'     restart: always     ports:       - 9090:9090     volumes:       - .\/prometheus.yml:\/etc\/prometheus\/prometheus.yml     networks:       - tier    grafana:     container_name: 'telegram-bots-grafana'     image: grafana\/grafana:7.1.1     ports:       - 3000:3000     environment:       - GF_RENDERING_SERVER_URL=http:\/\/renderer:8081\/render       - GF_RENDERING_CALLBACK_URL=http:\/\/grafana:3000\/       - GF_LOG_FILTERS=rendering:debug     volumes:       - .\/grafana.ini:\/etc\/grafana\/grafana.ini       - grafanadata:\/var\/lib\/grafana     networks:       - tier     restart: always   renderer:     image: grafana\/grafana-image-renderer:latest     container_name: 'telegram-bots-grafana-renderer'     restart: always     ports:       - 8081     networks:       - tier<\/code><\/pre>\n<p>\u041e\u043d\u0438 \u0442\u0430\u043a \u0436\u0435 \u0437\u0430\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u043d\u044b \u043e\u0434\u043d\u043e\u0439 \u0441\u0435\u0442\u044c\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0442\u043e\u043c \u043b\u0438\u043d\u043a\u0443\u0435\u0442\u0441\u044f \u0441 external docker network. <\/p>\n<p><strong>Prometheus<\/strong>: \u044f \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u044e \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433 prometheus.yml, \u0433\u0434\u0435 \u044f \u043c\u043e\u0433\u0443 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043c\u0435\u0442\u0440\u0438\u043a<\/p>\n<p><strong>Grafana<\/strong>: \u044f \u0441\u043e\u0437\u0434\u0430\u044e volume, \u0433\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b. \u0422\u0430\u043a \u0436\u0435 \u044f \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0438\u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 alert. \u0421 \u044d\u0442\u0438\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c alert \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0441\u043e \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043e\u043c \u0433\u0440\u0430\u0444\u0438\u043a\u0430.<\/p>\n<p>\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u044e \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u043f\u043b\u0430\u0433\u0438\u043d, \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e Grafana \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/p>\n<pre><code>docker-compose up -d docker-compose exec grafana grafana-cli plugins install grafana-image-renderer docker-compose stop  grafana  docker-compose up -d grafana<\/code><\/pre>\n<h3>\u0428\u0430\u0433 8: \u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043c\u0435\u0442\u0440\u0438\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u0430 \u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u0440\u0438\u043a \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b <a href=\"https:\/\/github.com\/endclothing\/prometheus_client_php\" rel=\"noopener noreferrer nofollow\">endclothing\/prometheus_client_php <\/a><\/p>\n<p>\u0422\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043c\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043c\u0435\u0442\u0440\u0438\u043a<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace AsteriosBot\\Core\\Connection;  use AsteriosBot\\Core\\App; use AsteriosBot\\Core\\Support\\Singleton; use Prometheus\\CollectorRegistry; use Prometheus\\Exception\\MetricsRegistrationException; use Prometheus\\Storage\\Redis;  class Metrics extends Singleton {     private const METRIC_HEALTH_CHECK_PREFIX = 'healthcheck_';     \/**      * @var CollectorRegistry      *\/     private $registry;      protected function __construct()     {         $dto = App::getInstance()-&gt;getConfig()-&gt;getRedisDTO();         Redis::setDefaultOptions(             [                 'host' =&gt; $dto-&gt;getHost(),                 'port' =&gt; $dto-&gt;getPort(),                 'database' =&gt; $dto-&gt;getDatabase(),                 'password' =&gt; null,                 'timeout' =&gt; 0.1, \/\/ in seconds                 'read_timeout' =&gt; '10', \/\/ in seconds                 'persistent_connections' =&gt; false             ]         );         $this-&gt;registry = CollectorRegistry::getDefault();     }      \/**      * @return CollectorRegistry      *\/     public function getRegistry(): CollectorRegistry     {         return $this-&gt;registry;     }      \/**      * @param string $metricName      *      * @throws MetricsRegistrationException      *\/     public function increaseMetric(string $metricName): void     {         $counter = $this-&gt;registry-&gt;getOrRegisterCounter('asterios_bot', $metricName, 'it increases');         $counter-&gt;incBy(1, []);     }      \/**      * @param string $serverName      *      * @throws MetricsRegistrationException      *\/     public function increaseHealthCheck(string $serverName): void     {         $prefix = App::getInstance()-&gt;getConfig()-&gt;isTestServer() ? 'test_' : '';         $this-&gt;increaseMetric($prefix . self::METRIC_HEALTH_CHECK_PREFIX . $serverName);     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0443 \u0432 Redis \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 RSS. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b, \u0437\u043d\u0430\u0447\u0438\u0442 \u0432\u0441\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0443<\/p>\n<pre><code>        if ($counter) {             $this-&gt;metrics-&gt;increaseHealthCheck($serverName);         }<\/code><\/pre>\n<p>\u0413\u0434\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f $counter \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 RSS. \u0422\u0430\u043c \u0431\u0443\u0434\u0435\u0442 0, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u0438 \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u0435\u0442\u0440\u0438\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430. \u042d\u0442\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043b\u044f alert \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430. <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0443\u0436\u043d\u043e \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \/metric \u0447\u0442\u043e\u0431\u044b Prometheus \u0438\u0445 \u0441\u043f\u0430\u0440\u0441\u0438\u043b. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0445\u043e\u0441\u0442 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433 prometheus.yml \u0438\u0437 \u0448\u0430\u0433\u0430 7.<\/p>\n<pre><code># my global config global:   scrape_interval:     5s # Set the scrape interval to every 15 seconds. Default is every 1 minute.   evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.   # scrape_timeout is set to the global default (10s).  scrape_configs:   - job_name: 'bots-env'     static_configs:       - targets:           - prometheus:9090           - pushgateway:9091           - grafana:3000           - metrics:80 # \u0442\u0443\u0442 \u0431\u0443\u0434\u0443\u0442 \u043c\u043e\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043f\u043e uri \/metrics<\/code><\/pre>\n<p>\u041a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0442\u0430\u0449\u0438\u0442 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0438\u0437 Redis \u0438 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u042d\u0442\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c Prometheus<\/p>\n<pre><code class=\"php\">$metrics = Metrics::getInstance(); $renderer = new RenderTextFormat(); $result = $renderer-&gt;render($metrics-&gt;getRegistry()-&gt;getMetricFamilySamples()); header('Content-type: ' . RenderTextFormat::MIME_TYPE); echo $result;<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0441\u0430\u043c \u0434\u0430\u0448\u0431\u043e\u0440\u0434 \u0438 alert. \u0412 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 Grafana \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 Prometheus \u043a\u0430\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u0430\u043d\u0430\u043b \u043d\u043e\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c (\u0442\u0430\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0441\u0432\u043e\u0435\u0433\u043e \u0431\u043e\u0442\u0430 \u0438 \u0441\u0432\u043e\u0439 chat_id \u0441 \u044d\u0442\u0438\u043c \u0431\u043e\u0442\u043e\u043c)<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/387\/a8a\/c1f\/387a8ac1f6b4dc66db0d521f008b3a62.png\" alt=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Grafana\" title=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Grafana\" width=\"1920\" height=\"965\"><figcaption>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Grafana<\/figcaption><\/figure>\n<ol>\n<li>\n<p>\u041c\u0435\u0442\u0440\u0438\u043a\u0430 <code>increase(asterios_bot_healthcheck_x3[1m])<\/code> \u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u0440\u0438\u043a\u0430 asterios_bot_healthcheck_x3 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b\u0430\u0441\u044c \u0437\u0430 1 \u043c\u0438\u043d\u0443\u0442\u0443 <\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 (\u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u043c)<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043b\u0435\u0433\u0435\u043d\u0434\u044b \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 4.<\/p>\n<\/li>\n<li>\n<p>\u041b\u0435\u0433\u0435\u043d\u0434\u0430 \u0441\u043f\u0440\u0430\u0432\u0430 \u0438\u0437 \u043f\u0443\u043d\u043a\u0442\u0430 3.<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c57\/55d\/47b\/c5755d47be83774ae6ad6a0bfa19776a.png\" width=\"1493\" height=\"704\"><figcaption><\/figcaption><\/figure>\n<ol>\n<li>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u0440\u0438\u043a\u0430. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0447\u0442\u043e \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043d\u0435 \u0431\u044b\u043b\u043e<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c alert. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#171;\u041a\u043e\u0433\u0434\u0430 \u0441\u0443\u043c\u043c\u0430 \u0438\u0437 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0410 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u0438 10 \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430\u0437\u0430\u0434&#187;<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043e\u043e\u0431\u0449\u0435 &#8212; \u0441\u043b\u0430\u0442\u044c alert<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 alert<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 alert \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0442\u0430\u043a (\u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0434\u043b\u044f alert?)<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fba\/c58\/c41\/fbac58c416a3ad88977f5b00192b889d.png\" alt=\"Alert \u0432 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c\" title=\"Alert \u0432 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c\" width=\"546\" height=\"473\"><figcaption>Alert \u0432 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c<\/figcaption><\/figure>\n<ol>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, alert \u0437\u0430\u043c\u0435\u0442\u0438\u043b \u043f\u0430\u0434\u0435\u043d\u0438\u0435, \u043d\u043e \u0432\u0441\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u043e\u0441\u044c. Grafana \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0430\u0441\u044c \u0441\u043b\u0430\u0442\u044c alert, \u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0443\u043c\u0430\u043b\u0430. \u042d\u0442\u043e \u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e 30 \u0441\u0435\u043a\u0443\u043d\u0434<\/p>\n<\/li>\n<li>\n<p>\u0422\u0443\u0442 \u0443\u0436\u0435 \u0432\u0441\u0435 \u0443\u043f\u0430\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u043d\u0430 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u0438 alert \u0431\u044b\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 alert<\/p>\n<\/li>\n<li>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 dashboard<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043c\u0435\u0442\u0440\u0438\u043a\u0438<\/p>\n<\/li>\n<\/ol>\n<h2>\u0428\u0430\u0433 9: \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442<\/h2>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u0430 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u043e\u0440\u043a\u0435\u0440\u0430. \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442 \u043f\u043e \u0441\u0443\u0442\u0438 \u0443 \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0432\u043e\u0440\u043a\u0435\u0440, \u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0432 supervisor. \u0422\u0443\u0442 \u0443\u0436\u0435 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u0430\u043b \u0441\u0432\u043e\u0438 \u043f\u043b\u043e\u0434\u044b, \u0437\u0430\u043f\u0443\u0441\u043a \u0431\u043e\u0442\u0430 \u0431\u044b\u043b \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u043c.<\/p>\n<h2>\u0418\u0442\u043e\u0433\u0438<\/h2>\n<p>\u042f \u0436\u0430\u043b\u0435\u044e, \u0447\u0442\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u043b \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u043d\u044c\u0448\u0435. \u042f \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u043b \u0431\u043e\u0442\u0430 \u043d\u0430 \u043f\u0435\u0440\u0438\u043e\u0434 \u043f\u0435\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441 \u043d\u043e\u0432\u044b\u043c\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0430\u043c\u0438, \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u0441\u0442\u0430\u043b\u0438 \u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u0430\u0440\u0443 \u043d\u043e\u0432\u044b\u0445 \u0444\u0438\u0447\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u043b\u0438 \u043b\u0435\u0433\u0447\u0435 \u0438 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u044d\u0442\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u0442 \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u043f\u0435\u0442-\u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u043f\u043e\u0440\u044f\u0434\u043e\u043a. \u041d\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c. <\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u044b<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/omentes\/asterios-bot\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/omentes\/asterios-bot<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/omentes\/bots-environment \" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/omentes\/bots-environment <\/a><\/p>\n<\/li>\n<\/ul>\n<\/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=\"https:\/\/habr.com\/ru\/post\/542978\/\"> https:\/\/habr.com\/ru\/post\/542978\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u044f php \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u042f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439, \u043a\u0430\u043a \u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043b \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u0432\u043e\u0438\u0445 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0431\u043e\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437 \u043f\u043e\u0434\u0435\u043b\u043a\u0438 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435 \u0441\u0442\u0430\u043b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0441 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c 1000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u043e\u0447\u0435\u043d\u044c \u0443\u0437\u043a\u043e\u0439 \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438. <\/p>\n<h2>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h2>\n<p>\u041f\u0430\u0440\u0443 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u044f \u0440\u0435\u0448\u0438\u043b \u0442\u0440\u044f\u0445\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u0438\u043d\u043e\u0439 \u0438 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0432 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/Lineage_II\" rel=\"noopener noreferrer nofollow\">LineAge II <\/a>\u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043f\u0438\u0440\u0430\u0442\u0441\u043a\u0438\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0438\u0433\u0440\u0435 \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f &#171;\u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c&#187; \u0441 \u044f\u0449\u0438\u043a\u0430\u043c\u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 4 \u0431\u043e\u0441\u0441\u043e\u0432. \u042f\u0449\u0438\u043a \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 2 \u043c\u0438\u043d\u0443\u0442\u044b. \u0421\u0430\u043c\u0438 \u0431\u043e\u0441\u0441\u044b \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u044f 24 +\/- 6\u0447, \u0442\u043e \u0435\u0441\u0442\u044c \u0448\u0430\u043d\u0441 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0435\u0441\u0442\u044c \u043a\u0430\u043a \u0447\u0435\u0440\u0435\u0437 18\u0447, \u0442\u0430\u043a \u0438 \u0447\u0435\u0440\u0435\u0437 30\u0447. \u0423 \u043c\u0435\u043d\u044f \u043d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u044b\u043b\u0430 \u0444\u0443\u043b\u043b\u0442\u0430\u0439\u043c \u0440\u0430\u0431\u043e\u0442\u0430, \u0434\u0430 \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0436\u0434\u0430\u0442\u044c \u044d\u0442\u0438 \u044f\u0449\u0438\u043a\u0438. \u041d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043c\u043e\u0438\u043c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u044d\u0442\u043e\u0442 \u043a\u0432\u0435\u0441\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b &#171;\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c&#187; \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0435\u0441\u0442\u044c RSS \u0444\u0438\u0434 \u0432 \u0444\u043e\u0440\u043c\u0435\u0442 XML, \u0433\u0434\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u044e\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u043c\u0435\u0440\u0442\u0438 \u0431\u043e\u0441\u0441\u0430.<\/p>\n<p>\u0417\u0430\u0434\u0443\u043c\u043a\u0430 \u0431\u044b\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 RSS<\/p>\n<\/li>\n<li>\n<p>\u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0435\u0439 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043a\u0430\u043d\u0430\u043b<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u0431\u043e\u0441\u0441\u0430 \u043d\u0435 \u0443\u0431\u0438\u043b\u0438 \u0437\u0430 \u043f\u0435\u0440\u0432\u044b\u0435 9\u0447 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c &#171;\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c 3\u0447&#187;, \u0438 &#171;\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c 1,5\u0447&#187;. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0432\u0435\u0447\u0435\u0440\u043e\u043c \u043f\u0440\u0438\u0448\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c 3\u0447, \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043c\u0435\u0440\u0442\u044c \u0431\u043e\u0441\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044f \u043f\u043e\u0439\u0434\u0443 \u0441\u043f\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0434 \u043d\u0430 php \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e 3 php \u0444\u0430\u0439\u043b\u0430. \u041e\u0434\u0438\u043d \u0431\u044b\u043b \u0441 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%91%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82\" rel=\"noopener noreferrer nofollow\">god object <\/a>\u043a\u043b\u0430\u0441\u0441\u043e\u043c, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u0432\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432 \u0434\u0432\u0443\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 &#8212; \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u043e\u0432\u044b\u0445, \u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0435\u0441\u0442\u044c \u043b\u0438 \u0431\u043e\u0441\u0441\u044b \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c &#171;\u0440\u0435\u0441\u043f\u0435&#187;. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u043b \u044f \u0438\u0445 \u043a\u0440\u043e\u043d \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438. \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0438 \u0440\u0435\u0448\u0430\u043b\u043e \u043c\u043e\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443.<\/p>\n<p>\u0414\u0440\u0443\u0433\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043b\u0438, \u0447\u0442\u043e \u044f \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0441\u044c \u0432 \u0438\u0433\u0440\u0435 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 \u0431\u043e\u0441\u0441\u043e\u0432, \u0438 \u0447\u0435\u0440\u0435\u0437 10 \u0434\u043d\u0435\u0439 \u0443 \u043c\u0435\u043d\u044f \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 \u0431\u044b\u043b\u043e \u043e\u043a\u043e\u043b\u043e 50 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432. \u0422\u0430\u043a \u0436\u0435 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0434\u043b\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430\u0442\u0441\u043a\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0417\u0430\u0434\u0430\u0447\u0443 \u044f \u0442\u043e\u0436\u0435 \u0440\u0435\u0448\u0438\u043b \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u043e\u0439. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0443 \u043c\u0435\u043d\u044f \u0443\u0436\u0435 4 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043f\u043e\u0447\u0442\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0438 \u0444\u0430\u0439\u043b \u0441 god object. \u041f\u043e\u0442\u043e\u043c \u043c\u0435\u043d\u044f \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043b\u044f \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430\u0442\u0441\u043a\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0418 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0443 \u043c\u0435\u043d\u044f \u0441\u043f\u0443\u0441\u0442\u044f \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u0443 \u043c\u0435\u043d\u044f 6 \u0444\u0430\u0439\u043b\u043e\u0432, \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0442 \u0441\u0435\u0431\u044f \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e (\u043f\u043e 2 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440)<\/p>\n<\/li>\n<li>\n<p>\u043e\u0434\u0438\u043d god object \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0442\u0435\u043d \u0441\u0442\u0440\u043e\u043a<\/p>\n<\/li>\n<li>\n<p>MySQL \u0438 Redis \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0433\u0434\u0435 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043b \u043a\u043e\u0434<\/p>\n<\/li>\n<li>\n<p>cron \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0444\u0430\u0439\u043b\u044b<\/p>\n<\/li>\n<li>\n<p>~1400 \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u043e\u0432 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043b \u043c\u0435\u0441\u044f\u0446\u0430\u043c\u0438 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f &#171;\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 &#8212; \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0439&#187;. \u041d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0432 \u043f\u043e\u0440\u044f\u0434\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0449\u0435 \u0431\u044b\u043b\u043e \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043b\u0435\u0433\u0447\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0438 \u0442\u0434. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0437\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435, \u0432 \u0441\u0432\u043e\u0435 \u043b\u0438\u0447\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<h2>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0441\u043b\u0435 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430<\/h2>\n<ol>\n<li>\n<p>\u041e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043b\u0435\u0433\u0447\u0435 \u0431\u044b\u043b\u043e \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 &#8212; \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438, \u043f\u043e \u0441\u0443\u0442\u0438 \u0440\u0430\u0441\u043a\u0438\u0434\u0430\u0442\u044c god object \u043f\u043e \u0444\u0430\u0439\u043b\u0430\u043c, \u0441\u0430\u043c \u043a\u043e\u0434 \u043d\u0435 \u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u0438\u043d\u0430\u0447\u0435 \u044d\u0442\u043e \u0437\u0430\u0442\u044f\u043d\u0435\u0442 \u0441\u0440\u043e\u043a\u0438. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c PSR-12.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 supervisor<\/p>\n<\/li>\n<li>\n<p>\u0412\u043d\u0435\u0434\u0440\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Codeception<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c MySQL \u0438 Redis<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Github Actions \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 code style<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u043d\u044f\u0442\u044c Prometheus, Grafana \u0434\u043b\u044f \u043c\u0435\u0442\u0440\u0438\u043a \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<li>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \/metrics \u0434\u043b\u044f Prometheus<\/p>\n<\/li>\n<li>\n<p>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u0435\u0440 \u043e\u0431\u0440\u0430\u0437 \u0434\u043b\u044f \u0431\u043e\u0442\u0430 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0440\u0435\u0437 \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c 4 \u0431\u043e\u0441\u0441\u043e\u0432 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u0431\u043e\u0442\u0443 \u0432 \u043b\u0438\u0447\u043a\u0443<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0430\u0436\u043d\u043e\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u0412\u0441\u0435 \u044d\u0442\u0438 \u0448\u0430\u0433\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0432 \u0442\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043a\u0430\u043a \u044f \u0438\u0445 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e \u0432 \u044d\u0442\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435. \u0421\u0434\u0435\u043b\u0430\u043b \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0435 \u0437\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u043b\u044e\u0441 \u043f\u0430\u0440\u0430 \u0432\u0435\u0447\u0435\u0440\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u0422\u0430\u043a \u0436\u0435 \u0432 \u0446\u0435\u043b\u044f\u0445 \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 &#171;\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u043c&#187;, \u043d\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c &#171;\u0440\u0435\u0432\u043e\u043b\u044e\u0446\u0438\u0438&#187;, \u0430 \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043f\u043b\u0430\u0432\u043d\u043e \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u0438\u0437 \u043f\u043b\u0430\u043d\u0430 \u0434\u0430\u0432\u0430\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<h2>\u0428\u0430\u0433 1. \u0420\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u0431\u044b\u043b\u043e \u043d\u0435 \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u043e \u043d\u0435\u0434\u0435\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430\u043c\u0438 Singleton<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace AsteriosBot\\Core\\Support;  use AsteriosBot\\Core\\Exception\\DeserializeException; use AsteriosBot\\Core\\Exception\\SerializeException;  class Singleton {     protected static $instances = [];      \/**      * Singleton constructor.      *\/     protected function __construct()     {         \/\/ do nothing     }      \/**      * Disable clone object.      *\/     protected function __clone()     {         \/\/ do nothing     }      \/**      * Disable serialize object.      *      * @throws SerializeException      *\/     public function __sleep()     {         throw new SerializeException(\"Cannot serialize singleton\");     }      \/**      * Disable deserialize object.      *      * @throws DeserializeException      *\/     public function __wakeup()     {         throw new DeserializeException(\"Cannot deserialize singleton\");     }      \/**      * @return static      *\/     public static function getInstance(): Singleton     {         $subclass = static::class;         if (!isset(self::$instances[$subclass])) {             self::$instances[$subclass] = new static();         }         return self::$instances[$subclass];     } }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b\u0437\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442 \u043d\u0435\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>getInstance()<\/code><\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace AsteriosBot\\Core\\Connection;  use AsteriosBot\\Core\\App; use AsteriosBot\\Core\\Support\\Config; use AsteriosBot\\Core\\Support\\Singleton; use FaaPz\\PDO\\Database as DB;  class Database extends Singleton {     \/**      * @var DB      *\/     protected DB $connection;      \/**      * @var Config      *\/     protected Config $config;      \/**      * Database constructor.      *\/     protected function __construct()     {         $this-&gt;config = App::getInstance()-&gt;getConfig();         $dto = $this-&gt;config-&gt;getDatabaseDTO();         $this-&gt;connection = new DB($dto-&gt;getDsn(), $dto-&gt;getUser(), $dto-&gt;getPassword());     }      \/**      * @return DB      *\/     public function getConnection(): DB     {         return $this-&gt;connection;     } }<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u044f \u043d\u0435 \u043c\u0435\u043d\u044f\u043b \u0441\u0430\u043c\u0443 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0443, \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0432\u0441\u0435 &#171;\u043a\u0430\u043a \u0431\u044b\u043b\u043e&#187;. \u0426\u0435\u043b\u044c \u0431\u044b\u043b\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u0435\u0441\u0442\u0438 \u043f\u043e \u0444\u0430\u0439\u043b\u0430\u043c \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u043e\u043a, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0434\u043b\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u0441\u0442\u0430\u043c\u0438.<\/p>\n<h2>\u0428\u0430\u0433 2: \u0414\u043e\u043a\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432<\/h2>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0447\u0435\u0440\u0435\u0437 <code>docker-compose.yml<\/code><\/p>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043b\u044f \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"markdown\">  worker:     build:       context: .       dockerfile: docker\/worker\/Dockerfile     container_name: 'asterios-bot-worker'     restart: always     volumes:       - .:\/app\/     networks:       - tier<\/code><\/pre>\n<p>\u0410 \u0441\u0430\u043c  <code>docker\/worker\/Dockerfile<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>FROM php:7.4.3-alpine3.11  # Copy the application code COPY . \/app  RUN apk update &amp;&amp; apk add --no-cache \\     build-base shadow vim curl supervisor \\     php7 \\     php7-fpm \\     php7-common \\     php7-pdo \\     php7-pdo_mysql \\     php7-mysqli \\     php7-mcrypt \\     php7-mbstring \\     php7-xml \\     php7-simplexml \\     php7-openssl \\     php7-json \\     php7-phar \\     php7-zip \\     php7-gd \\     php7-dom \\     php7-session \\     php7-zlib \\     php7-redis \\     php7-session   # Add and Enable PHP-PDO Extenstions RUN docker-php-ext-install pdo pdo_mysql RUN docker-php-ext-enable pdo_mysql  # Redis RUN apk add --no-cache pcre-dev $PHPIZE_DEPS \\         &amp;&amp; pecl install redis \\         &amp;&amp; docker-php-ext-enable redis.so  # Install PHP Composer RUN curl -sS https:\/\/getcomposer.org\/installer | php -- --install-dir=\/usr\/local\/bin --filename=composer  # Remove Cache RUN rm -rf \/var\/cache\/apk\/*  # setup supervisor ADD docker\/supervisor\/asterios.conf \/etc\/supervisor\/conf.d\/asterios.conf ADD docker\/supervisor\/supervisord.conf \/etc\/supervisord.conf  VOLUME [\"\/app\"]  WORKDIR \/app  RUN composer install  CMD [\"\/usr\/bin\/supervisord\", \"-c\", \"\/etc\/supervisord.conf\"] <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 Dockerfile, \u0442\u0430\u043c \u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e supervisord, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432.<\/p>\n<h2>\u0428\u0430\u0433 3: \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 supervisor<\/h2>\n<p>\u0412\u0430\u0436\u043d\u044b\u0439 \u0434\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440 \u043f\u043e supervisor. \u041e\u043d \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0434\u043e\u043b\u0433\u043e, \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0433\u043e &#171;\u043f\u0430\u0434\u0435\u043d\u0438\u044f&#187; &#8212; \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c. \u041c\u043e\u0438 \u0436\u0435 php \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u043b\u0438\u0441\u044c. supervisor \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0438\u0445 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u0430\u043b \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0441\u043d\u043e\u0432\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u0430\u043c \u043a\u043e\u0434 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430 1 \u043c\u0438\u043d\u0443\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0441  supervisor. <\/p>\n<p>\u041a\u043e\u0434 \u0444\u0430\u0439\u043b\u0430 worker.php<\/p>\n<pre><code class=\"php\">&lt;?php  require __DIR__ . '\/vendor\/autoload.php';  use AsteriosBot\\Channel\\Checker; use AsteriosBot\\Channel\\Parser; use AsteriosBot\\Core\\App; use AsteriosBot\\Core\\Connection\\Log;  $app = App::getInstance(); $checker = new Checker(); $parser = new Parser(); $servers = $app-&gt;getConfig()-&gt;getEnableServers(); $logger = Log::getInstance()-&gt;getLogger(); $expectedTime = time() + 60; \/\/ +1 min in seconds $oneSecond = time(); while (true) {     $now = time();     if ($now &gt;= $oneSecond) {         $oneSecond = $now + 1;         try {             foreach ($servers as $server) {                 $parser-&gt;execute($server);                 $checker-&gt;execute($server);             }         } catch (\\Throwable $e) {             $logger-&gt;error($e-&gt;getMessage(), $e-&gt;getTrace());         }     }     if ($expectedTime &lt; $now) {         die(0);     } }<\/code><\/pre>\n<p>\u0423 RSS \u0435\u0441\u0442\u044c \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0441\u043f\u0430\u043c\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0438 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 1\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0439 \u0432\u043e\u0440\u043a\u0435\u0440 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 2 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 rss, \u0430 \u0437\u0430\u0442\u0435\u043c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0431\u043e\u0441\u0441\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e \u0441\u0442\u0430\u0440\u0442\u0435 \u0438\u043b\u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0435\u0441\u043f\u0430\u0443\u043d\u0430 \u0431\u043e\u0441\u0441\u043e\u0432. \u041f\u043e\u0441\u043b\u0435 1 \u043c\u0438\u043d\u0443\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u043e\u0440\u043a\u0435\u0440 \u0443\u043c\u0438\u0440\u0430\u0435\u0442, \u0438 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 supervisor<\/p>\n<p>\u0421\u0430\u043c \u043a\u043e\u043d\u0444\u0438\u0433 supervisor \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"markdown\">[program:worker] command = php \/app\/worker.php stderr_logfile=\/app\/logs\/supervisor\/worker.log numprocs = 1 user = root startsecs = 3 startretries = 10 exitcodes = 0,2 stopsignal = SIGINT reloadsignal = SIGHUP stopwaitsecs = 10 autostart = true autorestart = true stdout_logfile = \/dev\/stdout stdout_logfile_maxbytes = 0 redirect_stderr = true<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0441\u0443\u043f\u0435\u0440\u0432\u0438\u0437\u043e\u0440 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0432\u043e\u0440\u043a\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 &#8212; \u0432 \u0444\u0430\u0439\u043b\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430 <code>\/etc\/supervisord.conf<\/code>\u043e\u0431\u044f\u0437<\/p>\n<\/div>\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-318189","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318189","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=318189"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318189\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=318189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=318189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=318189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}