Upgrade to Pro — share decks privately, control downloads, hide ads and more …

マルチテナントアーキテクチャ x Elixir / Phoenix

yujikawa
February 23, 2018

マルチテナントアーキテクチャ x Elixir / Phoenix

マルチテナントアーキテクチャ x Elixir / Phoenix

yujikawa

February 23, 2018
Tweet

More Decks by yujikawa

Other Decks in Programming

Transcript

  1. w ໊લ w ઒্༞࢘ Ώ͔͡Θ  w ॴଐ w ΧϥϏφςΫϊϩδʔ

    w ৬छ w όοΫΤϯυΤϯδχΞ w 5XJUUFS w !ZVKJLBXB@QZ w ීஈͷ͓࢓ࣄ w &MJYJS1IPFOJYΛ࢖ͬͨ8FC։ൃ w ޷͖ͳݴޠ w &MJYJS w 1ZUIPO w ࠷ۙͷ׆ಈ w 1Z$PO,ZVTZVͷϝϯόʔͱͯ͠׆ಈத ࣗݾ঺հ
  2. ໨࣍ w &MJYJSͱ1IPFOJYʹ͍ͭͯ w ࠷ۙͷฐࣾͷ&MJYJSࣄ৘ w ࠷ۙͷੈͷதͷ&MJYJSࣄ৘ w Ϛϧνςφϯτͱ͸ʁ w

    &MJYJS1IPFOJYͰϚϧνςφϯτΛ͢Δʹ͸ʁ w ։ൃ؀ڥʹ͍ͭͯ w ࣮૷ฤBQBSUNFOUFY w ·ͱΊ
  3. ࠷ۙͷฐࣾͷ&MJYJSࣄ৘ w ͜Ε·Ͱʢ݄͝Ζ·Ͱʣ w 1ZUIPOΛ࢖ͬͨγεςϜ։ൃ w ͜Ε͔Βʢ݄͔Βʣ w &MJYJS1IPFOJYΛ࢖ͬͨγεςϜ։ൃ w

    ؔ਺ܕݴޠͷอकੑɾฒྻॲཧͳͲͷߴ଎ੑʹັྗΛײ͡બఆɺγεςϜͷί Ξ෦෼͸&MJYJSΛ࢖͏ɻ͍͟ͱͳΕ͹&SMQPSUΛ࢖͍ɺ1ZUIPO౳ଞͷݴޠͱͷ ૊Έ߹Θͤ΋Մೳ w ࢀߟɿʮ&MJYJSʴ,FSBTʹखܰʹߴ଎ͳʮσʔλαΠΤϯεϓϥοτϑΥʔ Ϝʯʙ'MPXͰͷϚϧνίΞ׆༻ࣄྫʙʯIUUQTRJJUBDPNQJBDFSF JUFNTDBGCDFECD⒎
  4. ࠷ۙͷฐࣾͷ&MJYJSࣄ৘ w ͜Ε·Ͱ࢖ͬͯΈͯͷײ૝ w ϙδςΟϒ 㱼ʆ  w 1IPFOJYͰ3BJMTฒΈͷര଎։ൃ͕Ͱ͖Δ w

    5%%ʢςετۦಈ։ൃʣ͕͠΍͍͢ w ίʔυ͕ಡΈ΍͍͢ʢอक͠΍͍͢ʣ w ॲཧ଎౓͕଎͍ʢ1ZUIPOͩͱؾʹͳΔ͕࣌͋Δʣ w ڧྗͳύλʔϯϚονͰίʔυྔ͕গͳ͘ࡁΜͩ w ωΨςΟϒ ʀ㱼ʀ  w ৭ʑͳαʔϏεͷެࣜͷϥΠϒϥϦ͸·ͩগͳ͍ w υΩϡϝϯτ΋গͳ͍ʢ೔ຊޠ͸ಛʹʣ ॻ͖΍͍͢ɾಡΈ΍͍͢ɾύΠϓॲཧָ͕͍͠
  5. Ϛϧνςφϯτͱ͸ w ϚϧνςφϯτԽʹඞཁͳཁૉ w ΞϓϦέʔγϣϯ͕ϚϧνςφϯγʔΛαϙʔτ͢Δ͜ͱ w ΞϓϦέʔγϣϯ͕͋Δఔ౓ͷࣗಈαΠϯΞοϓػೳΛඋ͍͑ͯΔ͜ͱ w ొ࿥՝ۚϝΧχζϜ͕༻ҙ͞Ε͍ͯΔ͜ͱ w

    ΞϓϦέʔγϣϯΛޮ཰తʹεέʔϦϯάͰ͖Δ͜ͱ w ΞϓϦέʔγϣϯͱςφϯτΛ؂ࢹɺߏ੒ɺ؅ཧ͢ΔͨΊͷػೳ͕༻ҙ͞Ε͍ͯΔ͜ͱ w ҰҙͷϢʔβʔ*%͓ΑͼೝূΛαϙʔτ͢ΔϝΧχζϜ͕༻ҙ͞Ε͍ͯΔ͜ͱ w ςφϯτ͝ͱͷΧελϚΠζΛ͋Δఔ౓Մೳʹ͢ΔͨΊͷϝΧχζϜ͕༻ҙ͞Ε͍ͯΔ ͜ͱ Ҿ༻ɿʮ8FCΞϓϦέʔγϣϯΛϚϧνςφϯτܕ4BB4ιϦϡʔγϣϯʹม׵͢Δʯ IUUQTXXXJCNDPNEFWFMPQFSXPSLTKQDMPVEMJCSBSZDMNVMUJUFOBOUTBBT ஫໨ &MJYJSͰ Ͳ͏΍Δʁ
  6. &MJYJS1IPFOJYͰ Ϛϧνςφϯτʹ͢Δʹ͸ʁ w 044ͷϥΠϒϥϦ͕ଘࡏ͠·͢ w BQBSUNFOUFY  EPXOMPBET  w

    IUUQTIFYQNQBDLBHFTBQBSUNFOUFY w 5SJQMFY  EPXOMPBET  w IUUQTIFYQNQBDLBHFTUSJQMFY ˞࣌఺ͷσʔλ ஫໨ ࠓճ͸ ͜Ε࢖͏Αʂ 5SJQMFYͷ࢖͍ํ͸2JJUBʹॻ͖·ͨ͠ IUUQTRJJUBDPNZVKJLBXBJUFNTCCDFBFEDD
  7. ࣮૷ฤBQBSUNFOUFY w 1IPFOJYͷϓϩδΣΫτΛ࡞੒ $ mix phx.new tenant_app ………লུ $ cd

    tenant_app/ $ mix ecto.create $ mix phx.server $ [info] Running TenantAppWeb.Endpoint with Cowboy using http://0.0.0.0:4000 IUUQʹΞΫηεͯ͠Έ·͠ΐ͏
  8. ࣮૷ฤBQBSUNFOUFY w BQBSUNFOUFYΛNJYFYTʹ௥Ճ defp deps do [ {:phoenix, "~> 1.3.0"},

    {:phoenix_pubsub, "~> 1.0"}, {:phoenix_ecto, "~> 3.2"}, {:postgrex, ">= 0.0.0"}, {:phoenix_html, "~> 2.10"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.11"}, {:apartmentex, github: "Dania02525/apartmentex"}, {:cowboy, "~> 1.0"} ] end ࣌఺͸)FYʹ্͕͍ͬͯΔϓϩάϥϜʹ ෆ۩߹͕͋ΓHJUIVC͔ΒΠϯετʔϧ͢ΔΑ͏ʹมߋͨ͠
  9. ࣮૷ฤBQBSUNFOUFY w ςφϯτςʔϒϧͷ࡞੒ w αϒυϝΠϯଐੑΛ࣋ͨͤͨDPNQBOJFTςʔϒϧΛ࡞੒ʢί ϚϯυͰҰൃʣ $ mix phx.gen.context Accounts

    Company companies sub_domain:string ͜ͷίϚϯυ͸ςʔϒϧ࡞੒༻ͷϚΠάϨʔγϣϯϑΝΠϧ΍ .7$Ͱ͍͏.෦෼·ͰࣗಈͰ࡞੒ͯ͘͠Ε·͢ɻ
  10. ࣮૷ฤBQBSUNFOUFY w Ϣʔβ৘ใϓϩάϥϜͷ࡞੒ w ؆୯ͷͨΊϢʔβͷ໊લ͚ͩΛొ࿥͢ΔΞϓϦΛ࡞੒ $ mix phx.gen.html Accounts User

    users name:string ͜ͷίϚϯυ͸ςʔϒϧ࡞੒༻ͷϚΠάϨʔγϣϯϑΝΠϧ΍ .7$Ͱ͍͏.7$શͯࣗಈͰ࡞੒ͯ͘͠Ε·͢ɻ
  11. ࣮૷ฤBQBSUNFOUFY w ϧʔςΟϯάΛ௥Ճ MJCUFOBOU@BQQ@XFCSPVUFSFY  w Ϣʔβ৘ใͷϧʔςΟϯάΛઃఆ͠·͢ scope "/", TenantAppWeb

    do pipe_through :browser # Use the default browser stack get "/", PageController, :index resources "/users", UserController end
  12. ࣮૷ฤBQBSUNFOUFY w $PNQBOZϚΠάϨʔγϣϯϑΝΠϧʹVOJRVFJOEFYΛઃ ఆ defmodule TenantApp.Repo.Migrations.CreateCompanies do use Ecto.Migration def

    change do create table(:companies) do add :sub_domain, :string timestamps() end create unique_index(:companies, [:sub_domain]) end end
  13. ࣮૷ฤBQBSUNFOUFY w ϚΠάϨʔγϣϯΛ͠·͢ $ mix ecto.migrate [info] == Running TenantApp.Repo.Migrations.CreateCompanies.change/0

    forward [info] create table companies [info] create index companies_sub_domain_index [info] == Migrated in 0.0s
  14. ࣮૷ฤBQBSUNFOUFY w %#ૢ࡞ͷؔ਺Λมߋ͠·͢ MJCUFOBOU@BQQBDDPVOUTBDDPPVOUTFY def create_company(attrs \\ %{}) do with

    changeset <- Company.changeset(%Company{}, attrs), {:ok, company} <- Repo.insert(changeset), do: Apartmentex.new_tenant(Repo, company.sub_domain) end def create_user(attrs \\ %{}, sub_domain) do with changeset <- User.changeset(%User{}, attrs), do: Apartmentex.insert(Repo, changeset, sub_domain) end def list_users(sub_domain) do Apartmentex.all(Repo, User, sub_domain) end ొ࿥ͱऔಘͷؔ਺ʹαϒυϝΠϯରԠΛ͢Δ
  15. ࣮૷ฤBQBSUNFOUFY w ςετσʔλͷ࡞੒ w ಈ࡞֬ೝͷͨΊʹखಈͰ࡞੒͠·͢ $ iex -S mix iex(1)>

    alias TenantApp.Accounts iex(2)> Accounts.create_company(%{sub_domain: "company-aaa"}) iex(3)> Accounts.create_company(%{sub_domain: "company-zzz"}) iex(4)> Accounts.create_user(%{name: "Yuji Kawakami"}, "company-aaa") iex(5)> Accounts.create_user(%{name: "Taro Tanaka"}, "company-zzz") iex(6)> Accounts.create_user(%{name: "Hanako Takahashi"}, "company-zzz")
  16. ࣮૷ฤBQBSUNFOUFY w 6TFSίϯτϩʔϥͷมߋ MJCUFOBOU@BQQ@XFCDPOUSPMMFSTVTFS@DPOUSPMMFSFY  w Ϣʔβ৘ใͷίϯτϩʔϥΛมߋ͠·͢ def action(conn, _)

    do [sub_domain|_] = String.split(conn.host, ".") apply(__MODULE__, action_name(conn), [conn, conn.params, sub_domain]) end def index(conn, _params, sub_domain) do users = Accounts.list_users(sub_domain) render(conn, "index.html", users: users) end BDUJPOؔ਺ͰίϯτϩʔϥͰఆٛͨؔ͠਺ʹ TVC@EPNBJOΛҾ਺Ͱ౉͢Α͏ʹ͍ͯ͠Δ
  17. ࣮૷ฤBQBSUNFOUFY w ςετ༻ʹIPTUTʹυϝΠϯΛઃఆ͠ɺαʔόىಈ $ vim /etc/hosts 127.0.0.1 company-aaa.dev.local dev 127.0.0.1

    company-zzz.dev.local dev $ mix phx.server Compiling 1 file (.ex) [info] Running TenantAppWeb.Endpoint with Cowboy using http:// 0.0.0.0:4000