【Go活用事例】 安全運転支援サービスを支える 運用管理システム

【Go活用事例】 安全運転支援サービスを支える 運用管理システム

2019/11/1 の、DeNA.go #3 の発表資料です。

Ea82bff59a575a8bf00a60a82af6b297?s=128

Hirotaka Suzuki

November 01, 2019
Tweet

Transcript

  1. ʲ(P׆༻ࣄྫʳ ҆શӡసࢧԉαʔϏεΛࢧ͑Δ ӡ༻؅ཧγεςϜ ླ໦༟ਸ!TVIJSPUBLB ΦʔτϞʔςΟϒࣄۀຊ෦εϚʔτυϥΠϏϯά෦γεςϜ։ൃάϧʔϓ גࣜձࣾσΟʔɾΤψɾΤʔ   The Go

    gopher was designed by Renee French.
  2. ࣗݾ঺հ   ླ໦༟ਸ!TVIJSPUBLB ϑϦʔϥϯεɾϔϧεςοΫܥελʔτΞοϓΛܦͯɺ ೥%F/"ೖࣾɻ ަ௨ࣄނ࡟ݮαʔϏε%3*7&$)"35ͷαʔόʔΞϓϦ έʔγϣϯ։ൃΛ΍͍ͬͯ·͢ɻ 8FCͷਐԽͱͱ΋ʹಈըαΠτ͔ΒϞϏϦςΟαʔϏε ·ͰؔΘ͖ͬͯͯɺ΋ͬͱ΋ͬͱ8FC͕׆༂͢Δࣾձʹ

    ͍͖͍ͯͨ͠ɻ
  3. ຊ೔ͷΞδΣϯμ (PΛ࢖ͬͨ։ൃͷݱ৔ͷงғؾΛ͓఻͍͑ͨ͠ʂ • (PΛ࢖ͬͯͳʹΛͭͬͨ͘ͷʁ • ͳΜͰ(PΛ࠾༻ͨ͠ͷʁ • ͲΜͳϥΠϒϥϦΛ࢖ͬͯΔͷʁ • ۩ମతͳ࣮૷ʹ͍ͭͯ

    • 3BJMTͱͷซ༻ͷίπ • ։ൃͰۤ࿑ͨͯ͠͠Δ͜ͱ͸ʁ  
  4.   (PͰͳʹΛ͍ͭͬͯ͘Δ͔

  5.   %3*7&$)"35ͱ͸ʁ

  6. %3*7&$)"35ͱ͸   4 A2 DRIVE CHART

  7. %3*7&$)"35ͷ࣮ূޮՌ   5 A3 DRIVE CHART

  8. ं֎ΧϝϥͷΑ͏͢   㾎ंؒڑ཭ෆ଍ 㾎Ұ࣌ෆఀࢭ 㾎଎౓௒ա

  9. ं಺ΧϝϥͷΑ͏͢   㾎࿬ݟ 㾎ډ຾Γ

  10. ೔ʑͷӡసϨϙʔτ   9 A7     ӡసͷΫηΛݟ͑ΔԽ͠ɺةݥͳಈը͚ͩϐοΫΞοϓɻ

  11.   %3*7&$)"35ͷӡ༻؅ཧ͕Ͱ͖Δ 8&#γεςϜΛͭ͘Γ·ͨ͠

  12. ͨͱ͑͹ɺ͜Μͳ͜ͱ͕Ͱ͖·͢ ✓ ֤ςʔϒϧʢҎ্ʣͷ$36%ૢ࡞΍ΠϯϙʔτɾΤΫεϙʔτ ✓ ंࡌثͷ෦඼Λൃ஫ͯ͠ɺൃ஫ॻͷ1%'Λμ΢ϯϩʔυ͢Δ ✓ ෦඼͕ೲ඼͞Εͨͱ͖΍෦඼͕࢖༻͞Εͨͱ͖ʹɺࡏݿ਺Λਖ਼͘͠อͭ ✓ ޻৔Ͱͷंࡌثͷ૊Έཱ͔ͯΒൃૹ·ͰΛτϥοΩϯά͢Δ ✓

    Ͳͷंࡌث͕Ͳͷं྆ʹऔΓ෇͚ΒΕ͍ͯΔ͔؅ཧ͢Δ ✓ ंࡌثʹ഑৴͢ΔΞϓϦέʔγϣϯΛΞοϓϩʔυ͢Δ ✓ "*ʹΑΔϢʔβʔͷإೝূͷਖ਼֬ੑΛνΣοΫ͢Δ ✓ Ϣʔβʔ͔ΒͷϑΟʔυόοΫΛ֬ೝͯ͠ɺϝʔϧฦ৴͢Δ ✓ ϢʔβʔͷݖݶΛΘ͔Γ΍͍͢(6*Ͱ֬ೝɾมߋ͢Δ ✓ ंࡌثͷՔಇঢ়گΛϦΞϧλΠϜͰूܭ͢Δ ɾɾɾɾɾɾ  
  13.   ը໘঺հ

  14. ं྆Ұཡը໘  

  15. ं྆Ұཡը໘ʢ֦େʣ   $47Πϯϙʔτ $47ΤΫεϙʔτ ϑΟϧλʢΠϯΫϦϝϯλϧαʔνʣ ϑΟϧλʢϓϧμ΢ϯʣ ৄࡉදࣔϘλϯ ࡟আϘλϯ ҹ࡮Ϙλϯ

  16. ෦඼ൃ஫ը໘  

  17. ंࡌثऔΓ෇͚ը໘  

  18. ंࡌثΞϓϦέʔγϣϯ഑৴ը໘  

  19. Ϣʔβʔ؅ཧը໘  

  20.   (PΛ࠾༻͢Δ·ͰͷಓͷΓ

  21. ΞʔΩςΫνϟ  

  22. ΞʔΩςΫνϟʢ֦େʣ   (P 3BJMT ֤ίϯϙʔωϯτ͸ ϚΠΫϩαʔϏεԽ

  23. (PͰॻ͔Ε͍ͯΔ΋ͷ • ӡ༻؅ཧγεςϜͷ"1*ɾϏϡʔ 3BJMTͰॻ͔Ε͍ͯΔ΋ͷ • ंࡌثͱͷ௨৴"1* • ंࡌث͔ΒͷϑΝΠϧΞοϓϩʔυ"1* • 8&#ΫϥΠΞϯτͱͷ௨৴"1*

    • ఆظόον΍σʔϞϯ   3BJMT͕ଟ͍ ΞʔΩςΫνϟʢݴޠผʣ
  24. %3*7&$)"35ࣄۀԽ·ͰͷಓͷΓ ࣮ূ࣮ݧʢ̎೥ʣ ύʔτφʔ༷ͱ࣮ݧతʹαʔϏεΛӡ༻ͯ͠ɺຊ౰ʹަ௨ࣄނ࡟ݮޮՌ͕͋Δͷ͔Λݕূ ‑ ࣄۀԽ0,͔ͷ൑அ ΋͠/(Ͱ͋Ε͹ɺ࣮ূ࣮ݧதͷιʔείʔυ͸͓ଂೖΓʹɾɾɾ ‑ ຊαʔϏε։࢝ ௕ظؒͷαʔϏεΛܧଓΛલఏʹɺεέʔϥϏϦςΟΛߟྀͨ͠γεςϜߏங͕ඞཁ 

    
  25. (PPS3BJMT ˒࣮ূ࣮ݧ࣌͸ɺεϐʔυॏࢹͰ3BJMT 8FC։ൃʹඞཁͳϥΠϒϥϦ͕ͦΖ͍ͬͯͯɺͳΜͱ͍ͬͯ΋։ൃ଎౓͕଎͍ w ࣮ূ࣮ݧத͸සൟʹ࢓༷มߋ͕ൃੜ͠ɺεϐʔυউෛ ˒ຊαʔϏε͸ɺύϑΥʔϚϯεॏࢹͰ(P ࣮ߦ଎౓ͷ଎͞ • ଎౓͕̎ഒʹͳΕ͹αʔόʔ୆਺͕൒෼ͰࡁΉʢίετϝϦοτʣ ੩తܕ෇͚

    • ௕ظؒͷӡ༻Λߟ͑Δͱɺܕ͕͋Δ͜ͱͰେن໛ͳϦϑΝΫλϦϯάָ͕ʹͳΔ ʢӡ༻ϝϦοτʣ  
  26. (PͰॻ͔Ε͍ͯΔ΋ͷ • ӡ༻؅ཧγεςϜͷ"1*ɾϏϡʔ 3BJMTͰॻ͔Ε͍ͯΔ΋ͷ • ंࡌثͱͷ௨৴"1* • ंࡌث͔ΒͷϑΝΠϧΞοϓϩʔυ"1* • 8&#ΫϥΠΞϯτͱͷ௨৴"1*

    • ఆظόον΍σʔϞϯ   3BJMT͕ଟ͍ ΞʔΩςΫνϟʢݴޠผʣ ࣮ূ࣮ݧதʹ͸ ͳ͔ͬͨαʔϏε ࣮ূ࣮ݧத͔Β ͋ͬͨαʔϏε
  27.   ӡ༻؅ཧγεςϜ͔Β(PΛ࠾༻͠ɺ ͦͷଞͷαʔϏε΋ ॱ࣍(PʹϦϓϨΠε༧ఆ

  28. (PΛ͞Θͬͯ࠷ॳʹײͨ͜͡ͱ • ίϯύΠϧ͕௨Ε͹ɺ͍͍ͩͨҙਤ௨Γʹਖ਼͘͠ಈ͍͍ͯΔɻݴޠઃ ܭ͕लҳͳͷͩͱࢥ͏ • ܕ·ΘΓ͕ॊೈͳͷͰɺಈతܕ෇͚ͷݴޠ͔ΒͰ΋ۤ࿑͠ͳ͍ • "5PVSPG(PΛҰ௨Γऴ͑Ε͹ɺ044ͷιʔείʔυ΋ಡΊΔ • ιʔε͕௕͍ɾɾɾ

    • จࣈྻૢ࡞͸େมɾɾɾ  
  29.   ࢖͍ͬͯΔϥΠϒϥϦ

  30. 8"'ʢϑϨʔϜϫʔΫʣ ˒(PͷϑϨʔϜϫʔΫΛίϯηϓτ͔Βେࡶ೺ʹ̎ͭʹେผ͢Δͱɾɾ ϑϧελοΫɾ.7$WTϛχϚϧɾߴ଎   ˒ͳͥͳΒɾɾ w యܕతͳ8FCγεςϜͷͨΊɺϑϧελοΫϑϨʔϜϫʔΫͷԸܙʹ͔͋ͣΓ͍ͨ w ӡ༻؅ཧγεςϜ͕ߴ଎ʹಈ࡞͢Δඞཁੑ͸͏͍͢

    ݕ౼ͨ͠ϑϨʔϜϫʔΫ #FFHP ˕ 3FWFM ͻͱͱ͓Γͷػೳ͸ͦΖ͍ͬͯΔ͕ɺ΍΍ఀ଺ؾຯ *SJT ϓϩδΣΫτͷӡӦ໘Ͱ໰୊Λ๊͍͑ͯΔΑ͏ ࠓճ͸ͬͪ͜ʂ
  31. #FFHPʹ͍ͭͯ   • ϑϧελοΫͷ.7$ϑϨʔϜϫʔΫ • தࠃͰਓؾ͕͋ΓɺΤϯλʔϓϥΠζͰͷ࣮੷΋๛෋ʢςϯηϯτɾϑΝʔ΢ΣΠɾɾɾʣ • 8FC։ൃ޲͚ͷػೳ͸Ұ௨ΓͦΖ͍ͬͯΔ •

    ֤ػೳ͸ϞδϡʔϧԽ͞Ε͓ͯΓɺ޷͖ͳϥΠϒϥϦʹೖΕସ͑ΒΕΔ • ηογϣϯɾΩϟογϡɾϩΨʔɾJOɺɺɺ03.·Ͱ͍͍ͭͯΔ • ϑϧελοΫϑϨʔϜϫʔΫͷΘΓʹ͸ɺϕϯνϚʔΫ଎౓΋ͦͦ͜͜଎͍ • 3BJMTಉ༷ʹɺCFFͱ͍͏$-*πʔϧ͕͋Δ • ίʔυࣗಈੜ੒ʢTDBGGPMEJOHʣ΋Ͱ͖Δ
  32. ϥΠϒϥϦ঺հ   03. (03. কདྷͷ3BJMT͔ΒͷϦϓϨΠεͷͨΊɺ"DUJWF3FDPSEʹ ࣅͨػೳ͕΄͍͠ ϩΨʔ MPHSVT #FFHPͷMPHTϞδϡʔϧ΋༻ҙ͞Ε͍ͯΔ͕ɺMPHSVTΛ

    ࢖༻͍ͯ͠Δ ؀ڥઃఆ $POpHPS ؀ڥ͝ͱʹઃఆϑΝΠϧΛ࡞੒Ͱ͖Δ ύοέʔδ؅ཧ HMJEFˠ (P.PEVMFT HMJEFΛ࢖͍͕ͬͯͨɺ(P.PEVMFTͷಋೖޙʹҠߦ ߦ਺औಘ XIFSFBNJ ࣮ߦதͷιʔείʔυͷߦ਺ΛऔಘͰ͖ΔɻΤϥʔ௨஌ ࣌ʹ࢖༻
  33. ϥΠϒϥϦ঺հ   ߏ଄ମͷൺֱ HPDNQ ߏ଄ମͳͲͷҰகΛྑ͍ײ͡ʹൺֱͯ͘͠ΕΔ *%ੜ੒ YJE ϢχʔΫ*%Λੜ੒͢ΔɻΞηοτͷμΠδΣετ෇༩ ͳͲͰ࢖༻

    1%'ੜ੒ HPQEG ೔ຊޠ΋͖Ε͍ʹ1%'ग़ྗͯ͘͠ΕΔɺ͋Γ͕͍ͨϥ ΠϒϥϦ ը૾ੜ੒ HH ޷͖ͳϑΥϯτΛϩʔυͯ͠ςΩετΛը૾ԽͰ͖Δ όʔίʔυੜ੒ #BSDPEF 23ίʔυͷ࡞੒ʹ࢖༻
  34.   ࣮૷ʹ͍ͭͯ

  35.   #FFHPΛ࢖ͬͯ ࣮૷͍͖ͯ͠·͢

  36. ࣮૷ʢ$POUSPMMFSʣ ˒ϕʔεͷίϯτϩʔϥߏ଄ମΛఆٛ͢Δ • ϨεϙϯεͷϑΥʔϚοτʢ)5.-+40/ʣͰɺߏ଄ମΛ෼͚Δ   // controllers/html/base.go type HTMLController

    struct { beego.Controller accesslog *logger.AccessLog } // controllers/api/base.go type APIController struct { beego.Controller accesslog *logger.AccessLog }
  37. ࣮૷ʢ$POUSPMMFSʣ ˒ϧʔςΟϯάΛఆٛ͢Δ   // routers.go // ϩάΠϯ༻ΤϯυϙΠϯτ beego.Router("/login", &opshtml.HTMLController{},

    "get:LoginIndex") beego.Router("/api/login", &opsapi.APIController{}, "post:LoginIndex")
  38. ࣮૷ʢ$POUSPMMFSʣ ˒ίϯτϩʔϥڞ௨ॲཧΛ࣮૷͢Δ • 1SFQBSF Ͱίϯτϩʔϥͷલॲཧɺ'JOJTI Ͱίϯτϩʔϥͷޙॲཧ͕ॻ͚Δʢ3BJMT ͷCFGPSF@BDUJPOɾBGUFS@BDUJPOͷΑ͏ͳ΋ͷʣ   //

    controllers/api/base.go func (c *APIController) Prepare() { // ΫοΩʔೝূ΍ݖݶνΣοΫͳͲ } func (c *APIController) Finish() { // ϩάͷॻ͖ग़͠ͳͲ }
  39. ࣮૷ʢ$POUSPMMFSʣ ˒ίϯτϩʔϥݸผॲཧΛ࣮૷͢Δ   // controllers/api/login.go func (c *APIController) LoginIndex()

    { // ϩάΠϯॲཧΛͯ͠ɺJSONΛฦ͢ c.ServeJSON() } // controllers/html/login.go func (c *HTMLController) LoginIndex() { // ϩάΠϯϖʔδͷϏϡʔΛฦ͢ c.TplName = "ops/login/index.tpl" }
  40. ࣮૷ʢ.PEFMʣ ˒%#εΩʔϚʹରԠ͢Δߏ଄ମΛఆٛ͢Δ   // models/car_schema.go type Car struct {

    ID int `gorm:"column:id;primary_key" json:"id" csv:"id" chart:"display:ID;sortable:true;filterable:true;type:number;formable:f alse;listable:true"` Name *string `gorm:"column:name" json:"name" csv:"name" chart:"display:ं྆ ໊;sortable:true;filterable:true;type:text;formable:true;listable:true "` // ...... }
  41. ࣮૷ʢ.PEFMʣ ˒Ϩίʔυͷݕࡧ݁ՌΛ֨ೲ͢Δߏ଄ମΛఆٛ͢Δ   // models/car_schema.go type Cars struct {

    Cars []Car `json:"data"` CountTotal int `json:"recordsTotal"` // ...... }
  42. ࣮૷ʢ.PEFMʣ ˒ϞσϧϩδοΫΛ࣮૷͢Δ • ϝιου໊͸ɺ"DUJWF3FDPSEͷϝιου໊Λҙࣝ͢Δ • (03.ͷϑοΫʢ#FGPSF$SFBUFɾ"GUFS$SFBUFʣ͕࢖͑Δ   // models/car.go

    func (car *Car) FindBy() error { // ̍݅औಘ } func (cars *Cars) Where() error { // ෳ਺݅औಘ } func (car *Car) Update() error { // ̍݅ߋ৽ } func (cars *Cars) UpdateAll() error { // ෳ਺݅ߋ৽ }
  43. ࣮૷ʢ7JFXʣ ˒ϏϡʔςϯϓϨʔτΛ࣮૷͢Δ • HPͷςϯϓϨʔτύοέʔδΛ࢖͏ • +40/͸ϏϡʔΛ࢖ΘͣʹɺϞσϧͷߏ଄ମͰϨεϙϯεΛఆٛ͢Δ   {{/* views/login/index.tpl

    */}} <div> <img src="{{ .baseURL }}/logo.png" width="100" height="100"> </div>
  44.   // main.go beego.Run()

  45.   ࣮૷্ͷ޻෉

  46. εΩʔϚߏ଄ମ ˒ςʔϒϧ͝ͱʹɺ%#ͷεΩʔϚఆٛΛ൓өͨ͠εΩʔϚߏ଄ମΛͭ͘Δ ˒ܕͱWBMJEBUFλάͰεΩʔϚΛදݱ͢Δ w (03.ͷ࢓্༷ɺ/6--ڐՄͷΧϥϜ͸ϙΠϯλܕʹ͢Δඞཁ͕͋Δ   type TableExample struct

    { // int unsigned (NOT NULL) DeviceID int `validate:"min=0"` // int unsigned (NOT NULL DEFAULT 0) UserCertBy *int `validate:"min=0"` // int unsigned UserID *int // varchar (NOT NULL) Result string `validate:"required"` // varchar Name *string }
  47. εΩʔϚߏ଄ମ ˒ΫϥΠΞϯταΠυͰͷڍಈΛߏ଄ମͷλάʹఆٛ͢Δ • +BWB4DSJQUʹλάͷ಺༰Λ+40/Ͱฦ٫͢Δ • ʢྫʣ͋ΔΧϥϜʹରͯ͠ɺιʔτػೳΛ༗ޮʹ͢Δ͔Ͳ͏͔ • ʢྫʣ͋ΔΧϥϜΛɺ$47ͷग़ྗର৅ʹ͢Δ͔Ͳ͏͔  

    type TableExample struct { Name *string `gorm:"column:name" json:"name" csv:"name" chart:”display:Name;sortable:true;filterable:true;type:text;formab le:true;listable:true"` UpdatedByUserName string `gorm:"-" json:"updated_by_user_name" csv:"-" chart:"display:ߋ৽ ऀ;sortable:false;filterable:false;type:text;formable:false"` }
  48. ࣮૷ͷڞ௨Խ ˒ଟ਺ͷςʔϒϧʹରͯ͠ɺڞ௨ͷػೳΛ࣮૷͍ͨ͠ • ʢྫʣDBSTʹର͢Δ$SFBUFͷϩδοΫͱɺVTFSTʹର͢Δ$SFBUFͷϩδοΫ͸ಉ͡ ˒͔͠͠໰୊͕ɾɾ • ςʔϒϧ਺͕ଟ͍ͷͰɺಉ͡ϩδοΫ͸࣮૷Λڞ௨Խ͍ͨ͠ • (PʹδΣωϦΫε͕ͳ͍ʢ˞࣮૷࣌࣌఺ʣͷͰɺڞ௨ϝιουΛͭ͘Δ͜ͱ͸೉͍͠ •

    ·ͨڞ௨ϝιουʹͯ͠͠·͏ͱɺ࢓༷ͷॊೈੑ͕ࣦΘΕΔ ‑ ϞσϧɾίϯτϩʔϥɾϏϡʔͷ਽ܗΛࣗಈੜ੒Ͱ͖ΔΑ͏ʹ͢ΔʢಠࣗͷTDBGGPMEJOHػೳʣ  
  49.   ͱ͸͍͑ɺଞͷαʔϏε͸ 3BJMTͰಈ͍͍ͯΔɾɾ

  50. 3BJMTαʔϏεͱͷซଘ ˒%#·ΘΓͷఆٛͷڞ௨Խ • (PͷαʔϏεͱ3BJMTͷαʔϏε͕ಉ͡%#Λࢀর͍ͯ͠Δ৔߹͸ɺ%#·ΘΓͷఆٛͷ ߋ৽ࠩ෼͕όάͷԹচʹͳΔ • Ͱ͖Δ͚ͩೋॏ؅ཧΛආ͚ΔΑ͏ʹ޻෉͢Δ   ڞ௨ԽͷҰྫ

    %#εΩʔϚఆٛ 3VCZ SJEHFQPMF ͰҰݩ؅ཧ εΩʔϚߏ଄ମ %#εΩʔϚ͔ΒεΩʔϚߏ଄ମΛࣗಈੜ੒ɻ·ͨɺ%#εΩʔ Ϛͱͷࠩ෼͕ൃੜ͍ͯ͠ͳ͍͔ΛνΣοΫ͢ΔπʔϧΛ༻ҙ FOVNఆٛ ZBNMʹFOVN஋ͷఆٛΛॻ͖ग़͠ɺ྆γεςϜ͔ΒಡΈࠐΉ
  51. 3BJMTαʔϏεͱͷซଘ ˒҉߸Խ·ΘΓͷڞ௨Խ • ҰํͷαʔϏεͰ҉߸Խͨ͠஋Λ΋͏ҰํͷαʔϏεͰ΋ࢀর͍ͨ͠৔߹ɺ҉߸Խํࣜ ΍伴Λ߹ΘͤΔඞཁ͕͋Δ • ʢྫʣγϯάϧαΠϯΦϯ • ෳ਺ͷαʔϏεͰɺಉ͡Ϣʔβʔ໊ɾύεϫʔυͰϩάΠϯ͍ͨ͠ •

    3VCZͷ%FWJTF͸ɺϢʔβʔύεϫʔυͷ҉߸Խʹ#$SZQUΛ࢖༻͢Δ • (PଆͰ΋#$SZQU·ΘΓͷॲཧΛ࣮૷͢Δඞཁ͕͋Δ • 伴ͷ؅ཧ͕໘౗ʹͳΔ • 伴ͷߋ৽λΠϛϯάΛͦΖ͑ΔͳͲͷ޻෉ • Ϋϥ΢υαʔϏεΛ࢖͏ͱָʢ"844FDSFUT.BOBHFSͳͲʣ  
  52. 3BJMTαʔϏεͱͷซଘ ˒ϢʔςΟϦςΟػೳͷڞ௨Խ • ൚༻తͳϢʔςΟϦςΟΛͲͪΒଆͷαʔϏεʹ࣮૷͢Δ͔ʁ • ϝʔϧૹ৴ɾ௨஌γεςϜɾ֎෦"1*࿈ܞɾɾɾ • ͲͪΒ͔ҰํʹدͤΔʁ • αʔϏεؒͷ௨৴͕ൃੜ͢Δʢ3&45"1*PSH31$ʁʣ

    • υΩϡϝϯτ੔උͷඞཁੑ্͕͕Δ • ྆αʔϏεͰ࣮૷͢Δʁ • ࣮૷ίετ͕๲ΒΉ • ߋ৽ࠩ෼͕όάͷԹচʹͳΔ  
  53.   ͜Ε͔Β΋(PΛ ͕Μ͕Μ࢖͍͖ͬͯ·͢