Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

ࣗݾ঺հ ҆ా ཽ (΍ͩ͢ Γΐ͏) 2015೥: NTTݚڀॴ ೖࣾ - ίϯςφܕԾ૝Խٕज़ؔ࿈ͷݚڀΛ͢Δ༧ఆͩͬͨ 2016೥: ೔ຊܦࡁ৽ฉࣾ ೖࣾ - ೔ܦిࢠ൛ϦχϡʔΞϧ൛ ։ൃϝϯόʔ - ϑϩϯτΤϯυɾόοΫΤϯυɾAWSɾFastlyͷઃఆ౳ॾʑ୲౰

Slide 3

Slide 3 text

೔ܦిࢠ൛ ຖ೔໿900ຊͷهࣄΛ഑৴ ༗ྉձһ54ສਓҎ্ɾແྉձһ300ສਓҎ্ ݄ؒ3ԯΞΫηε

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Microservicesͱ͸ Auth Service DB Service Ranking Service Search Service web iOS App γεςϜΛෳ਺ͷখ͞ͳαʔϏεͷू߹Ͱߏ੒͢ΔΞʔΩςΫνϟ API

Slide 6

Slide 6 text

Microservicesͱ͸ ServiceA ServiceB ServiceC ServiceD Service Registry ֤αʔϏεͷ৘ใ؅ཧ΍ϔϧενΣοΫ ϦΫΤετઌαʔϏεͷ৘ใऔಘ ϦΫΤετͷૹ৴ αʔϏεؒΛܨ͙ͨΊʹɺService RegistryͳͲΛ༻͍Δ

Slide 7

Slide 7 text

FastlyΛ࢖ͬͨMicroservices ServiceB ServiceC ɾFastlyͰService RegistryΛ୅༻ ɾશϦΫΤετ͕Fastlyܦ༝ ɾFastly͕ϦΫΤετΛϧʔςΟϯά ServiceA ServiceC

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Ωϟογϡͷू໿ ServiceB ServiceC Ωϟογϡ ServiceD ServiceA ɾΩϟογϡ͕'BTUMZʹू໿Ͱ͖Δ ෳ਺ͷαʔϏεɾϨΠϠʹ෼ࢄ͠ͳ͍ QVSHF͢Δ͚ͩͰ*OWBMJEBUJPOՄೳ ো֐ൃੜ࣌ʹ೾ٴΛ๷͛Δ Next NikkeiͰ͸·ͩαʔϏε͝ͱʹΩϟογϡΛ΋ͬͯ ͠·͍ͬͯΔ࣮૷͕ଟʑ͋Δ͕…

Slide 13

Slide 13 text

ϩΪϯάɾϞχλϦϯά ServiceB ServiceC ServiceD ɾϩΪϯά શϦΫΤετͷϞχλϦϯάͰ͖Δ Ωϟογϡ ServiceA ϩΪϯά

Slide 14

Slide 14 text

ϩΪϯάɾϞχλϦϯά Real Time Log Streaming request url status code response size taken time cache HIT/MISS ... αʔϏε

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

ೝՄͷඞཁͳίϯςϯπͷΩϟογϡ هࣄϖʔδ /article/123 Cookie: Auth=a124b5… Cache-control: no-cache, no-store Cookie: Auth=a124b5... OAuth2ೝূͰಘΒΕͨ JWTτʔΫϯ

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

ೝՄͷඞཁͳίϯςϯπͷΩϟογϡώοτ཰ Ϣʔβछผ͝ͱͷهࣄϖʔδΩϟογϡώοτ཰ ϩάΠϯϢʔβʹରͯ͠΋ΩϟογϡͰ͖ͯΔ ඇձһ ༗ྉձһ ແྉձһ

Slide 24

Slide 24 text

VCL ࣮૷ྫ

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

[ { "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

Slide 28

Slide 28 text

μΠφϛοΫϧʔςΟϯά Top Article API Routing-Override: API-> API-dev ϦΫΤετϔομ API-dev ϦΫΤετϔομͰϧʔςΟϯάΛ ಈతʹมߋ Ұ෦ͷαʔϏεΛ։ൃதͷ΋ͷʹ ࠩ͠ସ͑ΒΕΔ

Slide 29

Slide 29 text

ো֐ͷ೾ٴΛ๷͙ if (beresp.http.Cache-Control !~ "(stale-if-error|immutable|private)") { set beresp.stale_if_error = 86400s; } ϦΫΤετʹࣦഊͯ͠΋ɺࢦఆ͞Εͨظؒ͸ΩϟογϡΛར༻͢Δ Next NikkeiͰ͸ɺstale-if-errorΛࣗಈͰ෇༩ αʔϏε͕ࢮΜͰ΋ɺΩϟογϡ͕͋Ε͹͠͹Β͘͸ίϯςϯπΛฦͤΔ stale-if-error

Slide 30

Slide 30 text

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");

Slide 31

Slide 31 text

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");

Slide 32

Slide 32 text

ϩΪϯάɾϞχλϦϯά - 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ܗࣜͰͷϩάग़ྗྫ

Slide 33

Slide 33 text

FastlyΛ࢖ͬͨMicroservices ·ͱΊ ✔ Service Registry͕ෆཁ ✔ Cache͕Fastlyʹू໿͞ΕInvalidation؆୯ ✔ ো֐ൃੜ࣌ʹ೾ٴΛ๷͛Δ ✔ ؆୯ͳϞχλϦϯά΍ೝՄ΋࣮ݱͰ͖Δ ✔ μΠφϛοΫϧʔςΟϯάͰ։ൃָ͕ʹͳΔ

Slide 34

Slide 34 text

͋Γ͕ͱ͏͍͟͝·ͨ͠