Microservices on Fastly

7d6e26a4f1a9b5a866337f09178b0c9c?s=47 Ryo yasuda
October 17, 2017
18k

Microservices on Fastly

7d6e26a4f1a9b5a866337f09178b0c9c?s=128

Ryo yasuda

October 17, 2017
Tweet

Transcript

  1. Microservices on Fastly ೔ຊܦࡁ৽ฉࣾ ҆ా ཽ 'BTUMZ :BNBHPZB .FFUVQ 

  2. ࣗݾ঺հ ҆ా ཽ (΍ͩ͢ Γΐ͏) 2015೥: NTTݚڀॴ ೖࣾ - ίϯςφܕԾ૝Խٕज़ؔ࿈ͷݚڀΛ͢Δ༧ఆͩͬͨ

    2016೥: ೔ຊܦࡁ৽ฉࣾ ೖࣾ - ೔ܦిࢠ൛ϦχϡʔΞϧ൛ ։ൃϝϯόʔ - ϑϩϯτΤϯυɾόοΫΤϯυɾAWSɾFastlyͷઃఆ౳ॾʑ୲౰
  3. ೔ܦిࢠ൛ ຖ೔໿900ຊͷهࣄΛ഑৴ ༗ྉձһ54ສਓҎ্ɾແྉձһ300ສਓҎ্ ݄ؒ3ԯΞΫηε

  4. ೔ܦిࢠ൛ ϦχϡʔΞϧ ϓϩδΣΫτ (Next Nikkei) UI/UXվળ (PWAԽɾϨεϙϯγϒԽ) ಺੡Խ FastlyɾMicroservicesΞʔΩςΫνϟͷར༻

  5. Microservicesͱ͸ Auth Service DB Service Ranking Service Search Service web

    iOS App γεςϜΛෳ਺ͷখ͞ͳαʔϏεͷू߹Ͱߏ੒͢ΔΞʔΩςΫνϟ API
  6. Microservicesͱ͸ ServiceA ServiceB ServiceC ServiceD Service Registry ֤αʔϏεͷ৘ใ؅ཧ΍ϔϧενΣοΫ ϦΫΤετઌαʔϏεͷ৘ใऔಘ ϦΫΤετͷૹ৴

    αʔϏεؒΛܨ͙ͨΊʹɺService RegistryͳͲΛ༻͍Δ
  7. FastlyΛ࢖ͬͨMicroservices ServiceB ServiceC ɾFastlyͰService RegistryΛ୅༻ ɾશϦΫΤετ͕Fastlyܦ༝ ɾFastly͕ϦΫΤετΛϧʔςΟϯά ServiceA ServiceC

  8. Ωϟογϡͷू໿ ServiceB ServiceC ServiceD ɾΩϟογϡ͕'BTUMZʹू໿Ͱ͖Δ Ωϟογϡ ServiceA

  9. Ωϟογϡͷू໿ ServiceB ServiceC ServiceD ɾΩϟογϡ͕'BTUMZʹू໿Ͱ͖Δ ෳ਺ͷαʔϏεɾϨΠϠʹ෼ࢄ͠ͳ͍ Ωϟογϡ ServiceA

  10. Ωϟογϡͷू໿ ServiceB ServiceC ServiceD ɾΩϟογϡ͕'BTUMZʹू໿Ͱ͖Δ ෳ਺ͷαʔϏεɾϨΠϠʹ෼ࢄ͠ͳ͍ QVSHF͢Δ͚ͩͰ*OWBMJEBUJPOՄೳ Ωϟογϡ ServiceA

  11. Ωϟογϡͷू໿ ServiceB ServiceC Ωϟογϡ ServiceD ServiceA ɾΩϟογϡ͕'BTUMZʹू໿Ͱ͖Δ ෳ਺ͷαʔϏεɾϨΠϠʹ෼ࢄ͠ͳ͍ QVSHF͢Δ͚ͩͰ*OWBMJEBUJPOՄೳ ো֐ൃੜ࣌ʹ೾ٴΛ๷͛Δ

    ServiceB͕ࢮΜͰ΋ΩϟογϡΛ࢖ͬͯՔಇ
  12. Ωϟογϡͷू໿ ServiceB ServiceC Ωϟογϡ ServiceD ServiceA ɾΩϟογϡ͕'BTUMZʹू໿Ͱ͖Δ ෳ਺ͷαʔϏεɾϨΠϠʹ෼ࢄ͠ͳ͍ QVSHF͢Δ͚ͩͰ*OWBMJEBUJPOՄೳ ো֐ൃੜ࣌ʹ೾ٴΛ๷͛Δ

    Next NikkeiͰ͸·ͩαʔϏε͝ͱʹΩϟογϡΛ΋ͬͯ ͠·͍ͬͯΔ࣮૷͕ଟʑ͋Δ͕…
  13. ϩΪϯάɾϞχλϦϯά ServiceB ServiceC ServiceD ɾϩΪϯά શϦΫΤετͷϞχλϦϯάͰ͖Δ Ωϟογϡ ServiceA ϩΪϯά

  14. ϩΪϯάɾϞχλϦϯά Real Time Log Streaming request url status code response

    size taken time cache HIT/MISS ... αʔϏε
  15. ϩΪϯάɾϞχλϦϯά – kibanaͰՄࢹԽ ֤αʔϏε΁ͷΞΫηεྔ Τϥʔ਺ ֤ϦΫΤετͷstatus code ֤αʔϏεͷฏۉϨεϙϯελΠϜ

  16. ϩΪϯάɾϞχλϦϯά - Ωϟογϡώοτ཰ՄࢹԽ ֤αʔϏεɾ֤ύεʹର͢ΔΩϟογϡώοτ཰ Ϣʔβछผ͝ͱͷΩϟογϡώοτ཰ (هࣄϖʔδ) ༗ྉձһ ແྉձһ ඇձһ

  17. ϩΪϯάɾϞχλϦϯά – ಠࣗdashboards ֤αʔϏεͷΩϟογϡώοτ཰ͳͲΛνΣοΫ

  18. ೝՄ ServiceB ServiceC ServiceD ɾ'BTUMZ্ͰೝՄΛ࣮૷ ֤αʔϏεʹ࣮૷͠ͳͯ͘ྑ͍ Ωϟογϡώοτ཰্͕Δ Ωϟογϡ ೝՄ ServiceA

    ϩΪϯά
  19. ೝՄͷඞཁͳίϯςϯπͷΩϟογϡ هࣄϖʔδ /article/123 Cookie: Auth=a124b5... OAuth2ೝূͰಘΒΕͨ JWTτʔΫϯ ϢʔβͷݖݶʹΑͬͯ ίϯςϯπมΘΔ

  20. ೝՄͷඞཁͳίϯςϯπͷΩϟογϡ هࣄϖʔδ /article/123 Cookie: Auth=a124b5… Cache-control: no-cache, no-store Cookie: Auth=a124b5...

    OAuth2ೝূͰಘΒΕͨ JWTτʔΫϯ
  21. ೝՄͷඞཁͳίϯςϯπͷΩϟογϡ هࣄϖʔδ /article/123 ϦΫΤετϔομ User-ID: 98765 User-Rank: paid Ϩεϙϯεϔομ Vary:

    User-Rank Cookie: Auth=a124b5... ೝূΫοΩʔͷ decodeɾvalidate OAuth2ೝূͰಘΒΕͨ JWTτʔΫϯ
  22. ೝՄͷඞཁͳίϯςϯπͷΩϟογϡ هࣄϖʔδ /article/123 ϦΫΤετϔομ User-ID: 98765 User-Rank: paid Ϩεϙϯεϔομ Vary:

    User-Rank Cookie: Auth=a124b5... ೝূΫοΩʔͷ decodeɾvalidate OAuth2ೝূͰಘΒΕͨ JWTτʔΫϯ User-Rank͝ͱʹΩϟογϡ෼͚ ΔΑ͏CDNʹ໋ྩ
  23. ೝՄͷඞཁͳίϯςϯπͷΩϟογϡώοτ཰ Ϣʔβछผ͝ͱͷهࣄϖʔδΩϟογϡώοτ཰ ϩάΠϯϢʔβʹରͯ͠΋ΩϟογϡͰ͖ͯΔ ඇձһ ༗ྉձһ ແྉձһ

  24. VCL ࣮૷ྫ

  25. ϧʔςΟϯά Top Article API Assets /article/123 Path Based Routing

  26. backends.vcl routing.vcl ϧʔςΟϯά - VCL backend article { .host: "article.xx.jp";

    .port: 443 .ssl: true } ... if (req.url ~ "/article/.+") { req.backend = article; } ... vclͰαʔϏεΛఆٛ ϧʔςΟϯά༻ͷvcl
  27. [ { "name": "article", "path": "/article/.+", "host": "article.xx.jp", "ssl": true

    } … ] services.json backends.vcl routing.vcl શαʔϏεͷఆٛϑΝΠϧ ͲΜͳαʔϏεɺϧʔτ͕͋Δ ͔ͻͱ໨ͰΘ͔Δ ϧʔςΟϯά - VCLࣗಈੜ੒ backend article { .host: "article.xx.jp"; .port: 443 .ssl: true } ... if (req.url ~ "/article/.+") { req.backend = article; } ... vclͰαʔϏεΛఆٛ ϧʔςΟϯά༻ͷvcl
  28. μΠφϛοΫϧʔςΟϯά Top Article API Routing-Override: API-> API-dev ϦΫΤετϔομ API-dev ϦΫΤετϔομͰϧʔςΟϯάΛ

    ಈతʹมߋ Ұ෦ͷαʔϏεΛ։ൃதͷ΋ͷʹ ࠩ͠ସ͑ΒΕΔ
  29. ো֐ͷ೾ٴΛ๷͙ if (beresp.http.Cache-Control !~ "(stale-if-error|immutable|private)") { set beresp.stale_if_error = 86400s;

    } ϦΫΤετʹࣦഊͯ͠΋ɺࢦఆ͞Εͨظؒ͸ΩϟογϡΛར༻͢Δ Next NikkeiͰ͸ɺstale-if-errorΛࣗಈͰ෇༩ αʔϏε͕ࢮΜͰ΋ɺΩϟογϡ͕͋Ε͹͠͹Β͘͸ίϯςϯπΛฦͤΔ stale-if-error
  30. Fastly্ͰͷೝՄ - VCL ೝূΫοΩʔ(JWTܗࣜ): eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4 gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ ɾΫοΩʔऔಘ: req.http.Cookie:Auth ɾJWTτʔΫϯ෼ղ: regsub(req.http.Cookie.Auth,

    " (^[^.]+).[^.]+.[^.]+$ ", "$1") ɾBase64σίʔυ: digest.base64_decode ɾJWTγάωνϟݕূ: digest.hmac_sha256_base64() ɾreq.http.Nikkei-Auth-UserID = regsub(var.payload, {"^.*?"uid"¥s*:¥s*"(¥w+)".*?$"}, "¥1");
  31. Fastly্ͰͷೝՄ – VCL if (req.http.Cookie:Auth !~ "(^[^¥.]+)¥.([^¥.]+)¥.([^¥.]+)$") { set req.http.Auth-Valid

    = "false"; } set var.base64Header = re.group.1; set var.base64Payload = re.group.2; set var.signature = digest.base64url_decode(re.group.3); set var.validSignature = digest.base64_decode(digest.hmac_sha256_base64(var.jwtSecret, var.base64Header "." var.base64Payload)); set var.payload = digest.base64_decode(var.base64Payload); set var.expires = regsub(var.payload, {"^.*?"exp"¥s*:¥s*(¥d+).*?$"}, "¥1"); # γάωνϟͷਖ਼౰ੑͱ༗ޮظݶͷ֬ೝ if (var.signature != var.validSignature || time.is_after(now, std.integer2time(std.atoi(var.expires)))) { set req.http.Auth-Valid = "false"; } # payload͔Βݖݶ৘ใͳͲΛநग़ req.http. UserID = regsub(var.payload, {"^.*?"uid"¥s*:¥s*"(¥w+)".*?$"}, "¥1");
  32. ϩΪϯάɾϞχλϦϯά - VCL sub vcl_log { log {"syslog "} req.service_id

    {" fastly-log :: "} {" timestamp_us:"} time.start.usec {" host:"} regsuball(req.http.X-Forwarded-Host, {" "}, "") {" upstream_host:"} regsuball(req.http.Host, {" "}, "") {" remote_addr:"} client.ip {" method:"} req.request {" fastly_x_cache:"} req.http.X-Cache {" fastly_x_cache_hits:"} req.http.X-Cache-Hits {" user_id:"} req.http.User-ID {" user_rank:"} req.http.User-Rank; … } LTSVܗࣜͰͷϩάग़ྗྫ
  33. FastlyΛ࢖ͬͨMicroservices ·ͱΊ ✔ Service Registry͕ෆཁ ✔ Cache͕Fastlyʹू໿͞ΕInvalidation؆୯ ✔ ো֐ൃੜ࣌ʹ೾ٴΛ๷͛Δ ✔

    ؆୯ͳϞχλϦϯά΍ೝՄ΋࣮ݱͰ͖Δ ✔ μΠφϛοΫϧʔςΟϯάͰ։ൃָ͕ʹͳΔ
  34. ͋Γ͕ͱ͏͍͟͝·ͨ͠