nashcft's blog

時々何か書く。

第3回 マイクロサービス アーキテクチャ 読書会 メモ

書くだけ書いて投稿し忘れていた当日書いたメモ。もう第4回も終わってるんだけど...

architect-club.doorkeeper.jp

スライド: 前半

www.slideshare.net

後半

www.slideshare.net

統合

  • 数ある選択肢
  • 統合から何を得たいのか?
    • 破壊的変更を回避する
    • APIを技術日依存に
      • サービス間の通信に使うAPIを特定技術に依存させない
    • コンシューマにとって単純なサービスに
      • 利用コストが高いと価値がない
      • クライアントライブラリ: 結合度が高まる
    • 内部の実装詳細を隠蔽
      • 変更コスト、破壊リスク、技術的負債
      • ECサイトに対する会員登録API,メール送信APIを公開するべきではない -> ドメインモデル貧血症

顧客とのinterface

  • 単純なCRUD: 登録、削除とか

共有データベース

サービス間でDBを共有しても良いか否か

  • 大規模な共有APIの場合
    • スキーマ変更によりコンシューマを破壊してしまう
    • データモデル、プロダクトの変更がむずい (ドライバの問題とかあるね)
    • ロジックが分散する: 凝集性の喪失
  • いかなる代償を払ってもDB統合を避けるべき

共有しない場合の手段

  • 特に言及なし?

REST vs RPC (Remote Procedure Call): Trade-off?

RPC

  • finagle, gRPC
  • ひどくはない
  • プロダクトを選ぶ

REST

  • HATEOAS
    • リチャードソンの成熟モデル level 3
      • level 0: the swamp of POX - URI と HTTPが 1to1
      • level 1: Resources - リソースが紐付いている
      • level 2: HTTP Verbs - methodを活用している
      • level 3: Hypermedia controls - RESTful、状態と振る舞いを表している
        • 次の振る舞いを返却してくれたりする

JSON or XML?

  • JSONにはlink controlがない -> HAL e.g. Spring HATEOAS
  • SIREN
  • JSON API
  • JSON-LD (linked data)
  • de fact standard はなさそう

コレオグラフィ

Coreography

the art or job of deciding how dancers will move in a performance; also : the movements that are done by dancers in a performance

マイクロサービスアーキテクチャにおけるオーケストレーションとコレオグラフィ

  • クライアントが直接サービスを呼び出すのではなく、イベントを間に挟んで、イベントが必要な各サービスを呼び出す
    • pub/sub
  • Zabbix, Zipkin

orchestration vs coreography どちらを採用するべき?

  • coreographyはバッチみたいな大量の処理をするときに向いてそう
  • クライアントサービスはorchestrationでも良い?
  • 弊社サービスの構成はAPI gatewayというらしい
    • BFFかも?

req/res vs event-based

  • 同期モデルか非同期モデルか
  • SOAPとかRMIみたいな重いのよりJSONみたいな軽量のものを使いたいよね
  • level 3の採用は難しそうですねえ
  • まあ両方使うよね
    • ms間はevent-based
    • frontからはreq/res

色々なサービスを呼び出して結果的に1枚のHTMLに収めたい時

↓はアジェンダに当てはめるとここ?

UI

API合成

  • UIとサービス作成者の違い
    • 歩調を合わせるのは難しい
  • レスポンスの調整ができない

UI部品合成

  • SSRとか
  • wigetとか

API GatewayとかBFFとか

レガシーシステムやパッケージ製品ともやりとりする時の方法

↓はアジェンダに当てはめるとここ?

versioning

  • 最大限の見送り
    • フィールドの場所を曖昧にしておく (XPath)
      • 耐性のあるリーダー by Martin Fowler
    • ポステルの法則
  • 破壊的変更の早期把握
    • Consumer Driven Contract
      • 回避
      • 受け入れてコンシューマと相談
  • semverの利用
  • 異なるエンドポイントの共存
    • v1, v2がエンドポイントとして存在するけどロジックは1つ
    • テストの負担がやばいので3つ以上はやめとけ
  • 複数バージョンを同時に使う
    • 短時間ならまあいいかも
    • 「慎重に」

会の後

『自閉症の脳を読み解く: どのように考え、感じているのか』を読んだ

自閉症の脳を読み解く―どのように考え、感じているのか

自閉症の脳を読み解く―どのように考え、感じているのか

いつだったかTLでプログラマに向いてる人向いてない人の思考パターンについて会話しているのを見かけて、その中でこの本が紹介されていたので読んでみた。自閉症、というよりは人間の思考パターンに対する興味の方が強かった。
今月頭に購入してから時間を見つけてはちまちま読んでいて、今日の外出中に電車の中で読み終わった。

※ちょうどこの後目的地に着いて、昼だったので外食屋に入って以下をメモってた

思考パターンについて

本書によると人間の思考パターンには3つのタイプがあって「視覚的画像で考えるタイプ」「言語や事実で考えるタイプ」「パターンで考えるタイプ」があるのだそうだ。

8章「活躍の場を切り開く」の "対人関係のスキルを身につける" の項について

Gitを学ぶ

前の記事で勤め先のVCSをhgからgitに移行する機運があると書いたが、そちらの向きが強くなってきたのでgitについて少し真面目に勉強し始めていて、その中で良さげに感じた資料を一旦まとめることにする。

www.slideshare.net

このスライドはκeenさんのブログ記事で紹介されているのを見て読んだ。
gitで管理される情報の構造やユーザが操作するコマンドの裏側でどのようなことが行われているかをイメージしやすく、これを読んでおけば大体のことはこなせるようになるはず。
操作周りのスライドを読んでいて、hgを使っているのにrebaseやmqをガシガシ使っている人の多い弊社に本当に必要だったのはgitなのでは... と思った。

www.slideshare.net

最初のスライドに次に読むスライドとして勧められていた。所謂git-flow?
resetの部分だけ面倒だなと思ったので、これのresetしない版を普段やっているような気がする。
github-flow, gitlab-flowと他にもあるようだし、比較しながらブランチ戦略的なものを検討しよう。

Seven More Languages in Seven Weeks: Julia Day 1の演習問題をやった (ずいぶん前に)

間が空きすぎてしまった...
Day 1 の演習自体は前の記事を書いた後すぐにやってはいたのだけど
下書きを書いた後先に進めている間に詰まったか何かして公開しないまま投げてしまったようです (記憶が朧げ)
とりあえず書いた当時のまま晒すだけ晒しておこう...


github.com

設問の中に5x5x5の配列を作れとあって、3次元以上の配列の作り方を知ってから「じゃあ4次元配列を作ったらどうなるんだろう?」と思って試した結果がこちら:

julia> Array(Int64, 5,5,5,5)
5x5x5x5 Array{Int64,4}:
[:, :, 1, 1] =
 4469252560           0  4469252560           0  4469252560
          0  4469251016           0  4469252560           0
 4469255624           0  4469252560           0  4469252560
          0  4469252560           0  4469252560           0
 4469252560           0  4469252560           0  4469252560

[:, :, 2, 1] =
                   0  78152697455975698193556471915367379232  0
     140278440639040  7867888721079460201     3556471915367379232  0
 5417930524443302683  2319735731304618779     3539894578555400480  0
 5129700148190993179  2319735477633097777     3539883321446117664  0
 7868170196776672027  2319735477633097777     5132187517736263739  0

[:, :, 3, 1] =
 0  0                    0  7868170196776672027  2319735477633097777
 0  0                    0  7815269745597569819  2319735477633097777
 0  0      140278440639328  7867888721079460201  2319735477633097777
 0  0  5417930524443302683  2319735731304618779  3556471770077798449
 0  0  5129700148190993179  2319735477633097777  3556471915367379232

[:, :, 4, 1] =
 3556471915367379232  20046507979529531  0  0                    0
 3556471915367379232                  0  0  0                    0
 3556471915367379232                  0  0  0                    0
 3539894578555400480                  0  0  0      140278440639616
 3539883321446117664                  0  0  0  5417930524443302683

[:, :, 5, 1] =
 5129700148190993179  23197354776330977773539883321446117664  0
 7868170196776672027  2319735477633097777          78302376827741  0
 7815269745597569819  2319735477633097777                       0  0
 7867888721079460201  2319735477633097777                       0  0
 2319735731304618779  3556471770077798449                       0  0

[:, :, 1, 2] =
 0                0  54179305244433026833556471770077798449
 0                0  5129700148190993179     3556471915367379232
 0                0  7868170196776672027     3556471915367379232
 0                0  7815269745597569819     3556471915367379232
 0  140278440639904  7867888721079460201     3556471915367379232

[:, :, 2, 2] =
 3539894578555400480  0  0  0      140278440640192
 6710417459114946848  0  0  0  5417930524443302683
        305851882267  0  0  0  5129700148190993179
                   0  0  0  0  7868170196776672027
                   0  0  0  0  7815269745597569819

[:, :, 3, 2] =
 7867888721079460201  2319735477633097777  3556471915367379232  0  0
 2319735731304618779  3556471770077798449  3539894578555400480  0  0
 2319735477633097777  3556471915367379232  1971786226191053088  0  0
 2319735477633097777  3556471915367379232           1194668379  0  0
 2319735477633097777  3556471915367379232                    0  0  0

[:, :, 4, 2] =
 0                    0  78152697455975698193556471915367379232
 0      140278440640480  7867888721079460201     3556471915367379232
 0  5417930524443302683  2319735731304618779     3539894578555400480
 0  5129700148190993179  2319735477633097777     6564943274667159840
 0  7868170196776672027  2319735477633097777                 4666417

[:, :, 5, 2] =
 0  0  0                    0  7868170196776672027
 0  0  0                    0  7815269745597569819
 0  0  0      140278440640768  7867888721079460201
 0  0  0  5417930524443302683  2319735731304618779
 0  0  0  5129700148190993179  2319735477633097777

[:, :, 1, 3] =
 2319735477633097777  3556471915367379232  18227  0  0
 2319735477633097777  3556471915367379232      0  0  0
 2319735477633097777  3556471915367379232      0  0  0
 3556471770077798449  3539894578555400480      0  0  0
 3556471915367379232  3556466417809240352      0  0  0

[:, :, 2, 3] =
                   0  51297001481909931793616772148839854368
                   0  7868170196776672027                      71
                   0  7815269745597569819                       0
     140278440641056  7867888721079460201                       0
 5417930524443302683  2319735731304618779                       0

[:, :, 3, 3] =
 0  0                0  5417930524443302683  2319735731304618779
 0  0                0  5129700148190993179  2319735477633097777
 0  0                0  7868170196776672027  2319735477633097777
 0  0                0  7815269745597569819  2319735477633097777
 0  0  140278440641344  7867888721079460201  2319735477633097777

[:, :, 4, 3] =
 3556471770077798449  3539894578555400480  0  0  0
 3556471915367379232  5129935717922582816  0  0  0
 3556471915367379232                    0  0  0  0
 3556471915367379232                    0  0  0  0
 3556471915367379232                    0  0  0  0

[:, :, 5, 3] =
     140278440641632  78678887210794602013556471915367379232  0
 5417930524443302683  2319735731304618779     3539894578555400480  0
 5129700148190993179  2319735477633097777       20037711886507296  0
 7868170196776672027  2319735477633097777                       0  0
 7815269745597569819  2319735477633097777                       0  0

[:, :, 1, 4] =
 0  0                    0  7815269745597569819  2319735477633097777
 0  0      140278440641920  7867888721079460201  2319735477633097777
 0  0  5417930524443302683  2319735731304618779  3556471770077798449
 0  0  5129700148190993179  2319735477633097777  3556471915367379232
 0  0  7868170196776672027  2319735477633097777  3556471915367379232

[:, :, 2, 4] =
 3556471915367379232  0  0  0                    0
 3556471915367379232  0  0  0                    0
 3539894578555400480  0  0  0      140278440642208
        305904950109  0  0  0  5417930524443302683
                   0  0  0  0  5129700148190993179

[:, :, 3, 4] =
 7868170196776672027  2319735477633097777  3556471915367379232  0  0
 7815269745597569819  2319735477633097777  3556471915367379232  0  0
 7867888721079460201  2319735477633097777  3556471915367379232  0  0
 2319735731304618779  3556471770077798449  6710428716224229664  0  0
 2319735477633097777  3556471915367379232           1194875675  0  0

[:, :, 4, 4] =
 0                    0  51297001481909931793556471915367379232
 0                    0  7868170196776672027     3556471915367379232
 0                    0  7815269745597569819     3556471915367379232
 0      140278440642496  7867888721079460201     3556471915367379232
 0  5417930524443302683  2319735731304618779     1971797483300335904

[:, :, 5, 4] =
 4667227  0  0                0  5417930524443302683
       0  0  0                0  5129700148190993179
       0  0  0                0  7868170196776672027
       0  0  0                0  7815269745597569819
       0  0  0  140278440642784  7867888721079460201

[:, :, 1, 5] =
  2319735731304618779  0  0  0  0
  2319735477633097777  0  0  0  0
 -6917529027641081856  0  0  0  0
 -6917529027641081856  0  0  0  0
                    0  0  0  0  0

[:, :, 2, 5] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 3, 5] =
 140278443538256  0  0  0  0
 140278438868112  0  0  0  0
               0  0  0  0  0
               0  0  0  0  0
               0  0  0  0  0

[:, :, 4, 5] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 5, 5] =
 0                0  140278443539344                0  0
 0                0  140278438866256  140278438864720  0
 0                0  140278443538768  140278438868016  0
 0  140278443538896  140278443540944                0  0
 0  140278438867888                0                0  0

なんでや...
ちなみに5次元配列、6次元配列を作るとちゃんと0で初期化された配列が返ってくる(そこまでしか試していない)。

julia> Array(Int64, 5,5,5,5,5)
5x5x5x5x5 Array{Int64,5}:
[:, :, 1, 1, 1] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 2, 1, 1] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 3, 1, 1] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 4, 1, 1] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 5, 1, 1] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 1, 2, 1] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

...

[:, :, 3, 5, 5] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 4, 5, 5] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

[:, :, 5, 5, 5] =
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0
 0  0  0  0  0

Seven More Languages in Seven Weeks の Juliaパートを読む: Day 1

Julia入門の為に買ったSeven more Languages in Seven Weeksを読み始めたので1日分ずつブログに書いて記録する事にした。

この本で扱われているJuliaのバージョンは0.3.0だけど自分の環境が0.4.0-devなので、その辺の差異は夜道さんのJulia本やブログ記事、公式docで調べつつ進めている。

Day 1: Resistance Is Futile

インストールの話などもそこそこに、まずはJuliaの型の紹介から始まる。
延々とtypeof()に値を突っ込んでみていく。気になったのでtypeof()に型名を入れるとDataTypeと出力された。
型紹介の最後にDictが出てきたがこれは0.3.xと0.4.xでは定義方法が異なる。

# v0.3
# {}で括ると型の束縛のないDictができる。
julia> {:a => 12}
Dict{Any,Any} with 1 entry:
  :a => 12

# []で括ると値からの型推論で型が固定される。
julia> [:a => 12]
Dict{Symbol,Int64} with 1 entry:
  :a => 12

# 前に(KeyType => ValueType)と書く事で型を指定できる。
julia> (ASCIIString => Float32)["a" => 1.2]
Dict{ASCIIString,Float32} with 1 entry:
  "a" => 1.2f0
# v0.4
# Dict(key => value, ...)と定義する。この定義方法だと型推論される。
julia> Dict(:a => 12)
Dict{Symbol,Int64} with 1 entry:
  :a => 12

# 型を明示的に指定する際はDict{KeyType, ValueType}(key => value, ...)
julia> Dict{Any, Any}(:a => 12)
Dict{Any,Any} with 1 entry:
  :a => 12

次は演算子の紹介。除算関係には関数もある。この辺について夜道さんのJulia本に挙動の違いが書かれている。/を使うとInt同士の除算でも返り値がFloatになるが、div()を使うと返り値は整数値になる。div()の引数にFloatを入れると、Float型の整数(1.0とか)が返却される。
後はbit表現する為のbits()とか、bit演算子とか。

続いてDictionaryとSetの紹介。定義の方法はさっき書いた通り。値の取り出し方はdict[key]の他、存在しないkeyを指定した際のdefault値も指定するget(dict, key, default)もある。keyを全て取得するkeys()の返り値はKeyIteratorになる。collect()Iteratorから配列を作成する。

julia> numbers = Dict(:a => 1, :b => 2, :c => 3)
Dict{Symbol,Int64} with 3 entries:
  :b => 2
  :c => 3
  :a => 1

julia> numkey = keys(numbers)
KeyIterator for a Dict{Symbol,Int64} with 3 entries. Keys:
  :b
  :c
  :a

julia> numkey[2]
ERROR: MethodError: `getindex` has no method matching getindex(::KeyIterator{Dict{Symbol,Int64}}, ::Int64)
Closest candidates are:
  getindex(::(Any...,), ::Int64)
  getindex(::(Any...,), ::Real)
  getindex(::FloatRange{T}, ::Integer)
  ...

julia> collect(numkey)[2]
:c

in演算子と関数とがあるDictionaryに対してin()を用いるときは第一引数がkeyとvalueのpairでなければならない。
Setにはunion(), intersection(), setdiff(), issubset()等の関数が備えられている。

Array。indexが1スタートなのが違和感ある。基本的に1つのArrayに複数の型の要素を入れられる。型指定するときはType[]と書く。zeros(), ones(),fill()といった初期化用の関数がある。あとはindex指定にendとかsliceがある。 sliceを使って再代入すると指定範囲全てに変更が適用される。 次元まわりは以下のような感じ。

julia> [1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> [1 2 3]
1x3 Array{Int64,2}:
 1  2  3

julia> [[1,2,3],[4,5,6],[7,8,9]]
9-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8
 9

julia> [1 2 3; 4 5 6; 7 8 9]
3x3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9

コンマでなくてセミコロンでもいいみたい。線形代数関係の演算をする為の関数も色々ある。eye()でidentity matrixを定義できたり、.*で要素ごとの乗算ができたり、Arrayの後に'をつけるとtransposeができたり。

Day 1の解説部分はこれでおしまい。この後に練習問題があるので解いてどこかに放り投げる予定。