{"id":485017,"date":"2026-06-25T12:42:33","date_gmt":"2026-06-25T12:42:33","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=485017"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=485017","title":{"rendered":"Kafka Consumer \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438: \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u0415\u0433\u043e\u0440 \u041b\u0430\u043f\u0442\u0435\u0432 \u2014 QA Fullstack Java \u0432 <a href=\"https:\/\/sense-it.ru\">SENSE<\/a> \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043a\u0440\u0443\u043f\u043d\u043e\u0433\u043e \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u0431\u0430\u043d\u043a\u0430.<\/p>\n<p>End-to-end \u0442\u0435\u0441\u0442\u044b UI \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435: \u043a\u043d\u043e\u043f\u043a\u0430 \u043d\u0430\u0436\u0430\u043b\u0430\u0441\u044c, \u0444\u043e\u0440\u043c\u0430 \u043e\u0442\u043a\u0440\u044b\u043b\u0430\u0441\u044c, \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u043b\u0438\u0441\u044c. \u041d\u043e \u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u0443\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u043a\u0430\u0434\u0440 \u2014 \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0442\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 Kafka. \u0415\u0441\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0435 \u0434\u043e\u0448\u043b\u043e \u0434\u043e \u0442\u043e\u043f\u0438\u043a\u0430 \u0438\u043b\u0438 \u043f\u0440\u0438\u0448\u043b\u043e \u0441 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u043c payload, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0442, \u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445 \u2014 \u0431\u0435\u0437 Kafka UI, kcat \u0438 \u043e\u0431\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043e\u0434\u043d\u043e\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u0438 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0432 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0441 SSL. \u041f\u043e\u043a\u0430\u0436\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430, \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b (SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b, \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b consumer group \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0438), \u0438 \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 AI-\u0430\u0433\u0435\u043d\u0442\u043e\u043c.<\/p>\n<p><strong>\u041a\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e:<\/strong> QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430\u043c \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u0430\u043c \u043f\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0445\u043e\u0442\u044f\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445; \u0438 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 AI-\u0430\u0433\u0435\u043d\u0442\u043e\u043c \u2014 \u043a\u0430\u043a \u043e\u043d\u0430 \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<h2>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>\u041c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0437\u0435\u043b\u0451\u043d\u044b\u0439, \u0430 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0441\u044b\u043f\u0430\u043b\u0438\u0441\u044c \u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b, \u0434\u043e\u0445\u043e\u0434\u044f\u0442 \u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e Kafka. \u0413\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b, \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c: \u0432\u0441\u0451 \u043b\u0438\u0431\u043e \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043b\u0438\u0431\u043e \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0435\u0442\u044f\u0445 \u0441 SSL.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0438 \u0440\u0443\u0447\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a. \u0420\u0430\u043d\u044c\u0448\u0435 \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u044b\u043b\u0430 \u0440\u0443\u0447\u043d\u043e\u0439: \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b \u0442\u0435\u0441\u0442, \u0448\u0451\u043b \u0432 Kafka UI \u0438\u043b\u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0438\u0441\u043a\u0430\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b payload. \u042d\u0442\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e, \u043d\u0435\u043d\u0430\u0434\u0451\u0436\u043d\u043e \u0438 \u043d\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u041c\u044b \u0445\u043e\u0442\u0435\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u044b\u043b\u0430 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439, \u043a\u0430\u043a \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 UI.<\/p>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0430\u043c \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u2014 \u043b\u0438\u0448\u044c \u0447\u0430\u0441\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0448\u0438\u0440\u043e\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430. \u041e\u043d \u043d\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0431\u044b \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435: \u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u043f\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u043b\u044c\u044e \u00ab\u043f\u0438\u0448\u0443 \u0442\u0435\u0441\u0442\u044b \u043f\u043e \u0422\u0417\u00bb, \u0430 \u0438\u0449\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u2014 \u043c\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u0440\u0443\u0447\u043d\u043e\u0439 \u0442\u0440\u0443\u0434 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0441\u0438\u043b\u0438\u0442\u044c AI. AI-\u0430\u0433\u0435\u043d\u0442 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u043a\u0430\u043a \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u044b: \u043e\u0442 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043e \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0440\u0435\u0432\u044c\u044e. \u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u2014 \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430.<\/p>\n<p><strong>\u0427\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/strong> \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0431\u0435\u0437 \u043e\u0431\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e Kafka UI, Confluent Control Center, Kafka REST Proxy \u0438\u043b\u0438 kcat \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044f\u043c\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 kafka-clients. \u041e\u0434\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 build.gradle, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u043e\u043a\u0441\u0438. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0432 CI\/CD, \u0432 Docker \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c bootstrapServers \u0438 \u043a\u0440\u0435\u0434\u044b.<\/p>\n<p><strong>\u0427\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u0446\u0438\u0444\u0440\u0430\u0445:<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u0435\u0442\u0440\u0438\u043a\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0414\u043e<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0441\u043b\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0394<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">~3 \u043c\u0438\u043d \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\">~5 \u0441\u0435\u043a \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0432 36 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u0433\u043e\u0432 \u0432 Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">~40% \u043e\u0442 \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0434-\u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">&lt;5%<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0432 8 \u0440\u0430\u0437 \u043c\u0435\u043d\u044c\u0448\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u043a\u0440\u044b\u0442\u0438\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0441 Kafka-\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">0 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">15+ \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0441 \u043d\u0443\u043b\u044f<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e Kafka-\u0442\u0435\u0441\u0442\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2 \u0434\u043d\u044f \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\">~2 \u0447\u0430\u0441\u0430 \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u043e\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0432 8 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041a\u0430\u043a\u0438\u0435 \u0431\u043e\u043b\u0438 \u0440\u0435\u0448\u0430\u0435\u0442 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440<\/h2>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>#<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0411\u043e\u043b\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b<\/strong> \u2014 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 CA \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 Java truststore, consumer \u043f\u0430\u0434\u0430\u0435\u0442 \u0441 SSLHandshakeException<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f SslEngineFactory \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 consumer \u0438 \u0434\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u043c\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0443<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Consumer Group \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b<\/strong> \u2014 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b \u0441 \u0442\u0435\u043c \u0436\u0435 groupId \u043e\u0442\u0431\u0438\u0440\u0430\u044e\u0442 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0443 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 groupId \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 + \u0440\u0435\u0436\u0438\u043c assignAllPartitions() \u0431\u0435\u0437 \u0443\u0447\u0430\u0441\u0442\u0438\u044f \u0432 consumer group<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0438<\/strong> \u2014 Thread.sleep() \u0442\u043e \u043d\u0435\u0434\u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u0436\u0434\u0451\u0442 \u0432\u043f\u0443\u0441\u0442\u0443\u044e, \u0442\u0435\u0441\u0442\u044b \u0444\u043b\u0430\u043a\u0430\u044e\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">Poll-\u0446\u0438\u043a\u043b \u0441 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0420\u0443\u0447\u043d\u0430\u044f \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/strong> \u2014 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438\u0434\u0451\u0442 \u0432 Kafka UI, \u0438\u0449\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 payload \u0440\u0443\u043a\u0430\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">BDD-\u0448\u0430\u0433\u0438: \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u0435\u043d\u0438\u0435, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u2014 \u0432\u0441\u0451 \u0432 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">5<\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/strong> \u2014 Kafka REST Proxy, kcat, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u2014 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0438 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432\u0435\u0437\u0434\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u044f\u043c\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 kafka-clients, \u043e\u0434\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0435\u0437\u0434\u0435<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u2014 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u043a\u0430\u0436\u0434\u043e\u0439 \u0431\u043e\u043b\u0438 \u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430<\/h2>\n<pre><code class=\"java\">src\/test\/java\/com\/example\/\u251c\u2500\u2500 client\/kafka\/\u2502   \u251c\u2500\u2500 KafkaConsumerClientjava \u2014 \u044f\u0434\u0440\u043e: consumer, poll, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f |\u2500\u2500 CustomSslEngineFactory.java   \u2014 SSL-\u043e\u0431\u0445\u043e\u0434 \u0434\u043b\u044f \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432\u251c\u2500\u2500 steps\/\u2502   \u2514\u2500\u2500 KafkaBddSteps.java        \u2014 BDD-\u0448\u0430\u0433\u0438 (Given\/When\/Then)\u2514\u2500\u2500 utils\/\u2514\u2500\u2500 ScenarioContext.java       \u2014 Singleton-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f src\/test\/resources\/\u251c\u2500\u2500 configuration\/config.properties\u2014 Kafka-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f (camelCase)\u2514\u2500\u2500 .env                           \u2014 Kafka-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f (UPPER_SNAKE_CASE)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c<\/strong> (build.gradle):<\/p>\n<p>testImplementation &#8216;org.apache.kafka:kafka-clients:3.7.0&#8217;<\/p>\n<h2>Consumer-\u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u2014 \u044f\u0434\u0440\u043e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430<\/h2>\n<p><strong>\u0414\u0432\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0438\u0442\u0430\u0435\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438\u0437 <a href=\"http:\/\/config.properties\">config.properties<\/a> \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0440\u0438\u0434\u0435\u0440<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421 \u044f\u0432\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 (bootstrapServers, saslMechanism, saslUsername, saslPassword, groupId, securityProtocol)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e groupId<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u0422\u0440\u0438 \u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u0435\u0442\u043e\u0434<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0420\u0435\u0436\u0438\u043c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>Offset<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">subscribe(topic)<\/p>\n<\/td>\n<td>\n<p align=\"left\">Consumer Group<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0442\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">assignPartition(topic, partition)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u044f\u043c\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">seekToBeginning<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">assignAllPartitions(topic)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">seekToBeginning<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0442\u043e\u043f\u0438\u043a\u0430 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430:<\/strong> subscribe() \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 consumer group \u2014 offset \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f. assign*() \u2014 \u043f\u0440\u044f\u043c\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439, \u0431\u0435\u0437 \u0432\u043b\u0438\u044f\u043d\u0438\u044f \u043d\u0430 consumer group offset.<\/p>\n<p><strong>\u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u0435\u0442\u043e\u0434<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pollMessages(timeoutSeconds)<\/p>\n<\/td>\n<td>\n<p align=\"left\">List&lt;ConsumerRecord&lt;String, String&gt;&gt;<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0426\u0438\u043a\u043b poll \u043f\u043e 1 \u0441\u0435\u043a \u0434\u043e \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pollOneMessage(timeoutSeconds)<\/p>\n<\/td>\n<td>\n<p align=\"left\">ConsumerRecord&lt;String, String&gt;<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u0435 \u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">pollMessageValues(timeoutSeconds)<\/p>\n<\/td>\n<td>\n<p align=\"left\">List&lt;String&gt;<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (\u0431\u0435\u0437 \u043a\u043b\u044e\u0447\u0435\u0439\/\u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u0441\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f <strong>\u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f<\/strong> \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c \u0431\u0443\u0444\u0435\u0440\u0435 \u2014 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p><strong>\u0424\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/strong><\/p>\n<pre><code class=\"java\">findMessagesContaining(substring)findMessagesByKey(key)getConsumedMessages()clearConsumedMessages()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 Consumer<\/strong><\/p>\n<p>Consumer \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438: \u0447\u0442\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u043e\u043f\u0438\u043a\u0430 (earliest), \u0440\u0443\u0447\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0438\u0442 offset \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043b\u0438\u043c\u0438\u0442 \u0432 100 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0437\u0430 \u043e\u0434\u0438\u043d poll. \u0414\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u043a\u043b\u044e\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u2014 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435.<\/p>\n<pre><code class=\"java\">auto.offset.reset=earliestenable.auto.commit=falsemax.poll.records=100key.deserializer=StringDeserializervalue.deserializer=StringDeserializer<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0416\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b<\/strong><\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 AutoCloseable \u2014 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 consumer&#8217;\u0430 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432 \u0445\u0443\u043a\u0435 \u043f\u043e\u0441\u043b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f:<\/p>\n<pre><code class=\"java\">@Afterpublic void closeKafkaConsumer() {Object consumer = context.getData(\"consumerKey\");if (consumer instanceof KafkaConsumerWrapper) {    ((KafkaConsumerWrapper) consumer).close();}}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>CustomSslEngineFactory \u2014 \u043c\u0435\u0442\u043e\u0434 configure()<\/strong><\/p>\n<pre><code class=\"java\">public class CustomSslEngineFactory implements SslEngineFactory {    private SSLContext sslContext;    @Override    public void configure(Map&lt;String, ?&gt; configs) {        try {            TrustManager[] trustAllCerts = new TrustManager[]{                new X509TrustManager() {                    public X509Certificate[] getAcceptedIssuers() {                        return new X509Certificate[0];                    }                    public void checkClientTrusted(X509Certificate[] certs,                                                    String authType) {}                    public void checkServerTrusted(X509Certificate[] certs,                                                    String authType) {}                }            };            sslContext = SSLContext.getInstance(\"TLS\");            sslContext.init(null, trustAllCerts, new SecureRandom());        } catch (Exception e) {            throw new RuntimeException(                    \"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c CustomSslEngineFactory\", e);        }    }    @Override    public SSLEngine createClientSslEngine(String peerHost, int peerPort,                                            String endpointIdentification) {        SSLEngine engine = sslContext.createSSLEngine(peerHost, peerPort);        engine.setUseClientMode(true);        engine.setSSLParameters(new SSLParameters());        return engine;    }\/\/ shouldBeRebuilt, reconfigurableConfigs, keystore, truststore, close \u2014 \u0431\u043e\u0439\u043b\u0435\u0440\u043f\u043b\u0435\u0439\u0442}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>KafkaConsumerClient \u2014 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 poll-\u0446\u0438\u043a\u043b<\/strong><\/p>\n<pre><code class=\"java\">public class KafkaConsumerClient implements AutoCloseable {    private KafkaConsumer&lt;String, String&gt; consumer;    private final List&lt;ConsumerRecord&lt;String, String&gt;&gt; consumedMessages = new ArrayList&lt;&gt;();    \/\/ ... \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u043f\u043e\u043b\u044f, buildConsumerProperties() ...    @Step(\"\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 Kafka \u0442\u043e\u043f\u0438\u043a: {topic}\")    public void subscribe(String topic) {        consumer = new KafkaConsumer&lt;&gt;(buildConsumerProperties());        consumer.subscribe(Collections.singletonList(topic));        consumer.poll(Duration.ofMillis(3000));    }    @Step(\"\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0442\u043e\u043f\u0438\u043a\u0430: {topic}, \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044f: {partition}\")    public void assignPartition(String topic, int partition) {        consumer = new KafkaConsumer&lt;&gt;(buildConsumerProperties());        TopicPartition tp = new TopicPartition(topic, partition);        consumer.assign(Collections.singletonList(tp));        consumer.seekToBeginning(Collections.singletonList(tp));    }    @Step(\"\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0442\u043e\u043f\u0438\u043a\u0430: {topic}\")    public void assignAllPartitions(String topic) {        consumer = new KafkaConsumer&lt;&gt;(buildConsumerProperties());        List&lt;TopicPartition&gt; partitions = consumer.partitionsFor(topic).stream()                .map(pi -&gt; new TopicPartition(topic, pi.partition()))                .toList();        consumer.assign(partitions);        consumer.seekToBeginning(partitions);    }    @Step(\"\u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430: {timeoutSeconds} \u0441\u0435\u043a\")    public List&lt;ConsumerRecord&lt;String, String&gt;&gt; pollMessages(int timeoutSeconds) {        List&lt;ConsumerRecord&lt;String, String&gt;&gt; result = new ArrayList&lt;&gt;();        long endTime = System.currentTimeMillis() + timeoutSeconds * 1000L;        while (System.currentTimeMillis() &lt; endTime) {            ConsumerRecords&lt;String, String&gt; records = consumer.poll(Duration.ofSeconds(1));            for (ConsumerRecord&lt;String, String&gt; record : records) {                result.add(record);                consumedMessages.add(record);            }            if (!records.isEmpty()) {                consumer.commitSync();            }        }        return result;    }    @Step(\"\u0427\u0442\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430\")    public ConsumerRecord&lt;String, String&gt; pollOneMessage(int timeoutSeconds) {        long endTime = System.currentTimeMillis() + timeoutSeconds * 1000L;        while (System.currentTimeMillis() &lt; endTime) {            ConsumerRecords&lt;String, String&gt; records = consumer.poll(Duration.ofSeconds(1));            if (!records.isEmpty()) {                ConsumerRecord&lt;String, String&gt; record = records.iterator().next();                consumedMessages.add(record);                consumer.commitSync();                return record;            }        }        return null;    }    \/\/ findMessagesContaining, findMessagesByKey, getConsumedMessages,    \/\/ clearConsumedMessages, close \u2014 \u043e\u043f\u0443\u0449\u0435\u043d\u044b \u0434\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>KafkaSteps \u2014 \u043f\u0440\u0438\u043c\u0435\u0440\u044b BDD-\u0448\u0430\u0433\u043e\u0432<\/strong><\/p>\n<pre><code class=\"java\">public class KafkaSteps {    @\u0414\u0430\u043d\u043e(\"\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Kafka \u0442\u043e\u043f\u0438\u043a\u0443 {string}\")    public void subscribeToTopic(String topic) {        getConsumer().subscribe(topic);    }    @\u0414\u0430\u043d\u043e(\"\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 Kafka \u0442\u043e\u043f\u0438\u043a\u0430 {string}\")    public void assignAllPartitions(String topic) {        getConsumer().assignAllPartitions(topic);    }      @\u041a\u043e\u0433\u0434\u0430(\"\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 {int} \u0441\u0435\u043a\u0443\u043d\u0434\")    public void pollMessages(int timeoutSeconds) {        List&lt;ConsumerRecord&lt;String, String&gt;&gt; messages =                getConsumer().pollMessages(timeoutSeconds);        ScenarioContext.getInstance().setData(\"kafkaMessages\", messages);    }    @\u0422\u043e\u0433\u0434\u0430(\"\u0432 Kafka \u0442\u043e\u043f\u0438\u043a\u0435 \u0435\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\")    public void verifyMessagesExist() {        @SuppressWarnings(\"unchecked\")        List&lt;ConsumerRecord&lt;String, String&gt;&gt; messages = (List&lt;ConsumerRecord&lt;String, String&gt;&gt;)                ScenarioContext.getInstance().getData(\"kafkaMessages\");        assertNotNull(messages);        assertFalse(messages.isEmpty(), \"\u0412 Kafka \u0442\u043e\u043f\u0438\u043a\u0435 \u043d\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\");    }      @\u0422\u043e\u0433\u0434\u0430(\"\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0435\u043a\u0441\u0442 {string}\")    public void verifyMessageContainsText(String expectedText) {        @SuppressWarnings(\"unchecked\")        List&lt;ConsumerRecord&lt;String, String&gt;&gt; messages = (List&lt;ConsumerRecord&lt;String, String&gt;&gt;)                ScenarioContext.getInstance().getData(\"kafkaMessages\");        boolean found = messages.stream()                .anyMatch(r -&gt; r.value() != null &amp;&amp; r.value().contains(expectedText));        assertTrue(found, \"\u041d\u0438 \u043e\u0434\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0435\u043a\u0441\u0442: \" + expectedText);    }      @\u0422\u043e\u0433\u0434\u0430(\"\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043a\u0430\u043a {string}\")    public void saveLastMessageValueToContext(String key) {        ConsumerRecord&lt;String, String&gt; message = (ConsumerRecord&lt;String, String&gt;)                ScenarioContext.getInstance().getData(\"kafkaLastMessage\");        assertNotNull(message, \"\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e\");        ScenarioContext.getInstance().setData(key, message.value());    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>1. SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b: \u043a\u043e\u0433\u0434\u0430 Java \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f<\/h2>\n<p>Kafka-\u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0432 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 SASL_SSL \u0441 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 Java truststore. \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f consumer \u043f\u0430\u0434\u0430\u043b \u0441 SSLHandshakeException \u2014 Java \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0434\u043e\u0432\u0435\u0440\u044f\u043b\u0430 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c\u0443 CA.<\/p>\n<p><strong>\u0427\u0442\u043e \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u0432 JVM truststore (keytool -import) \u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435, \u043d\u043e \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u0432 CI\/CD, \u0433\u0434\u0435 \u0430\u0433\u0435\u043d\u0442\u044b \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438 truststore \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0440\u0430\u043d\u043d\u0435\u0440\u0435;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 truststore \u0447\u0435\u0440\u0435\u0437 ssl.truststore.location \u2014 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f JKS-\u0444\u0430\u0439\u043b\u0430 \u0438 \u0435\u0433\u043e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0440\u0435\u0434\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b (Kafka REST Proxy, kcat) \u2014 \u0442\u044f\u043d\u0443\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0427\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438:<\/strong> \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e CustomSslEngineFactory \u2014 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 SslEngineFactory \u0438\u0437 kafka-clients. \u042d\u0442\u043e \u043d\u0435 \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 \u0433\u043e\u0442\u043e\u0432\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u0438 \u043d\u0435 \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u0441 TrustManager[] \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 HttpsURLConnection. \u042d\u0442\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0444\u0430\u0431\u0440\u0438\u043a\u0430 SSL-\u0434\u0432\u0438\u0436\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 Kafka consumer \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e:<\/p>\n<p>props.put(&#171;ssl.engine.factory.class&#187;, &#171;com.example.client.kafka.CustomSslEngineFactory&#187;);<\/p>\n<p>\u0424\u0430\u0431\u0440\u0438\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 SSLContext \u0441 TrustManager, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442, \u0438 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 SSLEngine \u0447\u0435\u0440\u0435\u0437 createSSLEngine(String peerHost, int peerPort). \u0411\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 <strong>\u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043c\u043e\u0433 \u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/strong> \u0432 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u2014 \u043d\u0438 \u043e\u0434\u0438\u043d \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043b \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 CI\/CD-\u0430\u0433\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u26a0\ufe0f <strong>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430.<\/strong> TrustAllSslEngineFactory \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432, \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043a MITM-\u0430\u0442\u0430\u043a\u0430\u043c. \u041c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 <strong>\u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0443\u0440\u0430 (Staging\/QA)<\/strong>, \u0433\u0434\u0435:<\/p>\n<ul>\n<li>\n<p>Kafka-\u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438\u0437\u0432\u043d\u0435 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0435\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0432\u0441\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u2014 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0435\u043d\u0434\u044b, \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0443 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d SASL\/SCRAM \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 JKS truststore. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 CA \u0432 JVM truststore \u2014 \u044d\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442. \u041d\u0430\u0448 \u043f\u043e\u0434\u0445\u043e\u0434 \u2014 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 CI\/CD-\u0430\u0433\u0435\u043d\u0442\u043e\u0432, \u0433\u0434\u0435 truststore \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c AI-\u0430\u0433\u0435\u043d\u0442 \u043f\u0440\u043e\u044f\u0432\u0438\u043b \u0441\u0435\u0431\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u044f\u0440\u043a\u043e: \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f SslEngineFactory \u2014 \u044d\u0442\u043e \u043d\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0433\u0443\u0433\u043b\u0438\u0442\u044c. \u041f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 kafka-clients \u0438 Java SSL API. AI-\u0430\u0433\u0435\u043d\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0430, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u2014 createSSLEngine, createClientSslEngine, createServerSslEngine, shouldBeRebuilt \u0438 \u0434\u0440\u0443\u0433\u0438\u0435. \u042d\u0442\u043e \u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 AI \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u043f\u043e\u043c\u043e\u0433 \u0441 \u043a\u043e\u0434\u043e\u043c\u00bb, \u0430 \u0440\u0435\u0448\u0438\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0435\u0437 \u043d\u0435\u0433\u043e \u0437\u0430\u043d\u044f\u043b\u0430 \u0431\u044b \u0434\u043d\u0438 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n<h2>2. Consumer Group \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b: \u043a\u043e\u0433\u0434\u0430 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b \u043b\u043e\u043c\u0430\u044e\u0442 \u0442\u0435\u0441\u0442\u043e\u0432\u0443\u044e \u0441\u0440\u0435\u0434\u0443<\/h2>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430 subscribe() \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c groupId \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u2014 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e. \u041d\u043e \u043f\u0440\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b-\u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b \u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 <strong>\u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/strong>. \u041f\u0440\u0438\u0447\u0438\u043d\u0430: \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b \u0441 \u0442\u0435\u043c \u0436\u0435 groupId \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u0432 rebalance \u0438 \u00ab\u043e\u0442\u0431\u0438\u0440\u0430\u043b\u0438\u00bb \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0443 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432.<\/p>\n<p><strong>\u0427\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438:<\/strong><\/p>\n<ol>\n<li>\n<p>\u0412\u0432\u0435\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u043e: <strong>\u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 groupId<\/strong>, \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u0441 \u0433\u0440\u0443\u043f\u043f\u0430\u043c\u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u0436\u0438\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u2014 assignAllPartitions() \u2014 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u043e\u043f\u0438\u043a\u0430 <strong>\u0431\u0435\u0437 \u0443\u0447\u0430\u0441\u0442\u0438\u044f \u0432 consumer group<\/strong> \u0432\u043e\u043e\u0431\u0449\u0435. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e rebalance, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 BDD-\u0448\u0430\u0433 \u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c groupId \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432 \u2014 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0432\u043e\u044e \u0433\u0440\u0443\u043f\u043f\u0443.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u0427\u0435\u0442\u044b\u0440\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 consumer groups \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445:<\/strong><\/p>\n<p><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u21161:<\/strong> \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0434\u0435\u043b\u044f\u0439\u0442\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e consumer group \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432. \u0412 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 groupId, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u0433\u0440\u0443\u043f\u043f\u0430\u043c\u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432:<\/p>\n<p>kafkaGroupId=<a href=\"http:\/\/some-topic.ui\">some-topic.ui<\/a>-autotests<\/p>\n<p><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u21162:<\/strong> \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u043e\u043f\u0438\u043a\u0430 \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 assignAllPartitions(). \u0420\u0435\u0436\u0438\u043c assign \u043d\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 consumer group rebalance \u0438 \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b.<\/p>\n<p><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u21163:<\/strong> \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0439\u0442\u0435\u0441\u044c \u043a Kafka \u0414\u041e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. Consumer \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0441\u043f\u0435\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u043e\u0439\u0442\u0438 rebalance \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0418\u043d\u0430\u0447\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u043c \u0433\u0440\u0443\u043f\u043f\u044b \u0438\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043e:<\/p>\n<p>1. [\u0448\u0430\u0433 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0442\u043e\u043f\u0438\u043a\u0443&#8230;]<\/p>\n<p>2. [\u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u044e\u0449\u0435\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435&#8230;]<\/p>\n<p>3. [\u0448\u0430\u0433 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0441 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c&#8230;]<\/p>\n<p><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u21164:<\/strong> \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 groupId \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439. \u0415\u0441\u043b\u0438 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043e\u0434\u0438\u043d groupId, \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0439 consumer group. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 groupId \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f.<\/p>\n<p>\u042d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u2014 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u0430 <strong>\u043f\u043e\u043d\u044f\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/strong>: \u043a\u0430\u043a \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0446\u0435\u043b\u043e\u043c, \u043a\u0442\u043e \u0435\u0449\u0451 \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u0437 \u0442\u043e\u043f\u0438\u043a\u0430, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u043f\u0440\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u0418\u043d\u0436\u0435\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0449\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432, \u0432\u0438\u0434\u0438\u0442 \u0442\u0430\u043a\u0438\u0435 \u0440\u0438\u0441\u043a\u0438 \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043d\u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u044b.<\/p>\n<h2>3. \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0438: \u043a\u043e\u0433\u0434\u0430 sleep() \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/h2>\n<p>\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 Kafka \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u2014 \u043c\u0435\u0436\u0434\u0443 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u043c \u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u0442\u043e\u043f\u0438\u043a\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043e \u043c\u0438\u043d\u0443\u0442\u044b. \u041f\u0435\u0440\u0432\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Thread.sleep(10000) \u043f\u0440\u0438\u0432\u0435\u043b\u0430 \u043a \u0434\u0432\u0443\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c: \u0438\u043d\u043e\u0433\u0434\u0430 10 \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e (\u0442\u0435\u0441\u0442 \u043f\u0430\u0434\u0430\u043b), \u0438\u043d\u043e\u0433\u0434\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u043b\u043e\u0441\u044c \u0437\u0430 2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b (\u0442\u0435\u0441\u0442 \u0436\u0434\u0430\u043b \u0432\u043f\u0443\u0441\u0442\u0443\u044e 8 \u0441\u0435\u043a\u0443\u043d\u0434, \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u044f \u043f\u0440\u043e\u0433\u043e\u043d).<\/p>\n<p><strong>\u0427\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438:<\/strong> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 poll-\u0446\u0438\u043a\u043b \u0441 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c. Consumer \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043f\u0438\u043a \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0435\u043a\u0443\u043d\u0434\u0443 (poll(Duration.ofSeconds(1))) \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0438\u0441\u0442\u0435\u0447\u0451\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <strong>\u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f<\/strong> \u2014 \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0438\u0445 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0439 \u0438 \u0431\u0435\u0437 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043e\u0432:<\/p>\n<pre><code class=\"java\">while (elapsed &lt; timeoutSeconds) {ConsumerRecords&lt;String, String&gt; records = consumer.poll(Duration.ofSeconds(1));if (!records.isEmpty()) {    break;}elapsed++;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>4. \u0420\u0443\u0447\u043d\u0430\u044f \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u2192 BDD-\u0448\u0430\u0433\u0438<\/h2>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u0430 \u0448\u0451\u043b \u0432 Kafka UI \u0438\u043b\u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0438\u0441\u043a\u0430\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b payload \u0440\u0443\u043a\u0430\u043c\u0438. \u042d\u0442\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e, \u043d\u0435\u043d\u0430\u0434\u0451\u0436\u043d\u043e \u0438 \u043d\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u0435\u0441\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430 BDD-\u0448\u0430\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438.<\/p>\n<p><strong>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 (Given \/ \u0414\u0430\u043d\u043e)<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0448\u0430\u0433\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 \u0442\u043e\u043f\u0438\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0435\u0440\u0435\u0437 consumer group \u0441 groupId \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c groupId<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432 \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u043d\u0430 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0442\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0435\u0437 \u0443\u0447\u0430\u0441\u0442\u0438\u044f \u0432 consumer group<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u0427\u0442\u0435\u043d\u0438\u0435 (When \/ \u041a\u043e\u0433\u0434\u0430)<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0448\u0430\u0433\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0427\u0442\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0427\u0442\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0432\u043e\u0435 \u043f\u043e\u043f\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0437\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0438\u0441\u043a \u0441\u0440\u0435\u0434\u0438 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u0431\u0443\u0444\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0431\u0440\u043e\u0441 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (Then \/ \u0422\u043e\u0433\u0434\u0430)<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0448\u0430\u0433\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">assertNotEmpty<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">assertEmpty<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0422\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">assertEquals<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043e\u043b\u044c\u0448\u0435 N<\/p>\n<\/td>\n<td>\n<p align=\"left\">assertTrue(size &gt; N)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0438\u0441\u043a \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">contains() \u043f\u043e value<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0432\u0435\u0436\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0448\u0430\u0433\u0430\u0445<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/strong><\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d 1: \u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u0414\u041e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/strong><\/p>\n<p>\u2192 \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u044f \u2192 \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Kafka \u2192 \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2192 \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0438\u0434\u0435\u044f: consumer \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f <strong>\u0434\u043e<\/strong> \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u0437\u0430\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.<\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d 2: \u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u041f\u041e\u0421\u041b\u0415 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/strong><\/p>\n<p>\u2192 \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u044f \u2192 \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2192 \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Kafka \u2192 \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2192 \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c: \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d 3: \u041d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u2014 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0431\u044b\u0442\u044c \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e<\/strong><\/p>\n<p>\u2192 \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u044f \u2192 \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Kafka \u2192 \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2192 \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u041d\u0415\u0422<\/p>\n<p>\u041d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430: \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 Kafka.<\/p>\n<h2>5. \u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u2192 \u043f\u0440\u044f\u043c\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>Kafka REST Proxy, kcat, Confluent Control Center \u2014 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0442\u044f\u043d\u0443\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443. \u0412 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u044d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e: \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u2014 \u044d\u0442\u043e \u0437\u0430\u044f\u0432\u043a\u0430 \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 SSL, \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u0439.<\/p>\n<p>\u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <strong>\u043f\u0440\u044f\u043c\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 kafka-clients<\/strong> \u2014 \u043e\u0434\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 build.gradle, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u043e\u043a\u0441\u0438. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0432 CI\/CD, \u0432 Docker \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c bootstrapServers \u0438 \u043a\u0440\u0435\u0434\u044b.<\/p>\n<p>\u042d\u0442\u043e \u0434\u0430\u0451\u0442:<\/p>\n<ul>\n<li>\n<p><strong>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/strong> \u2014 \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u0432 build.gradle;<\/p>\n<\/li>\n<li>\n<p><strong>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c<\/strong> \u2014 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f, \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b, \u0440\u0435\u0436\u0438\u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u2014 \u0432\u0441\u0451 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0435\u0437\u0434\u0435<\/strong> \u2014 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0432 CI\/CD, \u0432 Docker;<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043e\u0442\u0447\u0451\u0442\u0430\u043c\u0438<\/strong> \u2014 \u043a\u0430\u0436\u0434\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0432 \u043e\u0442\u0447\u0451\u0442\u0435 \u0432\u0438\u0434\u0435\u043d \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u0442\u043e\u043f\u0438\u043a\u0430 \u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043e\u0442\u0447\u0451\u0442\u0430\u043c\u0438<\/h2>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u043e\u0432\u0430\u043d @Step \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043e\u0442\u0447\u0451\u0442:<\/p>\n<pre><code class=\"java\">@Step(\"\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 Kafka \u0442\u043e\u043f\u0438\u043a: {topic}\")public void subscribe(String topic) { ...Allure.addAttachment(\"Kafka \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430\", \"\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 \u0442\u043e\u043f\u0438\u043a: \" + topic + \", groupId: \" + groupId);} @Step(\"\u0427\u0442\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430\")public ConsumerRecord&lt;String, String&gt; pollOneMessage(int timeoutSeconds) { ...Allure.addAttachment(\"Kafka \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\",    \"\u0422\u043e\u043f\u0438\u043a: \" + record.topic() + \", \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044f: \" + record.partition() +    \", offset: \" + record.offset() + \", key: \" + record.key() + \", value: \" + record.value());}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043e\u0442\u0447\u0451\u0442\u0435 \u0432\u0438\u0434\u043d\u043e: \u043a\u0430\u043a\u043e\u0439 \u0442\u043e\u043f\u0438\u043a, \u043a\u0430\u043a\u043e\u0439 groupId, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e, \u0438 \u043f\u043e\u043b\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u2014 \u043a\u0430\u043a \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/h2>\n<p>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u2014 Singleton \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 HashMap&lt;String, Object&gt;. Kafka \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <strong>3 \u043a\u043b\u044e\u0447\u0430<\/strong>:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041a\u043b\u044e\u0447<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0422\u0438\u043f<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041a\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041a\u0442\u043e \u0447\u0438\u0442\u0430\u0435\u0442<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 consumer&#8217;\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">Consumer-\u043e\u0431\u0451\u0440\u0442\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">BDD-\u0448\u0430\u0433\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0425\u0443\u043a \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">List&lt;ConsumerRecord&gt;<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u0435\u0442\u043e\u0434\u044b \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u044b\u0435 \u0448\u0430\u0433\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">ConsumerRecord<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u0435\u0442\u043e\u0434 \u0447\u0442\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0428\u0430\u0433\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438: \u043d\u0435\u0434\u0435\u043b\u044f \u0437\u0430 \u043e\u0434\u0438\u043d \u0434\u0435\u043d\u044c<\/h2>\n<p>\u041e\u0446\u0435\u043d\u043a\u0430 \u0440\u0443\u0447\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u00ab\u0441 \u043d\u0443\u043b\u044f\u00bb \u2014 <strong>\u043e\u043a\u043e\u043b\u043e \u043d\u0435\u0434\u0435\u043b\u0438<\/strong>: \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 SASL\/SCRAM-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f SslEngineFactory, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 consumer \u0441 poll-\u0446\u0438\u043a\u043b\u043e\u043c, BDD-\u0448\u0430\u0433\u0438, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0438 \u0445\u0443\u043a\u0430\u043c\u0438, \u043e\u0442\u043b\u0430\u0434\u043a\u0430 SSL-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043e\u0442\u0447\u0451\u0442\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0421 AI-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0440\u0435\u0432\u044c\u044e, \u0431\u044b\u043b\u043e \u0433\u043e\u0442\u043e\u0432\u043e <strong>\u0437\u0430 \u043e\u0434\u0438\u043d \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0434\u0435\u043d\u044c<\/strong>. \u0424\u043e\u0440\u043c\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b:<\/p>\n<ol>\n<li>\n<p><strong>\u0418\u043d\u0436\u0435\u043d\u0435\u0440<\/strong> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f: \u0440\u0435\u0436\u0438\u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f, \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><strong>AI-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442<\/strong> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0434: consumer-\u043e\u0431\u0451\u0440\u0442\u043a\u0443, \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e SSL-\u0444\u0430\u0431\u0440\u0438\u043a\u0443, BDD-\u0448\u0430\u0433\u0438, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0438 \u0445\u0443\u043a\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0436\u0435\u043d\u0435\u0440<\/strong> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u2014 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0435\u0439.<\/p>\n<\/li>\n<\/ol>\n<p>\u042d\u0442\u043e \u043d\u0435 \u00abAI \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043a\u043e\u0434, \u0430 \u044f \u043d\u0430\u0436\u0430\u043b \u043a\u043d\u043e\u043f\u043a\u0443\u00bb. \u042d\u0442\u043e <strong>\u043f\u0430\u0440\u0442\u043d\u0451\u0440\u0441\u043a\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c<\/strong>: \u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e, AI-\u0430\u0433\u0435\u043d\u0442 \u2014 \u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432 \u0438 \u0440\u0443\u0442\u0438\u043d\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u2014 \u043d\u0435\u0434\u0435\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0437\u0430 \u043e\u0434\u0438\u043d \u0434\u0435\u043d\u044c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435 \u043d\u0438\u0436\u0435, \u0430 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0430\u0441\u043f\u0435\u043a\u0442\u0430\u0445 \u0432\u044b\u0448\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, SslEngineFactory \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0430 \u2014 \u0431\u0435\u0437 \u0431\u0430\u0433\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u043e\u043a).<\/p>\n<h2>\u0418\u043d\u0436\u0435\u043d\u0435\u0440 + AI-\u0430\u0433\u0435\u043d\u0442: \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/h2>\n<p>\u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0431\u044b\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u0443\u0447\u0430\u0441\u0442\u0438\u0438 AI-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u0430 \u043f\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438 \u0434\u0438\u0437\u0430\u0439\u043d-\u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c, \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043e\u043c \u043f\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438. \u041d\u043e \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c: \u044d\u0442\u043e \u043d\u0435 \u0440\u0430\u0437\u043e\u0432\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043f\u0440\u043e \u00ab\u043e\u0434\u0438\u043d \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u00bb. \u042d\u0442\u043e <strong>\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u044b<\/strong>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u043b\u044e\u0431\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p><strong>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u042d\u0442\u0430\u043f<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0418\u043d\u0436\u0435\u043d\u0435\u0440<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>AI-\u0430\u0433\u0435\u043d\u0442<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0438\u0441\u043a \u0442\u043e\u0447\u0435\u043a \u0432\u0445\u043e\u0434\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0438\u0434\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043e\u0446\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u043b: \u00ab\u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c UI, \u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u00bb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c: \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0434, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u044f: \u0440\u0435\u0436\u0438\u043c\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u044b, \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044b, \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0438\u0441\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u0435\u0432\u044c\u044e\u0438\u0442, \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u0430\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0438\u0448\u0435\u0442 \u043a\u043e\u0434: \u043a\u043b\u0430\u0441\u0441\u044b, \u0448\u0430\u0433\u0438, \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041e\u0442\u043b\u0430\u0434\u043a\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043b\u043e\u0433\u0438, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0444\u0438\u043a\u0441\u044b, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u0441\u0442\u0430\u0442\u044c\u0438, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0448\u0430\u0433\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><strong>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/strong><\/p>\n<ol>\n<li>\n<p><strong>\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u0451\u043d \u2014 \u043e\u043d \u0443\u0441\u0438\u043b\u0435\u043d.<\/strong> AI-\u0430\u0433\u0435\u043d\u0442 \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0438 \u043d\u0435 \u043d\u0435\u0441\u0451\u0442 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e. \u041d\u043e \u043e\u043d \u0441\u043d\u0438\u043c\u0430\u0435\u0442 \u0440\u0443\u0442\u0438\u043d\u0443 \u0438 \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u0440\u0430\u0437\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>\u0422\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u2014 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043a\u043e\u0434\u0435.<\/strong> \u0418\u043d\u0436\u0435\u043d\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0449\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0438\u0445 \u0432\u0435\u0437\u0434\u0435: \u0432 \u0440\u0443\u0447\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u0445, \u0432 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u0433\u0430\u0445, \u0432 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u0445. AI-\u0430\u0433\u0435\u043d\u0442 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043e\u0446\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438.<\/strong> Kafka-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u2014 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440. \u0422\u043e\u0442 \u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f API-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, DB-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u043e\u0432, CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432, \u043e\u0442\u0447\u0451\u0442\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 \u2014 AI-\u0430\u0433\u0435\u043d\u0442 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0430 \u0447\u0430\u0441\u044b, \u0430 \u043d\u0435 \u043d\u0435\u0434\u0435\u043b\u0438.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/strong><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0418\u043d\u0436\u0435\u043d\u0435\u0440 + AI-\u0430\u0433\u0435\u043d\u0442<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0412\u0440\u0435\u043c\u044f \u043e\u0442 \u0438\u0434\u0435\u0438 \u0434\u043e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0434\u0435\u043b\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043d\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043e\u043f\u044b\u0442\u0430 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u0448\u0435 \u0437\u0430 \u0441\u0447\u0451\u0442 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0438 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u043a\u0440\u044b\u0442\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u043d\u0430 \u0447\u0442\u043e \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0441\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0448\u0451\u043b \u0438\u043d\u0436\u0435\u043d\u0435\u0440<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0430\u0441\u044b \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430 \u00d7 \u043d\u0435\u0434\u0435\u043b\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0430\u0441\u044b \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430 \u00d7 \u0434\u043d\u0438<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043f\u044b\u0442\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Kafka-\u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u0445 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430, \u0433\u0434\u0435 \u0440\u0443\u0447\u043d\u043e\u0439 \u0442\u0440\u0443\u0434 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0441\u0438\u043b\u0438\u0442\u044c AI, \u2014 \u044d\u0442\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>P.S. \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u2014 \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u043e\u0442\u0432\u0435\u0447\u0443 \u043d\u0430 \u0432\u0441\u0435!<\/p>\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\/articles\/1051890\/\">https:\/\/habr.com\/ru\/articles\/1051890\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041d\u0430 \u0441\u0432\u044f\u0437\u0438 \u0415\u0433\u043e\u0440 \u041b\u0430\u043f\u0442\u0435\u0432 \u2014 QA Fullstack Java \u0432 SENSE \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043a\u0440\u0443\u043f\u043d\u043e\u0433\u043e \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u0431\u0430\u043d\u043a\u0430.End-to-end \u0442\u0435\u0441\u0442\u044b UI \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u0438\u0434\u043d\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435: \u043a\u043d\u043e\u043f\u043a\u0430 \u043d\u0430\u0436\u0430\u043b\u0430\u0441\u044c, \u0444\u043e\u0440\u043c\u0430 \u043e\u0442\u043a\u0440\u044b\u043b\u0430\u0441\u044c, \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u043b\u0438\u0441\u044c. \u041d\u043e \u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u0443\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u043a\u0430\u0434\u0440 \u2014 \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0442\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 Kafka. \u0415\u0441\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0435 \u0434\u043e\u0448\u043b\u043e \u0434\u043e \u0442\u043e\u043f\u0438\u043a\u0430 \u0438\u043b\u0438 \u043f\u0440\u0438\u0448\u043b\u043e \u0441 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u043c payload, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0442, \u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f.\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445 \u2014 \u0431\u0435\u0437 Kafka UI, kcat \u0438 \u043e\u0431\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043e\u0434\u043d\u043e\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u0438 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0432 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0441 SSL. \u041f\u043e\u043a\u0430\u0436\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430, \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b (SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b, \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b consumer group \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0438), \u0438 \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 AI-\u0430\u0433\u0435\u043d\u0442\u043e\u043c.\u041a\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e: QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430\u043c \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u0430\u043c \u043f\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0445\u043e\u0442\u044f\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430\u0445; \u0438 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 AI-\u0430\u0433\u0435\u043d\u0442\u043e\u043c \u2014 \u043a\u0430\u043a \u043e\u043d\u0430 \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u041c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0438 \u0437\u0435\u043b\u0451\u043d\u044b\u0439, \u0430 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0441\u044b\u043f\u0430\u043b\u0438\u0441\u044c \u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b, \u0434\u043e\u0445\u043e\u0434\u044f\u0442 \u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043e Kafka. \u0413\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b, \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c: \u0432\u0441\u0451 \u043b\u0438\u0431\u043e \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043b\u0438\u0431\u043e \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0435\u0442\u044f\u0445 \u0441 SSL.\u0417\u0430\u0434\u0430\u0447\u0430 \u0431\u044b\u043b\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0438 \u0440\u0443\u0447\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a. \u0420\u0430\u043d\u044c\u0448\u0435 \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u044b\u043b\u0430 \u0440\u0443\u0447\u043d\u043e\u0439: \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b \u0442\u0435\u0441\u0442, \u0448\u0451\u043b \u0432 Kafka UI \u0438\u043b\u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c, \u0438\u0441\u043a\u0430\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b payload. \u042d\u0442\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e, \u043d\u0435\u043d\u0430\u0434\u0451\u0436\u043d\u043e \u0438 \u043d\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u041c\u044b \u0445\u043e\u0442\u0435\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0431\u044b\u043b\u0430 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439, \u043a\u0430\u043a \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 UI.\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0430\u043c \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u2014 \u043b\u0438\u0448\u044c \u0447\u0430\u0441\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0448\u0438\u0440\u043e\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430. \u041e\u043d \u043d\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0431\u044b \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435: \u0435\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u043f\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u043e\u043b\u044c\u044e \u00ab\u043f\u0438\u0448\u0443 \u0442\u0435\u0441\u0442\u044b \u043f\u043e \u0422\u0417\u00bb, \u0430 \u0438\u0449\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u2014 \u043c\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u0440\u0443\u0447\u043d\u043e\u0439 \u0442\u0440\u0443\u0434 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0443\u0441\u0438\u043b\u0438\u0442\u044c AI. AI-\u0430\u0433\u0435\u043d\u0442 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u043a\u0430\u043a \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u044b: \u043e\u0442 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043e \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0440\u0435\u0432\u044c\u044e. \u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u2014 \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430.\u0427\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c: \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 \u0431\u0435\u0437 \u043e\u0431\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e Kafka UI, Confluent Control Center, Kafka REST Proxy \u0438\u043b\u0438 kcat \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044f\u043c\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 kafka-clients. \u041e\u0434\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 build.gradle, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u043e\u043a\u0441\u0438. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0432 CI\/CD, \u0432 Docker \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c bootstrapServers \u0438 \u043a\u0440\u0435\u0434\u044b.\u0427\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u0446\u0438\u0444\u0440\u0430\u0445:\u041c\u0435\u0442\u0440\u0438\u043a\u0430\u0414\u043e\u041f\u043e\u0441\u043b\u0435\u0394\u0412\u0440\u0435\u043c\u044f \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f~3 \u043c\u0438\u043d \u0432\u0440\u0443\u0447\u043d\u0443\u044e~5 \u0441\u0435\u043a \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0432 36 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0431\u0430\u0433\u043e\u0432 \u0432 Kafka-\u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445~40% \u043e\u0442 \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0434-\u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u043e\u0432&lt;5%\u0432 8 \u0440\u0430\u0437 \u043c\u0435\u043d\u044c\u0448\u0435\u041f\u043e\u043a\u0440\u044b\u0442\u0438\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0441 Kafka-\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u04380 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u043215+ \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432\u0441 \u043d\u0443\u043b\u044f\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e Kafka-\u0442\u0435\u0441\u0442\u0430~2 \u0434\u043d\u044f \u0432\u0440\u0443\u0447\u043d\u0443\u044e~2 \u0447\u0430\u0441\u0430 \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u043e\u043c\u0432 8 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435\u041a\u0430\u043a\u0438\u0435 \u0431\u043e\u043b\u0438 \u0440\u0435\u0448\u0430\u0435\u0442 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440#\u0411\u043e\u043b\u044c\u0420\u0435\u0448\u0435\u043d\u0438\u04351SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b \u2014 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 CA \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 Java truststore, consumer \u043f\u0430\u0434\u0430\u0435\u0442 \u0441 SSLHandshakeException\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f SslEngineFactory \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 consumer \u0438 \u0434\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u043c\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u04432Consumer Group \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b \u2014 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b \u0441 \u0442\u0435\u043c \u0436\u0435 groupId \u043e\u0442\u0431\u0438\u0440\u0430\u044e\u0442 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0443 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 groupId \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 + \u0440\u0435\u0436\u0438\u043c assignAllPartitions() \u0431\u0435\u0437 \u0443\u0447\u0430\u0441\u0442\u0438\u044f \u0432 consumer group3\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0438 \u2014 Thread.sleep() \u0442\u043e \u043d\u0435\u0434\u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u0436\u0434\u0451\u0442 \u0432\u043f\u0443\u0441\u0442\u0443\u044e, \u0442\u0435\u0441\u0442\u044b \u0444\u043b\u0430\u043a\u0430\u044e\u0442Poll-\u0446\u0438\u043a\u043b \u0441 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f4\u0420\u0443\u0447\u043d\u0430\u044f \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u2014 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438\u0434\u0451\u0442 \u0432 Kafka UI, \u0438\u0449\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 payload \u0440\u0443\u043a\u0430\u043c\u0438BDD-\u0448\u0430\u0433\u0438: \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u0435\u043d\u0438\u0435, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u2014 \u0432\u0441\u0451 \u0432 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u04385\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u2014 Kafka REST Proxy, kcat, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u2014 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0438 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432\u0435\u0437\u0434\u0435\u041f\u0440\u044f\u043c\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 kafka-clients, \u043e\u0434\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0435\u0437\u0434\u0435\u0414\u0430\u043b\u044c\u0448\u0435 \u2014 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u043a\u0430\u0436\u0434\u043e\u0439 \u0431\u043e\u043b\u0438 \u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f.\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430src\/test\/java\/com\/example\/\u251c\u2500\u2500 client\/kafka\/\u2502   \u251c\u2500\u2500 KafkaConsumerClientjava \u2014 \u044f\u0434\u0440\u043e: consumer, poll, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f |\u2500\u2500 CustomSslEngineFactory.java   \u2014 SSL-\u043e\u0431\u0445\u043e\u0434 \u0434\u043b\u044f \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432\u251c\u2500\u2500 steps\/\u2502   \u2514\u2500\u2500 KafkaBddSteps.java        \u2014 BDD-\u0448\u0430\u0433\u0438 (Given\/When\/Then)\u2514\u2500\u2500 utils\/\u2514\u2500\u2500 ScenarioContext.java       \u2014 Singleton-\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f src\/test\/resources\/\u251c\u2500\u2500 configuration\/config.properties\u2014 Kafka-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f (camelCase)\u2514\u2500\u2500 .env                           \u2014 Kafka-\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f (UPPER_SNAKE_CASE)\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c (build.gradle):testImplementation &#8216;org.apache.kafka:kafka-clients:3.7.0&#8217;Consumer-\u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u2014 \u044f\u0434\u0440\u043e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0430\u0414\u0432\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u0427\u0438\u0442\u0430\u0435\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438\u0437 config.properties \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0440\u0438\u0434\u0435\u0440\u0421 \u044f\u0432\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 (bootstrapServers, saslMechanism, saslUsername, saslPassword, groupId, securityProtocol)\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e groupId\u0422\u0440\u0438 \u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u041c\u0435\u0442\u043e\u0434\u0420\u0435\u0436\u0438\u043cOffset\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044csubscribe(topic)Consumer Group\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0439\u0427\u0442\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438assignPartition(topic, partition)\u041f\u0440\u044f\u043c\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435seekToBeginning\u0427\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430assignAllPartitions(topic)\u0412\u0441\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438seekToBeginning\u041f\u043e\u043b\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0442\u043e\u043f\u0438\u043a\u0430 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430: subscribe() \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 consumer group \u2014 offset \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442\u0441\u044f. assign*() \u2014 \u043f\u0440\u044f\u043c\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439, \u0431\u0435\u0437 \u0432\u043b\u0438\u044f\u043d\u0438\u044f \u043d\u0430 consumer group offset.\u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\u041c\u0435\u0442\u043e\u0434\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044cpollMessages(timeoutSeconds)List&lt;ConsumerRecord&lt;String, String&gt;&gt;\u0426\u0438\u043a\u043b poll \u043f\u043e 1 \u0441\u0435\u043a \u0434\u043e \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430pollOneMessage(timeoutSeconds)ConsumerRecord&lt;String, String&gt;\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u0435 \u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435pollMessageValues(timeoutSeconds)List&lt;String&gt;\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (\u0431\u0435\u0437 \u043a\u043b\u044e\u0447\u0435\u0439\/\u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445)\u0412\u0441\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c \u0431\u0443\u0444\u0435\u0440\u0435 \u2014 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043f\u043e\u0437\u0436\u0435.\u0424\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439findMessagesContaining(substring)findMessagesByKey(key)getConsumedMessages()clearConsumedMessages()\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 ConsumerConsumer \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438: \u0447\u0442\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u043e\u043f\u0438\u043a\u0430 (earliest), \u0440\u0443\u0447\u043d\u043e\u0439 \u043a\u043e\u043c\u043c\u0438\u0442 offset \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043b\u0438\u043c\u0438\u0442 \u0432 100 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0437\u0430 \u043e\u0434\u0438\u043d poll. \u0414\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u043a\u043b\u044e\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u2014 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435.auto.offset.reset=earliestenable.auto.commit=falsemax.poll.records=100key.deserializer=StringDeserializervalue.deserializer=StringDeserializer\u0416\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b\u041a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 AutoCloseable \u2014 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 consumer&#8217;\u0430 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432 \u0445\u0443\u043a\u0435 \u043f\u043e\u0441\u043b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f:@Afterpublic void closeKafkaConsumer() {Object consumer = context.getData(&#171;consumerKey&#187;);if (consumer instanceof KafkaConsumerWrapper) {    ((KafkaConsumerWrapper) consumer).close();}}CustomSslEngineFactory \u2014 \u043c\u0435\u0442\u043e\u0434 configure()public class CustomSslEngineFactory implements SslEngineFactory {    private SSLContext sslContext;    @Override    public void configure(Map&lt;String, ?&gt; configs) {        try {            TrustManager[] trustAllCerts = new TrustManager[]{                new X509TrustManager() {                    public X509Certificate[] getAcceptedIssuers() {                        return new X509Certificate[0];                    }                    public void checkClientTrusted(X509Certificate[] certs,                                                    String authType) {}                    public void checkServerTrusted(X509Certificate[] certs,                                                    String authType) {}                }            };            sslContext = SSLContext.getInstance(&#171;TLS&#187;);            sslContext.init(null, trustAllCerts, new SecureRandom());        } catch (Exception e) {            throw new RuntimeException(                    &#171;\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c CustomSslEngineFactory&#187;, e);        }    }    @Override    public SSLEngine createClientSslEngine(String peerHost, int peerPort,                                            String endpointIdentification) {        SSLEngine engine = sslContext.createSSLEngine(peerHost, peerPort);        engine.setUseClientMode(true);        engine.setSSLParameters(new SSLParameters());        return engine;    }\/\/ shouldBeRebuilt, reconfigurableConfigs, keystore, truststore, close \u2014 \u0431\u043e\u0439\u043b\u0435\u0440\u043f\u043b\u0435\u0439\u0442}KafkaConsumerClient \u2014 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 poll-\u0446\u0438\u043a\u043bpublic class KafkaConsumerClient implements AutoCloseable {    private KafkaConsumer&lt;String, String&gt; consumer;    private final List&lt;ConsumerRecord&lt;String, String&gt;&gt; consumedMessages = new ArrayList&lt;&gt;();    \/\/ &#8230; \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u043f\u043e\u043b\u044f, buildConsumerProperties() &#8230;    @Step(&#171;\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 Kafka \u0442\u043e\u043f\u0438\u043a: {topic}&#187;)    public void subscribe(String topic) {        consumer = new KafkaConsumer&lt;&gt;(buildConsumerProperties());        consumer.subscribe(Collections.singletonList(topic));        consumer.poll(Duration.ofMillis(3000));    }    @Step(&#171;\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0442\u043e\u043f\u0438\u043a\u0430: {topic}, \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044f: {partition}&#187;)    public void assignPartition(String topic, int partition) {        consumer = new KafkaConsumer&lt;&gt;(buildConsumerProperties());        TopicPartition tp = new TopicPartition(topic, partition);        consumer.assign(Collections.singletonList(tp));        consumer.seekToBeginning(Collections.singletonList(tp));    }    @Step(&#171;\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0442\u043e\u043f\u0438\u043a\u0430: {topic}&#187;)    public void assignAllPartitions(String topic) {        consumer = new KafkaConsumer&lt;&gt;(buildConsumerProperties());        List&lt;TopicPartition&gt; partitions = consumer.partitionsFor(topic).stream()                .map(pi -&gt; new TopicPartition(topic, pi.partition()))                .toList();        consumer.assign(partitions);        consumer.seekToBeginning(partitions);    }    @Step(&#171;\u0427\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0437 Kafka \u0442\u043e\u043f\u0438\u043a\u0430: {timeoutSeconds} \u0441\u0435\u043a&#187;)    public List&lt;ConsumerRecord&lt;String, String&gt;&gt; pollMessages(int timeoutSeconds) {        List&lt;ConsumerRecord&lt;String, String&gt;&gt; result = new ArrayList&lt;&gt;();        long endTime = System.currentTimeMillis() + timeoutSeconds * 1000L;        while (System.currentTimeMillis() &lt; endTime) {            ConsumerRecords&lt;String,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-485017","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/485017","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=485017"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/485017\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=485017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=485017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=485017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}