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

[#JSUG] SmartNews における container friendly な Spring Boot アプリケーション開発

[#JSUG] SmartNews における container friendly な Spring Boot アプリケーション開発

SmartNews に新たに登場した「タイムセール」のバックエンドシステムの開発の裏側をお話しました。

E77287648aff5484ac7659748e45c936?s=128

KOMIYA Atsushi

May 31, 2019
Tweet

Transcript

  1. SmartNews ʹ͓͚Δ container friendly ͳ Spring Boot ΞϓϦέʔγϣϯ։ൃ JSUG ษڧձ

    2019 ͦͷ5 / 2019-05-31 KOMIYA Atsushi
  2. @komiya_atsushi

  3. SmartNews ʹ͓͚Δ container friendly ͳ Spring Boot ΞϓϦέʔγϣϯ։ൃ

  4. SmartNews ʹ͓͚Δ container friendly ͳ Spring Boot ΞϓϦέʔγϣϯ։ൃ (container friendly

    ݴ͏΄Ͳͷൃද಺༰͡Όͳ͍ͳ ) (Spring Boot ͕ओ໾ͱ͍͏ײ͡Ͱ΋ͳ͍ͳ… )
  5. Spring Boot Docker Έ͍ͨͳ࿩Λظ଴͞Εͯͨํ ͢Έ·ͤΜ

  6. Docker Λ·͋·͋׆༻ͨ͠ Spring Boot ΞϓϦέʔγϣϯ։ൃ ͷࣄྫΛ͓࿩͠·͢

  7. http://about.smartnews.com/ja/2019/05/21/20190521/

  8. SmartNews ͷ ඪ४తͳٕज़ελοΫ

  9. http://bit.ly/smartnews-tech-stack-2019

  10. None
  11. ૡ͍ఠΜͰ࿩Λ͢Δͱ… • AWS + AmazonLinux • ALB/CLB + ASG +

    EC2 • nginx + Spring Boot w/ embedded Tomcat • Java 8 (Java, Scala, Kotlin) • Terraform, CircleCI, CodeDeploy, Nexus, Datadog
  12. λΠϜηʔϧ։ൃͷ෣୆ཪ

  13. ։ൃ౰ॳͷঢ়گ • 2019 Q1 தʹ։࢝ͯ͠ Q1 தʹϦϦʔε༧ఆ • ࣮ࡍʹϦϦʔεͰ͖ͨͷ͸ Q2

    ಄ • ϦϦʔε·Ͱͷ࣌ؒత༛༧͕গͳ͍ • ׳Ε਌͠Έɺ։ൃޮ཰Α͍ϑϨʔϜϫʔΫ / ݴޠΛ બ୒ • Spring Boot + Kotlin
  14. ։ൃ౰ॳͷঢ়گ • 2019 Q1 ࣌఺ͷࣾ಺֎ͷঢ়گ • Java 11 ͕ϦϦʔε͞Εͯ 1Q

    Ҏ্ܦա • ࣾ಺తʹ͸·ͩ Java 8 ͕ݱ໾ͷγεςϜ͕େ൒ Λ઎Ί͍ͯͨ • ৽ن։ൃ͢ΔαʔϏεͳͷͰɺ͍·͞Β Java 8 ͸ બ୒ͨ͘͠ͳ͍
  15. ։ൃ౰ॳͷঢ়گ • ࣾ಺ͷඪ४తͳٕज़ελοΫ͸ Java 8 લఏ • طଘγεςϜͷ Java 11

    ҠߦΛݕ౼ • ඪ४తͳٕज़ελοΫͷԸܙ͸ڗड͍ͨ͠ • Spring Boot ΞϓϦέʔγϣϯ & JDK Λ
 ߹ΘͤͯίϯςφԽͤ͞Δ͜ͱʹͨ͠
  16. ͜ͷޙͷ͓࿩ • ։ൃ • Ϗϧυ • σϓϩΠɾ؂ࢹ

  17. ։ൃ

  18. API ※࣮ࡍͷߏ੒ΛҰ෦؆ུԽ͍ͯ͠·͢ όοΫΤϯυγεςϜͷ֓ཁ

  19. ։ൃ؀ڥͷ੔උ • ։ൃ؀ڥͷݸਓࠩΛ࠷খԽ͍ͨ͠ • MySQL αʔόΛखݩͷ؀ڥʹ༻ҙ͢Δ • ଞαʔϏεͰ΋ MySQL Λར༻͍ͯ͠Δ͕ɺ


    όʔδϣϯ͕ҟͳΓಘΔͨΊڞ༻͠೉͍ • Datadog agent (ͷ DogStatsD) ͕ඞཁʹͳΔ • ϝτϦΫεͷ؂ࢹʹ Datadog Λར༻͍ͯ͠Δ
  20. ։ൃ؀ڥͷ੔උ • Vagrant / VirtualBox Λ༻͍Δखஈ΋͋Γ͏Δ • ϓϩϏδϣχϯάνϣοτδΧϯΧΧϧ • ࠷ۙ͸৽نʹ։ൃ؀ڥΛߏங͢Δͱ͖ʹ


    όʔδϣϯབྷΈͷτϥϒϧʹר͖ࠐ·Ε
 ͕ͪͳͷͰܟԕ͍ͨ͠
  21. None
  22. # docker-compose.yml version: '3.1' services: db: image: mysql:5.7.25 environment: MYSQL_ROOT_PASSWORD:

    password MYSQL_DATABASE: main_db volumes: - ./tmp/mysql:/var/lib/mysql ports: - "13307:3306" dogstatsd: image: datadog/docker-dd-agent:12.7.5321-dogstatsd environment: API_KEY: ${DATADOG_API_KEY} ports: - “8125:8125/udp"
  23. $ docker stack deploy \ -c docker-compose.yml \ stack-name $

    docker stack rm stack-name
  24. # application.yml spring: profiles: local-dev datasource: url: jdbc:mysql://127.0.0.1:3306/main_db username: root

    password: password management.metrics.export.statsd.host: 127.0.0.1 --- spring: profiles: docker-dev datasource: url: jdbc:mysql://host.docker.internal:3306/main_db username: root password: password management.metrics.export.statsd.host: host.docker.internal
  25. Ϗϧυ

  26. Spring Boot ΞϓϦέʔγϣϯΛ Docker Πϝʔδͱͯ͠Ϗϧυ͢Δ

  27. Ұൠతͳ Spring Boot app ͷϏϧυ • Spring Boot Gradle plugin

    Λಋೖ͢Δ • ./gradlew build ͢Δ • fat jar ͕࡞ΒΕΔ
  28. # Dockerfile FROM adoptopenjdk/openjdk11:jdk-11.0.3_7 COPY build/libs/spring-boot-app.jar /app/ CMD ["java", "-jar",

    “/app/spring-boot-app.jar”]
  29. Docker Πϝʔδͱͯ͠Ϗϧυ͢Δ • Docker Gradle plugin (Palantir) Λಋೖ͢Δ • ./gradlew

    build docker Ͱ Docker
 ΠϝʔδΛϏϧυ͢Δ • ./gradlew dockerPush Ͱ Docker
 ΠϝʔδΛϨδετϦʹ push ͢Δ
  30. # build.gradle plugins { id 'org.springframework.boot' id 'com.palantir.docker' id 'net.researchgate.release'

    } // ... docker { name “$dockerNamespace/spring-boot-app:$version” copySpec.from(“build/libs/spring-boot-app—${version}.jar”) .into('build/libs') .rename { “spring-boot-app.jar” } } docker.dependsOn(build) // ... afterReleaseBuild.dependsOn(dockerPush)
  31. Docker ϕʔεΠϝʔδΛબͿ

  32. ϕʔεΠϝʔδɺԿΛબͿʁ • ༷ʑͳ૊৫͕͍ΖΜͳΠϝʔδΛఏڙ͍ͯͯ͠ɺ ͱͯ΋ ΧΦε ଟ༷ੑʹ෋ΜͰ͍Δ • OS: Debian, Ubuntu,

    Alpine Linux, Oracle Linux, Amazon Linux, … • ૊৫: Docker official, Oracle, AdoptOpenJDK, Azul systems, … • ͦͷଞ: LTS ͷ༗ແ, JRE/JDK, …
  33. ϕʔεΠϝʔδɺԿΛબͿʁ • AdoptOpenJDK ΛબΜͩ • “LTS ͕͋ͬͯ JDK ͷΠϝʔδͰ͋Ε͹ԿͰ΋Α͔ͬ ͨɻࠓʹͯ͠ΈΕ͹

    Amazon Corretto ΛબΜͰ΋Α ͔͔ͬͨ΋͠Εͳ͍ͱ൓ল͍ͯ͠Δ” • OS ͸ (Alpine Ͱ͸ͳ͘) Ubuntu Λબ୒, slim ͸બ͹ͣ • slim Πϝʔδͩͱ jstack ͳͲ͕ೖ͍ͬͯͳ͍
  34. λΠϜηʔϧͷ ϏϧυύΠϓϥΠϯ

  35. Docker image CodeDeploy artifact Jar git push

  36. ΑΓΑ͍ Docker ΠϝʔδΛ ࡞Δ

  37. ྑ࣭ͳ৘ใ͕ͪ͜Βʹ… • https://spring.io/guides/topicals/spring-boot-docker/ • https://spring.io/guides/gs/spring-boot-docker/

  38. ϨΠϠΛ͋͑ͯ෼͚Δ FROM adoptopenjdk/openjdk11:jdk-11.0.3_7 ARG DEPENDENCY=build/dependency COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib COPY ${DEPENDENCY}/META-INF

    /app/META-INF COPY ${DEPENDENCY}/BOOT-INF/classes /app CMD ["java", "-cp", "app:app/lib/*", "foo.bar.EntryPoint"]
  39. ϨΠϠΛ͋͑ͯ෼͚Δ $ ./gradlew build $ mkdir build/dependency $ (cd build/dependency;

    jar -xf ../libs/spring-boot-app.jar) $ ./gradlew docker
  40. ϨΠϠΛ͋͑ͯ෼͚Δ • ґଘϥΠϒϥϦʹมߋ͕ੜ͡ͳ͍ݶΓɺ
 ΠϝʔδͷϏϧυߴ଎Խ͕ظ଴Ͱ͖Δ • JarLauncher Λܦ༝ͤͣ௚઀ main Ϋϥε͔Β
 ࣮ߦ͢ΔͷͰɺىಈͷߴ଎Խ΋ظ଴Ͱ͖Δ

  41. None
  42. σϓϩΠɾ؂ࢹ

  43. Docker image start.sh CodeDeploy artifact create-deployment docker run

  44. Spring Boot app ͷίϯςφΛಈ͔͢ $ docker run -d —name spring-boot-app

    \ -p 8080:8080 \ -e SPRING_PROFILES_ACTIVE=production \ -v /path/to/host/log:/path/to/container/log \ spring-boot-app:X.Y.Z
  45. Spring Boot app ͷίϯςφΛಈ͔͢ $ docker run -d —name spring-boot-app

    \ -p 8080:8080 \ -e SPRING_PROFILES_ACTIVE=production \ -v /path/to/host/log:/path/to/container/log \ spring-boot-app:X.Y.Z
  46. # application.yml spring.profiles: production spring: profiles: include: common, aws, prd-db

    --- spring.profiles: staging spring: profiles: include: common, aws, stg-db --- spring.profiles: local spring: profiles: include: common, local-db
  47. ϗετͷϑΝΠϧγεςϜʹϩάग़ྗ͢Δ $ docker run -d —name spring-boot-app \ -p 8080:8080

    \ -e SPRING_PROFILES_ACTIVE=production \ -v /path/to/host/log:/path/to/container/log \ spring-boot-app:X.Y.Z
  48. Datadog ʹΑΔϝτϦΫε؂ࢹ Datadog agent VEQ

  49. # build.gradle dependencies { // ... implementation ‘org.springframework.boot:spring-boot-starter-actuator’ implementation ‘io.micrometer:micrometer-registry-statsd’

    } # application.yml management: metrics: export: statsd: flavor: datadog host: host.docker.internal # 18.03 ΑΓલͷ docker Λ࢖͏৔߹͸ --network=host ͷΦϓγϣϯ෇͚ͯ # docker run ͱ͢Δɻ·ͨ host ͷࢦఆ͸ҎԼͷΑ͏ʹ 127.0.0.1 ͱ͢Δ host: 127.0.0.1
  50. jstack ͨ͘͠ͳͬͨͱ͖͸ʁ $ docker exec spring-boot-app jstack 1

  51. ·ͱΊ

  52. ·ͱΊ • Java 11 + Spring Boot + Kotlin ͱ͍͏ߏ੒ͷ


    ৽نαʔϏεͷ։ൃͰ Docker Λ׆༻ͨ͠ • ։ൃ؀ڥͷ੔උ • Docker Πϝʔδͷߏஙํ๏ • σϓϩΠɾΞϓϦέʔγϣϯ࣮ߦํ๏