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

LINE NEWSにおけるJava移行の5年間の歩みとこれから / Five Years of Java Migration and the Future of LINE NEWS

LINE NEWSにおけるJava移行の5年間の歩みとこれから / Five Years of Java Migration and the Future of LINE NEWS

LINE NEWSでは約5年の歳月をかけて、バックエンドの開発言語をPerlからJavaへ移行してきました。
本セッションでは、Javaに移行した理由や、どのように移行していったのか、また、移行途中で発生したイシューについてどのように対処したかをご説明します。
技術的負債の返済やトラブルシューティングにご興味がある方は是非ご視聴ください。

森藤 賢司 / LINE

以下イベントでの登壇資料となります。
https://fortee.jp/jjug-ccc-2022-fall/proposal/21d0b5f4-2f79-41ee-a740-8eebfe0100ff

LINE Developers
PRO

November 27, 2022
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

  1. LINE NEWSにおける Java移行の5年間の歩みとこれから LINE株式会社 森藤賢司 2022.11

  2. 1SPGJMF ೥݄ த్ೖࣾ -*/&."--ɺ-*/&Ϊϑτɺ-*/&#-0(ͳͲ 1FSMͰ࣮૷͞ΕͨαʔϏεͷόοΫΤϯυ։ൃ Λओʹ୲౰ ೥͔Β-*/&/&84ͷόοΫΤϯυ։ൃʹ ܞΘΓɺ೥͝Ζ͔Β+BWBΛϝΠϯͰॻ͖ ࢝ΊΔ ৿౻

    ݡ࢘ ,FOKJ .PSJUP -*/&גࣜձࣾ /&84։ൃνʔϜ Ϛωʔδϟʔ
  3. "HFOEB  -*/& /&84ʹ͍ͭͯ  1FSMUP+BWBϓϩδΣΫτ  ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ  -*/&/&84ͷ͜Ε͔Β

  4. -*/& /&84ʹ͍ͭͯ

  5. χϡʔελϒ • -*/& "QQ಺ͷʮχϡʔεʯλϒ • ࠓ࿩୊ͷχϡʔε΍Ϣʔβʔͷڵຯʹ߹ΘͤͨهࣄΛදࣔ • Ϣʔβʔ͕ઃఆͨ͠ΩʔϫʔυʹϚον͢Δ࠷৽هࣄΛදࣔ Ͱ͖ΔʮϑΥϩʔʯλϒͳͲͦͷଞʹ΋͍͔ͭ͘ͷػೳ͕͋ Δ

  6. χϡʔελϒ • ʮ஍ҬʯλϒΛ݄ʹ৽ઃ ʢ౎಺ͷҰ෦ ϢʔβʔͷΈʣ • ݱࡏ஍ɾډॅ஍ɾۈ຿஍ɾΑ͘ߦ͘஍ҬͳͲ Ϣʔβʔͷੜ׆ΤϦΞʹີணͨ͠৘ใΛ഑৴ • ஍Ҭ৘ใͰ͋Δχϡʔεɺఱؾɺӡߦ৘ใɺ

    ίϩφ৘ใΛఏڙ
  7. μΠδΣετ • -*/&ެࣜΞΧ΢ϯτͰχϡʔεΛఆ࣌഑৴͢Δػೳ • ଎ใੑͷߴ͍χϡʔε͸߸֎ͱͯ͠ଈ࣌഑৴͢Δ͜ͱ΋Ͱ͖Δ • Ϣʔβʔ͕ڵຯ͕͋Δ-*/&ެࣜΞΧ΢ϯτͱ༑ͩͪʹͳΔ͜ ͱͰهࣄΛड͚औΔ͜ͱ͕Ͱ͖Δ

  8. -*/&εϚʔτ௨஌ • Ϣʔβʔ͕ઃఆͨ͠৘ใΛϓογϡ௨஌Ͱ഑৴ͯ͘͠ΕΔػೳ • ఱؾ༧ใ • ๷ࡂ଎ใ • ϑΥϩʔதͷΩʔϫʔυʹϚον͢Δ৽ணهࣄ •

    FUD
  9. 5 τϥϑΟοΫ CZUFTEBZ . $%/&EHF˞ SFRVFTUTTFD QFBL , 0SJHJO ˞

    ˞೥݄࣌఺ ˞೥݄࣌఺ɻը૾΍ಈըͷτϥϑΟοΫ͸আ͘ CZUFTEBZ 5 0SJHJO ˞ ."6˞
  10.  αʔϏεϩʔϯν /BUJWF "QQ8FC  -*/&ʹχϡʔελ ϒ௥Ճ -*/&/&84ͷྺ࢙  ݕࡧػೳ௥Ճ

     μΠδΣετ഑৴։࢝  χϡʔελϒͷϦ χϡʔΞϧ  Ϣʔβʔ୯Ґͷهࣄ Ϩίϝϯσʔγϣϯ  χϡʔελϒͷϦ χϡʔΞϧ  /BUJWF "QQ൛ -*/& /&84Ϋϩʔζ  εϚʔτ௨஌ ๷ࡂ଎ใ௥Ճ  ϑΥϩʔλϒ௥Ճ  ஍Ҭλϒ ݶఆެ։
  11. 1FSMUP+BWBϓϩδΣΫτ d

  12. +BWBϦϓϨΠεલͷγεςϜ֓ཁ -PBE #BMBODFS 3FWFSTF1SPYZ 8FC"QQ 1FSM

  13. ͳͥ+BWBʹϦϓϨΠε͢Δඞཁ͕͋ͬͨͷ͔ • 1FSMΤϯδχΞෆ଍ • ࣾ಺Ͱ΋ෆ଍͍ͯ͠Δ • ৽ن࠾༻΋೉͍͠ • -*/&ࣾ಺Ͱ͸+7.ݴޠ޲͚ͷΤίγεςϜ͕ॆ࣮͍ͯ͠Δ •

    %FQMPZNFOU -PH.BOBHFNFOU $PNNPO-JCSBSZ FUD • ӡ༻࣮੷΋ଟ͘ɺφϨοδ΋஝ੵ͍ͯ͠Δ
  14. ݴޠϦϓϨΠεͷͭΒΈ  ػೳ։ൃ͸ࢭΊΒΕͳ͍  1FSM͕ॻ͚ΔΤϯδχΞͰͳ͍ͱطଘͷ࣮૷Λཧղ͢Δͷ͕೉͍͠  ࢖ΘΕͳ͘ͳͬͨ"1*ͳͲ͕ଘࡏ͠ɺͲΕΛҠߦ͢Ε͹͍͍ͷ͔Θ͔Γʹ͍͘

  15. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠ • ৽ػೳ͸+BWBͰ࡞Δ • ػೳվमͷ৔߹΋ՄೳͳݶΓ+BWBʹϦϓϨΠε͢Δ • ػೳվमҎ֎ͰϦϓϨΠεͷࡍ͸ɺ"1* TQFD͸ݪଇมߋ͠ͳ͍ • ϑϩϯτΤϯυଆ΍2"ͷίετ͕ൃੜ͢Δ

    • ৽چ"1*ͷ୯७ͳൺֱݕূ͕ͮ͠Β͘ͳΔ ػೳ։ൃ͸ࢭΊΒΕͳ͍
  16. +BWBϦϓϨΠεલͷαʔόʔߏ੒ -PBE #BMBODFS 3FWFSTF1SPYZ 8FC"QQ 1FSM /api/hoge/1

  17. +BWBϦϓϨΠεதͷαʔόʔߏ੒ -PBE #BMBODFS 3FWFSTF1SPYZ 8FC"QQ 1FSM /api/hoge/1 8FC"QQ +BWB /api/hoge/**

    /z/**
  18. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠ • 1FSMͱ+BWBͷ྆ํॻ͚ΔΤϯδχΞ͕ϦϓϨΠε͢Δͷ͕ཧ૝ • 1FSMΤϯδχΞ͕࣮૷ΛυΩϡϝϯτʹىͯ͜͠ɺͦͷυΩϡϝϯτΛ΋ͱʹ+BWBΤϯδχΞ͕࣮૷ • ͜ͷ৔߹υΩϡϝϯτΛॻ͍ͨ1FSMΤϯδχΞ͕ग़དྷ্͕ͬͨ"1*ͷݕূΛߦ͏ • 1FSMΤϯδχΞ΋؆୯ͳ΋ͷ͔Β+BWB࣮૷ʹτϥΠ 1FSM͕ॻ͚ΔΤϯδχΞͰͳ͍ͱطଘͷ࣮૷Λཧղ͢Δͷ͕೉͍͠

  19. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠ • Ҡߦͱಉ࣌ฒߦͰ1FSMͷະ࢖༻ίʔυ࡟আ΋࣮ࢪ • ίʔυྔ͕ݮΓҠߦ࿙Εʹؾ͖ͮ΍͘͢ͳΔ • ௚ۙͷΞΫηεϩάʹه࿥ͷͳ͍"1*͸࡟আ • ࢖ΘΕ͍ͯΔ͔Ͳ͏͔ෆ໌ͳ"1* ·ΕʹΞΫηε͕͋Δ͕ϑϩϯτΤϯυͰ͸࢖ΘΕ͍ͯͳ͍͸ͣͷ"1*

    ͸ঃʑʹϑΣʔυΞ΢τ • Ұఆ֬཰ͰΤϥʔίʔυΛฦ͠ɺ໰୊͕ൃੜ͠ͳ͍͔िؒ΄ͲϞχλϦϯά • ໰୊ͳ͚Ε͹֬཰Λ্͍͖͛ͯɺ࠷ऴతʹ͸"1*Λ࡟আ͢Δ  ࢖ΘΕͳ͘ͳͬͨ"1*ͳͲ͕ଘࡏ͠ɺͲΕΛҠߦ͢Ε͹͍͍ͷ͔Θ͔Γʹ͍͘
  20. ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ • ࣮૷ݴޠ͕ͭڞଘ͢Δظ͕ؒ௕͔ͬͨͨΊɺػೳվम΍໰୊ൃੜ࣌ͷ੾Γ෼͚ͷ೉͠͞͸͋ͬͨ • ݴޠ࢓༷ͷࠩҟʹΑΓҾ͖ى͜͞Εͨόά͸ҙ֎ͱগͳ͔ͬͨ • Կ͔͋ͬͨͱͯ͠΋։ൃ؀ڥͰ༰қʹൃݟͰ͖ΔͨΊ • ෛՙʹ͞Β͞ΕΔ͜ͱʹΑΓൃੜ͢Δ໰୊͸ଟ͔ͬͨ •

    ($ 4UPQ5IF8PSME • .FNPSZMFBL΍3BDF $POEJUJPO • FUD
  21. ࣄྫ঺հ • ఆظϦϦʔεͰຊ൪؀ڥʹσϓϩΠΛߦͬͨͱ͜Ζ8FCαʔόʔͷϨεϙϯελΠϜ͕૿Ճ • Ωϟογϡऔಘ༻ͷ3FEJTίϚϯυͷλΠϜΞ΢τྫ֎΋ಉ࣌ʹେྔൃੜ • 3FEJTΫϥΠΞϯτͱͯ͠-FUUVDFΛར༻ • ಛఆͷΩϟογϡΩʔ΁ͷภΓ͸ͳ͘ɺ΄΅͢΂ͯͷΩϟογϡΩʔͰϥϯμϜʹൃੜ [WARN]

    Get key from redis failed: cache:json://... io.lettuce.core.RedisCommandTimeoutException: Command timed out after 200 millisecond(s) at io.lettuce.core.ExceptionFactory.createTimeoutException(ExceptionFactory.java:51) at io.lettuce.core.LettuceFutures.awaitOrCancel(LettuceFutures.java:119) at io.lettuce.core.FutureSyncInvocationHandler.handleInvocation(FutureSyncInvocationHandler.java:75) at io.lettuce.core.internal.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:79) at com.sun.proxy.$Proxy180.get(Unknown Source) ...
  22. Ծઆͱݕূᶃ • <Ծઆ>Ͳ͔͜ͷॲཧͰڊେͳΦϒδΣΫτΛΩϟογϡ͓ͯ͠Γɺ3FEJTͰεϩʔίϚϯυ͕ൃੜ͍ͯ͠Δʁ • 3FEJT͸γϯάϧεϨουͷͨΊεϩʔίϚϯυʹΑΓϒϩοΩϯά͕ൃੜ͢Δ͜ͱ͕͋Δ • <ݕূ݁Ռ> ✗ • ຊ൪؀ڥʹΩϟογϡΦϒδΣεταΠζΛग़ྗ͢Δϩά࢓ࠐΜͩΓ3FEJTͷ4-08-0(Λ֬ೝ͕ͨ͠ಛ

    ʹҟৗͳ͠ • ·ͨɺ3FEJTͷϒϩοΩϯά͕ݪҼͷ৔߹8FCαʔόʔҎ֎Ͱ΋λΠϜΞ΢τ͕ൃੜ͢Δ͸ͣ
  23. Ծઆͱݕূᶄ • <Ծઆ>($ ͕ݪҼʁ • ఆظϦϦʔεޙɺ($-PDLFS *OJUJBUFE($ʹΑΔఀࢭ͕࣌ؒ૿Ճ NBYNTNT͙Β͍ • ($ʹΑΔεϨουఀࢭʹΑΓλΠϜΞ΢τ͕͓͖͍ͯΔͷͰ͸ʁ

    • ΩϟογϡΦϒδΣΫτͷѹॖॲཧͰKBWBVUJM[JQ*OGMBUFSJOGMBUF CZUF<> %FGMBUFSEFGMBUF CZUF<> Λසൟʹ࢖͍ͬͯΔͷͰɺ($-PDLFS*OJUJBUFE($͕ൃੜ͍ͯ͠Δ
  24. Ծઆͱݕূᶄ ͜ͷؒ($͕อཹ͞ΕΔ ※https://github.com/AdoptOpenJDK/openjdk- jdk11u/blob/fa3ecefdd6eb14a910ae75b7c0aefb1cf8eedcce/src/java.base/share/native/libzip/Inflater.c#L219-L242

  25. Ծઆͱݕূᶄ • +%,Ҏ߱JOGMBUFEFGMBUFϝιουʹ#ZUF#VGGFS͕౉ͤΔΑ͏ʹͳ͓ͬͯΓɺJOQVUͱPVUQVUͷόο ϑΝ͕྆ํͱ΋%JSFDU#VGGFSͰ͋Ε͹($อཹ͕ൃੜ͠ͳ͍ ※https://github.com/AdoptOpenJDK/openjdk- jdk11u/blob/fa3ecefdd6eb14a910ae75b7c0aefb1cf8eedcce/src/java.base/share/native/libzip/Inflater.c#L268-L281

  26. Ծઆͱݕূᶄ • <ݕূ݁Ռ> ✗ • ಛʹ࣮ߦස౓ͷଟ͍JOGMBUFΛ%JSFDU#VGGFSར༻ʹมߋͯ͠σϓϩΠͯ͠Έ͕ͨɺϨεϙϯε஗Ԇ΍ λΠϜΞ΢τ໰୊͸վળͤͣ • ($-PDLFS *OJUJBUFE($΋ଟগݮ͔ͬͨͳʜʁͱ͍͏ײ͡

    • ͨͩ͠෭࢈෺ͱͯ͠ѹॖ͞ΕͨΩϟογϡΦϒδΣΫτల։࣌ͷύϑΥʔϚϯε͸ྑ͘ͳͬͨ Benchmark Mode Cnt Score Error Units DeflateCompressingCodecBenchmark.benchmarkDecodeValue thrpt 5 1365.530 ± 286.953 ops/ms Benchmark Mode Cnt Score Error Units DeflateCompressingCodecBenchmark.benchmarkDecodeValue thrpt 5 4108.440 ± 304.715 ops/ms
  27. Ծઆͱݕূᶅ • <Ծઆ>-FUUVDFͷΠϕϯτϧʔϓεϨουͰͷϒϩοΩϯάૢ࡞͕ݪҼʁ • -FUUVDF 3FGFSFODF (VJEFʹ͸ҎԼͷهࡌ͕͋Δ • As a

    rule of thumb, never block the event loop. If you need to chain futures using blocking calls, use the thenAcceptAsync()/thenRunAsync() methods to fork the processing to another thread. ˞ • ϦϦʔε͞ΕͨίʔυΛͬ͘͡ΓಡΜͰΈͨΒ͔֬ʹLettuceͷεϨου্ͰJDBCͰΫΤϦΛ࣮ߦ ͍ͯ͠Δ… ※出典: https://lettuce.io/core/release/reference/#asynchronous-api.consuming-futures
  28. Ծઆͱݕূᶅ lettuceAsyncCommand.get(key) .thenApply(value -> { final var entity = hogeService.get(value.field);

    ... }) ͜ͷ'VODUJPO͸-FUUVDFͷΠϕϯτϧʔϓεϨου্Ͱ࣮ߦ͞ΕΔ վળલ ※説明用のコードで実際に稼働中のものではありません
  29. Ծઆͱݕূᶅ lettuceAsyncCommand.get(key) .thenApply(value -> { final var entity = hogeService.get(value.field);

    ... }) ͜ͷϝιουͷ಺෦Ͱ͸+%#$ʹΑΓ ΫΤϦΛ࣮ߦ ϒϩοΩϯάૢ࡞ ͢Δ վળલ ※説明用のコードで実際に稼働中のものではありません
  30. Ծઆͱݕূᶅ lettuceAsyncCommand.get(key) .thenApplyAsync(value -> { final var entity = hogeService.get(value.field);

    ... }, executer) UIFO"QQMZ"TZOD Λ࢖ͬͯϒϩοΩϯάૢ࡞ΛผεϨουͰ࣮ߦ վળޙ ※説明用のコードで実際に稼働中のものではありません
  31. Ծઆͱݕূᶅ • <ݕূ݁Ռ> ˓ • ݟࣄʹ3FEJTίϚϯυͷλΠϜΞ΢τ͕ফࣦʂ • αʔόʔͷϨεϙϯελΠϜ΋ਖ਼ৗʹ໭ͬͨʂ

  32. ࠶ൃ๷ࢭରԠ  #MPDL)PVOE˞ಋೖ • ΠϕϯτϧʔϓεϨου಺ͰͷϒϩοΩϯάૢ࡞Λݕ஌ͯ͘͠ΕΔ+7.ΤʔδΣϯτ • -FUUVDFͷΠϕϯτϧʔϓεϨου಺ͰϒϩοΩϯάૢ࡞͕ߦΘΕͨͱ͖ʹϩάΛग़ྗ͢ΔΑ͏ʹ͠ ͨ  ։ൃ؀ڥͰͷఆظతͳෛՙςετ

    • ػೳΛϦϦʔε͢Δ·Ͱؾ͚ͮͳ͔ͬͨͱ͍͏൓লΛ౿·͑ͯɺ։ൃ؀ڥͰఆظతʹෛՙςετΛ ߦ͍ύϑΥʔϚϯε௿ԼΛݕ஌Ͱ͖ΔΑ͏ʹͨ͠ ※BlockHound: https://github.com/reactor/BlockHound
  33. ࠶ൃ๷ࢭରԠ ※説明用のコードで実際に稼働中のものではありません #MPDL)PVOEಋೖ public class Application { public static void

    main(String[] args) { BlockHound.builder() .with(new LettuceBlockHoundIntegration()) .blockingMethodCallback(method -> log.warn(”Blocking call detected”, new Throwable(method.toString()))) .install(); } }
  34. ࠶ൃ๷ࢭରԠ ※説明用のコードで実際に稼働中のものではありません  #MPDL)PVOE˞ಋೖ public class Application { public static

    void main(String[] args) { BlockHound.builder() .with(new LettuceBlockHoundIntegration()) .blockingMethodCallback(method -> log.warn(”Blocking call detected”, new Throwable(method.toString()))) .install(); } } ͜ͷΫϥεͷதͰ؂ࢹ͢ΔεϨου໊ͳͲͷ৚݅Λࢦఆ
  35. ࠶ൃ๷ࢭରԠ ※説明用のコードで実際に稼働中のものではありません  #MPDL)PVOE˞ಋೖ public class Application { public static

    void main(String[] args) { BlockHound.builder() .with(new LettuceBlockHoundIntegration()) .blockingMethodCallback(method -> log.warn(”Blocking call detected”, new Throwable(method.toString()))) .install(); } } ϒϩοΩϯάૢ࡞Λݕ஌ͨ͠ͱ͖ͷಈ࡞Λఆٛ
  36. ࠶ൃ๷ࢭରԠ ։ൃ؀ڥͰͷఆظతͳෛՙςετ • ࣾ಺ͷෛՙςετج൫ (SBGBOBLϕʔε Λར༻͠ςετ࣮ߦ • %BJMZͰ։ൃ؀ڥʹ޲͚ͯςετΛ࣮ߦ • γφϦΦͷϝϯςφϯείετ࡟ݮͷͨΊɺγφϦΦੜ੒ΛQVQQFUFFSΛ༻͍ͯࣗಈԽ

  37. -*/& /&84ͷ͜Ε͔Β

  38. +BWBϦϓϨΠεޙͷ࣍ͳΔ՝୊  1FSM"QQαʔόʔͷTVOTFU  ϨΨγʔͳ"QBDIFIUUQEͷϦϓϨΠε  +7.ϥΠϒϥϦͷܧଓతͳΞοϓσʔτ ͜ΕΒ໰୊ղܾͷͨΊʹ,VCFSOFUFTҠߦΛਐߦத

  39. ,VCFSOFUFTҠߦ -PBE #BMBODFS 3FWFSTF1SPYZ 8FC"QQ 1FSM 8FC"QQ +BWB

  40. ,VCFSOFUFTҠߦ -PBE #BMBODFS 8FC"QQ +BWB *OHSFTT 3PMMPVUT

  41. ·ͱΊ • ࣮૷ݴޠͷϦϓϨΠεʹ͍ͭͯ • 1FSMͱ+BWB͕ڞଘͰ͖ΔΑ͏ʹͯ͠ɺαʔϏε։ൃΛࢭΊͣʹϦϓϨΠεΛߦͬͨ • ϦϓϨΠε͢Δ͜ͱʹ஫ྗ͠"1*TQFDͷมߋ͕ඞཁͳվળ͸ϦϓϨΠεޙʹରԠ͢Δ • ྆ํͷݴޠΛॻ͚Δਓ͕࣮૷͢Δ΋͘͠͸طଘͷ࣮૷ΛಡΊΔਓʹυΩϡϝϯτʹམͯ͠΋Βͬͯ ͔ΒϦϓϨΠε͢Δ

    • ະ࢖༻࣮૷΍ϦϓϨΠεࡁΈ࣮૷͸࡟আ͢Δ͜ͱͰҠߦ࿙Ε๷ࢭ • ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ • ΠϕϯτϧʔϓεϨουͷϒϩοΩϯάૢ࡞͸#MPDL)PVOEͰݕ஌Ͱ͖Δ • ύϑΥʔϚϯε௿ԼΛ։ൃ؀ڥͰݕ஌͢ΔͨΊʹఆظతͳෛՙςετ΋ॏཁ • +BWBϦϓϨΠεޙͷ՝୊ղܾͷͨΊʹ,VCFSOFUFTҠߦΛਐߦத
  42. 8&`3&)*3*/( • -*/&Ͱ͸ΤϯδχΞΛืूதͰ͢ʂ • -*/& /&84ͷΑ͏ͳେن໛8FCαʔϏεͷ։ൃΛ͍ͨ͠ํ • IUUQTMJOFDPSQDPNKBDBSFFSQPTJUJPO • ͦͷଞʹ΋༷ʑͳϙδγϣϯ͕͋ΔͷͰ͝ڵຯ͕͋Δํ͸ੋඇʂ

  43. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠