自社サービスのDjangoを 1.3から1.11(LTS)に アップグレードするまでの道のり

自社サービスのDjangoを 1.3から1.11(LTS)に アップグレードするまでの道のり

DjangoCongress JP 2019
https://djangocongress.jp/

A12373843afc54857a845404bdd5f5cb?s=128

Toshikazu Ohashi

May 18, 2019
Tweet

Transcript

  1. ࣗࣾαʔϏεͷ%KBOHPΛ ͔Β -54 ʹ ΞοϓάϨʔυ͢Δ·ͰͷಓͷΓ %KBOHP$POHSFTT+1 1

  2. MJHIUUJHFS w େڮฏ࿨ w ࡾे࿏ ੜ 2

  3. w αʔόαΠυΤϯδχΞ ݉εΫϥϜϚελʔ  w 8FC"1*αʔό 8SJUUFOJO1ZUIPO✕%KBOHP  w ϓογϡ഑৴γεςϜ

    8SJUUFOJO(P 3
  4. ϓϥΠϕʔτ w $-*ίϚϯυ w MBC (JU-BCΫϥΠΞϯτ  w 7JNϓϥάΠϯ w

    EFPQMFUFWJNMTQ -41ࣗಈิ׬ 4
  5. ΠϯτϩμΫγϣϯ 5

  6. J3JEHFͷఏڙ͢Δ164)഑৴ϓϥοτϑΥʔϜ 6

  7. QPQJOGPͱ͸ 7 اۀ Ϣʔβ اۀͱϢʔβͷίϛϡχέʔγϣϯ

  8. QPQJOGPͱ͸ 8 اۀ Ϣʔβ اۀͱϢʔβͷίϛϡχέʔγϣϯ

  9. QPQJOGPͷ ߏ੒ʹ͍ͭͯ 9

  10. 10 ؅ཧը໘ ؅ཧAPI Τϯυ ϢʔβAPI ഑৴ γεςϜ Πϕϯτ ऩूAPI όονॲཧ

    Ϣʔβ ϓογϡ഑৴ऀ Ϣʔβ
  11. 11 ؅ཧը໘ ؅ཧAPI Τϯυ ϢʔβAPI ഑৴ γεςϜ Πϕϯτ ऩूAPI όονॲཧ

    Ϣʔβ ϓογϡ഑৴ऀ Ϣʔβ
  12. 12 ELB NAT GW MYSQL Aurora EC2 EC2 ΠϕϯτऩूAPI EC2

    ΤϯυϢʔβAPI ؅ཧAPI EC2 όονॲཧ ؅ཧը໘ ഑৴γεςϜ ELB ELB
  13. 13 EC2 EC2 ΠϕϯτऩूAPI EC2 ΤϯυϢʔβAPI ؅ཧAPI EC2 όονॲཧ ୯ҰͷϦϙδτϦͰ؅ཧ͞Εͨ

    ϞϊϦγοΫͳΞϓϦέʔγϣϯ EC2
  14. όʔδϣϯ৘ใ 14 Python/Django όʔδϣϯ ϦϦʔε೔ Python 2.7.6 2013/10/11 Django 1.3.7

    2013/02/20
  15. ໨ࢦ͢͸ 15 Python/Django όʔδϣϯ ϦϦʔε೔ Python 2.7.15 2018/04/01 Django 1.11.18

    2019/01/04
  16. ͷ ։͔࢝Βϲ݄ؒ 16

  17.  %KBOHPରԠ൛ ϦϦʔε׬ྃ 17

  18. ຊ೔ͷλʔήοτΰʔϧ w λʔήοτ w ݹ͍%KBOHPΛ࢖ͬͯࠔ͍ͬͯΔਓ w ۤ࿑࿩͕ฉ͖͍ͨਓ w ΰʔϧ w

    ࣮ྫΛ౿·͑ͯͷ࣍ͷ̎఺Λ఻͑Δ w ΞοϓάϨʔυதʹ৺͕͚ͯΑ͔ͬͨ͜ͱ w ΞοϓάϨʔυதʹ৺͕͚Δ΂͖ͩͬͨ͜ͱ 18
  19. ࿩͞ͳ͍͜ͱ w %KBOHP03.ʹΑΔϚΠάϨʔγϣϯͱͷઓ͍ w %#ͷ%KBOHPͷϚΠάϨʔγϣϯ؅ཧΛ͍ͯ͠ͳ͍ w खಈΫΤϦʹΑΔ؅ཧ 19

  20. ΞδΣϯμ  ͳͥΞοϓάϨʔυ͕ඞཁ͔ߟ͑Δ  ΰʔϧʹ͍͖ͳΓ޲͔Θͳ͍  ඞཁͳ΋ͷ͚ͩΛΞοϓάϨʔυ͢Δ  αΠΫϧΛߴ଎Խ͢Δ 

    %KBOHPͷΞοϓάϨʔυ಺༰Λཧղ͢Δ  पΓͷϓϩϑΣογϣφϧΛཔΔ  ΞοϓάϨʔυ͸ऴΘΓͰ͸ͳ͍ 20
  21. ͳͥΞοϓάϨʔυ͕ ඞཁ͔ߟ͑Δ 21 1 ————— 7

  22. ΞοϓάϨʔυ͠ͳͯ͘΋ w γεςϜ͸Կͷ໰୊΋ͳ͘ಈ͍͍ͯΔ w ௥Ճ͢΂͖ػೳ͸๲େʹ͋Δ w ΞοϓάϨʔυͯ͠΋ػೳ͸૿͑ͳ͍ w 71$಺ͳͷͰηΩϡϦςΟΛڧԽ͠ͳͯ͘΋ 22

  23. /P 23

  24. ද໘తʹݟ͑ͳ͍͚ͩͰ ฐ֐͸ͨ͘͞Μ͋Δ 24

  25. %KBOHPͷ ηΩϡϦςΟαϙʔτ 25

  26. ͷηΩϡϦςΟαϙʔτ͸ʁ 26 1.3

  27. ηΩϡϦςΟαϙʔτ͕ ੾Ε͔ͯΒ೥ 27 1.3 5೥

  28. ηΩϡϦςΟαϙʔτ੾Ε w ੬ऑੑ͕์ஔ͞Εͨແ๷උͳঢ়ଶ w γεςϜ͸҆શͳঢ়ଶ͕౰ͨΓલ w Կ͔͕ى͖͔ͯΒͰ͸஗͍ 28

  29. Ϟνϕʔγϣϯ΋Լ͕Δ w ةݥͳγεςϜΛҡ࣋͢Δ͜ͱʹތΓΛ࣋ͯΔ͔ w ϨΨγʔΛ৮Γଓ͚Δࣗ෼ʹະདྷ͸͋Δͷ͔ 29

  30. %KBOHP࠷৽ػೳ͕࢖͑ͳ͍ w %#઀ଓճ਺͕ଟ͗ͯ͢"1*ͷϨΠςϯγ͕ w $0//@."9@"(&Λ࢖͑͹઀ଓෛՙ͕ݮΔͧ w %KBOHP͔Βαϙʔτ 30

  31. SEύʔςΟϥΠϒϥϦ͕ ରԠ͍ͯ͠ͳ͍ 31 ϥΠϒϥϦ ରԠόʔδϣϯ django-rest-framework Django ≧ 1.11 django-debug-toolbar

    Django ≧ 1.11 django-extensions Django ≧ 1.11 django-security Django ≧ 1.8 django-import-export Django ≧ 2.0
  32. ݹ͍৘ใ͸ ͲΜͲΜ୧Εͳ͘ͳΔ w ࣌ͱͱ΋ʹͷ৘ใ͸গͳ͘ͳΔҰํ w (PPHMFͰݕࡧͯ͠΋ώοτ͢Δͷ͸৽όʔδϣϯ͹͔Γ 32

  33. %KBOHPެࣜυΩϡϝϯτʹ 33

  34. ͸ࡌ͍ͬͯͳ͍ 34

  35. ΋΋͏͢Ͱʹ 35

  36. ໨తҙࣝΛ໌֬ʹ΋ͭ w ΞοϓάϨʔυ͸γεςϜͷػೳ௥ՃʹߩݙͰ͖ͳ͍ͷͰ ͸ͳ͍ w શମʹେ͖ͳӨڹΛ༩͑Δେࣄͳ஍ݻΊΛ΍͍ͬͯΔࣗෛ Λ࣋ͭ 36

  37. ΰʔϧʹ͍͖ͳΓ ޲͔Θͳ͍ 37 1 2 ———— 7

  38. ͳΔ΂͘ϦϦʔε͢Δ 38

  39. ΰʔϧ͸ -54 39 Django 1.3.7 Django 1.11.18

  40. ೥Ҏ্ͷࡀ݄ 40 Django 1.3.7 Django 1.11.18 2013/02/20 Release 2019/01/04 Release

  41. ೥Ҏ্ͷࡀ݄ 41 Django 1.3.7 Django 1.11.18 2013/02/20 Release 2019/01/04 Release

    ϦϦʔεճ਺ ϚΠφʔόʔδϣϯΞοϓ: 8ճ ύον: 114ճ
  42. ΞοϓάϨʔυͱฒߦͰ ৽ػೳ௥Ճ΋ߦΘΕΔ 42 ৽ػೳ௥Ճ Django ΞοϓάϨʔυ ຊ൪؀ڥ ϦϦʔε ίϛοτ

  43. ϦϦʔε࣌ʹ͸৽ػೳΛ Ϛʔδ্ͨ͠Ͱ΍Δඞཁ͕͋Δ 43 ৽ػೳ௥Ճ Django ΞοϓάϨʔυ ຊ൪؀ڥ ϦϦʔε Ϛʔδ

  44. ΞοϓάϨʔυ͕௕Ҿ͚͹ औΓࠐΈྔ΋૿͑Δ 44 ৽ػೳ௥Ճ Django ΞοϓάϨʔυ ຊ൪؀ڥ ϦϦʔε Ϛʔδ

  45. தؒϦϦʔεʹΑΓ ࣮֬ͳεςοϓΛ౿Ή 45 Django 1.3.7 Django 1.11.18 Django 1.8.18

  46. ͳͥখ͞ͳεςοϓΛ౿Ήʁ w ϦϦʔεਖ਼ৗՔಇ͍ͯ͠Διʔε͸ϕʔεϥΠϯ͔ͩΒ w ϦϦʔεͨ͠Β৽ػೳ௥ՃͷϕʔεʹͳΕΔ w Ұ౓ʹ౿Ήόάͷྔ͕ݮΔ w ϦϦʔε͔ͯ͠Βൃݟͨ͠όά΋ଟ਺ w

    ݪҼௐࠪͷείʔϓ΋খ͘͞ͳΔ 46
  47. ͪΐͬͱ͚ͩ ϦϦʔε͢Δ 47

  48. ͢΂ͯΛςετ͢Δ͜ͱ͸ Ͱ͖ͳ͍ w %KBOHPͷߋ৽ػೳ͸๲େ w ͢΂ͯͷมߋ಺༰ΛνΣοΫ͢Δίετͱਓһ͸ͳ͍ w ҎԼͷςετͰόάͷ΄ͱΜͲ͸ݟ͔ͭΔ͸ͣ w طଘૢ࡞ͷϦάϨογϣϯ

    ୀߦ ςετ w %KBOHPΞοϓάϨʔυӨڹՕॴͷڧԽςετ 48
  49. ͚ͩͲݟಀ͕͠ ͋Δ͔΋ 49

  50. ΧφϦΞϦϦʔε 50 ELB EC2 1.3 EC2 1.3 EC2 1.3 EC2

    1.3
  51. %KBOHPΛҰ෦ϦϦʔε 51 ELB EC2 1.3 EC2 1.3 EC2 1.3 EC2

    1.8 EC2 1.3 νϣοτ ͓͡Ό·͠·͢
  52. ໰୊͕͋ͬͨΒ੾Γ໭͠ 52 ELB EC2 1.3 EC2 1.3 EC2 1.3 EC2

    1.3 EC2 1.8 Τϥʔ͓ͯ͜͠ ͝ΊΜͳ͍
  53. ໰୊ͳ͚Ε͹શ୆ϦϦʔε 53 ELB EC2 1.8 EC2 1.8 EC2 1.8 EC2

    1.8 EC2 1.3 EC2 1.3 EC2 1.3
  54. ΧφϦΞϦϦʔεಛ༗ͷ໰୊ w ΧφϦΞϦϦʔεΛ͢Δ͜ͱͰൃੜ͢Δ໰୊΋͋Δ w ͭͷ%KBOHPόʔδϣϯ͕ಉ࣌Քಇ͢ΔέʔεΛߟྀ 54

  55. 1SPCMFN த్൒୺ͳ %#ϚΠάϨʔγϣϯ 55

  56. ൃੜࣄ৅ w %KBOHPͷΧφϦΞϦϦʔε࣌ɺ%KBOHP؅ཧαΠτͰϢʔβ௥Ճ Ͱ͖ͳ͍ w %KBOHP؅ཧαΠτ͸$4͕Ϣʔβ؅ཧʹ࢖༻͍ͯ͠Δ 56

  57. ΧφϦΞϦϦʔε͍ͯͨ͠ 57 ELB EC2 1.3 EC2 1.3 EC2 1.3 EC2

    1.8 MYSQL
  58. %KBOHP࡞੒ςʔϒϧͷ όʔδϣϯ͕ 58 EC2 1.3 EC2 1.3 EC2 1.3 EC2

    1.8 MYSQL django.auth Table Django 1.3
  59. Ͱ͸NJHSBUF͢Ε͹ 59 EC2 1.3 EC2 1.3 EC2 1.3 EC2 1.8

    MYSQL django.auth Table Django 1.8
  60. Ͳ͏͠Α͏ w ΧφϦΞϦϦʔε͸਺೔ؒߦΘΕΔ w $4νʔϜͷ࡞ۀʹࢧো͕ग़Δ w %KBOHPͱͷ྆ํͰૢ࡞Ͱ͖Δঢ়ଶ͕๬·͍͠ 60

  61. %KBOHPͱͷ ྆ํͰಈ͘όʔδϣϯΛ୳͢ 61

  62. ϚΠάϨʔγϣϯ಺༰Λௐࠪ 62 auth [ ] 0001_initial [ ] 0002_alter_permission_name_max_length [

    ] 0003_alter_user_email_max_length [ ] 0004_alter_user_username_opts [ ] 0005_alter_user_last_login_null [ ] 0006_require_contenttypes_0002 $ python manage.py showmigrations
  63. ൃߦ42-Λௐࠪ͢Δ 63 BEGIN; CREATE TABLE `auth_permission` ( `id` integer AUTO_INCREMENT

    NOT NULL PRIMARY KEY, `name` varchar(50) NOT NULL, `content_type_id` integer NOT NULL, `codename` varchar(100) NOT NULL, UNIQUE (`content_type_id`, `codename`) ); ... $ python manage.py sqlmigrate auth 0001_initial
  64. ͪΐ͏Ͳ͍͍ͱ͜·Ͱ ϚΠάϨʔγϣϯ 64 auth [X] 0001_initial [X] 0002_alter_permission_name_max_length [X] 0003_alter_user_email_max_length

    [X] 0004_alter_user_username_opts [X] 0005_alter_user_last_login_null [ ] 0006_require_contenttypes_0002 $ python manage.py migrate auth 0001_initial --fake $ python manage.py migrate auth 0005_alter_user_last_login_null $ python manage.py showmigrations
  65. ࢒ͬͨ෦෼͸ શ෦ϦϦʔε͔ͯ͠Β 65 auth [X] 0001_initial [X] 0002_alter_permission_name_max_length [X] 0003_alter_user_email_max_length

    [X] 0004_alter_user_username_opts [X] 0005_alter_user_last_login_null [ ] 0006_require_contenttypes_0002
  66. ͳͥΧφϦΞϦϦʔε w ςετͯ͠΋ຊ൪τϥϑΟοΫ͸ྲྀΕͳ͍ w ࣮ࡍΧφϦΞϦϦʔεͰ͔͠Έ͚ͭΒΕͳ͔ͬͨ΋ ͷ΋͋Δ 66

  67. ϦϦʔεશମܭը 67 Django 1.3.7 Django 1.11.18 Django 1.8.18 ΧφϦΞ ϦϦʔε

    શମ ϦϦʔε ΧφϦΞ ϦϦʔε શମ ϦϦʔε
  68. ඞཁͳ΋ͷ͚ͩΛ ΞοϓάϨʔυ͢Δ 68 1 — 3 ——— 7

  69. τʔλϧίετΛҙࣝ͢Δ 69 ιʔεमਖ਼ Unit Test मਖ਼ खಈςετ/ը໘ςετ ϦϦʔεޙͷόάൃੜ؂ࢹ ͱʹ͔͘DjangoͷΞοϓάϨʔυΛૣ͘΍Γ͍ͨ Ͱ΋ͦͷमਖ਼ɺຊ౰ʹඞཁʁ

  70. τʔλϧίετΛҙࣝ͢Δ 70 ιʔεमਖ਼ Unit Test मਖ਼ खಈςετ/ը໘ςετ ϦϦʔεޙͷόάൃੜ؂ࢹ ιʔεΛमਖ਼͢Δ=मਖ਼͕ਖ਼͍͔͠ςετ͢Δ

  71. τʔλϧίετΛҙࣝ͢Δ 71 ιʔεमਖ਼ Unit Test मਖ਼ खಈςετ/ը໘ςετ ϦϦʔεޙͷόάൃੜ؂ࢹ ΋͠मਖ਼͢΂͖ιʔε͕ݮΔͷͰ͋Ε͹ʁ ࡟ݮ

  72. τʔλϧίετΛҙࣝ͢Δ 72 ιʔεमਖ਼ Unit Test मਖ਼ खಈςετ/ը໘ςετ ϦϦʔεޙͷόάൃੜ؂ࢹ ͢΂ͯͷ޻ఔʹ͓͍ͯͦͷίετ͸Լ͕Δ ࡟ݮ

    ࡟ݮ ࡟ݮ ࡟ݮ
  73. मਖ਼ର৅֎ͱͳΔ ༨෼ͳॲཧΛௐࠪ 73

  74. ༨෼ͳॲཧ͸͋ͬͨ w چόʔδϣϯ"1* w ͓Αͼچ"1*Ͱ࡞੒͞ΕͨσʔλΛࢀর͢Δόον w چ؅ཧը໘ 74

  75. 75 ELB NAT GW MYSQL Aurora EC2 EC2 EC2 ΤϯυϢʔβAPI

    ؅ཧAPI EC2 όονॲཧ ؅ཧը໘ ഑৴γεςϜ ELB ELB
  76. ؅ཧ"1*ʹ͸ چόʔδϣϯ͕͋ͬͨ 76 MYSQL ؅ཧAPI چόʔδϣϯ API &؅ཧը໘ چόʔδϣϯ σʔλ

    ݱόʔδϣϯ API ݱόʔδϣϯ σʔλ چ഑৴ γεςϜ ৽഑৴ γεςϜ چVerސ٬ ݱVerސ٬
  77. ݶΒΕͨҰ෦ͷސ٬ͷΈ͕ ࢖༻͍ͯͨ͠ 77 MYSQL ؅ཧAPI چόʔδϣϯ API &؅ཧը໘ چόʔδϣϯ σʔλ

    ݱόʔδϣϯ API ݱόʔδϣϯ σʔλ چ഑৴ γεςϜ ৽഑৴ γεςϜ چVerސ٬ ݱVerސ٬
  78. σʔλޓ׵ੑ͕ͳ͘ چόʔδϣϯͷͨΊʹಈ͘ػೳ͕͋ͬͨ 78 MYSQL ؅ཧAPI چόʔδϣϯ API &؅ཧը໘ چόʔδϣϯ σʔλ

    چ഑৴ γεςϜ چVerސ٬ چόον όονॲཧ ৽όον
  79. ࡟ݮͰ͖Ε͹ʁ 79 APIϦιʔε਺ όονॲཧ਺ ݱঢ় 177 28 چόʔδϣϯ ࡟আޙ 59

    5 ࠩ෼ -118 -23 ࡟আޙͷൺ཰ 33.33% 17.85%
  80. چόʔδϣϯΛ ফ͢ஈऔΓ 80

  81. چόʔδϣϯΛফ͢ w چόʔδϣϯʹ͸গ਺ͳ͕Β࢖༻ސ٬͕͍Δ w ސ٬ʹ৽όʔδϣϯʹҠߦͯ͠΋Β͏ w Ӧۀ1.ͱ࿈ܞͯ͠ސ٬ʹΞϓϩʔν͢Δ 81

  82. چόʔδϣϯ ҡ࣋ίετͷࢼࢉ w چόʔδϣϯΛҡ࣋͢ΔίετΛ࡟ݮ͢ΔͱͲΕ͚͓ͩಘ ͔Λ਺ࣈʹͨ͠ w ηΩϡϦςΟΞοϓσʔτΛ౰ͯଓ͚Δίετ w ػೳ௥ՃʹΑΔچόʔδϣϯ΁ͷӨڹௐࠪճؼςετ w

    چόʔδϣϯΛՔಇͤ͞Δαʔόͷίετ 82
  83. ҎԼͷύλʔϯΛൺֱ w چόʔδϣϯΛҡ࣋͠ଓ͚ͨ৔߹ w Ұ࣌తʹίετΛ͔͚ͯ৽όʔδϣϯʹҠߦͨ͠৔߹ 83

  84. ࢼࢉ׬ྃ 84

  85. ࢼࢉ׬ྃ 85 چόʔδϣϯ࡟আίετ͸೥݄·ͰʹϖΠͰ͖Δ

  86. 86

  87. આ໌ձͷ։࠵ w આ໌ࢿྉΛ࡞੒ͯ͠શࣾͷ1.ɺӦۀʹઆ໌ w چ"1*ɺ؅ཧը໘ͷ৽όʔδϣϯͱͷੑೳࠩϝϦσϝ w چόʔδϣϯ࢖༻ऀ΁ͷӨڹͱ50%0ͷઆ໌ 87

  88. ސ٬આ໌ w Ӧۀɺ1.αΠυ͔Βݸผʹސ٬ʹઆ໌ w ৔߹ʹΑͬͯ͸ࣗ෼΋ಉߦ w ӦۀϑΟʔυόοΫʹΑΓݸผରԠ͕ඞཁͳސ٬Λબఆ 88

  89. چόʔδϣϯഇࢭ͸  ʹܾఆ 89

  90. ͙͢ʹফͤΔΘ͚Ͱ͸ͳ͍ w ফ͢͜ͱ͕ܾ·ͬͯ΋ഇࢭ೔·Ͱސ٬͸࢖༻͢Δ w چ"1*ɺ؅ཧը໘͸ίʔυ͔Βফͤͳ͍ w ফͤͳͯ͘͸݁ہमਖ਼ίετΛ෷͏ 90

  91. چόʔδϣϯ ઐ༻αʔόͷߏங 91

  92. ݱঢ়ͷϦϙδτϦ͔Β چόʔδϣϯ༻ΛϑΥʔΫ 92 ݱόʔδϣϯͷϦϙδτϦ (ࠓޙͷϝϯςର৅) چόʔδϣϯ༻ϦϙδτϦ

  93. ຊྲྀϦϙδτϦ͔Β چόʔδϣϯ༻ίʔυΛ࡟আ 93 ݱόʔδϣϯͷϦϙδτϦ (ࠓޙͷϝϯςର৅) چόʔδϣϯ༻ϦϙδτϦ ৽ چ ৽ چ

  94. چόʔδϣϯ༻ ؅ཧ"1*αʔόΛߏங 94 EC2 چόʔδϣϯ༻؅ཧAPI EC2 ؅ཧAPI ݱঢ়ͷϦϙδτϦ (ࠓޙͷϝϯςର৅) چόʔδϣϯ༻ϦϙδτϦ

    ݱόʔδϣϯϦΫΤετ چόʔδϣϯϦΫΤετ
  95. چόʔδϣϯ༻ ؅ཧ"1*αʔόΛߏங 95 EC2 چόʔδϣϯ༻؅ཧAPI EC2 ؅ཧAPI ݱঢ়ͷϦϙδτϦ (ࠓޙͷϝϯςର৅) چόʔδϣϯ༻ϦϙδτϦ

    ݱόʔδϣϯϦΫΤετ چόʔδϣϯϦΫΤετ چόʔδϣϯϦΫΤετ
  96. چόʔδϣϯͷִ཭͸׬ྃ w چόʔδϣϯͷϦΫΤετ͸͢΂ͯઐ༻αʔόͰॲཧ w ϦϙδτϦ͔ΒچόʔδϣϯΛফͯ͠΋ϦΫΤετ͞Ε ͳ͍ w چόʔδϣϯͰ໰୊ൃੜͨ͠Βॏʹमਖ਼͢Δඞཁ w ϦεΫ͸ವΉ

    96
  97. ࡟ݮͷ݁Ռ 97 Files Lines Code Comments Blanks ࡟ݮલ 431 71835

    57995 3798 10042 ࡟ݮޙ 293 50226 40782 2456 6988 ࠩ෼ -138 -21609 -17213 -1342 -3054 ࡟ݮޙͷൺ཰ 67.98% 69.92% 70.32% 64.67% 69.59% Pythonίʔυྔ͕70%ఔ౓·Ͱ཈͑ΒΕͨ
  98. αΠΫϧΛߴ଎Խ͢Δ 98 1 —— 4 —— 7

  99. Ϣχοτςετ w %KBOHPΞοϓάϨʔυͱϢχοτςετ͸੾ͬͯ΋੾Ε ͳ͍ؔ܎ੑ w मਖ਼ɺϢχοτςετΛԿ౓Ͱ΋܁Γฦ͢ 99

  100. Ϣχοτςετ͕஗͔ͬͨ w Ϣχοτςετॴཁ࣌ؒd෼ w Ҏલ͸࣌ؒd࣌ؒͩͬͨ w Ϣχοτςετͷ஗͞͸࡞ۀͷ஗͞ʹ௚݁͢Δ 100

  101. Ϣχοτςετͷ࣮ߦ؀ڥ w ηϧϑϗεςΟϯά͞Εͨ(JU-BCϦϙδτϦʹ164)͢ Δͱ(JU-BC3VOOFS͕$*࣮ߦ w QPQJOGPઐ༻3VOOFSͱͯ͠αʔό୆Λ༻ҙ 101 Push Run Unit

    Test
  102. ۚͷ஄ؙͰղܾ w ϢχοτςετΛ࣏͢ख΋͕͓͋ͬͨۚͰղܾͨ͠ w ൚༻Πϯελϯε UTNBMM ͔Β$16࠷దԽΠϯελϯε DMBSHF ʹมߋ w

    Ϣχοτςετॴཁ࣌ؒ෼·Ͱ࡟ݮ 102 Scale Up
  103. "1*ςετͷ࡞੒ w ࠓճ͸1PTUNBOΛ࠾༻ w Ұ୴ਖ਼ৗέʔεͷΈΛ໢ཏతʹγφϦΦͱͯ͠هࡌ w $*ʹ૊ΈࠐΈ 103

  104. merge push ։ൃϓϩηε͸੔ͬͨ 104 Python unittest EC2

  105. %KBOHPͷ ΞοϓάϨʔυ಺༰Λ ཧղ͢Δ 105 1 ——— 5 — 7

  106. ͪͳΈʹࢲ͸શવཧղ ͍ͯ͠ͳ͔ͬͨ 106

  107. ԿΑΓઌʹެࣜΛ֬ೝ 107 Upgrading Django to a newer version

  108. ΞοϓάϨʔυͷ มߋ఺Λௐ΂Δ w ެࣜʹ͸֤%KBOHPόʔδϣϯͷ࠷ऴϦϦʔεϊʔτΛಡ Ίͱॻ͍ͯ͋Δ w %KBOHPͷ3FMFBTF/PUF͸ඇৗʹ༏ल w ֤όʔδϣϯΞοϓͷ಺༰Λաෆ଍ͳ͘໢ཏͰ͖Δ 108

    > Read the release notes for each ‘final’ release from the one after your current Django version, up to and including the version to which you plan to upgrade.
  109. ಛʹؾΛ͚͍ͭͨ w ഇࢭ͞Εͨ΋ͷ͸मਖ਼͢ΔͷͰ஫ҙ͕޲͘ w σϑΥϧτڍಈͷมߋ͸࣮ࡍʹಈ͔͢·Ͱؾ͔ͮͳ͍͜ ͱ΋ w طଘϝιου΁ͷ௥ՃΦϓγϣϯ w EKBOHPTFUUJOHT΁ͷઃఆ஋௥Ճ

    109
  110. ௐ΂͍ͯͳ͍ͱ ͜͏ͳΓ·͢ 110

  111. 1SPCMFN *OTFSU࣌ σουϩοΫ͢ΔΫΤϦ 111

  112. .PEFMTBWF ͷ ΞϧΰϦζϜมߋ w ಛఆϞσϧͷTBWF Λ࣮ߦ͢Δͱ6QEBUFͱ*OTFSU͕࣮ߦ ͞ΕΔΑ͏ʹͳͬͨ w ओΩʔ QSJNBSZ@LFZΦϓγϣϯ͕5SVFͷ*OUFHFS'JFME

    Λ ΋ͭϞσϧ 112 1.6/Model.save() algorithm changed hoge_id = models.IntegerField(primary_key=True)
  113. ໰୊ൃੜ࣌ظ 113 Django 1.3.7 Django 1.11.18 Django 1.8.18 ΧφϦΞ ϦϦʔε

    શମ ϦϦʔε ΧφϦΞ ϦϦʔε શମ ϦϦʔε
  114. ໰୊ൃੜ w Ͱ͸ൃੜ͠ͳ͍σουϩοΫ͕Ͱ͸ൃੜ͢Δ 114 OperationalError: (1213, 'Deadlock found when trying

    to get lock; try restarting transaction') w %#ͷΞΠιϨʔγϣϯϨϕϧ͕3&1&"5"#-&3&"%ͩ ͱ
  115. ൃੜͤ͞Δํ๏ w ৽نϨίʔυ௥Ճ͢ΔॲཧΛ୹࣌ؒʹ࿈ଓ࣮ߦ w ҰͭͷτϥϯβΫγϣϯ͕׬ྃ͠ͳ͍͏ͪʹ࣍ͷτ ϥϯβΫγϣϯ͕͸͡·Δ͘Β͍ʹ͸ 115

  116. .PEFMTBWF ࣮ߦ 116 Model.save() Model.save()

  117. ࣮ࡍʹൃߦ͞Ε͍ͯΔΫΤϦ 117 BEGIN UPDATE `hoge` SET `foo` = 3, `bar`

    = 2310, WHERE `hoge_id` = 85524878 INSERT INTO `hoge` (`foo`, `bar`) VALUES (85524878, 3, 2310, 914) BEGIN UPDATE `hoge` SET `foo` = 3, `bar` = 2310, WHERE `hoge_id` = 85524879 INSERT INTO `hoge` (`foo`, `bar`) VALUES (85524879, 3, 2310, 914) SessionA SessionB DeadLock DeadLock
  118. ࣮ࡍʹൃߦ͞Ε͍ͯΔΫΤϦ 118 BEGIN UPDATE `hoge` SET `foo` = 3, `bar`

    = 2310, WHERE `hoge_id` = 85524878 INSERT INTO `hoge` (`foo`, `bar`) VALUES (85524878, 3, 2310, 914) BEGIN UPDATE `hoge` SET `foo` = 3, `bar` = 2310, WHERE `hoge_id` = 85524879 INSERT INTO `hoge` (`foo`, `bar`) VALUES (85524879, 3, 2310, 914) SessionA SessionB DeadLock DeadLock ৄ͘͠͸ωΫετΩʔϩοΫͰ ௐ΂ͯΈ͍ͯͩ͘͞
  119. ରԠํ๏ w *OTFSUΛ໌ࣔతʹࢦఆ͢Δ w .PEFMPCKFDUTDSFBUF  w .PEFMTBWF GPSDF@JOTFSU5SVF 119

  120. ༨ஊ ௐࠪํ๏ 120

  121. .:42-ͷϩά͔Β ର৅ςʔϒϧΛ֬ೝ 121 mysql> SHOW ENGINE INNODB STATUS 2019-01-16 09:33:07

    2acb1339d700 *** (1) TRANSACTION: TRANSACTION 45525172536, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 14 lock struct(s), heap size 2936, 6 row lock(s), undo log entries 4 MySQL thread id 210690, OS thread handle 0x2acb433de700, query id 1591163 ec2-52-193-113-252.ap-northeast-1.compute.amazonaws.com 52.193.113.252 popinfo update INSERT INTO `delivery_indexedmessage` (`infobase_id`, `delivery_state`, `operator_id`, `shop_id`) VALUES (85524410, 3, 2310, 914) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 965 page no 274660 n bits 488 index `PRIMARY` of table `popinfo`.`delivery_indexedmessage` trx id 45525172536 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) TRANSACTION: TRANSACTION 45525172535, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 14 lock struct(s), heap size 2936, 6 row lock(s), undo log entries 4 MySQL thread id 210689, OS thread handle 0x2acb1339d700, query id 1591164 ec2-52-193-113-252.ap-northeast-1.compute.amazonaws.com 52.193.113.252 popinfo update INSERT INTO `delivery_indexedmessage` (`infobase_id`, `delivery_state`, `operator_id`, `shop_id`) VALUES (85524409, 3, 2310, 914) *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 965 page no 274660 n bits 488 index `PRIMARY` of table `popinfo`.`delivery_indexedmessage` trx id 45525172535 lock_mode X Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 965 page no 274660 n bits 488 index `PRIMARY` of table `popinfo`.`delivery_indexedmessage` trx id 45525172535 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;;
  122. ൃߦ42-Λ֬ೝ 122 sudo tcpdump -i eth0 -s 0 -w -

    port 3306 | strings SELECT ... UPDATE ... Djangoαʔόʹೖͬͯtcpdump͔Βൃߦ͍ͯ͠ΔSQLΛऔಘ͢Δ
  123. 1SPCMFN ಥવ༗ޮʹͳΔ ϦΫΤετϘσΟ্ݶ 123

  124. ϦΫΤετϘσΟ ࠷େαΠζ੍ݶͷ௥Ճ w %KBOHPʹର͢ΔϦΫΤετϘσΟͷαΠζ੍ݶΛߦ͏ w σϑΥϧτ஋.# w EKBOHPTFUUJOHTʹهࡌ͕ͳ͘ͱ΋੍ݶ͞ΕΔ 124 1.10/Maximum

    size of a request body and the number of GET/POST parameters is limited DATA_UPLOAD_MAX_MEMORY_SIZE
  125. ໰୊ൃੜ࣌ظ 125 Django 1.3.7 Django 1.11.18 Django 1.8.18 ΧφϦΞ ϦϦʔε

    શମ ϦϦʔε ΧφϦΞ ϦϦʔε શମ ϦϦʔε
  126. ໰୊ൃੜ w ސ٬ͷϦΫΤετ͕ࣦഊ w େ༰ྔͷϦΫΤετϘσΟΛࡌͤͨ΋ͷͷΈ 126

  127. ରԠํ๏ w /HJOYV8THJͰରԠ͢ΔͷͰ%KBOHPଆͰ͸ແޮʹ 127 DATA_UPLOAD_MAX_MEMORY_SIZE=None

  128. 1SPCMFN ϦμΠϨΫτઌ͕ ૬ରύεʹ 128

  129. )551ϦμΠϨΫτઌ͕ ઈର63*͔Β૬ର63*ʹ w 3'$͸ϦμΠϨΫτϨεϙϯεͷ-PDBUJPOϔομ ͕ઈର63*ͱͳΔ͜ͱΛڧ੍ w 3'$Ͱ-PDBUJPOͷ૬ର63*ΛڐՄ 129 )551SFEJSFDUTOPMPOHFSGPSDFEUPBCTPMVUF63*T

  130. ͭ·Γ͜͏͍͏͜ͱ 130 Location: "https://docs.djangoproject.com/en/2.1/ releases/1.9/" Location: "/en/2.1/releases/1.9/" 1.8ͷϦμΠϨΫτ 1.9ͷϦμΠϨΫτ

  131. ໰୊ൃੜ࣌ظ 131 Django 1.3.7 Django 1.11.18 Django 1.8.18 ΧφϦΞ ϦϦʔε

    શମ ϦϦʔε ΧφϦΞ ϦϦʔε શମ ϦϦʔε
  132. ໰୊ൃੜ w ಛఆͷސ٬͕ࣗࣾγεςϜ͕QPQJOGP"1*Λίʔϧ͢Δͱ ΤϥʔʹͳΔͱͷใࠂ w গ͠ಛघͳίʔϧํ๏Λ͍ͯͨ͠ 132

  133. มߋલ 133 https://nyan.jp/hoge "Location": "https://nyan.jp/hoge/" https://nyan.jp/hoge/ ސ٬αʔό ؅ཧAPI Django 1.8

    αʔό
  134. มߋޙ 134 https://nyan.jp/hoge "Location": "/hoge/" /hoge/ ސ٬αʔό ؅ཧAPI Django 1.11

    αʔό
  135. ରԠํ๏ w ΧελϜϛυϧ΢ΣΞΛ௥Ճ͢Δ͜ͱͰɺҎલͷڍಈΛҡ ࣋Ͱ͖Δ 135 class LocationHeaderFix(object): def process_response(self, request,

    response): if 'Location' in response: response['Location'] = request.build_absolute_uri(response['Location']) return response
  136. 1SPCMFN ۭനจࣈྻͷ όϦσʔγϣϯมߋ 136

  137. 'PSN$IBS'JFME͕ ۭจࣈྻΛ࡟আ w $IBS'JFMEͷॳظԽҾ਺ʹTUSJQ͕௥Ճ w TUSJQ5SVFͷ৔߹ɺ'PSNೖྗ஋ͷલޙۭനΛআڈ w σϑΥϧτ͕5SVF 137 1.9/Forms

  138. ໰୊ൃੜ࣌ظ 138 Django 1.3.7 Django 1.11.18 Django 1.8.18 ΧφϦΞ ϦϦʔε

    શମ ϦϦʔε ΧφϦΞ ϦϦʔε શମ ϦϦʔε
  139. มߋલ 139 ސ٬αʔό ؅ཧAPI Django 1.8 αʔό https://nyan.jp/add { "title":

    "ೣ" "contents": " " } OK
  140. มߋલ 140 ސ٬αʔό ؅ཧAPI Django 1.8 αʔό https://nyan.jp/add { "title":

    "ೣ" "contents": " " } OK contents = forms.CharField( required=True, )
  141. มߋޙ 141 ސ٬αʔό ؅ཧAPI Django 1.11 αʔό https://nyan.jp/add { "title":

    "ೣ" "contents": " " } όϦσʔγϣϯΤϥʔ
  142. มߋޙ 142 ސ٬αʔό ؅ཧAPI Django 1.11 αʔό https://nyan.jp/add { "title":

    "ೣ" "contents": " " } όϦσʔγϣϯΤϥʔ Form { "title": "ೣ" "contents": "" }
  143. ରԠํ๏ 143 contents = forms.CharField( required=True, strip=False, )

  144. Ͷɻ3FMFBTF/PUF͸ ༏लͰ͠ΐ͏ w ϦϦʔε࣌ʹ౿ΜͩΤϥʔݪҼ͸͢΂ͯهࡌ͕͞Ε͍ͯͨ w ࣄલʹಡΜͰ֬ೝ͓͚ͯ͠͹ϦϦʔεͨ͋͠ͱʹސ٬ʹ ౖΒΕΔ͜ͱ΋ͳ͔͔ͬͨ΋͠Εͳ͍ 144

  145. पΓͷ ϓϩϑΣογϣφϧΛཔΔ 145 1 ———— 6 7

  146. ͋ͳͨ͸ҰਓͰ͸ͳ͍ w %KBOHPΞοϓάϨʔυΛ͍ͯ͠Δͱࣗ෼͚ͩͰ͸Ͳ͏͠ Α͏΋ͳ͍໰୊ʹ౰ͨΔ͜ͱ΋͋Δ w ͦΜͳͱ͖͸͋ͳͨͷपΓʹ͍ΔϓϩϑΣογϣφϧ ͷҙݟΛฉ͘΂͖ 146

  147. 1SPCMFN ٸ্ঢ͢ΔϨΠςϯγ 147

  148. %KBOHPʹ͸ਪ঑͞ΕΔ 1ZUIPOͷόʔδϣϯ͕͋Δ w %KBOHPެࣜΛݟͯΈΔͱ্هͷදه w ݱঢ়1ZUIPOͳͷͰਪ঑όʔδϣϯͰ͸ͳ͍ 148 > Since newer

    versions of Python are often faster, have more features, and are better supported, all else being equal, we recommend that you use the latest 2.x.y or 3.x.y release. 8IBU1ZUIPOWFSTJPOTIPVME*VTFXJUI%KBOHP
  149. ໰୊ൃੜ࣌ظ 149 Django 1.3.7 Django 1.11.18 Django 1.8.18 ΧφϦΞ ϦϦʔε

    શମ ϦϦʔε ΧφϦΞ ϦϦʔε શମ ϦϦʔε
  150. ΛͿΒԼ͛ͨ ΠϯελϯεͷϨΠςϯγ͕ٸ্ঢ 150 NAT GW MYSQL Aurora EC2 EC2 ΠϕϯτऩूAPI

    EC2 ΤϯυϢʔβAPI ؅ཧAPI ഑৴γεςϜ ELB ؅ཧը໘ ELB ELB
  151. /"5(BUFXBZܦ༝ͷ ௨৴ͷࢼߦճ਺͕ٸ্ঢ 151 NAT GW MYSQL Aurora EC2 EC2 ΠϕϯτऩूAPI

    EC2 ΤϯυϢʔβAPI ؅ཧAPI ഑৴γεςϜ ELB ؅ཧը໘ ELB ELB
  152. ҰԠղܾ͸͕ͨ͠ ݪҼ͸Θ͔Βͣ 152

  153. ݪҼௐࠪ w αʔόʹUDQEVNQΛ࢓ֻ͚ͯ௨৴Λμϯϓ w 8JSFTIBSLͰղੳͯ͠ݪҼΛௐࠪ 153

  154. ݪҼௐࠪ w %KBOHP͔Β%#΁ͷ઀ଓͰ5$1ͷXBZϋϯυγΣΠΫத ʹҟৗ͕͋ͬͨ w ҟৗ࣌ʹ઀ଓϦτϥΠ w ϦτϥΠ࣌ඵ଴ͭ Χʔωϧύϥϝʔλґଘ 154

  155. ਖ਼ৗͳ8BZϋϯυγΣΠΫ 155 ΞΫςΟϒΦʔϓϯ (APIαʔό) ύογϒΦʔϓϯ (DBαʔό) SYN SYN/ACK ACK

  156. ҟৗͳ8BZϋϯυγΣΠΫ 156 ΞΫςΟϒΦʔϓϯ (APIαʔό) ύογϒΦʔϓϯ (DBαʔό) SYN ACK RST ϦτϥΠ࣮ߦ

  157. ਪଌ w ύογϒΦʔϓϯ %#αʔόଆ ͕઀ଓऴྃ࣌ʹιέοτ ΛΫϩʔζͰ͖͍ͯͳ͍ 4UBUF͕&TUBCMJTIFEͳ͍͠'*/ 8"*5  w

    Ϋϩʔζ͍ͯ͠ͳ͍ιέοτʹ઀ଓ͔ͨ͠Β͍͖ͳΓ "$,͕ฦΔ w "1*(BUFXBZ͕தܧ࣌ʹޡͬͨϙʔτʹ޲͚͍ͯΔ ͷͰ͸ʁ 157
  158. ݪҼΘ͔Βͣ ͜ͷؒҰϲ݄΄Ͳ ຖ೔8JSFTIBSLͱ%KBOHPͷιʔεΛோΊΔ 158

  159. ౰ͨͬͯࡅ͚Δ͜ͱʹͨ͠ w ݪҼ͕Θ͔Βͳ͍ͳΒ53:&3303͢Δ͔͠ͳ͍ w ΍Γଓ͚Ε͹͖͔͚͕ͬ௫ΊΔ͔΋͠Εͳ͍ 159

  160. 53: 8BZϋϯυγΣΠΫݮΒ͢ w XBZϋϯυγΣΠΫճ਺͕ݮΕ͹345ݮΔͷͰ͸ w %KBOHPTFUUJOHʹ$0//@."9@"(&Λ௥Ճ w ϓϩηεຖʹ%#઀ଓΛࢦఆඵ਺ҡ࣋͢Δ 160

  161. คࡅ 161

  162. 53: .:42-υϥΠόߋ৽ w .:42-υϥΠό͕ݹ͘%KBOHP૬ੑ͕ѱ͍ͷͰ͸ w .Z42-υϥΠόʔΛ࠷৽όʔδϣϯʹߋ৽ 162

  163. ۄࡅ 163

  164. ΋͏%KBOHPΛ ϦϦʔε͢Δ͜ͱ͸Ͱ͖ͳ͍ ͷ͔΋͠Εͳ͍ʜ 164

  165. ίʔώʔϒϨΠΫதͷࡶஊ 165 Python 2.7.9͋ͨΓͰ SSLͷԿ͔มߋ͋ͬͨΑͶʁ ͦ͜·Ͱ͋͛Ε͹ͳΜ͔͋Δ͔΋ ಉ྅ͷHayao Suzukiࢯ ΋͒·ͫΉΓ Wireshark΋͏ݟͨ͘ͳ͍Α͒

  166. ެࣜΛ೷͍ͯΈΔ 166

  167. 53: 1ZUIPOͷΞοϓάϨʔυ w %KBOHPͷਪ঑͢Δ1ZUIPOόʔδϣϯͰ͸ͳ͍͔ΒͰ͸ w 1ZUIPOͷόʔδϣϯΛʹߋ৽ 167

  168. େ׃ࡃ ࣏ͬͨ 168

  169. %KBOHPͷ ΞοϓάϨʔυ࣌ʹ͸ ಉ࣌ʹ1ZUIPOΛ ਪ঑όʔδϣϯʹ͠·͠ΐ͏ 169

  170. Ұਓͷࢹ໺͸ڱ͍ w ϨΠςϯγ໰୊͸໰୊ղੳ͔Βमਖ਼ҊͷཱҊ·Ͱଟ͘ͷਓ ʹڠྗΛڼ͍ͩ w UDQEVNQ XBZIBOETIBLF ͳʹͦΕඒຯ͍͠ͷ  w

    Ұਓ͚ͩͰߟ͍͑ͯͨΒະͩʹ%KBOHP͸͔ͩͬͨ΋͠ Εͳ͍ 170
  171. ΞοϓάϨʔυͷ ׬ྃ͸ऴΘΓͰ͸ͳ͍ 171 1 ————— 7

  172. ࣍ʹ΍Δ΂͖͜ͱ͸ ͍͘ΒͰ΋͋Δ w 1ZUIPO w ·Ͱ w %KBOHP w ·Ͱ

    172
  173. कΓ͔Β߈ΊʹసͣΔ w αϙʔτ੾ΕͷରԠʹ௥ΘΕΔͷ͸͜͜·Ͱ w ߃ৗతʹΞοϓάϨʔυର৅ͷൃݟͱղܾΛߦ͏ଶ੎ ͷߏங w ࠓճͷΞοϓάϨʔυͷͨΊʹߏஙͨ͠αΠΫϧΛΑΓ ߴ଎Խ w

    ൃੜͨ͠όάʹର͢Δख౰ 173
  174. ·ͱΊ 174

  175.  ͳͥΞοϓάϨʔυ͕ඞཁ͔ߟ͑Δ  ΰʔϧʹ͍͖ͳΓ޲͔Θͳ͍  ඞཁͳ΋ͷ͚ͩΛΞοϓάϨʔυ͢Δ  αΠΫϧΛߴ଎Խ͢Δ  %KBOHPͷΞοϓάϨʔυ಺༰Λཧղ͢Δ

     पΓͷϓϩϑΣογϣφϧΛཔΔ  ΞοϓάϨʔυ͸ऴΘΓͰ͸ͳ͍ 175
  176. ͝ਗ਼ௌ ͋Γ͕ͱ͏ ͍͟͝·ͨ͠ 176