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

November 27, 2022
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

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

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

     μΠδΣετ഑৴։࢝  χϡʔελϒͷϦ χϡʔΞϧ  Ϣʔβʔ୯Ґͷهࣄ Ϩίϝϯσʔγϣϯ  χϡʔελϒͷϦ χϡʔΞϧ  /BUJWF "QQ൛ -*/& /&84Ϋϩʔζ  εϚʔτ௨஌ ๷ࡂ଎ใ௥Ճ  ϑΥϩʔλϒ௥Ճ  ஍Ҭλϒ ݶఆެ։
  3. ͲͷΑ͏ʹϦϓϨΠε͔ͨ͠ • Ҡߦͱಉ࣌ฒߦͰ1FSMͷະ࢖༻ίʔυ࡟আ΋࣮ࢪ • ίʔυྔ͕ݮΓҠߦ࿙Εʹؾ͖ͮ΍͘͢ͳΔ • ௚ۙͷΞΫηεϩάʹه࿥ͷͳ͍"1*͸࡟আ • ࢖ΘΕ͍ͯΔ͔Ͳ͏͔ෆ໌ͳ"1* ·ΕʹΞΫηε͕͋Δ͕ϑϩϯτΤϯυͰ͸࢖ΘΕ͍ͯͳ͍͸ͣͷ"1*

    ͸ঃʑʹϑΣʔυΞ΢τ • Ұఆ֬཰ͰΤϥʔίʔυΛฦ͠ɺ໰୊͕ൃੜ͠ͳ͍͔िؒ΄ͲϞχλϦϯά • ໰୊ͳ͚Ε͹֬཰Λ্͍͖͛ͯɺ࠷ऴతʹ͸"1*Λ࡟আ͢Δ  ࢖ΘΕͳ͘ͳͬͨ"1*ͳͲ͕ଘࡏ͠ɺͲΕΛҠߦ͢Ε͹͍͍ͷ͔Θ͔Γʹ͍͘
  4. ࣄྫ঺հ • ఆظϦϦʔεͰຊ൪؀ڥʹσϓϩΠΛߦͬͨͱ͜Ζ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) ...
  5. Ծઆͱݕূᶄ • <Ծઆ>($ ͕ݪҼʁ • ఆظϦϦʔεޙɺ($-PDLFS *OJUJBUFE($ʹΑΔఀࢭ͕࣌ؒ૿Ճ NBYNTNT͙Β͍ • ($ʹΑΔεϨουఀࢭʹΑΓλΠϜΞ΢τ͕͓͖͍ͯΔͷͰ͸ʁ

    • ΩϟογϡΦϒδΣΫτͷѹॖॲཧͰKBWBVUJM[JQ*OGMBUFSJOGMBUF CZUF<> %FGMBUFSEFGMBUF CZUF<> Λසൟʹ࢖͍ͬͯΔͷͰɺ($-PDLFS*OJUJBUFE($͕ൃੜ͍ͯ͠Δ
  6. Ծઆͱݕূᶄ • <ݕূ݁Ռ> ✗ • ಛʹ࣮ߦස౓ͷଟ͍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
  7. Ծઆͱݕূᶅ • <Ծઆ>-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
  8. Ծઆͱݕূᶅ lettuceAsyncCommand.get(key) .thenApply(value -> { final var entity = hogeService.get(value.field);

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

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

    ... }, executer) UIFO"QQMZ"TZOD Λ࢖ͬͯϒϩοΩϯάૢ࡞ΛผεϨουͰ࣮ߦ վળޙ ※説明用のコードで実際に稼働中のものではありません
  11. ࠶ൃ๷ࢭରԠ  #MPDL)PVOE˞ಋೖ • ΠϕϯτϧʔϓεϨου಺ͰͷϒϩοΩϯάૢ࡞Λݕ஌ͯ͘͠ΕΔ+7.ΤʔδΣϯτ • -FUUVDFͷΠϕϯτϧʔϓεϨου಺ͰϒϩοΩϯάૢ࡞͕ߦΘΕͨͱ͖ʹϩάΛग़ྗ͢ΔΑ͏ʹ͠ ͨ  ։ൃ؀ڥͰͷఆظతͳෛՙςετ

    • ػೳΛϦϦʔε͢Δ·Ͱؾ͚ͮͳ͔ͬͨͱ͍͏൓লΛ౿·͑ͯɺ։ൃ؀ڥͰఆظతʹෛՙςετΛ ߦ͍ύϑΥʔϚϯε௿ԼΛݕ஌Ͱ͖ΔΑ͏ʹͨ͠ ※BlockHound: https://github.com/reactor/BlockHound
  12. ࠶ൃ๷ࢭରԠ ※説明用のコードで実際に稼働中のものではありません #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(); } }
  13. ࠶ൃ๷ࢭରԠ ※説明用のコードで実際に稼働中のものではありません  #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(); } } ͜ͷΫϥεͷதͰ؂ࢹ͢ΔεϨου໊ͳͲͷ৚݅Λࢦఆ
  14. ࠶ൃ๷ࢭରԠ ※説明用のコードで実際に稼働中のものではありません  #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(); } } ϒϩοΩϯάૢ࡞Λݕ஌ͨ͠ͱ͖ͷಈ࡞Λఆٛ
  15. ·ͱΊ • ࣮૷ݴޠͷϦϓϨΠεʹ͍ͭͯ • 1FSMͱ+BWB͕ڞଘͰ͖ΔΑ͏ʹͯ͠ɺαʔϏε։ൃΛࢭΊͣʹϦϓϨΠεΛߦͬͨ • ϦϓϨΠε͢Δ͜ͱʹ஫ྗ͠"1*TQFDͷมߋ͕ඞཁͳվળ͸ϦϓϨΠεޙʹରԠ͢Δ • ྆ํͷݴޠΛॻ͚Δਓ͕࣮૷͢Δ΋͘͠͸طଘͷ࣮૷ΛಡΊΔਓʹυΩϡϝϯτʹམͯ͠΋Βͬͯ ͔ΒϦϓϨΠε͢Δ

    • ະ࢖༻࣮૷΍ϦϓϨΠεࡁΈ࣮૷͸࡟আ͢Δ͜ͱͰҠߦ࿙Ε๷ࢭ • ϦϓϨΠεதʹൃੜͨ͠Πγϡʔ • ΠϕϯτϧʔϓεϨουͷϒϩοΩϯάૢ࡞͸#MPDL)PVOEͰݕ஌Ͱ͖Δ • ύϑΥʔϚϯε௿ԼΛ։ൃ؀ڥͰݕ஌͢ΔͨΊʹఆظతͳෛՙςετ΋ॏཁ • +BWBϦϓϨΠεޙͷ՝୊ղܾͷͨΊʹ,VCFSOFUFTҠߦΛਐߦத