{"id":351337,"date":"2024-05-20T12:26:45","date_gmt":"2024-05-20T12:26:45","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=351337"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=351337","title":{"rendered":"<span>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Kotlin \u0438 WebFlux \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 ML \u0432 Apache Spark \u043d\u0430 GPU<\/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<p>\u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e \u0442\u0435\u043c\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 GPU \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Java, Kotlin, Spring \u0438 Spark. \u0421\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0441\u0442\u0430\u0442\u0435\u0439:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/679248\/\" rel=\"noopener noreferrer nofollow\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Java ML \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441\u043e Spring, Docker, Spark, Rapids, CUDA<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/739634\/\" rel=\"noopener noreferrer nofollow\">\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u0430\u044f Big Data \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 Kubernetes \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Spark \u0438 Cassandra<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/752702\/\" rel=\"noopener noreferrer nofollow\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Kotlin \u0438 WebFlux \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 ML \u0432 Apache Spark \u043d\u0430 GPU<\/a><\/p>\n<\/li>\n<\/ol>\n<h2>\u041e \u0447\u0435\u043c \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f<\/h2>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f Spark Driver \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u044b\u0439 \u0441\u0442\u0435\u043a Spring (Boot 2.7.11) \u0438 JDK 8. <\/p>\n<p>\u041d\u0430 \u0434\u0432\u043e\u0440\u0435 \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 2023 \u0433\u043e\u0434\u0430, \u0443 \u043c\u043d\u043e\u0433\u0438\u0445 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Boot 3+ (\u0430 \u0442\u043e \u0438 3.1+), \u0441\u043e\u0432\u0441\u0435\u043c \u0441\u043a\u043e\u0440\u043e \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0439\u0442\u0438 \u043d\u043e\u0432\u0430\u044f LTS \u0432\u0435\u0440\u0441\u0438\u044f Java, \u0438, \u043c\u044f\u0433\u043a\u043e \u0433\u043e\u0432\u043e\u0440\u044f, Boot 2+ \u0438 JDK8 \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u043d\u0438 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 GPU \u0432 \u0441\u0440\u0435\u0434\u0435 Spark \u0447\u0430\u0441\u0442\u044c\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0435\u043b\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 GPU <a href=\"https:\/\/github.com\/NVIDIA\/spark-rapids\" rel=\"noopener noreferrer nofollow\">NVidia Rapids<\/a>. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 JDK 17 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0440\u0435\u043b\u0438\u0437\u0435 v23.06.0 \u043e\u0442 27.06.23, \u0441 \u0435\u0435 \u0432\u044b\u0445\u043e\u0434\u043e\u043c \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e LTS \u0432\u0435\u0440\u0441\u0438\u044e Java, \u0430 \u0441 \u043d\u0435\u0439 &#8212; \u043d\u0430 Spring Boot 3+.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u0441 Boot 2 \u0438 JDK 8 \u0414\u043e Boot 3 \u0438 JDK 17, \u0441\u043e Spring Web \u043d\u0430 Spring WebFlux, \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f Web \u0438 WebFlux \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<h2>JDK8, Spring boot 2.7.11 \u2192 JDK17, Spring Boot 3.1.1<\/h2>\n<p>\u0414\u043b\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 Rapids \u0434\u043e 23.06.0, JDK \u0434\u043e 17, Spring Boot \u0434\u043e 3.1.1. \u041d\u044e\u0430\u043d\u0441\u043e\u0432 \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043c\u043d\u043e\u0433\u043e:<\/p>\n<ol>\n<li>\n<p>\u041a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 \u043b\u043e\u0433\u0435\u0440\u043e\u0432 Slf4j \u0438 Log4j \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Spark: \u0438\u0437 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 spring boot starter web \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c spring boot starter logging:<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>pom.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-web&lt;\/artifactId>     &lt;version>${spring.boot.version}&lt;\/version>     &lt;exclusions>         &lt;exclusion>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-logging&lt;\/artifactId>         &lt;\/exclusion>         &lt;exclusion>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-tomcat&lt;\/artifactId>         &lt;\/exclusion>     &lt;\/exclusions> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ol start=\"2\">\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c Spark Driver \u043d\u0430 JDK 17 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 (\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043e \u0434\u043b\u044f Dockerfile):<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>Application Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>ENV JAVA_OPTS='--add-opens=java.base\/java.lang=ALL-UNNAMED \\                --add-opens=java.base\/java.lang.invoke=ALL-UNNAMED \\                --add-opens=java.base\/java.lang.reflect=ALL-UNNAMED \\                --add-opens=java.base\/java.io=ALL-UNNAMED \\                --add-opens=java.base\/java.net=ALL-UNNAMED \\                --add-opens=java.base\/java.nio=ALL-UNNAMED \\                --add-opens=java.base\/java.util=ALL-UNNAMED \\                --add-opens=java.base\/java.util.concurrent=ALL-UNNAMED \\                --add-opens=java.base\/java.util.concurrent.atomic=ALL-UNNAMED \\                --add-opens=java.base\/sun.nio.ch=ALL-UNNAMED \\                --add-opens=java.base\/sun.nio.cs=ALL-UNNAMED \\                --add-opens=java.base\/sun.security.action=ALL-UNNAMED \\                --add-opens=java.base\/sun.util.calendar=ALL-UNNAMED \\                --add-opens=java.security.jgss\/sun.security.krb5=ALL-UNNAMED'<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ol start=\"3\">\n<li>\n<p>\u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043d\u0430 Hibernate 6, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 JSOB \u0438 BYTEA \u043f\u043e\u043b\u0435\u0439 \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445 Postgres \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c Entity:<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5c1\/63b\/20e\/5c163b20e6ab80ee4f28f0f2d8e28d7d.png\" width=\"709\" height=\"776\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5c1\/63b\/20e\/5c163b20e6ab80ee4f28f0f2d8e28d7d.png\"\/><\/figure>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0440\u0430\u043d\u0435\u0435 CustomPostgresDialect \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u043c \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0437\u0430\u043c\u0435\u043d\u0438\u0432 \u043d\u0430 <code>org.hibernate.dialect.PostgreSQLDialect<\/code>:<\/p>\n<details class=\"spoiler\">\n<summary>application.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">spring:   ...   jpa:     database-platform: com.mlwebservice.config.CustomPostgresDialect  # &lt;== delete     database-platform: org.hibernate.dialect.PostgreSQLDialect        # &lt;== add<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0439\u0441\u044f CustomPostgresDialect<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package com.mlwebservice.config  import com.vladmihalcea.hibernate.type.array.IntArrayType import com.vladmihalcea.hibernate.type.array.StringArrayType import com.vladmihalcea.hibernate.type.json.JsonBinaryType import com.vladmihalcea.hibernate.type.json.JsonNodeBinaryType import com.vladmihalcea.hibernate.type.json.JsonNodeStringType import com.vladmihalcea.hibernate.type.json.JsonStringType import org.hibernate.dialect.PostgreSQL10Dialect import java.sql.Types  class CustomPostgresDialect : PostgreSQL10Dialect() {     init {         registerHibernateType(Types.OTHER, StringArrayType::class.qualifiedName)         registerHibernateType(Types.OTHER, IntArrayType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonStringType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonBinaryType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonNodeBinaryType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonNodeStringType::class.qualifiedName)     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 jar&#8217;\u043d\u0438\u043a\u0430 Rapids \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 jar-\u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 Spark executors \u0438 \u0432 \u043e\u0431\u0440\u0430\u0437 executor\u2019\u0430, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c. \u0410\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c <a href=\"https:\/\/gitlab.com\/AlexPit\/java-ml-spark-example\/-\/tree\/kubernetes-java17-spark332\" rel=\"noopener noreferrer nofollow\">\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0432\u0435\u0442\u043a\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c, \u043d\u043e \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0441\u0442\u0432\u043e \u0432\u0435\u0434\u044c \u0431\u0435\u0440\u0435\u0442 \u0441\u0432\u043e\u0435, \u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u0438 \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0435\u043a\u0435, \u0438 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u044d\u0444\u0444\u0435\u043a\u0442?<\/p>\n<h2>\u0421\u0434\u0435\u043b\u0430\u0435\u043c ML \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c: Spring Web \u2192 Spring WebFlux <\/h2>\n<h3>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/h3>\n<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435, \u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b \u0432 \u0432\u0438\u0434\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438. \u0422\u0430\u043a, Netty, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0434\u043b\u044f Project Reactor (WebFlux) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c Spark \u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u043c Cassandra, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432\u0430\u043b\u0438. \u0420\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Netty<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependencies>     &lt;!-- Netty -->     &lt;dependency>         &lt;groupId>io.netty&lt;\/groupId>         &lt;artifactId>netty-all&lt;\/artifactId>         &lt;version>4.1.74.Final&lt;\/version>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>io.netty&lt;\/groupId>         &lt;artifactId>netty-codec-http&lt;\/artifactId>         &lt;version>4.1.74.Final&lt;\/version>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>io.netty&lt;\/groupId>         &lt;artifactId>netty-resolver-dns&lt;\/artifactId>         &lt;version>4.1.74.Final&lt;\/version>     &lt;\/dependency>      &lt;!-- Spring -->     &lt;dependency>         &lt;groupId>org.springframework.boot&lt;\/groupId>         &lt;artifactId>spring-boot-starter-webflux&lt;\/artifactId>         &lt;version>${spring.boot.version}&lt;\/version>         &lt;exclusions>             &lt;exclusion>                 &lt;artifactId>log4j-to-slf4j&lt;\/artifactId>                 &lt;groupId>org.apache.logging.log4j&lt;\/groupId>             &lt;\/exclusion>         &lt;\/exclusions>     &lt;\/dependency>     ... &lt;\/dependencies><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>Spring Data \u0442\u043e\u0436\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: R2DBC \u0438 Spring Data Cassandra Reactive<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-data-cassandra-reactive&lt;\/artifactId>     &lt;version>${spring.boot.version}&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-data-r2dbc&lt;\/artifactId>     &lt;version>${spring.boot.version}&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.r2dbc&lt;\/groupId>     &lt;artifactId>r2dbc-postgresql&lt;\/artifactId>     &lt;version>0.8.13.RELEASE&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b Kotlin \u0432 \u0441\u0440\u0435\u0434\u0435 WebFlux:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: Kotlin dependencies<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>     &lt;artifactId>kotlin-stdlib&lt;\/artifactId>     &lt;version>${kotlin.version}&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>     &lt;artifactId>kotlin-reflect&lt;\/artifactId>     &lt;version>${kotlin.version}&lt;\/version>     &lt;scope>runtime&lt;\/scope> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.jetbrains.kotlinx&lt;\/groupId>     &lt;artifactId>kotlinx-coroutines-reactor&lt;\/artifactId>     &lt;version>1.7.2&lt;\/version>     &lt;scope>runtime&lt;\/scope> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.projectreactor.kotlin&lt;\/groupId>     &lt;artifactId>reactor-kotlin-extensions&lt;\/artifactId>     &lt;version>1.2.2&lt;\/version>     &lt;scope>runtime&lt;\/scope> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0441\u0430\u043c Kotlin \u0442\u043e\u0436\u0435 \u043f\u043e\u0434\u043d\u044f\u043b \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.8.21 \u0434\u043e 1.9.0.<\/p>\n<p>\u0414\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f HTTP \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432-\u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Zalando Logbook:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: Zalando Logbook<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.zalando&lt;\/groupId>     &lt;artifactId>logbook-spring-boot-autoconfigure&lt;\/artifactId>     &lt;version>3.2.0&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.zalando&lt;\/groupId>     &lt;artifactId>logbook-netty&lt;\/artifactId>     &lt;version>3.2.0&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>pom.xml (\u043f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043b\u044f WebFlux)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?> &lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"          xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"          xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">     &lt;modelVersion>4.0.0&lt;\/modelVersion>      &lt;groupId>com.mlwebservice&lt;\/groupId>     &lt;artifactId>MLWebService&lt;\/artifactId>     &lt;version>1.0.0-SNAPSHOT&lt;\/version>      &lt;properties>         &lt;java.version>17&lt;\/java.version>         &lt;spring.boot.version>3.1.1&lt;\/spring.boot.version>         &lt;scala.version>2.12&lt;\/scala.version>         &lt;spark.version>3.3.2&lt;\/spark.version>         &lt;lombok.version>1.18.24&lt;\/lombok.version>         &lt;org.mapstruct.version>1.4.2.Final&lt;\/org.mapstruct.version>         &lt;kotlin.version>1.9.0&lt;\/kotlin.version>         &lt;jackson.version>2.13.5&lt;\/jackson.version>     &lt;\/properties>      &lt;distributionManagement>         &lt;repository>             &lt;id>XGBoost4J Snapshot Repo&lt;\/id>             &lt;name>XGBoost4J Snapshot Repo&lt;\/name>             &lt;url>https:\/\/s3-us-west-2.amazonaws.com\/xgboost-maven-repo\/snapshot\/&lt;\/url>         &lt;\/repository>     &lt;\/distributionManagement>      &lt;dependencies>         &lt;!-- Netty -->         &lt;dependency>             &lt;groupId>io.netty&lt;\/groupId>             &lt;artifactId>netty-all&lt;\/artifactId>             &lt;version>4.1.74.Final&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>io.netty&lt;\/groupId>             &lt;artifactId>netty-codec-http&lt;\/artifactId>             &lt;version>4.1.74.Final&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>io.netty&lt;\/groupId>             &lt;artifactId>netty-resolver-dns&lt;\/artifactId>             &lt;version>4.1.74.Final&lt;\/version>         &lt;\/dependency>          &lt;!-- Spring -->         &lt;dependency>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-webflux&lt;\/artifactId>             &lt;version>${spring.boot.version}&lt;\/version>             &lt;exclusions>                 &lt;exclusion>                     &lt;groupId>org.springframework.boot&lt;\/groupId>                     &lt;artifactId>spring-boot-starter-logging&lt;\/artifactId>                 &lt;\/exclusion>             &lt;\/exclusions>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.fasterxml.jackson.core&lt;\/groupId>             &lt;artifactId>jackson-core&lt;\/artifactId>             &lt;version>${jackson.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.fasterxml.jackson.module&lt;\/groupId>             &lt;artifactId>jackson-module-kotlin&lt;\/artifactId>             &lt;version>${jackson.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.fasterxml.jackson.core&lt;\/groupId>             &lt;artifactId>jackson-annotations&lt;\/artifactId>             &lt;version>${jackson.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.fasterxml.jackson.core&lt;\/groupId>             &lt;artifactId>jackson-databind&lt;\/artifactId>             &lt;version>${jackson.version}&lt;\/version>         &lt;\/dependency>          &lt;!-- Spring Data -->         &lt;dependency>             &lt;groupId>org.springframework.data&lt;\/groupId>             &lt;artifactId>spring-data-commons&lt;\/artifactId>             &lt;version>${spring.boot.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-data-cassandra-reactive&lt;\/artifactId>             &lt;version>${spring.boot.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-data-r2dbc&lt;\/artifactId>             &lt;version>${spring.boot.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-data-jpa&lt;\/artifactId>             &lt;version>${spring.boot.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.postgresql&lt;\/groupId>             &lt;artifactId>postgresql&lt;\/artifactId>             &lt;scope>runtime&lt;\/scope>             &lt;version>42.6.0&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>io.r2dbc&lt;\/groupId>             &lt;artifactId>r2dbc-postgresql&lt;\/artifactId>             &lt;version>0.8.13.RELEASE&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.vladmihalcea&lt;\/groupId>             &lt;artifactId>hibernate-types-60&lt;\/artifactId>             &lt;version>2.21.1&lt;\/version>         &lt;\/dependency>          &lt;!-- Cassandra -->         &lt;dependency>             &lt;groupId>com.datastax.oss&lt;\/groupId>             &lt;artifactId>java-driver-core&lt;\/artifactId>             &lt;version>4.13.0&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.scala-lang&lt;\/groupId>             &lt;artifactId>scala-library&lt;\/artifactId>             &lt;version>2.12.15&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>com.datastax.spark&lt;\/groupId>             &lt;artifactId>spark-cassandra-connector_2.12&lt;\/artifactId>             &lt;version>3.3.0&lt;\/version>         &lt;\/dependency>          &lt;dependency>             &lt;groupId>com.typesafe&lt;\/groupId>             &lt;artifactId>config&lt;\/artifactId>             &lt;version>1.4.2&lt;\/version>         &lt;\/dependency>          &lt;!-- Spark -->         &lt;dependency>             &lt;groupId>org.apache.spark&lt;\/groupId>             &lt;artifactId>spark-core_${scala.version}&lt;\/artifactId>             &lt;version>${spark.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.apache.spark&lt;\/groupId>             &lt;artifactId>spark-hive_${scala.version}&lt;\/artifactId>             &lt;version>${spark.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.apache.spark&lt;\/groupId>             &lt;artifactId>spark-streaming_${scala.version}&lt;\/artifactId>             &lt;version>${spark.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.apache.spark&lt;\/groupId>             &lt;artifactId>spark-sql_${scala.version}&lt;\/artifactId>             &lt;version>${spark.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.apache.spark&lt;\/groupId>             &lt;artifactId>spark-mllib_${scala.version}&lt;\/artifactId>             &lt;version>${spark.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.antlr&lt;\/groupId>             &lt;artifactId>antlr4-runtime&lt;\/artifactId>             &lt;version>4.8&lt;\/version>             &lt;scope>runtime&lt;\/scope>         &lt;\/dependency>          &lt;!-- GXBoost -->         &lt;dependency>             &lt;groupId>ml.dmlc&lt;\/groupId>             &lt;artifactId>xgboost4j-spark-gpu_${scala.version}&lt;\/artifactId>             &lt;version>1.7.5&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>ml.dmlc&lt;\/groupId>             &lt;artifactId>xgboost4j-gpu_${scala.version}&lt;\/artifactId>             &lt;version>1.7.5&lt;\/version>         &lt;\/dependency>          &lt;!-- Kubernetes -->         &lt;dependency>             &lt;groupId>org.apache.spark&lt;\/groupId>             &lt;artifactId>spark-kubernetes_${scala.version}&lt;\/artifactId>             &lt;version>${spark.version}&lt;\/version>         &lt;\/dependency>          &lt;dependency>             &lt;groupId>org.codehaus.janino&lt;\/groupId>             &lt;artifactId>commons-compiler&lt;\/artifactId>             &lt;version>3.0.16&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.codehaus.janino&lt;\/groupId>             &lt;artifactId>janino&lt;\/artifactId>             &lt;version>3.0.16&lt;\/version>         &lt;\/dependency>          &lt;!-- Rapids -->         &lt;dependency>             &lt;groupId>com.nvidia&lt;\/groupId>             &lt;artifactId>rapids-4-spark_${scala.version}&lt;\/artifactId>             &lt;version>23.06.0&lt;\/version>         &lt;\/dependency>          &lt;!-- Lombok -->         &lt;dependency>             &lt;groupId>org.projectlombok&lt;\/groupId>             &lt;artifactId>lombok&lt;\/artifactId>             &lt;version>${lombok.version}&lt;\/version>         &lt;\/dependency>          &lt;!-- Logging -->         &lt;dependency>             &lt;groupId>org.zalando&lt;\/groupId>             &lt;artifactId>logbook-spring-webflux&lt;\/artifactId>             &lt;version>3.1.0&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.zalando&lt;\/groupId>             &lt;artifactId>logbook-spring-boot-autoconfigure&lt;\/artifactId>             &lt;version>3.2.0&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.zalando&lt;\/groupId>             &lt;artifactId>logbook-netty&lt;\/artifactId>             &lt;version>3.2.0&lt;\/version>         &lt;\/dependency>          &lt;!-- Utils -->         &lt;dependency>             &lt;groupId>org.apache.commons&lt;\/groupId>             &lt;artifactId>commons-lang3&lt;\/artifactId>             &lt;version>3.12.0&lt;\/version>         &lt;\/dependency>          &lt;!-- Kotlin -->         &lt;dependency>             &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>             &lt;artifactId>kotlin-stdlib&lt;\/artifactId>             &lt;version>${kotlin.version}&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>             &lt;artifactId>kotlin-reflect&lt;\/artifactId>             &lt;version>${kotlin.version}&lt;\/version>             &lt;scope>runtime&lt;\/scope>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.jetbrains.kotlinx&lt;\/groupId>             &lt;artifactId>kotlinx-coroutines-reactor&lt;\/artifactId>             &lt;version>1.7.2&lt;\/version>             &lt;scope>runtime&lt;\/scope>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>io.projectreactor.kotlin&lt;\/groupId>             &lt;artifactId>reactor-kotlin-extensions&lt;\/artifactId>             &lt;version>1.2.2&lt;\/version>             &lt;scope>runtime&lt;\/scope>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.jetbrains.kotlinx.spark&lt;\/groupId>             &lt;artifactId>kotlin-spark-api_3.3.1_${scala.version}&lt;\/artifactId>             &lt;version>1.2.3&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>             &lt;artifactId>kotlin-test&lt;\/artifactId>             &lt;version>${kotlin.version}&lt;\/version>             &lt;scope>test&lt;\/scope>         &lt;\/dependency>     &lt;\/dependencies>      &lt;build>         &lt;finalName>service&lt;\/finalName>         &lt;plugins>             &lt;plugin>                 &lt;groupId>org.springframework.boot&lt;\/groupId>                 &lt;artifactId>spring-boot-maven-plugin&lt;\/artifactId>                 &lt;version>3.0.6&lt;\/version>                 &lt;configuration>                     &lt;mainClass>com.mlwebservice.MLWebServiceApplication&lt;\/mainClass>                 &lt;\/configuration>                 &lt;executions>                     &lt;execution>                         &lt;goals>                             &lt;goal>repackage&lt;\/goal>                         &lt;\/goals>                     &lt;\/execution>                 &lt;\/executions>             &lt;\/plugin>              &lt;plugin>                 &lt;groupId>org.apache.maven.plugins&lt;\/groupId>                 &lt;artifactId>maven-compiler-plugin&lt;\/artifactId>                 &lt;version>3.11.0&lt;\/version>                 &lt;executions>                     &lt;execution>                         &lt;id>compile&lt;\/id>                         &lt;phase>compile&lt;\/phase>                         &lt;goals>                             &lt;goal>compile&lt;\/goal>                         &lt;\/goals>                     &lt;\/execution>                     &lt;execution>                         &lt;id>testCompile&lt;\/id>                         &lt;phase>test-compile&lt;\/phase>                         &lt;goals>                             &lt;goal>testCompile&lt;\/goal>                         &lt;\/goals>                     &lt;\/execution>                 &lt;\/executions>                 &lt;configuration>                     &lt;source>${java.version}&lt;\/source>                     &lt;target>${java.version}&lt;\/target>                     &lt;annotationProcessorPaths>                         &lt;path>                             &lt;groupId>org.projectlombok&lt;\/groupId>                             &lt;artifactId>lombok&lt;\/artifactId>                             &lt;version>${lombok.version}&lt;\/version>                         &lt;\/path>                     &lt;\/annotationProcessorPaths>                 &lt;\/configuration>             &lt;\/plugin>              &lt;plugin>                 &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>                 &lt;artifactId>kotlin-maven-plugin&lt;\/artifactId>                 &lt;version>${kotlin.version}&lt;\/version>                 &lt;executions>                     &lt;execution>                         &lt;id>compile&lt;\/id>                         &lt;phase>process-sources&lt;\/phase>                         &lt;goals>                             &lt;goal>compile&lt;\/goal>                         &lt;\/goals>                         &lt;configuration>                             &lt;jvmTarget>${java.version}&lt;\/jvmTarget>                             &lt;sourceDirs>                                 &lt;source>src\/main\/java&lt;\/source>                                 &lt;source>src\/main\/kotlin&lt;\/source>                                 &lt;source>target\/generated-sources\/annotations&lt;\/source>                             &lt;\/sourceDirs>                         &lt;\/configuration>                     &lt;\/execution>                     &lt;execution>                         &lt;id>test-compile&lt;\/id>                         &lt;phase>test-compile&lt;\/phase>                         &lt;goals>                             &lt;goal>test-compile&lt;\/goal>                         &lt;\/goals>                         &lt;configuration>                             &lt;jvmTarget>${java.version}&lt;\/jvmTarget>                             &lt;sourceDirs>                                 &lt;source>src\/main\/java&lt;\/source>                                 &lt;source>src\/main\/kotlin&lt;\/source>                                 &lt;source>target\/generated-sources\/annotations&lt;\/source>                             &lt;\/sourceDirs>                         &lt;\/configuration>                     &lt;\/execution>                 &lt;\/executions>                 &lt;configuration>                     &lt;jvmTarget>${java.version}&lt;\/jvmTarget>                     &lt;sourceDirs>                         &lt;source>src\/main\/java&lt;\/source>                         &lt;source>src\/main\/kotlin&lt;\/source>                         &lt;source>target\/generated-sources\/annotations&lt;\/source>                     &lt;\/sourceDirs>                 &lt;\/configuration>             &lt;\/plugin>         &lt;\/plugins>     &lt;\/build> &lt;\/project> <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>Main \u043a\u043b\u0430\u0441\u0441<\/h3>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c Main \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@EnableWebFlux<\/code> \u0438 <code>@EnableR2dbcRepositories<\/code>, \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0438\u043f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f <code>REACTIVE<\/code><\/p>\n<details class=\"spoiler\">\n<summary>Main class<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package com.mlwebservice;  import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; import org.springframework.web.reactive.config.EnableWebFlux;  import java.net.InetAddress; import java.net.UnknownHostException;  @EnableWebFlux @EnableR2dbcRepositories @SpringBootApplication(exclude = {         GsonAutoConfiguration.class,         CassandraAutoConfiguration.class }) public class MLWebServiceApplication {     public static void main(String[] args) {         new SpringApplicationBuilder(MLWebServiceApplication.class)                 .web(WebApplicationType.REACTIVE)                 .run(args);         );     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>Spring Data \u2192 R2DBC<\/h3>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0411\u0414 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f JSONB \u043f\u043e\u043b\u0435 (\u0441 \u0435\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0432 \u0432\u0438\u0434\u0435 JsonNode), \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f R2DBC \u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430\u043c\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>Jsonb converters<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">package com.mlwebservice.config  import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import io.r2dbc.postgresql.codec.Json import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.convert.converter.Converter import org.springframework.data.convert.ReadingConverter import org.springframework.data.convert.WritingConverter import org.springframework.data.r2dbc.convert.R2dbcCustomConversions import org.springframework.data.r2dbc.dialect.PostgresDialect  @Configuration open class R2dbcConfiguration(private val objectMapper: ObjectMapper) {      @Bean     open fun customConversions() : R2dbcCustomConversions {         val converters = listOf&lt;Converter&lt;*, *>>(             JsonNodeWritingConverter(objectMapper),             JsonNodeReadingConverter(objectMapper)         )         return R2dbcCustomConversions.of(PostgresDialect.INSTANCE, converters);     } }  @WritingConverter class JsonNodeWritingConverter(private val objectMapper: ObjectMapper) : Converter&lt;JsonNode, Json> {     override fun convert(source: JsonNode): Json {         return Json.of(objectMapper.writeValueAsString(source));     } }  @ReadingConverter class JsonNodeReadingConverter(private val objectMapper: ObjectMapper) : Converter&lt;Json, JsonNode> {     override fun convert(source: Json): JsonNode? {         return objectMapper.readTree(source.asString());     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e\u0439 \u0432\u044b\u0448\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 <code>ModelEntity<\/code> \u043b\u0438\u0448\u043d\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438, \u0432 \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f:<\/p>\n<details class=\"spoiler\">\n<summary>ModelEntity<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">package com.mlwebservice.persist.entity  import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.Id import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.time.LocalDateTime import java.util.*  @Table(name = \"models\", schema = \"instrument_data\") data class ModelEntity constructor(     @Id     val id: Long? = null,        @Column(\"model\")     val model: ByteArray,      @Column(\"created_at\")     val createdAt: LocalDateTime,      @Column(\"last_trained_at\")     val lastTrainedAt: LocalDateTime,      @Column(\"task_id\")     val taskId: UUID,      @Column(\"parameters\")     val parameters: JsonNode ) \/\/ \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0438 \u043f\u0440\u043e\u0447\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0430\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 R2dbcRepository:<\/p>\n<pre><code class=\"kotlin\">@Repository interface ModelRepository : R2dbcRepository&lt;ModelEntity, Long><\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 WebFlux:<\/p>\n<details class=\"spoiler\">\n<summary>\u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445<\/summary>\n<div class=\"spoiler__content\">\n<p>\u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0411\u0414<\/p>\n<pre><code class=\"kotlin\">internal inline fun &lt;reified T> loadModel(modelId: Long): T {     val optional = modelRepository.findById(modelId)      val entity = optional.get()     val modelByteArray = entity.model      val byteArrayInputStream = ByteArrayInputStream(modelByteArray)     val modelObject = ObjectInputStream(byteArrayInputStream).use { it.readObject() }      if (modelObject is T) {         return modelObject     } else {         throw ServiceException.withMessage(\"Model id $modelId has incorrect format\")     } }<\/code><\/pre>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<pre><code class=\"kotlin\">internal inline fun &lt;reified T> loadModel(modelId: Long): Mono&lt;T> =         modelRepository.findById(modelId)             .map { modelEntity: ModelEntity ->                 ByteArrayInputStream(modelEntity.model)             }             .publishOn(Schedulers.boundedElastic())             .map { byteArrayInputStream: ByteArrayInputStream ->                 ObjectInputStream(byteArrayInputStream).use { it.readObject() }             }             .flatMap { modelObject ->                 if (modelObject is T) {                     Mono.just(modelObject)                 } else {                     Mono.error(ServiceException.withMessage(\"Model id $modelId has incorrect format\"))                 }             }<\/code><\/pre>\n<p>\u0430 \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"kotlin\">fun saveModel(     model : PredictionModel&lt;Vector, XGBoostRegressionModel>,     taskId : UUID,     modelParameters : AnalyticsRequest.ModelParameters ) {     val byteArrayOutputStream = ByteArrayOutputStream()     ObjectOutputStream(byteArrayOutputStream).use { it.writeObject(model) }     val modelByteArray: ByteArray = byteArrayOutputStream.toByteArray()     val jsonParams : JsonNode = objectMapper.convertValue(modelParameters, JsonNode::class.java)      val entity = ModelEntity(modelByteArray, taskId, jsonParams)     modelRepository.save(entity)     log.info(\"Model for task id {} saved. Parameters map: {}, jsonNode: {}\",         taskId, modelParameters, jsonParams) }<\/code><\/pre>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<pre><code class=\"kotlin\">fun saveModel(         model: PredictionModel&lt;Vector, XGBoostRegressionModel>,         taskId: UUID,         modelParameters: AnalyticsRequest.ModelParameters     ): Mono&lt;Void> =         Mono.fromCallable {             val jsonParams: JsonNode = objectMapper.convertValue(modelParameters, JsonNode::class.java)              val byteArrayOutputStream = ByteArrayOutputStream()             ObjectOutputStream(byteArrayOutputStream).use { objectOutputStream ->                 objectOutputStream.writeObject(model)             }             val modelByteArray: ByteArray = byteArrayOutputStream.toByteArray()              ModelEntity(modelByteArray, taskId, jsonParams)         }             .subscribeOn(Schedulers.boundedElastic())             .flatMap { entity ->                 modelRepository.save(entity)                     .doOnSuccess {                         log.info(                             \"Model for task id {} saved. Parameters map: {}, jsonNode: {}\",                             taskId, modelParameters, entity.parameters.toString()                         )                     }                     .then()             }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>Cassandra<\/h3>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 Cassandra \u0441\u0442\u0440\u043e\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u043f\u0430\u0440\u043a\u043e\u0432\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0435\u0439. \u041f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u0422\u0430\u043a, \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>cassandraDataset web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun cassandraDataset(keyspace: String, table: String): Dataset&lt;Row> {     val cassandraDataset: Dataset&lt;Row> = sparkSession.read()         .format(\"org.apache.spark.sql.cassandra\")         .option(\"keyspace\", keyspace)         .option(\"table\", table)         .load()      cassandraDataset.createOrReplaceTempView(table)     return cassandraDataset }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>cassandraDataset webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun cassandraDataset(keyspace: String, table: String): Mono&lt;Dataset&lt;Row>> =     Mono.fromCallable {         val cassandraDataset: Dataset&lt;Row> = sparkSession.read()             .format(\"org.apache.spark.sql.cassandra\")             .option(\"keyspace\", keyspace)             .option(\"table\", table)             .load()          cassandraDataset.createOrReplaceTempView(table)         cassandraDataset     }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>saveDataSet web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>open fun saveDataSet(dataset: Dataset&lt;Row>) {     dataset.write()         .format(\"org.apache.spark.sql.cassandra\")         .mode(\"append\")         .option(\"confirm.truncate\", \"false\")         .option(\"keyspace\", keyspace)         .option(\"table\", table)         .save(); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>saveDataSet webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">open fun saveDataSet(dataset: Dataset&lt;Row>): Mono&lt;Void> =     Mono.fromRunnable {         dataset.write()             .format(\"org.apache.spark.sql.cassandra\")             .mode(\"append\")             .option(\"confirm.truncate\", \"false\")             .option(\"keyspace\", keyspace)             .option(\"table\", table)             .save()     }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u0444\u0444\u0441\u0435\u0442\u0430\u043c\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>getBaseDataSet web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun getBaseDataSet(     ticker: String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     currentOffset : Int,     batchSize : Int ): Dataset&lt;Row> {     val filteredDataset = cassandraDataset(table)         .filter(             functions.col(\"ticker\").equalTo(ticker)                 .and(functions.col(\"task_number\").equalTo(taskNumber.toString()))                 .and(functions.col(\"datetime\").between(dateStart, dateEnd))         )      val offsetDataset = filteredDataset.withColumn(         \"row_number\",         functions.row_number().over(orderBy(\"datetime\"))     )      return offsetDataset         .filter(functions.col(\"row_number\")             .between(currentOffset + 1, currentOffset + batchSize))         .drop(\"row_number\") }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>getBaseDataSet webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun getBaseDataSet(     ticker: String,     taskNumber: UUID,     dateStart: LocalDate,     dateEnd: LocalDate,     currentOffset: Int,     batchSize: Int ): Mono&lt;Dataset&lt;Row>> =     cassandraDataset(table)         .map { dataset ->             dataset                 .filter(                     functions.col(\"ticker\").equalTo(ticker)                         .and(functions.col(\"task_number\").equalTo(taskNumber.toString()))                         .and(functions.col(\"datetime\").between(dateStart, dateEnd))                 ).withColumn(                     \"row_number\",                     functions.row_number().over(orderBy(\"datetime\"))                 )                 .filter(                     functions.col(\"row_number\")                         .between(currentOffset + 1, currentOffset + batchSize)                 )                 .drop(\"row_number\")         }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443.<\/p>\n<p>\u0412 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u043e\u0432 (\u0442\u0435\u043f\u0435\u0440\u044c \u0436\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 <code>Mono&lt;Dataset&lt;Row>><\/code>):<\/p>\n<details class=\"spoiler\">\n<summary>getMainDataset web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun getMainDataset(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate ) : Dataset&lt;Row> {     val timeSeries = timeSeriesRepository.getDataset(ticker, taskNumber, dateStart, dateEnd).`as`(\"ts\")     val emaDataSet = emaRepository.getEmaDataSet(ticker, dateStart, dateEnd).`as`(\"ema\")     val stochasticDataset = stochasticRepository.getStochasticDataSet(ticker, dateStart, dateEnd).`as`(\"stoch\")     val bBandsDataset = bBandIndicatorRepository.getBBandsDataSet(ticker, dateStart, dateEnd).`as`(\"bb\")     val macdDataset = macdRepository.getMacdDataSet(ticker, dateStart, dateEnd).`as`(\"macd\")     val rsiDataset = rsiRepository.getRsiDataSet(ticker, dateStart, dateEnd).`as`(\"rsi\")     val smaDataset = smaRepository.getSmaDataSet(ticker, dateStart, dateEnd).`as`(\"sma\")     val willrDataset = willrRepository.getWillrDataSet(ticker, dateStart, dateEnd).`as`(\"willr\")      return combineDatasets(         timeSeries, emaDataSet, stochasticDataset, bBandsDataset, macdDataset, rsiDataset, smaDataset, willrDataset     ) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>getMainDataset webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun getMainDataset(     ticker: String,     taskNumber: UUID,     dateStart: LocalDate,     dateEnd: LocalDate ): Mono&lt;Dataset&lt;Row>> {     val timeSeriesMono = timeSeriesRepository.getDataset(ticker, taskNumber, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"ts\") }     val emaDataSetMono = emaRepository.getEmaDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"ema\") }     val stochasticDatasetMono = stochasticRepository.getStochasticDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"stoch\") }     val bBandsDatasetMono = bBandIndicatorRepository.getBBandsDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"bb\") }     val macdDatasetMono = macdRepository.getMacdDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"macd\") }     val rsiDatasetMono = rsiRepository.getRsiDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"rsi\") }     val smaDatasetMono = smaRepository.getSmaDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"sma\") }     val willrDatasetMono = willrRepository.getWillrDataSet(ticker, dateStart, dateEnd)         .map { dataset -> dataset.alias(\"willr\") }      return Mono.zip(         timeSeriesMono, emaDataSetMono, stochasticDatasetMono, bBandsDatasetMono,         macdDatasetMono, rsiDatasetMono, smaDatasetMono, willrDatasetMono     ).map { tuple ->         combineDatasets(tuple.t1, tuple.t2, tuple.t3, tuple.t4, tuple.t5, tuple.t6, tuple.t7, tuple.t8)     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0437\u0434\u0435\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f 8 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u043e\u0432 \u0432 Mono-\u043e\u0431\u0435\u0440\u0442\u043a\u0430\u0445, \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u0438\u043d Mono \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c .zip() \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u043c\u0435\u043d\u044f\u043b\u0441\u044f.<\/p>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441 StockAnalyticsService<\/h3>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>predictWithExistingModel web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun predictWithExistingModel(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     modelId : Long ): StockPredictDto {     val model: PredictionModel&lt;Vector, XGBoostRegressionModel> = modelService.loadModel(modelId)     val data = dataReaderService.getMainDataset(ticker, taskNumber, dateStart, dateEnd)      var predictions = model.transform(data)     predictions = predictions.select(\"dateTime\", \"prediction\")     return StockPredictDto.fromDataset(predictions) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>predictWithExistingModel webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun predictWithExistingModel(     ticker: String,     taskNumber: UUID,     dateStart: LocalDate,     dateEnd: LocalDate,     modelId: Long ): Mono&lt;StockPredictDto> =     modelService.loadModel&lt;PredictionModel&lt;Vector, XGBoostRegressionModel>>(modelId)         .flatMap { model ->             dataReaderService.getMainDataset(ticker, taskNumber, dateStart, dateEnd)                 .map { data ->                     val predictions = model.transform(data)                         .select(\"dateTime\", \"prediction\")                     StockPredictDto.fromDataset(predictions)                 }         }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u0435\u0442\u043e\u0434 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>trainModel web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun trainModel(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     evalPivotPoint : Long,     offset : Long,     modelParameters : AnalyticsRequest.ModelParameters ) : ModelTrainResultResponse {     val pivot = dateEnd.minusDays(evalPivotPoint)      val tdf = dataReaderService.getDatasetWithLabel(ticker, taskNumber, dateStart, pivot, offset)     val edf = dataReaderService.getDatasetWithLabel(ticker, taskNumber, pivot, dateEnd, offset)         .selectExpr(*allColumns)      val modelParams = createModelParams(modelParameters)     val regressor = xgBoostRegressor(modelParams)      val model: PredictionModel&lt;Vector, XGBoostRegressionModel> = regressor.fit(tdf)     val predictions = model.transform(edf)      combinedDataRepository.saveData(tdf.selectExpr(*allColumns).unionAll(edf), ticker, taskNumber)     modelService.saveModel(model, taskNumber, modelParameters)      val result = predictions.withColumn(\"error\", col(\"prediction\").minus(col(labelName)))     return ModelTrainResultResponse(ModelTrainResult.listFromDataset(result.selectExpr(*resultExp))) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>trainModel webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun trainModel(         ticker: String,         taskNumber: UUID,         dateStart: LocalDate,         dateEnd: LocalDate,         evalPivotPoint: Long,         offset: Long,         modelParameters: AnalyticsRequest.ModelParameters     ): Mono&lt;ModelTrainResultResponse> =         Mono.just(dateEnd.minusDays(evalPivotPoint))             .flatMap { pivot: LocalDate ->                 dataReaderService.getDatasetWithLabel(ticker, taskNumber, dateStart, pivot, offset)                     .zipWith(dataReaderService.getDatasetWithLabel(ticker, taskNumber, pivot, dateEnd, offset))             }             .flatMap { tuple: Tuple2&lt;Dataset&lt;Row>, Dataset&lt;Row>> ->                 val tdf = tuple.t1                 val edf = tuple.t2                  val modelParams = createModelParams(modelParameters)                 val regressor = xgBoostRegressor(modelParams)                  Mono.fromCallable { regressor.fit(tdf) }                     .flatMap { model: XGBoostRegressionModel ->                         val predictions = model.transform(edf)                          val saveDataMono = combinedDataRepository.saveData(                             tdf.selectExpr(*allColumns).unionAll(edf),                             ticker,                             taskNumber                         )                          modelService.saveModel(model, taskNumber, modelParameters)                             .then(saveDataMono)                             .thenReturn(predictions)                     }             }             .map { predictions: Dataset&lt;Row> ->                 val result = predictions.withColumn(\"error\", col(\"prediction\").minus(col(labelName)))                 ModelTrainResultResponse(ModelTrainResult.listFromDataset(result.selectExpr(*resultExp)))             }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0437\u0434\u0435\u0441\u044c tdf \u0438 edf \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b \u0432 Mono, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u0442\u0435\u0436 \u0438\u0437 \u0434\u0432\u0443\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 <code>Mono&lt;Tuple2><\/code>, \u0434\u0430\u043b\u0435\u0435 \u0432 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432 <code>Callable<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>regressor.fit(tdf)<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0438 \u0432\u0435\u0440\u043d\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435 <code>model: XGBoostRegressionModel<\/code>. \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>flatMap<\/code> \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441 \u044d\u0432\u0430\u043b\u044e\u0438\u0440\u0443\u044e\u0449\u0438\u043c \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u043e\u0432, \u0437\u0430\u0442\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0411\u0414 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0448\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 saveModel. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430.<\/p>\n<p>\u041d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f (\u0434\u0430, \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u0430 XGBoost \u043d\u0430 \u0434\u0440\u0443\u0433\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c, \u043d\u043e \u0446\u0435\u043b\u044c \u0431\u044b\u043b\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e\u0434 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438). <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>incrementTrainModel web<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun incrementTrainModel(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     evalPivotPoint : Long,     offset : Long,     batchSize : Int,     modelParameters : AnalyticsRequest.ModelParameters ) : ModelTrainResultResponse {     val pivot = dateEnd.minusDays(evalPivotPoint)     var currentBatchOffset = 0     var i = 0      val modelParams = createModelParams(modelParameters)     val regressor = xgBoostRegressor(modelParams)      var model: PredictionModel&lt;Vector, XGBoostRegressionModel>? = null     var predictions: Dataset&lt;Row>? = null      var tdf: Dataset&lt;Row>?     do {         log.info(\"Iteration {}: currentOffset {}\", i, currentBatchOffset)         tdf = dataReaderService.getDatasetWithLabel(             ticker, taskNumber, dateStart, pivot, offset, currentBatchOffset, batchSize         )         if (tdf.isEmpty) break          model = regressor.fit(tdf)         combinedDataRepository.saveData(tdf.selectExpr(*allColumns), ticker, taskNumber)          currentBatchOffset += batchSize         i++     } while (tdf?.isEmpty == false)      val edf = dataReaderService.getDatasetWithLabel(         ticker, taskNumber, pivot, dateEnd, offset, 0, 100).selectExpr(*allColumns)     if (model != null) {         predictions = model.transform(edf)     }     combinedDataRepository.saveData(edf.selectExpr(*allColumns), ticker, taskNumber)     modelService.saveModel(model!!, taskNumber, modelParameters)      val result = predictions!!.withColumn(\"error\", col(\"prediction\").minus(col(labelName)))     return ModelTrainResultResponse(ModelTrainResult.listFromDataset(result.selectExpr(*resultExp))) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>incrementTrainModel webflux<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun incrementTrainModel(         ticker: String,         taskNumber: UUID,         dateStart: LocalDate,         dateEnd: LocalDate,         evalPivotPoint: Long,         offset: Long,         batchSize: Int,         modelParameters: AnalyticsRequest.ModelParameters     ): Mono&lt;ModelTrainResultResponse> {         val pivot = dateEnd.minusDays(evalPivotPoint)         var currentBatchOffset = 0         var i = 0          val modelParams = createModelParams(modelParameters)         val regressor = xgBoostRegressor(modelParams)          var model: PredictionModel&lt;Vector, XGBoostRegressionModel>? = null         var tdf: Dataset&lt;Row>? = null          return Mono.defer {             dataReaderService.getDatasetWithLabel(                 ticker, taskNumber, dateStart, pivot, offset, currentBatchOffset, batchSize             )         }             .map { dataset ->                 tdf = dataset                 log.info(\"Iteration {}: currentOffset {}\", i, currentBatchOffset)                 if (tdf?.isEmpty == true) {                     log.warn(                         \"tdf is empty, no more data for learning, Iteration {}: currentOffset {}\",                         i, currentBatchOffset                     )                     Mono.empty()                 } else {                     model = regressor.fit(tdf)                     log.info(\"model trained, Iteration {}: currentOffset {}\", i, currentBatchOffset)                     currentBatchOffset += batchSize                     i++                     combinedDataRepository.saveData(tdf!!.selectExpr(*allColumns), ticker, taskNumber)                         .thenReturn(currentBatchOffset + batchSize)                 }             }             .repeat { tdf?.isEmpty == false }             .then(dataReaderService                 .getDatasetWithLabel(ticker, taskNumber, pivot, dateEnd, offset, 0, 100)                 .flatMap { edf ->                     log.info(\"Got edf\")                     combinedDataRepository.saveData(edf.selectExpr(*allColumns), ticker, taskNumber)                         .then(modelService.saveModel(model!!, taskNumber, modelParameters))                         .thenReturn(model!!.transform(edf))                 }.map { predictions ->                     log.info(\"Predictions stage\")                     val result = predictions?.withColumn(                         \"error\", col(\"prediction\")                             .minus(col(labelName))                     )                     ModelTrainResultResponse(ModelTrainResult.listFromDataset(result!!.selectExpr(*resultExp)))                 })             .doOnError { exception ->                 log.error(\"Error while increment learning; taskNumber = {}\", taskNumber, exception)                 ModelTrainResultResponse()             }     }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 Java, \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 Kotlin \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043e\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0431\u044b\u043b\u0438 effectively final, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 <code>currentBatchOffset<\/code>, i, model \u0438 tdf \u043c\u043e\u0433\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0445\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u0438\u043c\u0430.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u043e\u0431\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 <code>Mono.defer()<\/code>. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0442\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 Mono. \u0410 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c .repeat() \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0435 <code>tdf?.isEmpty == false<\/code>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 tdf \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u044b\u043c, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0432 <code>then<\/code>: \u0438\u0437 \u043a\u0430\u0441\u0441\u0430\u043d\u0434\u0440\u044b \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0434\u0430\u0442\u0430\u0441\u0435\u0442 edf, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0441\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a \u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u044b \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430 \u0441\u0430\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u044c. \u0417\u0430\u0442\u0435\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u043e\u0432 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u0442\u043e\u0434\u0430. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<p>\u041d\u0435 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430, \u043d\u043e \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0439\u0434\u0435\u0442.<\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/gitlab.com\/AlexPit\/java-ml-spark-example\/-\/tree\/kubernetes-java17-spark332-reactive\" rel=\"noopener noreferrer nofollow\">\u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>.<\/p>\n<h2>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0434\u0432\u0443\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439<\/h2>\n<p>\u041a\u0430\u043a \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0435\u043a \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u043e\u0433\u043e \u0442\u0435\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u044c\u0448\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430.<\/p>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0435: <\/p>\n<ol>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0432 Docker-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0441 4 CPU \u0438 4 Gb \u043f\u0430\u043c\u044f\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Spark Executor (v. 3.3.2, JDK 17), \u0442\u0430\u043a \u0436\u0435 \u0432 Docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a Standalone-\u043c\u0430\u0441\u0442\u0435\u0440\u0443 Spark \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435. \u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c Windows 10 Pro, \u0437\u0430\u0434\u0430\u0447\u0438 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 GPU NVidia 4090.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 10 \u043c\u0438\u043d\u0443\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043c\u0435\u0442\u043e\u0434\u043e\u0432: \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 (POST \/analytics &#8212; \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u201c1 \u0437\u0430\u043f\u0440\u043e\u0441\u201d), \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 (GET \/analytics &#8212; \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u201c2 \u0437\u0430\u043f\u0440\u043e\u0441\u201d) \u0438 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f (POST \/analytics\/increment &#8212; \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u201c3 \u0437\u0430\u043f\u0440\u043e\u0441\u201d) \u0441 batch_size = 50 \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f 12 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430\u0434 6 \u0441\u043e\u0442\u043d\u044f\u043c\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 Cassandra. \u041f\u0435\u0440\u0432\u044b\u0439 \u0446\u0438\u043a\u043b \u043d\u0430 \u201c\u043d\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0442\u043e\u043c\u201d \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 (\u043f\u0435\u0440\u0432\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u043b\u044c\u0448\u0435), \u0434\u0430\u043b\u0435\u0435 \u0434\u0432\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0430 \u201c\u043f\u0440\u043e\u0433\u0440\u0435\u0442\u043e\u043c \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435\u201d \u0438 \u0432 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e 1, 2, 3 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<\/li>\n<li>\n<p>Driver \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 Spark Cluster, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 Spark Session \u043d\u0430 \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430 JVM \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435: \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0443\u0447\u0438 512 \u041c\u0431, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d, GC \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (G1).<\/p>\n<\/li>\n<\/ol>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"123\" width=\"123\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td data-colwidth=\"122\" width=\"122\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e Stop the world \u0437\u0430 10 \u043c\u0438\u043d\u0443\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Web<\/p>\n<\/td>\n<td data-colwidth=\"123\" width=\"123\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,5<\/p>\n<\/td>\n<td data-colwidth=\"122\" width=\"122\">\n<p align=\"left\">4<\/p>\n<\/td>\n<td>\n<p align=\"left\">2<\/p>\n<\/td>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Webflux<\/p>\n<\/td>\n<td data-colwidth=\"123\" width=\"123\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,1<\/p>\n<\/td>\n<td data-colwidth=\"122\" width=\"122\">\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0421 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u044b\u0448\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u043b\u043e\u0441\u044c 4 stop the world \u043e\u0442 G1 GC, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0438\u043a\u0442\u043e\u0432 \u0438\u0437 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u0442\u0430\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u041d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0440\u0430\u0441\u0442\u0435\u0442 \u043b\u0438\u043d\u0435\u0439\u043d\u043e \u0434\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u0434\u043b\u044f \u043a\u0443\u0447\u0438 \u0443\u0436\u0435 \u043d\u0435\u0442 \u0438 \u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0447\u0438\u0441\u0442\u0438\u0442\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e08\/f3c\/48d\/e08f3c48d26d8cce66809170930a50b7.png\" alt=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" title=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" width=\"2997\" height=\"1026\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e08\/f3c\/48d\/e08f3c48d26d8cce66809170930a50b7.png\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m<\/figcaption><\/div>\n<\/figure>\n<p>\u0423 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u0430: \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 ~0.5 \u0413\u0431 \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e CPU \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7e1\/064\/f04\/7e1064f04404b72302373b5dd2866755.png\" alt=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" title=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" width=\"2985\" height=\"1010\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7e1\/064\/f04\/7e1064f04404b72302373b5dd2866755.png\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8d5\/d2e\/23c\/8d5d2e23c9a420c265176e3e538629a3.png\" alt=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 Web \u0438 WebFlux \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" title=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 Web \u0438 WebFlux \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" width=\"1774\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8d5\/d2e\/23c\/8d5d2e23c9a420c265176e3e538629a3.png\"\/><\/p>\n<div><figcaption>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 Web \u0438 WebFlux \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u043e\u043f-5 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u043f\u0430\u043c\u044f\u0442\u0438:  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eb3\/7fa\/e74\/eb37fae743e1bb4f63e556859398410c.png\" width=\"1150\" height=\"223\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eb3\/7fa\/e74\/eb37fae743e1bb4f63e556859398410c.png\"\/><\/figure>\n<p>\u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u0432\u0435\u0441\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u043a\u043e\u043b\u043e 55 \u041c\u0431, \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0410\u043d\u0430\u043b\u0438\u0437 \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441\u043e\u0432 \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Spark \u0438 Rapids, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0440\u043e\u044f\u0442 \u043f\u043b\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0411\u0414, \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u043c, \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 GPU \u0438 \u0432\u044b\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437 \u043d\u0435\u0433\u043e. \u041f\u043e\u0442\u0440\u0430\u0442\u0438\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438, \u043c\u043e\u0433\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e \u044d\u0442\u043e \u0448\u0442\u0430\u0442\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0432 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0438 \u043d\u0430\u0434\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0436\u0438\u0442\u044c \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0436\u0438\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u0432 \u043f\u0440\u0438\u0432\u0435\u043b\u0438 \u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 JVM \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435: -Xms512m -Xmx3g -XX:GCTimeRatio=19 (\u0436\u0435\u0441\u0442\u043a\u043e\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0434\u043e 5% \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u043c\u0443\u0441\u043e\u0440\u0430 &#8212; (1 \/ (1+19))) -XX:+UseZGC. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u0441\u0442\u0435\u043a\u0443 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c 512 \u041c\u0431 \u043f\u0430\u043c\u044f\u0442\u0438, \u0438 \u0447\u0442\u043e Z GC \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u0447\u0435\u043c G1 GC, \u043f\u043b\u0430\u043d\u043a\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u0443\u0447\u0438 \u0441\u043d\u0438\u0437\u0438\u043b\u0430\u0441\u044c \u0434\u043e 3 \u0413\u0431. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0e1\/ed9\/277\/0e1ed92770b663be5470a9d0bd7de83f.png\" alt=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC\" title=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC\" width=\"2977\" height=\"1004\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0e1\/ed9\/277\/0e1ed92770b663be5470a9d0bd7de83f.png\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u0438\u0437\u0438\u043b\u043e\u0441\u044c, \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0445\u043e\u0436\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u043d\u043e stop the world \u0443\u0436\u0435 \u043d\u0435 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u0421\u0443\u0434\u044f \u043f\u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0443, \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u0435\u0442\u043e\u0434\u043e\u0432 POST \/analytics \u0438 GET \/analytics \u043a\u0443\u0447\u0430 \u043e\u0447\u0438\u0449\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 POST \/analytics\/increment \u043a\u0443\u0447\u0430 \u043e\u0447\u0438\u0449\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u044f \u043a \u0441\u0432\u043e\u0435\u043c\u0443 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u043c\u0435\u0440\u0443. \u041b\u043e\u0433\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u0432\u0435\u0441\u0442\u0438 \u043a \u0443\u0442\u0435\u0447\u043a\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u044b\u0441\u043e\u043a\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0432\u044b\u044f\u0441\u043d\u0435\u043d\u043d\u043e\u0439. <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f GC \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"126\" width=\"126\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td data-colwidth=\"124\" width=\"124\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e Stop the world<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Web<\/p>\n<\/td>\n<td data-colwidth=\"126\" width=\"126\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,5<\/p>\n<\/td>\n<td data-colwidth=\"124\" width=\"124\">\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Webflux<\/p>\n<\/td>\n<td data-colwidth=\"126\" width=\"126\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,1<\/p>\n<\/td>\n<td data-colwidth=\"124\" width=\"124\">\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7c5\/fbd\/ec8\/7c5fbdec89c06d57889dec93f531219c.png\" alt=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" title=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" width=\"1773\" height=\"246\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7c5\/fbd\/ec8\/7c5fbdec89c06d57889dec93f531219c.png\"\/><\/p>\n<div><figcaption>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u0434\u043b\u044f G1 GC \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0443\u0447\u0438 \u043a\u0430\u043a \u0434\u043b\u044f Z GC \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0436\u0435\u0441\u0442\u043a\u0438\u0439 \u043f\u0440\u0435\u0434\u0435\u043b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u043c\u0443\u0441\u043e\u0440\u0430. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u0430\u043c\u044f\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435, \u043d\u043e stop the world \u0441\u0442\u0430\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u0435\u043d\u044c\u0448\u0435, \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u041f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd8\/ac6\/471\/fd8ac6471e893d7b9c44a5b69718a8c6.png\" alt=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseG1GC\" title=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseG1GC\" width=\"2966\" height=\"1006\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd8\/ac6\/471\/fd8ac6471e893d7b9c44a5b69718a8c6.png\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseG1GC<\/figcaption><\/div>\n<\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"123\" width=\"123\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e Stop the world<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Web<\/p>\n<\/td>\n<td data-colwidth=\"123\" width=\"123\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,5<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">3<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">6<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Webflux<\/p>\n<\/td>\n<td data-colwidth=\"123\" width=\"123\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,1<\/p>\n<\/td>\n<td data-colwidth=\"125\" width=\"125\">\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432\u043e\u0437\u0440\u043e\u0441\u043b\u0430, \u043d\u043e \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/43c\/9a1\/f77\/43c9a1f77e2ab983ecd185a569e79d29.png\" alt=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseG1GC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" title=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseG1GC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" width=\"1774\" height=\"246\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/43c\/9a1\/f77\/43c9a1f77e2ab983ecd185a569e79d29.png\"\/><\/p>\n<div><figcaption>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseG1GC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0432 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u043e\u043c \u0441\u0442\u0435\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Parallel GC \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 -Xms512m -Xmx4g -XX:GCTimeRatio=19 -XX:+UseParallelGC. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u0430\u043c\u044b\u0435 \u0445\u0443\u0434\u0448\u0438\u0435, \u0437\u0430 10 \u043c\u0438\u043d\u0443\u0442 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e 2 \u0446\u0438\u043a\u043b\u0430. \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0437\u0430 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0431\u0435\u0437 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u0439, \u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 3\u043c\u0438\u043d 32\u0441, \u0447\u0442\u043e \u0445\u0443\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 1,5 \u043c\u0438\u043d\u0443\u0442\u044b \u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0434\u0432\u0438\u0441 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f 8\u043c\u0438\u043d 10\u0441. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 \u043d\u0435 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0a5\/529\/1a5\/0a55291a5dd00b285a5a6d8b0dbb5019.png\" alt=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 Pasrallel GC\" title=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 Pasrallel GC\" width=\"1445\" height=\"882\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0a5\/529\/1a5\/0a55291a5dd00b285a5a6d8b0dbb5019.png\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 Web \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 Pasrallel GC<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043a \u0432\u0435\u0440\u0441\u0438\u0438 WebFlux, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0430\u043c\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0435\u0440\u0441\u0438\u0438 \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0438 G1 GC \u0438 \u0432\u0435\u0440\u0441\u0438\u0438 \u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM \u0441 Z GC \u043d\u0438\u0436\u0435.<\/p>\n<p>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6b8\/0b7\/6eb\/6b80b76eb36d769f28e798de98753e98.png\" alt=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC\" title=\"\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC\" width=\"2965\" height=\"1007\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6b8\/0b7\/6eb\/6b80b76eb36d769f28e798de98753e98.png\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"124\" width=\"124\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 CPU<\/p>\n<\/td>\n<td data-colwidth=\"122\" width=\"122\">\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438, Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e Stop the world<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Webflux G1 GC<\/p>\n<\/td>\n<td data-colwidth=\"124\" width=\"124\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,1<\/p>\n<\/td>\n<td data-colwidth=\"122\" width=\"122\">\n<p align=\"left\">1<\/p>\n<\/td>\n<td>\n<p align=\"left\">0,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Spring Webflux Z GC<\/p>\n<\/td>\n<td data-colwidth=\"124\" width=\"124\">\n<p align=\"left\">3,4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,4<\/p>\n<\/td>\n<td data-colwidth=\"122\" width=\"122\">\n<p align=\"left\">2,84<\/p>\n<\/td>\n<td>\n<p align=\"left\">1,5<\/p>\n<\/td>\n<td>\n<p align=\"left\">0<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/98f\/2bd\/fb3\/98f2bdfb3f7d10d28fea2cc7e56ce918.png\" alt=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" title=\"\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m\" width=\"1773\" height=\"245\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/98f\/2bd\/fb3\/98f2bdfb3f7d10d28fea2cc7e56ce918.png\"\/><\/p>\n<div><figcaption>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m -Xmx3g -XX:GCTimeRatio=19 -XX:+UseZGC \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e WebFlux \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 G1 GC \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 JVM -Xms512m<\/figcaption><\/div>\n<\/figure>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 \u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 JVM \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0438\u0436\u0435. \u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u0437\u044f\u0442\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0434\u043b\u044f WebFlux \u043d\u0430 G1 GC \u0441 \u043e\u0434\u043d\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c JVM \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0445\u0438\u043f\u0430 512m.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ad5\/b75\/e4f\/ad5b75e4f9174de4db9df2c54e786ee9.png\" alt=\"\u0421\u0432\u043e\u0434\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432\" title=\"\u0421\u0432\u043e\u0434\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432\" width=\"1037\" height=\"737\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ad5\/b75\/e4f\/ad5b75e4f9174de4db9df2c54e786ee9.png\"\/><\/p>\n<div><figcaption>\u0421\u0432\u043e\u0434\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a1c\/78f\/d8d\/a1c78fd8d21977140396f9080f9b9d0d.png\" alt=\"\u0421\u0432\u043e\u0434\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432\" title=\"\u0421\u0432\u043e\u0434\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432\" width=\"1477\" height=\"860\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a1c\/78f\/d8d\/a1c78fd8d21977140396f9080f9b9d0d.png\"\/><\/p>\n<div><figcaption>\u0421\u0432\u043e\u0434\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<h2>\u0412\u044b\u0432\u043e\u0434<\/h2>\n<p>\u041f\u043e\u0434\u0432\u043e\u0434\u044f \u0447\u0435\u0440\u0442\u0443 \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430 \u0442\u0435\u043c\u0443 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 Java \u0438 Kotlin, \u0441\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u044b\u0432\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f &#8212; \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441\u043b\u043e\u0436\u043d\u043e, \u043c\u043d\u043e\u0433\u043e \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439, \u043d\u043e \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e, \u0431\u044b\u043b\u043e \u0431\u044b \u0436\u0435\u043b\u0430\u043d\u0438\u0435.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0430\u043a \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 ML \u043d\u0430 JVM \u0441\u0442\u0435\u043a\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439, <s>\u0443\u0447\u0438\u0442\u0435 Python \u0438 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0439\u0442\u0435\u0441\u044c \u0444\u0438\u0433\u043d\u0435\u0439, \u0430 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0443 \u043f\u0440\u043e\u0434\u0430\u0439\u0442\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443<\/s> \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0441\u043d\u043e\u0432\u044b \u0431\u0443\u0434\u0435\u0442 Kotlin \u0438 Spring Webflux (\u043a\u0430\u043a \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 &#8212; Web \u0441 Z GC), \u0438, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, Apache Spark. \u041f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044e \u0440\u0430\u0431\u043e\u0442 \u043d\u0430\u0434 \u043b\u044e\u0431\u044b\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0441 \u043e\u0447\u0435\u043d\u044c \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 JVM \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439.<\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432? \u0411\u0435\u0437 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Python + Dask) \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u044f \u0437\u0430\u0442\u0440\u0443\u0434\u043d\u044f\u044e\u0441\u044c. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u044e \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430 \u043f\u0438\u0442\u043e\u043d\u0435, \u0442\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441 \u0447\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0438 \u043e \u0447\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e.<\/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\/752702\/\"> https:\/\/habr.com\/ru\/articles\/752702\/<\/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<p>\u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e \u0442\u0435\u043c\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 GPU \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Java, Kotlin, Spring \u0438 Spark. \u0421\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0441\u0442\u0430\u0442\u0435\u0439:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/679248\/\" rel=\"noopener noreferrer nofollow\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Java ML \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441\u043e Spring, Docker, Spark, Rapids, CUDA<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/739634\/\" rel=\"noopener noreferrer nofollow\">\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u0430\u044f Big Data \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 Kubernetes \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Spark \u0438 Cassandra<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/752702\/\" rel=\"noopener noreferrer nofollow\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Kotlin \u0438 WebFlux \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 ML \u0432 Apache Spark \u043d\u0430 GPU<\/a><\/p>\n<\/li>\n<\/ol>\n<h2>\u041e \u0447\u0435\u043c \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f<\/h2>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f Spark Driver \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043d\u044b\u0439 \u0441\u0442\u0435\u043a Spring (Boot 2.7.11) \u0438 JDK 8. <\/p>\n<p>\u041d\u0430 \u0434\u0432\u043e\u0440\u0435 \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 2023 \u0433\u043e\u0434\u0430, \u0443 \u043c\u043d\u043e\u0433\u0438\u0445 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Boot 3+ (\u0430 \u0442\u043e \u0438 3.1+), \u0441\u043e\u0432\u0441\u0435\u043c \u0441\u043a\u043e\u0440\u043e \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0439\u0442\u0438 \u043d\u043e\u0432\u0430\u044f LTS \u0432\u0435\u0440\u0441\u0438\u044f Java, \u0438, \u043c\u044f\u0433\u043a\u043e \u0433\u043e\u0432\u043e\u0440\u044f, Boot 2+ \u0438 JDK8 \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u043d\u0438 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 GPU \u0432 \u0441\u0440\u0435\u0434\u0435 Spark \u0447\u0430\u0441\u0442\u044c\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0435\u043b\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 GPU <a href=\"https:\/\/github.com\/NVIDIA\/spark-rapids\" rel=\"noopener noreferrer nofollow\">NVidia Rapids<\/a>. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 JDK 17 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0440\u0435\u043b\u0438\u0437\u0435 v23.06.0 \u043e\u0442 27.06.23, \u0441 \u0435\u0435 \u0432\u044b\u0445\u043e\u0434\u043e\u043c \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e LTS \u0432\u0435\u0440\u0441\u0438\u044e Java, \u0430 \u0441 \u043d\u0435\u0439 &#8212; \u043d\u0430 Spring Boot 3+.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u0441 Boot 2 \u0438 JDK 8 \u0414\u043e Boot 3 \u0438 JDK 17, \u0441\u043e Spring Web \u043d\u0430 Spring WebFlux, \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f Web \u0438 WebFlux \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<h2>JDK8, Spring boot 2.7.11 \u2192 JDK17, Spring Boot 3.1.1<\/h2>\n<p>\u0414\u043b\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 Rapids \u0434\u043e 23.06.0, JDK \u0434\u043e 17, Spring Boot \u0434\u043e 3.1.1. \u041d\u044e\u0430\u043d\u0441\u043e\u0432 \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043c\u043d\u043e\u0433\u043e:<\/p>\n<ol>\n<li>\n<p>\u041a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 \u043b\u043e\u0433\u0435\u0440\u043e\u0432 Slf4j \u0438 Log4j \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 Spark: \u0438\u0437 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 spring boot starter web \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c spring boot starter logging:<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>pom.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-web&lt;\/artifactId>     &lt;version>${spring.boot.version}&lt;\/version>     &lt;exclusions>         &lt;exclusion>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-logging&lt;\/artifactId>         &lt;\/exclusion>         &lt;exclusion>             &lt;groupId>org.springframework.boot&lt;\/groupId>             &lt;artifactId>spring-boot-starter-tomcat&lt;\/artifactId>         &lt;\/exclusion>     &lt;\/exclusions> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ol start=\"2\">\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c Spark Driver \u043d\u0430 JDK 17 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 (\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043e \u0434\u043b\u044f Dockerfile):<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>Application Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>ENV JAVA_OPTS='--add-opens=java.base\/java.lang=ALL-UNNAMED \\                --add-opens=java.base\/java.lang.invoke=ALL-UNNAMED \\                --add-opens=java.base\/java.lang.reflect=ALL-UNNAMED \\                --add-opens=java.base\/java.io=ALL-UNNAMED \\                --add-opens=java.base\/java.net=ALL-UNNAMED \\                --add-opens=java.base\/java.nio=ALL-UNNAMED \\                --add-opens=java.base\/java.util=ALL-UNNAMED \\                --add-opens=java.base\/java.util.concurrent=ALL-UNNAMED \\                --add-opens=java.base\/java.util.concurrent.atomic=ALL-UNNAMED \\                --add-opens=java.base\/sun.nio.ch=ALL-UNNAMED \\                --add-opens=java.base\/sun.nio.cs=ALL-UNNAMED \\                --add-opens=java.base\/sun.security.action=ALL-UNNAMED \\                --add-opens=java.base\/sun.util.calendar=ALL-UNNAMED \\                --add-opens=java.security.jgss\/sun.security.krb5=ALL-UNNAMED'<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ol start=\"3\">\n<li>\n<p>\u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043d\u0430 Hibernate 6, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 JSOB \u0438 BYTEA \u043f\u043e\u043b\u0435\u0439 \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445 Postgres \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c Entity:<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u0440\u0430\u043d\u0435\u0435 CustomPostgresDialect \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u043c \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0437\u0430\u043c\u0435\u043d\u0438\u0432 \u043d\u0430 <code>org.hibernate.dialect.PostgreSQLDialect<\/code>:<\/p>\n<details class=\"spoiler\">\n<summary>application.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">spring:   ...   jpa:     database-platform: com.mlwebservice.config.CustomPostgresDialect  # &lt;== delete     database-platform: org.hibernate.dialect.PostgreSQLDialect        # &lt;== add<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0439\u0441\u044f CustomPostgresDialect<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">package com.mlwebservice.config  import com.vladmihalcea.hibernate.type.array.IntArrayType import com.vladmihalcea.hibernate.type.array.StringArrayType import com.vladmihalcea.hibernate.type.json.JsonBinaryType import com.vladmihalcea.hibernate.type.json.JsonNodeBinaryType import com.vladmihalcea.hibernate.type.json.JsonNodeStringType import com.vladmihalcea.hibernate.type.json.JsonStringType import org.hibernate.dialect.PostgreSQL10Dialect import java.sql.Types  class CustomPostgresDialect : PostgreSQL10Dialect() {     init {         registerHibernateType(Types.OTHER, StringArrayType::class.qualifiedName)         registerHibernateType(Types.OTHER, IntArrayType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonStringType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonBinaryType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonNodeBinaryType::class.qualifiedName)         registerHibernateType(Types.OTHER, JsonNodeStringType::class.qualifiedName)     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 jar&#8217;\u043d\u0438\u043a\u0430 Rapids \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 jar-\u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 Spark executors \u0438 \u0432 \u043e\u0431\u0440\u0430\u0437 executor\u2019\u0430, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c. \u0410\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c <a href=\"https:\/\/gitlab.com\/AlexPit\/java-ml-spark-example\/-\/tree\/kubernetes-java17-spark332\" rel=\"noopener noreferrer nofollow\">\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0432\u0435\u0442\u043a\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c, \u043d\u043e \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0441\u0442\u0432\u043e \u0432\u0435\u0434\u044c \u0431\u0435\u0440\u0435\u0442 \u0441\u0432\u043e\u0435, \u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u0438 \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0435\u043a\u0435, \u0438 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u044d\u0444\u0444\u0435\u043a\u0442?<\/p>\n<h2>\u0421\u0434\u0435\u043b\u0430\u0435\u043c ML \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c: Spring Web \u2192 Spring WebFlux <\/h2>\n<h3>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/h3>\n<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435, \u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b \u0432 \u0432\u0438\u0434\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438. \u0422\u0430\u043a, Netty, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0434\u043b\u044f Project Reactor (WebFlux) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c Spark \u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u043c Cassandra, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432\u0430\u043b\u0438. \u0420\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Netty<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependencies>     &lt;!-- Netty -->     &lt;dependency>         &lt;groupId>io.netty&lt;\/groupId>         &lt;artifactId>netty-all&lt;\/artifactId>         &lt;version>4.1.74.Final&lt;\/version>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>io.netty&lt;\/groupId>         &lt;artifactId>netty-codec-http&lt;\/artifactId>         &lt;version>4.1.74.Final&lt;\/version>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>io.netty&lt;\/groupId>         &lt;artifactId>netty-resolver-dns&lt;\/artifactId>         &lt;version>4.1.74.Final&lt;\/version>     &lt;\/dependency>      &lt;!-- Spring -->     &lt;dependency>         &lt;groupId>org.springframework.boot&lt;\/groupId>         &lt;artifactId>spring-boot-starter-webflux&lt;\/artifactId>         &lt;version>${spring.boot.version}&lt;\/version>         &lt;exclusions>             &lt;exclusion>                 &lt;artifactId>log4j-to-slf4j&lt;\/artifactId>                 &lt;groupId>org.apache.logging.log4j&lt;\/groupId>             &lt;\/exclusion>         &lt;\/exclusions>     &lt;\/dependency>     ... &lt;\/dependencies><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>Spring Data \u0442\u043e\u0436\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: R2DBC \u0438 Spring Data Cassandra Reactive<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-data-cassandra-reactive&lt;\/artifactId>     &lt;version>${spring.boot.version}&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.springframework.boot&lt;\/groupId>     &lt;artifactId>spring-boot-starter-data-r2dbc&lt;\/artifactId>     &lt;version>${spring.boot.version}&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.r2dbc&lt;\/groupId>     &lt;artifactId>r2dbc-postgresql&lt;\/artifactId>     &lt;version>0.8.13.RELEASE&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b Kotlin \u0432 \u0441\u0440\u0435\u0434\u0435 WebFlux:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: Kotlin dependencies<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>     &lt;artifactId>kotlin-stdlib&lt;\/artifactId>     &lt;version>${kotlin.version}&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.jetbrains.kotlin&lt;\/groupId>     &lt;artifactId>kotlin-reflect&lt;\/artifactId>     &lt;version>${kotlin.version}&lt;\/version>     &lt;scope>runtime&lt;\/scope> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.jetbrains.kotlinx&lt;\/groupId>     &lt;artifactId>kotlinx-coroutines-reactor&lt;\/artifactId>     &lt;version>1.7.2&lt;\/version>     &lt;scope>runtime&lt;\/scope> &lt;\/dependency> &lt;dependency>     &lt;groupId>io.projectreactor.kotlin&lt;\/groupId>     &lt;artifactId>reactor-kotlin-extensions&lt;\/artifactId>     &lt;version>1.2.2&lt;\/version>     &lt;scope>runtime&lt;\/scope> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u0441\u0430\u043c Kotlin \u0442\u043e\u0436\u0435 \u043f\u043e\u0434\u043d\u044f\u043b \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 1.8.21 \u0434\u043e 1.9.0.<\/p>\n<p>\u0414\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f HTTP \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432-\u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Zalando Logbook:<\/p>\n<details class=\"spoiler\">\n<summary>pom.xml: Zalando Logbook<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.zalando&lt;\/groupId>     &lt;artifactId>logbook-spring-boot-autoconfigure&lt;\/artifactId>     &lt;version>3.2.0&lt;\/version> &lt;\/dependency> &lt;dependency>     &lt;groupId>org.zalando&lt;\/groupId>     &lt;artifactId>logbook-netty&lt;\/artifactId>     &lt;version>3.2.0&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>pom.xml (\u043f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043b\u044f WebFlux)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?> &lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"          xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"          xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">     &lt;modelVersion>4.0.0&lt;\/modelVersion>      &lt;groupId>com.mlwebservice&lt;\/groupId>     &lt;artifactId>MLWebService&lt;\/artifactId>     &lt;version>1.0.0-SNAPSHOT&lt;\/version>      &lt;properties>         &lt;java.version>17&lt;\/java.version>         &lt;spring.boot.version>3.1.1&lt;\/spring.boot.version>         &lt;scala.version>2.12&lt;\/scala.version>         &lt;spark.version>3.3.2&lt;\/spark.version>         &lt;lombok.version>1.18.24&lt;\/lombok.version>         &lt;org.mapstruct.version>1.4.2.Final&lt;\/org.mapstruct.version>         &lt;kotlin.version>1.9.0&lt;\/kotlin.version>         &lt;jackson.version>2.13.5&lt;\/jackson.version>     &lt;\/properties>      &lt;distributionManagement>         &lt;repository>             &lt;id>XGBoost4J Snapshot Repo&lt;\/id>             &lt;name>XGBoost4J Snapshot Repo&lt;\/name>             &lt;url>https:\/\/s3-us-west-2.amazonaws.com\/xgboost-maven-repo\/snapshot\/&lt;\/url>         &lt;\/repository>     &lt;\/distributionManagement>      &lt;dependencies>         &lt;!-- Netty -->         &lt;dependency>             &lt;groupId>io.netty&lt;\/groupId>             &lt;artifactId>netty-all&lt;\/artifactId>             &lt;version>4.1.74.Final&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>io.netty&lt;\/groupId>             &lt;artifactId>netty-codec-http&lt;\/artifactId>             &lt;version>4.1.74.Final&lt;\/version>         &lt;\/dependency>         &lt;dependency>             &lt;groupId>io.nett<\/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-351337","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/351337","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=351337"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/351337\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=351337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=351337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=351337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}