Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spring Boot VS Micronaut — Smallest Framework Battle #jokerconf

Spring Boot VS Micronaut — Smallest Framework Battle #jokerconf

Вы занимаетесь энтерпрайз-разработкой и работаете с неповоротливыми серверами приложений? Вы каждый день реализуете все интерфейсы EJB 2.0 и упаковываете их в OSGI-бандл? Ваши друзья рассказывают вам про новые легковесные фреймворки, а у вас нет времени их попробовать?

Мы поможем вам найти ответ на вопрос, идти ли в дивный новый мир (но это не точно) или же остаться в уютном и тёплом углу со мхом. Вместе с вами мы попробуем разобраться, где же эталон меры «микро» у фреймворка и есть ли он. Начнём мы, конечно же, со Spring Boot. Злые языки скажут, что Spring Boot бы похудеть, но у нас есть ответ этим толстым микросервисам! И, чтобы не было так скучно, мы выбрали противника уже не такому хипстерскому SB2 — Micronaut. Хотя, может, и в семействе Spring Boot найдется кто-то маленький.

На деле, разрабатывая и тестируя, тестируя и разрабатывая, мы с вами посмотрим на компромиссы разработки на SB2 и Micronaut. Посмотрим, кто же самый-самый… Самый реактивный, самый удобный, самый «облачный». Да и вообще — годится ли «микро» для production?

https://jokerconf.com/2018/talks/1vzkputteosikmmakiqgci/

Kirill Tolkachev

October 20, 2018
Tweet

More Decks by Kirill Tolkachev

Other Decks in Technology

Transcript

  1. Micronaut vs Spring Boot,
    или «кто тут самый маленький?»
    1

    View Slide

  2. 2
    @tolkv
    @lavcraft
    @gorelikoff
    @gorelikov
    _Кирилл_ Максим

    View Slide

  3. Развлекательно – познавательный доклад
    3
    _Кирилл_ Максим
    @tolkv
    @lavcraft
    @gorelikoff
    @gorelikov

    View Slide

  4. 4
    Доклад про
    размеры фреймворков

    View Slide

  5. Такой большой зал
    5

    View Slide

  6. Такой большой зал
    И такой маленький фреймворк
    6

    View Slide

  7. 7
    Развлекательно – познавательный доклад
    - Сравнение «микро» фреймворков

    View Slide

  8. 8
    Развлекательно – познавательный доклад
    - Сравнение «микро» фреймворков
    - Демо — весёлое

    View Slide

  9. 9
    Развлекательно – познавательный доклад
    - Сравнение «микро» фреймворков
    - Демо — весёлое
    - Выводы — субъективные

    View Slide

  10. Что мы делаем на работе?
    10

    View Slide

  11. Что мы делаем на работе?
    11

    View Slide

  12. Что за микросервисы?
    12

    View Slide

  13. Что за микрофреймворки?
    13

    View Slide

  14. Как оценить «микроскопичность» ?
    Скорость
    Старта Работы
    Падения
    14

    View Slide

  15. Как оценить «микроскопичность» ?
    Скорость
    Старта Работы
    Падения
    Память
    На старте Мусорят
    На запрос
    15

    View Slide

  16. Как оценить «микроскопичность» ?
    Скорость
    Старта Работы
    Падения
    Память
    На старте Мусорят
    На запрос
    Простота
    Разработки Поддержки
    Обновления
    16

    View Slide

  17. Как оценить «микроскопичность» ?
    Скорость
    Старта Работы
    Падения
    Память
    На старте Мусорят
    На запрос
    Простота
    Разработки Поддержки
    Обновления
    17

    View Slide

  18. А в чем проблема-то?
    18

    View Slide

  19. Spring Boot потолстел cо временем*
    *По данным опросов и ВЦИОМ
    19

    View Slide

  20. Этот фреймворк
    не в моде
    20

    View Slide

  21. Этот память жрёт
    как не в себя
    21

    View Slide

  22. Этот слишком
    замороченный
    и сложный
    22

    View Slide

  23. А этот вообще,
    запускается
    больше 2 секунд
    23

    View Slide

  24. Сравним
    самое популярное
    c самым хайповым
    24

    View Slide

  25. Spring Boot
    vs
    Micronaut

    View Slide

  26. Spring Boot
    vs
    Micronaut

    View Slide

  27. На чем
    показываем?
    27

    View Slide

  28. Стартап – Собери компанию в бар
    Кто в бар
    после Joker?
    28

    View Slide

  29. Стартап – Собери компанию в бар
    Я далеко не
    поеду
    29

    View Slide

  30. Стартап – Собери компанию в бар
    До поздна не
    могу, жена
    ждёт
    30

    View Slide

  31. Стартап – Собери компанию в бар
    По сколько
    скидываемся?
    31

    View Slide

  32. Стартап – Собери компанию в бар
    32

    View Slide

  33. Стартап – Собери компанию в бар
    Бар Бульдог
    каждое 3я
    пинта
    бесплатно!
    33

    View Slide

  34. Архитектура

    View Slide

  35. 35

    View Slide

  36. 36
    Не плачь,
    херачь

    View Slide

  37. =
    Да начнётся битва
    =

    View Slide

  38. Да начнётся битва

    View Slide

  39. Условия
    - Intel Core I5 3.3 GHz
    - 16GB
    - OSX 10.13.6
    - Java 8.0.181-oracle(build 1.8.0_181-b13)
    39

    View Slide

  40. Шаг 1 - создание
    40

    View Slide

  41. CLI
    41
    Кто использует CLI для создания проекта?

    View Slide

  42. Инструменты
    ● spring cli
    ● micronaut cli
    → spring
    → mn
    42

    View Slide

  43. Инструменты
    ● spring cli
    ● micronaut cli
    → spring
    → mn
    43
    → 6
    → 2

    View Slide

  44. Инструменты
    ● spring cli
    ● micronaut cli
    → spring
    → mn
    44
    → 6
    → 2

    View Slide

  45. Обратимся к документации
    45

    View Slide

  46. ➜ mn create-federation buster --services application,categories,mess...
    MN CLI умеет создавать федерации
    46
    http://buster.igg.biz/iwantbeer/{nickname}/{money}

    View Slide

  47. Не все идет по плану
    47
    http://buster.igg.biz/iwantbeer/{nickname}/{money}

    View Slide

  48. Micronaut federation RC1
    | Generating Java project.....
    | Error Error occurred running Micronaut CLI: null
    java.lang.NullPointerException
    at io.mn.cli.pr.co.AbstractCreateCommand$_addDependentFeatures_closure17.doCall
    at io.mn.cli.pr.co.AbstractCreateCommand.addDependentFeatures(AbstractCreateCommand.groovy:571)
    at io.mn.cli.pr.co.AbstractCreateCommand.populateFeatures(AbstractCreateCommand.groovy:544)
    at io.mn.cli.pr.co.AbstractCreateCommand.evaluateFeatures(AbstractCreateCommand.groovy:477)
    at io.mn.cli.pr.co.AbstractCreateCommand.handle(AbstractCreateCommand.groovy:272)
    at io.mn.cli.pr.co.CreateFederationCommand.handle(CreateFederationCommand.groovy:92)
    at io.mn.cli.MicronautCli.executeCommand(MicronautCli.groovy:351)
    at io.mn.cli.MicronautCli.execute(MicronautCli.groovy:234)
    at io.mn.cli.MicronautCli.main(MicronautCli.groovy:175)
    | Error Error occurred running Micronaut CLI: null
    48
    MN CLI federation RC1
    http://buster.igg.biz/iwantbeer/{nickname}/{money}

    View Slide

  49. Micronaut federation RC2
    49
    $ tree -L 1
    .
    ├── bar-emulator
    ├── places-api
    └── beer-api

    View Slide

  50. Micronaut federation RC2
    50
    $ tree -L 1
    .
    ├── bar-emulator
    ├── places-api
    └── beer-api
    Никак не связанные
    проекты

    View Slide

  51. Micronaut federation RC3
    51
    $ tree -L 1
    .
    ├── bar-emulator
    ├── places-api
    ├── beer-api
    ├── gradle
    ├── gradlew
    ├── gradlew.bat
    └── settings.gradle
    Связанные на уровне
    сборки проекты

    View Slide

  52. Бывает IDE странно реагирует на что-то новое
    52

    View Slide

  53. Сколько
    нужно памяти
    53
    для запуска
    → 10m
    → 100m
    → 1g

    View Slide

  54. Критерии успеха
    54

    View Slide

  55. Критерии успеха
    55
    1. Успешный запуск без
    исключений

    View Slide

  56. Критерии успеха
    2. Стабильно отвечает
    на простой запрос
    56
    1. Успешный запуск без
    исключений

    View Slide

  57. → Demo
    57

    View Slide

  58. Добавим
    немного Injection
    58

    View Slide

  59. Spring
    59

    View Slide

  60. Micronaut DI + AOP
    60
    Compile

    View Slide

  61. _$ javac -cp build/*.jar *.java
    Spring DI + AOP
    61
    Compile
    Run
    javac

    View Slide

  62. Spring DI + AOP
    62
    Compile _$ java -jar build/libs/app.jar \
    --server.port=8081
    Run
    Scan Classpath
    java -jar
    javac

    View Slide

  63. Spring DI + AOP
    _$ java -jar build/libs/app.jar \
    --server.port=8081
    INFO 28687 main: Refreshing...
    ...
    INFO 28687 nio-1: Started HttpServer on :808
    ...
    63
    Compile
    Run
    Scan Classpath
    Create Definitions
    reflection
    java -jar
    javac

    View Slide

  64. Spring DI + AOP
    64
    Compile
    Run
    Scan Classpath
    Create Definitions
    Inject Beans
    _$ java -jar build/libs/app.jar \
    --server.port=8081
    INFO 28687 main: Refreshing...
    ...
    INFO 28687 main: BeanFactory id=...
    INFO 28687 main:
    f.a.AutowiredAnnotationBeanPostProcessor :
    JSR-330 'javax.inject.Inject' annotation
    found and supported for autowiring
    ...
    INFO 28687 nio-1: Started HttpServer on :808
    Cglib, Proxy
    reflection
    java -jar
    javac

    View Slide

  65. View Slide

  66. Micronaut DI + AOP
    66
    Compile
    APT/AST Transform
    javac/groovyc

    View Slide

  67. Micronaut DI + AOP
    67
    Compile
    APT/AST Transform
    Pure Java Inject
    java -jar
    javac/groovyc

    View Slide

  68. Inject Beans
    Micronaut DI + AOP
    68
    Compile
    APT/AST Transform
    Pure Java Inject
    new instance
    java -jar
    javac/groovyc

    View Slide

  69. Что там генерит Micronaut?
    m.b.a.controller.$BeerControllerDefinition$$exec1
    m.b.a.controller.$BeerControllerDefinitionClass
    m.b.a.service.$BarServiceDefinitionClass$$AnnotationMetadata
    m.b.a.Application
    m.b.a.service.$BarServiceDefinition
    m.b.a.controller.BeerController
    m.b.a.entity.Order
    m.b.a.controller.$BeerControllerDefinition
    m.b.a.controller.$BeerControllerDefinitionClass$$AnnotationMetadata
    m.b.a.service.$BarServiceDefinitionClass
    m.b.a.service.BarService
    m.b.a.controller.$BeerControllerDefinition$$exec1$$AnnotationMetadata
    69

    View Slide

  70. Как работает статический Injection
    70

    View Slide

  71. public class $BarServiceDefinition
    extends AbstractBeanDefinition
    implements BeanFactory {
    @Override
    public BarService build(BeanResolutionContext beanResolutionContext,
    BeanContext beanContext,
    BeanDefinition beanDefinition) {
    BarService barService = new BarService();
    barService =
    (BarService)this.injectBean(beanResolutionContext, beanContext, barService);
    return barService;
    }

    }
    Как работает статический Injection
    71

    View Slide

  72. public class $BeerControllerDefinition
    extends AbstractBeanDefinition
    implements BeanFactory {
    @Override
    public BeerController build(BeanResolutionContext context,
    BeanContext beanContext,
    BeanDefinition beanDefinition) {
    BeerController beerController = new BeerController(
    (BarService)super.getBeanForConstructorArgument(context,beanContext, 0)
    );
    beerController = (BeerController)this.injectBean(beanResolutionContext,
    beanContext,
    beerController);
    return beerController;
    }
    ...
    }
    Как работает статический Injection
    72

    View Slide

  73. Spring Boot
    следит за тенденциями
    73

    View Slide

  74. Spring Fu
    74

    View Slide

  75. Kotlin Fu → KoFu
    75

    View Slide

  76. Кратко о работе с очередями
    76
    Пока удобнее
    – Spring Boot

    View Slide

  77. 77
    Java FU → JaFu

    View Slide

  78. 78

    View Slide

  79. → Demo
    79

    View Slide

  80. Шаг 1 - итоги
    80

    View Slide

  81. Табличка с результатами
    81
    название →__
    условие →__
    -Xmx/mb время старта/ms
    -Xmx=enough
    время старта/ms
    -Xmx=min
    mn 6 950 1113
    mngroovy 7 950 1393
    boot 11 2200 7093
    spark 3 350 348
    kofu 6 1500 2500
    jafu 5 1041 5600

    View Slide

  82. Победители в номинациях
    82

    View Slide

  83. Победители в номинациях
    83
    Основной победитель
    в поединке – Micronaut

    View Slide

  84. Победители в номинациях
    Основной победитель
    в поединке – Micronaut
    84
    Я не толстый
    – Spring Boot

    View Slide

  85. Победители в номинациях
    Основной победитель
    в поединке – Micronaut
    85
    Шустрый мелкий
    Старичок – Spark
    Я не толстый
    – Spring Boot

    View Slide

  86. Победители в номинациях
    Основной победитель
    в поединке – Micronaut
    86
    Шустрый мелкий
    Старичок – Spark
    Я не толстый
    – Spring Boot
    Тёмная лошадка
    – Spring Fu

    View Slide

  87. Это вообще
    нормально
    работает?

    View Slide

  88. → Demo
    88

    View Slide

  89. Табличка с результатами
    89
    название →__
    условие →__
    -Xmx/mb время старта/ms
    -Xmx=enough
    время старта/ms
    -Xmx=min
    mn 6 950 1113
    mngroovy 7 950 1393
    boot 11 2200 7093
    spark 3 350 348
    kofu 6 1500 2500
    jafu 5 1041 5600

    View Slide

  90. Погрешность
    измерения?

    View Slide

  91. Какая
    погрешность
    измерения?

    View Slide

  92. View Slide

  93. GraalVM - в погоне за скоростью
    - Собираем долго
    93

    View Slide

  94. GraalVM - в погоне за скоростью
    - Собираем долго
    - Запускаем быстро
    94

    View Slide

  95. GraalVM - в погоне за скоростью
    - Собираем долго
    - Запускаем быстро
    - Работает – непонятно как
    95

    View Slide

  96. А в чем проблема-то?
    96

    View Slide

  97. $ native-image --no-server \
    -H:Name=target/app -Dio.netty.noUnsafe=true \
    -H:+ReportUnsupportedElementsAtRuntime \
    -cp ".:$(echo target/BOOT-INF/lib/*.jar | tr ' ' ':')"\
    :target/BOOT-INF/classes:target \
    com.example.jafu.beer.api.Application
    В погоне за GraalVM - сборка
    97

    View Slide

  98. $ native-image --no-server \
    -H:Name=target/app -Dio.netty.noUnsafe=true \
    -H:+ReportUnsupportedElementsAtRuntime \
    -cp ".:$(echo target/BOOT-INF/lib/*.jar | tr ' ' ':')"\
    :target/BOOT-INF/classes:target \
    com.example.jafu.beer.api.Application
    В погоне за GraalVM - сборка
    98
    maven/gradle dependencies

    View Slide

  99. $ native-image --no-server \
    -H:Name=target/app -Dio.netty.noUnsafe=true \
    -H:+ReportUnsupportedElementsAtRuntime \
    -cp ".:$(echo target/BOOT-INF/lib/*.jar | tr ' ' ':')"\
    :target/BOOT-INF/classes:target \
    com.example.jafu.beer.api.Application
    В погоне за GraalVM - сборка
    99
    Скомпилированный src/

    View Slide

  100. java.lang.InstantiationException:
    В погоне за GraalVM - сборка Reflection
    100
    Type `o.a.l.l.m.ReusableMessageFactory`
    can not be instantiated reflectively
    as it does not have a no-parameter
    constructor or the no-parameter
    constructor has not been added
    explicitly to the native image

    View Slide

  101. java.lang.NoSuchMethodException:
    c.e.j.b.a.c.BeerHandler.():
    ...
    В погоне за GraalVM - сборка Reflection
    101

    View Slide

  102. { "name": "org.s.b.a...$...FactoryBean",
    "allDeclaredConstructors": true },
    { "name": "org.s.b.a.e.PropertiesPropertySourceLoader",
    "allDeclaredConstructors": true },
    { "name": "org.s.b.a.e.YamlPropertySourceLoader",
    "allDeclaredConstructors": true },
    { "name": "org.s.b.c.event.EventPublishingRunListener",
    "allDeclaredConstructors": true },
    ...
    { "name": "org.s.b.logging.java.JavaLoggingSystem",
    "allDeclaredConstructors": true },
    {
    "name": "org.s.b.a.thymeleaf.ThymeleafTemplate...",
    В погоне за GraalVM - сборка Reflection
    102
    1
    2
    3
    4
    5
    6
    7
    8
    N
    201
    202
    203

    View Slide

  103. GraalVM Run - Micronaut Win
    103
    Сам генерит reflect.json

    View Slide

  104. Пока все руками или из репозитория Dave Syer
    GraalVM Run - Micronaut Win
    104
    Сам генерит reflect.json

    View Slide

  105. Пока все руками или из репозитория Dave Syer
    GraalVM Run - Micronaut Win
    105
    Сам генерит reflect.json

    View Slide

  106. → Demo
    106

    View Slide

  107. GraalVM Run - Micronaut Win!!!
    107
    i.m.r.Micronaut - Startup completed in 50 ms
    o.s.b.Spring - Started application in 120 ms

    View Slide

  108. Шаг 2 - данные.
    108

    View Slide

  109. Развиваем стартап - зачатки архитектуры
    109
    beer-api places-api
    Mongo
    Список баров в
    которые можно
    пойти

    View Slide

  110. → Demo
    110

    View Slide

  111. Шаг 2 - итоги.
    111

    View Slide

  112. Табличка с результатами
    112
    название →__
    условие →__
    -Xmx/mb
    min
    время старта/ms
    -Xmx=enough
    время старта/ms
    -Xmx=min
    mn 19 2400 6000
    spring 15 3400 11000
    spark 5 600 900

    View Slide

  113. Чем больше добавляем
    – тем меньше разницы
    113

    View Slide

  114. Победители в номинациях
    114
    Уже не торт,
    но еще вкусно
    – Micronaut

    View Slide

  115. Победители в номинациях
    Скрытая надежда
    – Spring
    Уже не торт,
    но еще вкусно
    – Micronaut

    View Slide

  116. Победители в номинациях
    Скрытая надежда
    – Spring
    построй счастье
    своими руками
    — Spark
    116
    Уже не торт,
    но еще вкусно
    – Micronaut

    View Slide

  117. Микросервисов в вакууме не бывает!
    117

    View Slide

  118. Шаг 3.
    Идем в сloud
    118

    View Slide

  119. Картинка с архитектурой
    119
    beer-api places-api
    Mongo
    discovery

    View Slide

  120. → Demo
    120

    View Slide

  121. CLI — реванш
    121
    ● spring cli
    ● micronaut cli
    → spring
    → mn
    → $ spring cloud eureka
    → $ -

    View Slide

  122. Шаг 3 - итоги
    122

    View Slide

  123. Табличка с результатами
    123
    название →__
    условие →__
    -Xmx/mb время старта
    -Xmx=enough/ms
    время
    старта
    -Xmx=min/ms
    mn 21 3000 7500
    spring 22 5800 30000

    View Slide

  124. Победители в номинациях
    Уходит в отрыв
    – Micronaut
    124
    Разбитые надежды
    – Spring Boot

    View Slide

  125. Шаг 4 - очереди/кэш
    125

    View Slide

  126. Картинка с архитектурой
    126
    beer-api places-api
    Mongo
    bar-0 bar-1 bar-N
    discovery
    from discovery

    View Slide

  127. В этой жизни надо попробовать все
    127
    beer-api places-api
    Mongo
    bar-0 bar-1 bar-N
    kafka
    discovery
    from discovery
    Redis

    View Slide

  128. В этой жизни надо попробовать все
    128
    beer-api places-api
    Mongo
    bar-0 bar-1 bar-N
    kafka
    discovery
    from discovery
    Redis

    View Slide

  129. Кратко о работе с Kafka и Redis
    129

    View Slide

  130. Кратко о работе с Kafka и Redis
    130
    Только очень
    кратко, пожалуйста.

    View Slide

  131. Кратко о работе с очередями
    131
    Пока удобнее
    – Spring Boot
    Погоди внедрять я доделаю
    – Micronaut

    View Slide

  132. Шаг 4 - итоги
    132

    View Slide

  133. 133
    beer-api
    kafka
    discovery
    Redis
    Что запускаем для замера?

    View Slide

  134. Табличка с результатами
    134
    название →__
    условие →__
    -Xmx/mb время старта
    -Xmx=enough/ms
    время старта
    -Xmx=min/ms
    mn_cloud_db 21 3000 7500
    mn_cloud_mq_cache 15 3000 3000
    spring_cloud_mq_cache 24 8000 64000

    View Slide

  135. Табличка с результатами
    135
    название →__
    условие →__
    -Xmx/mb время старта
    -Xmx=enough/ms
    время старта
    -Xmx=min/ms
    mn 15 3000 3000
    spring 24 8000 64000
    Надо было с
    этого начинать

    View Slide

  136. 136
    Выводы
    1. MicroFramework = 10-6 × Framework

    View Slide

  137. 137
    Выводы
    1. MicroFramework = 10-6 × Framework
    2. Область применимости узкая Нахуа?

    View Slide

  138. 138
    Выводы
    1. MicroFramework = 10-6 × Framework
    2. Область применимости узкая
    3. Разные внутри - одинаковые снаружи
    Нахуа?

    View Slide

  139. 139
    Выводы
    1. MicroFramework = 10-6 × Framework
    2. Область применимости узкая
    3. Разные внутри - одинаковые снаружи
    → Лучшее взято из Spring
    Нахуа?

    View Slide

  140. Интересные ресурсы
    Demo Source
    [Spring Blog] The Evolution Of Spring Fu
    Spring Fu Sample Sources
    [dsyer] Spring Init Experiments source
    [GraalVM Blog] Understanding Class Initialization in GraalVM Native Image Generation
    [GraalVM Blog] Netty Native Image Generation
    Micronaut docs
    140

    View Slide

  141. Кто же пошел в бар и в какой
    {
    "type": "American Pale Ale",
    "bottles": 1603,
    "totalPrice": 223962,
    "place": {
    "name": "Relaxed-Beagle",
    "averagePrice": 978,
    "maxTableSize": 33
    },
    141
    "companions": [
    "ivan",
    "pavel_ch",
    "kolemik",
    "sberkek",
    "yegor256",
    "vasya",
    "NPE",
    "baruh",
    "alexanzer",
    "ctap",
    "alexander.kochin",
    "andrew-q1",
    "Vitoss",
    "her_s_gory",
    "andrewserdyuk",
    "barnaulaltayka",
    "=)",
    "shurmeleva",
    "mgorelikov",
    "tolkv"
    ]
    }

    View Slide

  142. 142
    @tolkv
    @lavcraft
    @gorelikoff
    @gorelikov
    _Кирилл_ Максим
    _QA_

    View Slide

  143. 143
    @tolkv
    @lavcraft
    @gorelikoff
    @gorelikov
    _Кирилл_ Максим
    _QA_

    View Slide