{"id":358775,"date":"2024-05-21T00:18:52","date_gmt":"2024-05-21T00:18:52","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=358775"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T00:18:52","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=358775","title":{"rendered":"<span>\u0422\u0440\u0435\u0439\u0441\u044b \u0432 Spring Boot 3 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Zipkin \u0438 Kafka \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0430<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u0421\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u0410\u043b\u044c\u0444\u0430\u0421\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u043d\u0438\u0435 (\u0434\u0430\u043b\u0435\u0435 \u0421\u041a), \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u043e\u0434\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0444\u0438\u0441\u0430\u0445, \u043d\u043e \u0438 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u044c \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u044b\u0445 \u0430\u0433\u0435\u043d\u0442\u043e\u0432. \u0410\u0433\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0444\u043e\u0440\u043c\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u0438\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f REST API. \u042d\u0442\u043e\u0442 API \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043d\u0435 \u043f\u043e\u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u0438\u043b\u043e\u0441\u044c \u0442\u0440\u0443\u0434\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0442\u0435\u0445\u043d\u0438\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0412\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043b\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0440\u0430\u0437\u0434\u0435\u043b\u0443 &#171;\u041f\u0440\u0435\u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b&#187;.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f Zipkin \u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u0442\u0440\u0435\u0439\u0441\u043e\u0432. <a href=\"https:\/\/zipkin.io\/pages\/architecture.html\">\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e Zipkin \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435<\/a>.<\/p>\n<h2>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/h2>\n<h3>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442<\/h3>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u0438 \u043f\u0440\u043e\u0434\u0430\u0436\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u0420\u0430\u0441\u0447\u0435\u0442 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u0438\u0441\u0430 \u0432 core-\u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0421\u041a;<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u043b\u0430\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0447\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430\u043c\u0438. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0432 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043c\u044b \u0434\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435, \u043e\u043f\u043b\u0430\u0442\u0430 \u0438 \u0442.\u0434. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0437\u0430 \u043d\u0438\u0445.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u043a\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 core-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 &#8212; Spring Boot.<\/p>\n<h3>\u041a\u043e\u0433\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0438\u0434\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a<\/h3>\n<p>\u0412\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043f\u043e\u0440\u043e\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 HTTP 500, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 &#8212; \u0447\u0442\u043e \u0436\u0435 \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043b\u043e\u0433\u043e\u0432 \u0438 \u0442\u0440\u0435\u0439\u0441\u043e\u0432, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0434\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0434\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0442\u0440\u0443\u0434\u0430. \u0414\u0430\u043b\u0435\u0435 \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0443\u043b\u044c\u0442\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f).<\/p>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, Zipkin &#8212; \u043e\u0434\u0438\u043d<\/h3>\n<p>\u0414\u043b\u044f \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Zipkin. \u0422\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Kafka. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438. \u041d\u0430\u0448\u0435 \u0441\u0432\u0435\u0442\u043b\u043e\u0435 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 \u0432 \u0430\u0441\u043f\u0435\u043a\u0442\u0435 \u0442\u0440\u0435\u0439\u0441\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: <strong><em>\u0438\u043c\u0435\u044f \u0442\u0440\u0435\u0439\u0441\u044b \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0442\u0440\u0430\u0442\u0430\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a (\u0435\u0441\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a).<\/em><\/strong><\/p>\n<h2>\u041f\u0440\u0435\u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0430 \u0432\u0445\u043e\u0434\u0435:<\/p>\n<ul>\n<li>\n<p>Java 17;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Spring Boot 3.1.2;<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 Zipkin, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0442\u0440\u0435\u0439\u0441\u044b \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 Kafka;<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f Kafka \u0441 \u0442\u043e\u043f\u0438\u043a\u043e\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0410\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (\u0442.\u043a. \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043a\u0430\u0436\u0434\u043e\u043c) &#8212; \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u043c \u0448\u0430\u0433\u0435.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0428\u0430\u0433 1. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 (\u043a\u0430\u043a \u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445) \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u0432\u043e\u0434\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f.<\/p>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441 \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u0432 Zipkin \u0441 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043e\u043c Kafka. \u041f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0442.\u0435. \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u043d\u043e \u0438 \u0432\u043d\u0443\u0442\u0440\u0438, \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430.<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430<\/h3>\n<h4>Dependencies<\/h4>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0437\u0434\u0435\u0441\u044c \u0438 \u0434\u0430\u043b\u0435\u0435 \u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d parent <code>org.springframework.boot:spring-boot-starter-parent:3.1.2<\/code>, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0441\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u043b\u0438\u0441\u044c \u0441\u0430\u043c\u0438. \u041d\u0438\u0436\u0435 \u043e\u043d\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438.<\/p>\n<pre><code class=\"xml\">&lt;!-- \u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f observation \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 --> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-actuator&lt;\/artifactId>     &lt;version>3.1.2&lt;\/version> &lt;\/dependency> &lt;!-- \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f observations \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c @Observed --> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-aop&lt;\/artifactId>     &lt;version>3.1.2&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.springframework.kafka&lt;\/groupId>     &lt;artifactId>spring-kafka&lt;\/artifactId>     &lt;version>3.0.9&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.micrometer&lt;\/groupId>     &lt;artifactId>micrometer-tracing-bridge-brave&lt;\/artifactId>     &lt;version>1.1.3&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.zipkin.reporter2&lt;\/groupId>     &lt;artifactId>zipkin-reporter-brave&lt;\/artifactId>     &lt;version>2.16.3&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.zipkin.reporter2&lt;\/groupId>     &lt;artifactId>zipkin-sender-kafka&lt;\/artifactId>     &lt;version>2.16.3&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<h4>Properties<\/h4>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0442\u043e\u043f\u0438\u043a\u0443 Kafka, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b.<\/p>\n<p>\u0412\u044b\u043d\u0435\u0441\u0435\u043c \u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0442\u043a\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u041f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0435\u0447\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430:<\/p>\n<pre><code class=\"java\">@ConfigurationProperties(\"custom.tracing\") public record CustomTracingProperties(         \/* Kafka Producer username *\/         String username,         \/* Kafka Producer password *\/         String password,         \/* Kafka Producer topic *\/         String topic,         \/* Kafka Producer bootstrap servers *\/         String bootstrapServers ) { }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0441\u0447\u0435\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0438\u0437 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430 <code>application.yaml<\/code>:<\/p>\n<pre><code class=\"yaml\">custom:     tracing:         username: login \u0432 kafka         password: \u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442 \u043b\u043e\u0433\u0438\u043d\u0430         topic: \u0442\u043e\u043f\u0438\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0448\u0435\u043c \u0442\u0440\u0435\u0439\u0441\u044b         bootstrap-servers: broker1,broker2<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>@Test: CustomTracingProperties \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 `application.yaml`<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootTest(         properties = {                 \"custom.tracing.bootstrap-servers=server1,server2\",                 \"custom.tracing.password=pass\",                 \"custom.tracing.username=user\",                 \"custom.tracing.topic=topic\"         } ) @EnableConfigurationProperties(CustomTracingProperties.class) class CustomTracingPropertiesTest {      @Autowired     private CustomTracingProperties properties;      @Test     void should_FillProps() {         Assertions.assertThat(properties)                 .isNotNull()                 .satisfies(props -> {                     Assertions.assertThat(props.username())                             .isNotBlank()                             .isEqualTo(\"user\");                     Assertions.assertThat(props.password())                             .isNotBlank()                             .isEqualTo(\"pass\");                     Assertions.assertThat(props.topic())                             .isNotBlank()                             .isEqualTo(\"topic\");                     Assertions.assertThat(props.bootstrapServers())                             .isNotEmpty()                             .contains(\"server1\", \"server2\");                 });     }      @ConfigurationPropertiesScan(basePackageClasses = CustomTracingProperties.class)     @TestConfiguration     static class TestConfig {     }  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>KafkaSender<\/h4>\n<p>\u0412\u0440\u0443\u0447\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c KafkaSender. \u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 Kafka. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p><code>security.protocol=SASL_PLAINTEXT<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>sasl.mechanism=SCRAM-SHA-256<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u043d\u0430\u044f \u0432\u0441\u0435 \u0432\u0432\u043e\u0434\u043d\u044b\u0435, \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e:<\/p>\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties({KafkaProperties.class, CustomTracingProperties.class}) @RequiredArgsConstructor public class KafkaSenderConfiguration {      private final CustomTracingProperties customTracingProperties;      @Bean(\"zipkinSender\")     public Sender kafkaSender(KafkaProperties config, Environment environment) {          \/\/ Adding properties of Kafka for tracing         final Map&lt;String, Object> properties = config.buildProducerProperties();          \/\/ Bootstrap-servers \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0437 CustomTracingProperties, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043b\u0438\u0441\u0442         properties.put(\"bootstrap.servers\", STRING_TO_LIST.apply(customTracingProperties.bootstrapServers(), \",\"));          \/\/ Key\/Value serializers         properties.put(\"key.serializer\", ByteArraySerializer.class.getName());         properties.put(\"value.serializer\", ByteArraySerializer.class.getName());          \/\/ SASL properties         properties.put(\"sasl.jaas.config\",                 String.format(\"org.apache.kafka.common.security.scram.ScramLoginModule required username=%s password=%s;\",                         customTracingProperties.username(),                         customTracingProperties.password()));         properties.put(\"sasl.mechanism\", \"SCRAM-SHA-256\");          \/\/ Security         properties.put(\"security.protocol\", \"SASL_PLAINTEXT\");          \/\/ Client Id         final String serviceName = environment.getProperty(\"spring.application.name\");         properties.put(\"client.id\", serviceName);          \/\/ Building sender with properties         return KafkaSender                 .newBuilder()                 .topic(customTracingProperties.topic())                 .overrides(properties)                 .build();     } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0448\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>KafkaSender.newBuilder()<\/code> \u043c\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a Kafka \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u0432 \u0442.\u0447. \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>CustomTracingProperties<\/code> \u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b. \u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u0432\u0438\u0434\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432, \u0447\u0442\u043e\u0431 \u0431\u044b\u043b\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u0435\u0435.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u0421\u0442\u0440\u043e\u043a\u0430 \u0441 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043b\u0438\u0441\u0442 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/em><\/p>\n<pre><code class=\"java\">BiFunction&lt;String, String, List&lt;String>> STRING_TO_LIST = (sequence, delimiter) ->                 Arrays.stream(sequence.split(delimiter))                         .map(String::trim)                         .toList();<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>@Test: KafkaSender \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootTest(         classes = KafkaSenderConfiguration.class,         properties = {                 \"custom.tracing.bootstrap-servers=specified-server1,specified-server2\",                 \"custom.tracing.password=pass\",                 \"custom.tracing.username=user\",                 \"custom.tracing.topic=topic-for-traces\",                 \"spring.application.name=some-app\"         } ) class KafkaSenderConfigurationTest {      @Qualifier(\"zipkinSender\")     @Autowired     private Sender sender;      @Test     void shouldConfigureSender() {         Assertions.assertThat(sender)             .isNotNull()             .isInstanceOf(KafkaSender.class)             .satisfies(kafkaSender ->                     then(kafkaSender)                             .extracting(\"topic\")                             .isEqualTo(\"topic-for-traces\")             )             .extracting(\"properties\")             .isInstanceOfSatisfying(Properties.class, properties -> {                 then(properties.get(\"bootstrap.servers\"))                         .asList()                         .hasSize(2)                         .contains(\"specified-server1\", \"specified-server2\");                  then(properties.get(\"key.serializer\"))                         .isEqualTo(\"org.apache.kafka.common.serialization.ByteArraySerializer\");                  then(properties.get(\"value.serializer\"))                         .isEqualTo(\"org.apache.kafka.common.serialization.ByteArraySerializer\");                  then(properties.get(\"security.protocol\"))                         .isEqualTo(\"SASL_PLAINTEXT\");                  then(properties.get(\"sasl.jaas.config\"))                         .isEqualTo(\"org.apache.kafka.common.security.scram.ScramLoginModule required username=user password=pass;\");                  then(properties.get(\"client.id\"))                         .isEqualTo(\"some-app\");             });     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>Observation<\/h4>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e:<\/p>\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @EnableAspectJAutoProxy public class ObservedAspectConfiguration {      @Bean     public ObservedAspect observedAspect(ObservationRegistry observationRegistry) {         return new ObservedAspect(observationRegistry);     } }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u0443\u044f \u043c\u0435\u0442\u043e\u0434\u044b (\u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u044b) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>@Observed<\/code>, \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0440\u0435\u0439\u0441\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 (\u0438\u043b\u0438 \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430).<\/p>\n<pre><code class=\"java\">@Component public class SomeClass {     \/\/ \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u0438\u0436\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443     @Observed(name = \"observation-name\")     public void foo() {         System.out.println(\"bar\");     } }<\/code><\/pre>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>name<\/code> \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@Observed<\/code> \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u043d\u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0422\u0435\u0441\u0442 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0437\u0434\u043d\u0435\u0435, \u0432 \u044d\u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p><a href=\"https:\/\/spring.io\/blog\/2022\/10\/12\/observability-with-spring-boot-3\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Observability \u0432 Spring Boot 3<\/a>.<\/p>\n<h4>Management<\/h4>\n<p>\u0412 Spring Boot 3 \u0442\u0440\u0435\u0439\u0441\u044b <a href=\"https:\/\/github.com\/spring-cloud\/spring-cloud-sleuth#readme\">\u0431\u044b\u043b\u0438 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u0432 Micrometer Tracing<\/a>, \u043f\u0440\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c. \u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0442\u0430\u043a\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432 <code>application.yaml<\/code>:<\/p>\n<pre><code class=\"yaml\">management:     tracing:         enabled: true         sampling:             probability: 1.0<\/code><\/pre>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u0442\u0430\u0440\u0442\u0435\u0440\u0443<\/h3>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u0443\u0431\u0435\u0434\u0438\u0432\u0448\u0438\u0441\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0440\u0435\u0439\u0441\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 Zipkin, \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u0432\u0441\u0435 \u0432 \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0412\u0430\u043c \u043f\u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c \u0447\u0442\u043e \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u0448\u0430\u0433\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b. \u041e\u043d\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e.<\/p>\n<h2>\u0428\u0430\u0433 2. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e<\/h2>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0448\u0430\u0433\u0430<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043a \u0433\u043e\u0442\u043e\u0432\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0443, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u043c\u0443 \u043d\u0430 Spring Boot, \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 (\u0441\u0442\u0430\u0440\u0442\u0435\u0440).<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0448\u0430\u0433\u0430<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 Spring Boot \u043f\u0440\u043e\u0435\u043a\u0442, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043b\u0430\u0441\u0441 <code>MyTracingAutoConfiguration.class<\/code>. \u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u0441\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u043b\u0430\u0441\u044c \u043f\u0440\u0438 <code>management.tracing.enabled=true<\/code>.<\/p>\n<p>\u041d\u0438\u0436\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c, \u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0439 <code>&lt;scope>provided&lt;\/scope><\/code>. \u0414\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e <code>actuator<\/code> \u0443 \u043d\u0430\u0441 \u0438 \u0442\u0430\u043a \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 classpath \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u0435\u0440.<\/p>\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-actuator&lt;\/artifactId>     &lt;scope>provided&lt;\/scope> &lt;\/dependency><\/code><\/pre>\n<h4>\u041c\u043e\u043c\u0435\u043d\u0442 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/h4>\n<p>\u0425\u043e\u0447\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0412\u0430\u0448\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0434\u043e <code>ZipkinAutoConfiguration.class<\/code> \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0430 \u0431\u0438\u043d\u043e\u0432 (<code>restTemplateSender<\/code> vs. <code>kafkaSender<\/code>). \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@AutoConfigureBefore<\/code>.<\/p>\n<h4>\u0410\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f<\/h4>\n<pre><code class=\"java\">@AutoConfiguration @ConditionalOnProperty(name = \"management.tracing.enabled\", havingValue = \"true\") @AutoConfigureBefore(ZipkinAutoConfiguration.class) @Import({KafkaSenderConfiguration.class, ObservedAspectConfiguration.class}) public class MyTracingAutoConfiguration { }<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435 \u043c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><code>@ConditionalOnProperty<\/code> &#8212; \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 property <code>management.tracing.enabled<\/code> \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 <code>true<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>@AutoConfigureBefore(ZipkinAutoConfiguration.class)<\/code> &#8212; \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u0431\u0441\u0443\u0434\u0438\u043b\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f&#187; (\u0441\u043c.\u0432\u044b\u0448\u0435).<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><code>KafkaSenderConfiguration.class<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>ObservedAspectConfiguration.class<\/code>.<\/p>\n<\/li>\n<\/ul>\n<h4>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b Spring Boot \u0443\u0432\u0438\u0434\u0435\u043b \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b <code>\/src\/main\/resources\/META-INF\/spring\/org.springframework.boot.autoconfigure.AutoConfiguration.imports<\/code> \u0441 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 <code>MyTracingAutoConfiguration<\/code> (\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c <strong>\u043a\u0430\u043d\u043e\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435<\/strong> \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438).<\/p>\n<p><a href=\"https:\/\/github.com\/spring-projects\/spring-boot\/wiki\/Spring-Boot-3.0-Migration-Guide#auto-configuration-files\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0443\u0442<\/a>.<\/p>\n<h3>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0435\u0441\u0442\u044b<\/h3>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0442\u0435\u0441\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043f\u043e \u043c\u043e\u0435\u043c\u0443 \u043c\u043d\u0435\u043d\u0438\u044e, \u0432\u0430\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u0435, \u0442.\u043a. \u043e\u043d\u0438 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h4>@SpringBootConfiguration \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438<\/h4>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u043a\u043b\u0430\u0441\u0441 <code>TestConfiguration.class<\/code>, \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 <code>@SpringBootConfiguration<\/code> \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u044b \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/youtu.be\/uc-cfX-5wQA?t=3400\">\u044d\u0442\u043e\u043c \u0432\u0438\u0434\u0435\u043e<\/a>.<\/p>\n<pre><code class=\"java\">@SpringBootConfiguration public class TestConfiguration { }<\/code><\/pre>\n<h4>\u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c @Observed?<\/h4>\n<p>\u0422\u0435\u0441\u0442 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@Observed<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0435\u0439\u0441\u044b \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0428\u0430\u0433 1. \u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c:<\/p>\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>io.micrometer&lt;\/groupId>     &lt;artifactId>micrometer-tracing-integration-test&lt;\/artifactId>     &lt;scope>test&lt;\/scope> &lt;\/dependency><\/code><\/pre>\n<p>\u0428\u0430\u0433 2. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@EnableTestObservation<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0431\u0438\u043d\u0430 <code>observationRegistry<\/code> (TestObservationRegistry \u0438\u0437 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f). \u0422\u0430\u043a\u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448\u0443 <code>ObservedAspectConfiguration<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@AutoConfigureObservability<\/code>.<\/p>\n<p>\u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<pre><code class=\"java\">@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @AutoConfigureObservability @Import({         ObservedAspectConfiguration.class,         EnableTestObservation.ObservationTestConfiguration.class }) public @interface EnableTestObservation {      @TestConfiguration     class ObservationTestConfiguration {          @Bean         TestObservationRegistry observationRegistry() {             return TestObservationRegistry.create();         }     } }<\/code><\/pre>\n<p>\u0428\u0430\u0433 3. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0442\u0435\u0441\u0442 \u0438 \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e <code>@EnableTestObservation<\/code>:<\/p>\n<pre><code class=\"java\">@EnableTestObservation @SpringBootTest(classes = ObservedAspectConfigurationTest.SomeClass.class) @ImportAutoConfiguration(ZipkinAutoConfiguration.class) class ObservedAspectConfigurationTest {      @Autowired     private SomeClass someClass;      @Autowired     private ApplicationContext context;      @Test     void shouldObserve() {         someClass.foo();          final TestObservationRegistry observationRegistry = context.getBean(TestObservationRegistry.class);         TestObservationRegistryAssert.assertThat(observationRegistry)                 .hasObservationWithNameEqualTo(\"observation-name\")                 .that()                 .hasBeenStarted()                 .hasBeenStopped();     }      @TestComponent     public static class SomeClass {         @Observed(name = \"observation-name\")         public void foo() {             System.out.println(\"bar\");         }     } }<\/code><\/pre>\n<p>\u0412 \u0442\u0435\u0441\u0442\u0435 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438, \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>foo()<\/code> \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>someClass<\/code>, observation \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u043b\u0430 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c.<\/p>\n<h4>\u041f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\/\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438<\/h4>\n<details class=\"spoiler\">\n<summary>@Test: \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 management.tracing.enabled=true<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootTest(         classes = MyTracingAutoConfiguration.class,         properties = {                 \"custom.tracing.bootstrap-servers=specified-server1,specified-server2\",                 \"custom.tracing.password=pass\",                 \"custom.tracing.username=user\",                 \"custom.tracing.topic=topic-for-traces\",                 \"spring.application.name=some-app\",                 \"management.tracing.enabled=true\"         } ) @EnableTestObservation class MyTracingAutoConfigurationEnabledTest {      @Autowired     private ApplicationContext applicationContext;      @Test     void shouldConfigureSender() {         Assertions.assertThat(applicationContext.getBean(Sender.class))                 .isNotNull()                 .isInstanceOf(KafkaSender.class);     }      @Test     void shouldConfigureObservation() {         Assertions.assertThat(applicationContext.getBean(ObservedAspect.class))                 .isNotNull();     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>@Test: \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u041d\u0415 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 management.tracing.enabled=false<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootTest(properties = \"management.tracing.enabled=false\") class MyTracingAutoConfigurationDisabledTest {      @Autowired     private ApplicationContext context;      @Test     void shouldNotConfigureSender() {             assertThatThrownBy(() -> context.getBean(KafkaSender.class))                     .isInstanceOf(NoSuchBeanDefinitionException.class)                     .hasMessage(\"No qualifying bean of type 'zipkin2.reporter.kafka.KafkaSender' available\");     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0432 <code>pom.xml<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438: <\/p>\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-web&lt;\/artifactId> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-actuator&lt;\/artifactId> &lt;\/dependency> &lt;!-- \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430 --> &lt;dependency>     &lt;groupId>ru.alfastrah.api&lt;\/groupId>     &lt;artifactId>spring-boot-tracing-starter&lt;\/artifactId>     &lt;version>1.0.0&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.projectlombok&lt;\/groupId>     &lt;artifactId>lombok&lt;\/artifactId> &lt;\/dependency><\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c <code>application.yaml<\/code>, \u0443\u043a\u0430\u0436\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043d\u0430\u043c properties:<\/p>\n<pre><code class=\"yaml\">custom:   tracing:     username: login     password: password     topic: topic     bootstrap-servers: broker1,broker2      logging:   level:     org.apache.kafka.clients.NetworkClient: debug     root: info   pattern:     # \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0438\u0441\u044c traceId \u0438 spanId     level: \"%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]\" management:   tracing:     # \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0442\u0440\u0435\u0439\u0441\u044b     enabled: true     sampling:       probability: 1.0  spring:   application:     name: demo-tracing-app<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441 <code>FooService<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@Observed<\/code>:<\/p>\n<pre><code class=\"java\">@Service @Log4j2 public class FooService {      @Observed(name = \"observation-name\")     public void internalFoo() {         log.info(\"this is an internalFoo log\");     } }<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440:<\/p>\n<pre><code class=\"java\">@RestController @RequiredArgsConstructor public class TracingController {      private final FooService fooService;      @GetMapping(path = \"\/foo\")     public String foo() {         fooService.internalFoo();         return \"bar\";     } }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441<\/p>\n<pre><code class=\"bash\">curl http:\/\/localhost:8080\/foo $ bar                  <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043b\u043e\u0433\u0438. \u0412 <code>application.yaml<\/code> \u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u043e\u0432 \u0434\u043b\u044f <code>org.apache.kafka.clients.NetworkClient: debug<\/code>. \u0414\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 Kafka \u0431\u044b\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e. \u0423\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u044b\u043b:<\/p>\n<pre><code>2023-09-22T21:31:43.270+03:00 DEBUG [demo-tracing-app,,] 16342 --- [emo-tracing-app] org.apache.kafka.clients.NetworkClient   : [Producer clientId=demo-tracing-app] Sending PRODUCE request with header RequestHeader ... etc.<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u043b\u043e\u0433\u0438. \u041d\u0430\u0439\u0434\u0435\u043c traceId (<code>650ddd8f171924cbfc5d355d33fb9d9b<\/code>), \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441 \u0432 Zipkin:<\/p>\n<pre><code>2023-09-22T21:31:43.260+03:00  INFO [demo-tracing-app,650ddd8f171924cbfc5d355d33fb9d9b,c2987710f3440cd1] 15011 --- [nio-8080-exec-1] c.e.d.t.application.service.FooService   : this is an internalFoo log<\/code><\/pre>\n<p>\u041d\u0430\u0439\u0434\u0435\u043c \u0442\u0440\u0435\u0439\u0441 \u0432 Zipkin:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/134\/b98\/57b\/134b9857bf01cdb810b913dcbea3508a.png\" alt=\"\u0422\u0440\u0435\u0439\u0441 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Zipkin\" title=\"\u0422\u0440\u0435\u0439\u0441 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Zipkin\" width=\"2256\" height=\"574\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/134\/b98\/57b\/134b9857bf01cdb810b913dcbea3508a.png\"\/><\/p>\n<div><figcaption>\u0422\u0440\u0435\u0439\u0441 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Zipkin<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u0432\u044b\u0448\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u0442\u0440\u0435\u0439\u0441, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 2 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430 (span): \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 (parent) \u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 (\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439, \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>@Observed(name = \"observation-name\")<\/code>).<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0443\u043f\u0438\u043b\u043e \u043b\u0438 \u043d\u0430\u0448\u0435 \u0441\u0432\u0435\u0442\u043b\u043e\u0435 \u0431\u0443\u0434\u0443\u0449\u0435\u0435?<\/h2>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e. \u0414\u0430, \u0442\u0440\u0435\u0439\u0441\u044b \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c, \u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u043d\u0430 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0445 \u0432\u043e\u0435\u0434\u0438\u043d\u043e \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 (\u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434 \u043e\u0434\u043d\u0438\u043c traceId \u0443\u0432\u0438\u0434\u0435\u0442\u044c span&#8217;\u044b \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439).<\/p>\n<p>\u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438: \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043d\u044f\u0442\u044c 2 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0432 \u043a \u043d\u0438\u043c \u0441\u0442\u0430\u0440\u0442\u0435\u0440, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0434\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0435, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c 2 \u0440\u0430\u0437\u043d\u044b\u0445 traceId: 1\u0433\u043e \u0438 2\u0433\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0443\u0432\u044f\u0437\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0435\u0434\u0438\u043d\u043e &#8212; \u043d\u0430\u0448\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0446\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c. \u0423\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c, \u0435\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0432\u043e\u0434\u0443 &#8212; \u0431\u0443\u0434\u0443 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0435\u043d \u0438\u043c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0439\u0441\u043e\u0432 \u0432 Spring Boot 3 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0422\u0440\u0435\u0439\u0441\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 Zipkin \u0447\u0435\u0440\u0435\u0437 Kafka. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u043c\u0435\u0436\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0430\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/AlfaInsurance\/Zipkin_Spring_Starter\">\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.<\/a><\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u044b\u043b\u0430 \u0412\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430. <\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/770566\/\"> https:\/\/habr.com\/ru\/articles\/770566\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u0421\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u0410\u043b\u044c\u0444\u0430\u0421\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u043d\u0438\u0435 (\u0434\u0430\u043b\u0435\u0435 \u0421\u041a), \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e, \u043f\u0440\u043e\u0434\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0444\u0438\u0441\u0430\u0445, \u043d\u043e \u0438 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u044c \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u044b\u0445 \u0430\u0433\u0435\u043d\u0442\u043e\u0432. \u0410\u0433\u0435\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0444\u043e\u0440\u043c\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u0438\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f REST API. \u042d\u0442\u043e\u0442 API \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043d\u0435 \u043f\u043e\u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u0438\u043b\u043e\u0441\u044c \u0442\u0440\u0443\u0434\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0442\u0435\u0445\u043d\u0438\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0412\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043b\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0440\u0430\u0437\u0434\u0435\u043b\u0443 &#171;\u041f\u0440\u0435\u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b&#187;.<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f Zipkin \u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u0442\u0440\u0435\u0439\u0441\u043e\u0432. <a href=\"https:\/\/zipkin.io\/pages\/architecture.html\">\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e Zipkin \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435<\/a>.<\/p>\n<h2>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/h2>\n<h3>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442<\/h3>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u0438 \u043f\u0440\u043e\u0434\u0430\u0436\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u0420\u0430\u0441\u0447\u0435\u0442 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u0438\u0441\u0430 \u0432 core-\u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0421\u041a;<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u043b\u0430\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0447\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430\u043c\u0438. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0432 \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u043c\u044b \u0434\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435, \u043e\u043f\u043b\u0430\u0442\u0430 \u0438 \u0442.\u0434. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u0437\u0430 \u043d\u0438\u0445.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u043a\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 core-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 &#8212; Spring Boot.<\/p>\n<h3>\u041a\u043e\u0433\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0438\u0434\u0435\u0442 \u043d\u0435 \u0442\u0430\u043a<\/h3>\n<p>\u0412\u044b\u0448\u0435\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043f\u043e\u0440\u043e\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 HTTP 500, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 &#8212; \u0447\u0442\u043e \u0436\u0435 \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043b\u043e\u0433\u043e\u0432 \u0438 \u0442\u0440\u0435\u0439\u0441\u043e\u0432, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0434\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0434\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0441\u043e\u0431\u043e\u0433\u043e \u0442\u0440\u0443\u0434\u0430. \u0414\u0430\u043b\u0435\u0435 \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0443\u043b\u044c\u0442\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f).<\/p>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, Zipkin &#8212; \u043e\u0434\u0438\u043d<\/h3>\n<p>\u0414\u043b\u044f \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Zipkin. \u0422\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Kafka. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438. \u041d\u0430\u0448\u0435 \u0441\u0432\u0435\u0442\u043b\u043e\u0435 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 \u0432 \u0430\u0441\u043f\u0435\u043a\u0442\u0435 \u0442\u0440\u0435\u0439\u0441\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: <strong><em>\u0438\u043c\u0435\u044f \u0442\u0440\u0435\u0439\u0441\u044b \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0442\u0440\u0430\u0442\u0430\u043c\u0438 \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a (\u0435\u0441\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a).<\/em><\/strong><\/p>\n<h2>\u041f\u0440\u0435\u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0430 \u0432\u0445\u043e\u0434\u0435:<\/p>\n<ul>\n<li>\n<p>Java 17;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Spring Boot 3.1.2;<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 Zipkin, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0442\u0440\u0435\u0439\u0441\u044b \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 Kafka;<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f Kafka \u0441 \u0442\u043e\u043f\u0438\u043a\u043e\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b;<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0410\u0432\u0442\u043e\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (\u0442.\u043a. \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u043a\u0430\u0436\u0434\u043e\u043c) &#8212; \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u043c \u0448\u0430\u0433\u0435.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0428\u0430\u0433 1. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 (\u043a\u0430\u043a \u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445) \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u0432\u043e\u0434\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f.<\/p>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441 \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u0432 Zipkin \u0441 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043e\u043c Kafka. \u041f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0442.\u0435. \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u043d\u043e \u0438 \u0432\u043d\u0443\u0442\u0440\u0438, \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430.<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430<\/h3>\n<h4>Dependencies<\/h4>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0437\u0434\u0435\u0441\u044c \u0438 \u0434\u0430\u043b\u0435\u0435 \u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d parent <code>org.springframework.boot:spring-boot-starter-parent:3.1.2<\/code>, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0441\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u043b\u0438\u0441\u044c \u0441\u0430\u043c\u0438. \u041d\u0438\u0436\u0435 \u043e\u043d\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438.<\/p>\n<pre><code class=\"xml\">&lt;!-- \u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f observation \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 --> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-actuator&lt;\/artifactId>     &lt;version>3.1.2&lt;\/version> &lt;\/dependency> &lt;!-- \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f observations \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c @Observed --> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-aop&lt;\/artifactId>     &lt;version>3.1.2&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.springframework.kafka&lt;\/groupId>     &lt;artifactId>spring-kafka&lt;\/artifactId>     &lt;version>3.0.9&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.micrometer&lt;\/groupId>     &lt;artifactId>micrometer-tracing-bridge-brave&lt;\/artifactId>     &lt;version>1.1.3&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.zipkin.reporter2&lt;\/groupId>     &lt;artifactId>zipkin-reporter-brave&lt;\/artifactId>     &lt;version>2.16.3&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.zipkin.reporter2&lt;\/groupId>     &lt;artifactId>zipkin-sender-kafka&lt;\/artifactId>     &lt;version>2.16.3&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<h4>Properties<\/h4>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0442\u043e\u043f\u0438\u043a\u0443 Kafka, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0440\u0435\u0439\u0441\u044b.<\/p>\n<p>\u0412\u044b\u043d\u0435\u0441\u0435\u043c \u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0442\u043a\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. \u041f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0435\u0447\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430:<\/p>\n<pre><code class=\"java\">@ConfigurationProperties(\"custom.tracing\") public record CustomTracingProperties(         \/* Kafka Producer username *\/         String username,         \/* Kafka Producer password *\/         String password,         \/* Kafka Producer topic *\/         String topic,         \/* Kafka Producer bootstrap servers *\/         String bootstrapServers ) { }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0441\u0447\u0435\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0438\u0437 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430 <code>application.yaml<\/code>:<\/p>\n<pre><code class=\"yaml\">custom:     tracing:         username: login \u0432 kafka         password: \u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442 \u043b\u043e\u0433\u0438\u043d\u0430         topic: \u0442\u043e\u043f\u0438\u043a, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0448\u0435\u043c \u0442\u0440\u0435\u0439\u0441\u044b         bootstrap-servers: broker1,broker2<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>@Test: CustomTracingProperties \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 `application.yaml`<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootTest(         properties = {                 \"custom.tracing.bootstrap-servers=server1,server2\",                 \"custom.tracing.password=pass\",                 \"custom.tracing.username=user\",                 \"custom.tracing.topic=topic\"         } ) @EnableConfigurationProperties(CustomTracingProperties.class) class CustomTracingPropertiesTest {      @Autowired     private CustomTracingProperties properties;      @Test     void should_FillProps() {         Assertions.assertThat(properties)                 .isNotNull()                 .satisfies(props -> {                     Assertions.assertThat(props.username())                             .isNotBlank()                             .isEqualTo(\"user\");                     Assertions.assertThat(props.password())                             .isNotBlank()                             .isEqualTo(\"pass\");                     Assertions.assertThat(props.topic())                             .isNotBlank()                             .isEqualTo(\"topic\");                     Assertions.assertThat(props.bootstrapServers())                             .isNotEmpty()                             .contains(\"server1\", \"server2\");                 });     }      @ConfigurationPropertiesScan(basePackageClasses = CustomTracingProperties.class)     @TestConfiguration     static class TestConfig {     }  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>KafkaSender<\/h4>\n<p>\u0412\u0440\u0443\u0447\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c KafkaSender. \u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 Kafka. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p><code>security.protocol=SASL_PLAINTEXT<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>sasl.mechanism=SCRAM-SHA-256<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u043d\u0430\u044f \u0432\u0441\u0435 \u0432\u0432\u043e\u0434\u043d\u044b\u0435, \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e:<\/p>\n<pre><code class=\"java\">@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties({KafkaProperties.class, CustomTracingProperties.class}) @RequiredArgsConstructor public class KafkaSenderConfiguration {      private final CustomTracingProperties customTracingProperties;      @Bean(\"zipkinSender\")     public Sender kafkaSender(KafkaProperties config, Environment environment) {          \/\/ Adding properties of Kafka for tracing         final Map&lt;String, Object> properties = config.buildProducerProperties();          \/\/ Bootstrap-servers \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0437 CustomTracingProperties, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043b\u0438\u0441\u0442         properties.put(\"bootstrap.servers\", STRING_TO_LIST.apply(customTracingProperties.bootstrapServers(), \",\"));          \/\/ Key\/Value serializers         properties.put(\"key.serializer\", ByteArraySerializer.class.getName());         properties.put(\"value.serializer\", ByteArraySerializer.class.getName());          \/\/ SASL properties         properties.put(\"sasl.jaas.config\",                 String.format(\"org.apache.kafka.common.security.scram.ScramLoginModule required username=%s password=%s;\",                         customTracingProperties.username(),                         customTracingProperties.password()));         properties.put(\"sasl.mechanism\", \"SCRAM-SHA-256\");          \/\/ Security         properties.put(\"security.protocol\", \"SASL_PLAINTEXT\");          \/\/ Client Id         final String serviceName = environment.getProperty(\"spring.application.name\");         properties.put(\"client.id\", serviceName);          \/\/ Building sender with properties         return KafkaSender                 .newBuilder()                 .topic(customTracingProperties.topic())                 .overrides(properties)                 .build();     } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0448\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>KafkaSender.newBuilder()<\/code> \u043c\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a Kafka \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u0432 \u0442.\u0447. \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>CustomTracingProperties<\/code> \u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b. \u041a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u0432\u0438\u0434\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432, \u0447\u0442\u043e\u0431 \u0431\u044b\u043b\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u0435\u0435.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u0421\u0442\u0440\u043e\u043a\u0430 \u0441 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u043b\u0438\u0441\u0442 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/em><\/p>\n<pre><code class=\"java\">BiFunction&lt;String, String, List&lt;String>> STRING_TO_LIST = (sequence, delimiter) ->                 Arrays.stream(sequence.split(delimiter))                         .map(String::trim)                         .toList();<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>@Test: KafkaSender \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@SpringBootTest(         classes = KafkaSenderConfiguration.class,         properties = {                 \"custom.tracing.bootstrap-servers=specified-server1,specified-server2\",                 \"custom.tracing.password=pass\",                 \"custom.tracing.username=user\",                 \"custom.tracing.topic=topic-for-traces\",                 \"spring.application.name=some-app\"         } ) class KafkaSenderConfigurationTest {      @Qualifier(\"zipkinSender\")     @Autowired     private Sender sender;      @Test     void shouldConfigureSender() {         Assertions.assertThat(sender)             .isNotNull()             .isInstanceOf(KafkaSender.class)             .satisfies(kafkaSender ->                     then(kafkaSender)                             .extracting(\"topic\")                             .isEqualTo(\"topic-for-traces\")             )             .extracting(\"properties\")<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-358775","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/358775","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=358775"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/358775\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=358775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=358775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=358775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}