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 に新たに登場した「タイムセール」のバックエンドシステムの開発の裏側をお話しました。

KOMIYA Atsushi

May 31, 2019
Tweet

More Decks by KOMIYA Atsushi

Other Decks in Programming

Transcript

  1. SmartNews ʹ͓͚Δ
    container friendly ͳ
    Spring Boot ΞϓϦέʔγϣϯ։ൃ
    JSUG ษڧձ 2019 ͦͷ5 / 2019-05-31
    KOMIYA Atsushi

    View Slide

  2. @komiya_atsushi

    View Slide

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

    View Slide

  4. SmartNews ʹ͓͚Δ
    container friendly ͳ
    Spring Boot ΞϓϦέʔγϣϯ։ൃ
    (container friendly ݴ͏΄Ͳͷൃද಺༰͡Όͳ͍ͳ )
    (Spring Boot ͕ओ໾ͱ͍͏ײ͡Ͱ΋ͳ͍ͳ… )

    View Slide

  5. Spring Boot Docker
    Έ͍ͨͳ࿩Λظ଴͞Εͯͨํ
    ͢Έ·ͤΜ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  10. View Slide

  11. ૡ͍ఠΜͰ࿩Λ͢Δͱ…
    • AWS + AmazonLinux
    • ALB/CLB + ASG + EC2
    • nginx + Spring Boot w/ embedded Tomcat
    • Java 8 (Java, Scala, Kotlin)
    • Terraform, CircleCI, CodeDeploy, Nexus, Datadog

    View Slide

  12. λΠϜηʔϧ։ൃͷ෣୆ཪ

    View Slide

  13. ։ൃ౰ॳͷঢ়گ
    • 2019 Q1 தʹ։࢝ͯ͠ Q1 தʹϦϦʔε༧ఆ
    • ࣮ࡍʹϦϦʔεͰ͖ͨͷ͸ Q2 ಄
    • ϦϦʔε·Ͱͷ࣌ؒత༛༧͕গͳ͍
    • ׳Ε਌͠Έɺ։ൃޮ཰Α͍ϑϨʔϜϫʔΫ / ݴޠΛ
    બ୒
    • Spring Boot + Kotlin

    View Slide

  14. ։ൃ౰ॳͷঢ়گ
    • 2019 Q1 ࣌఺ͷࣾ಺֎ͷঢ়گ
    • Java 11 ͕ϦϦʔε͞Εͯ 1Q Ҏ্ܦա
    • ࣾ಺తʹ͸·ͩ Java 8 ͕ݱ໾ͷγεςϜ͕େ൒
    Λ઎Ί͍ͯͨ
    • ৽ن։ൃ͢ΔαʔϏεͳͷͰɺ͍·͞Β Java 8 ͸
    બ୒ͨ͘͠ͳ͍

    View Slide

  15. ։ൃ౰ॳͷঢ়گ
    • ࣾ಺ͷඪ४తͳٕज़ελοΫ͸ Java 8 લఏ
    • طଘγεςϜͷ Java 11 ҠߦΛݕ౼
    • ඪ४తͳٕज़ελοΫͷԸܙ͸ڗड͍ͨ͠
    • Spring Boot ΞϓϦέʔγϣϯ & JDK Λ

    ߹ΘͤͯίϯςφԽͤ͞Δ͜ͱʹͨ͠

    View Slide

  16. ͜ͷޙͷ͓࿩
    • ։ൃ
    • Ϗϧυ
    • σϓϩΠɾ؂ࢹ

    View Slide

  17. ։ൃ

    View Slide

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

    View Slide

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

    όʔδϣϯ͕ҟͳΓಘΔͨΊڞ༻͠೉͍
    • Datadog agent (ͷ DogStatsD) ͕ඞཁʹͳΔ
    • ϝτϦΫεͷ؂ࢹʹ Datadog Λར༻͍ͯ͠Δ

    View Slide

  20. ։ൃ؀ڥͷ੔උ
    • Vagrant / VirtualBox Λ༻͍Δखஈ΋͋Γ͏Δ
    • ϓϩϏδϣχϯάνϣοτδΧϯΧΧϧ
    • ࠷ۙ͸৽نʹ։ൃ؀ڥΛߏங͢Δͱ͖ʹ

    όʔδϣϯབྷΈͷτϥϒϧʹר͖ࠐ·Ε

    ͕ͪͳͷͰܟԕ͍ͨ͠

    View Slide

  21. View Slide

  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"

    View Slide

  23. $ docker stack deploy \
    -c docker-compose.yml \
    stack-name
    $ docker stack rm stack-name

    View Slide

  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

    View Slide

  25. Ϗϧυ

    View Slide

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

    View Slide

  27. Ұൠతͳ Spring Boot app ͷϏϧυ
    • Spring Boot Gradle plugin Λಋೖ͢Δ
    • ./gradlew build ͢Δ
    • fat jar ͕࡞ΒΕΔ

    View Slide

  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”]

    View Slide

  29. Docker Πϝʔδͱͯ͠Ϗϧυ͢Δ
    • Docker Gradle plugin (Palantir) Λಋೖ͢Δ
    • ./gradlew build docker Ͱ Docker

    ΠϝʔδΛϏϧυ͢Δ
    • ./gradlew dockerPush Ͱ Docker

    ΠϝʔδΛϨδετϦʹ push ͢Δ

    View Slide

  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)

    View Slide

  31. Docker ϕʔεΠϝʔδΛબͿ

    View Slide

  32. ϕʔεΠϝʔδɺԿΛબͿʁ
    • ༷ʑͳ૊৫͕͍ΖΜͳΠϝʔδΛఏڙ͍ͯͯ͠ɺ
    ͱͯ΋ ΧΦε ଟ༷ੑʹ෋ΜͰ͍Δ
    • OS: Debian, Ubuntu, Alpine Linux, Oracle Linux,
    Amazon Linux, …
    • ૊৫: Docker official, Oracle, AdoptOpenJDK,
    Azul systems, …
    • ͦͷଞ: LTS ͷ༗ແ, JRE/JDK, …

    View Slide

  33. ϕʔεΠϝʔδɺԿΛબͿʁ
    • AdoptOpenJDK ΛબΜͩ
    • “LTS ͕͋ͬͯ JDK ͷΠϝʔδͰ͋Ε͹ԿͰ΋Α͔ͬ
    ͨɻࠓʹͯ͠ΈΕ͹ Amazon Corretto ΛબΜͰ΋Α
    ͔͔ͬͨ΋͠Εͳ͍ͱ൓ল͍ͯ͠Δ”
    • OS ͸ (Alpine Ͱ͸ͳ͘) Ubuntu Λબ୒, slim ͸બ͹ͣ
    • slim Πϝʔδͩͱ jstack ͳͲ͕ೖ͍ͬͯͳ͍

    View Slide

  34. λΠϜηʔϧͷ
    ϏϧυύΠϓϥΠϯ

    View Slide



  35. Docker image
    CodeDeploy artifact
    Jar
    git push

    View Slide

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

    View Slide

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

    View Slide

  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"]

    View Slide

  39. ϨΠϠΛ͋͑ͯ෼͚Δ
    $ ./gradlew build
    $ mkdir build/dependency
    $ (cd build/dependency; jar -xf ../libs/spring-boot-app.jar)
    $ ./gradlew docker

    View Slide

  40. ϨΠϠΛ͋͑ͯ෼͚Δ
    • ґଘϥΠϒϥϦʹมߋ͕ੜ͡ͳ͍ݶΓɺ

    ΠϝʔδͷϏϧυߴ଎Խ͕ظ଴Ͱ͖Δ
    • JarLauncher Λܦ༝ͤͣ௚઀ main Ϋϥε͔Β

    ࣮ߦ͢ΔͷͰɺىಈͷߴ଎Խ΋ظ଴Ͱ͖Δ

    View Slide

  41. View Slide

  42. σϓϩΠɾ؂ࢹ

    View Slide

  43. Docker image
    start.sh

    CodeDeploy artifact
    create-deployment
    docker run

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  48. Datadog ʹΑΔϝτϦΫε؂ࢹ
    Datadog
    agent
    VEQ

    View Slide

  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

    View Slide

  50. jstack ͨ͘͠ͳͬͨͱ͖͸ʁ
    $ docker exec spring-boot-app jstack 1

    View Slide

  51. ·ͱΊ

    View Slide

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

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

    View Slide