Slide 1

Slide 1 text

Architecture & Go kit mercari.go #3

Slide 2

Slide 2 text

About me ● morikuni ● https://twitter.com/inukirom ● https://github.com/morikuni ● Mercari Microservices Development ● Go & Application Architecture

Slide 3

Slide 3 text

Architecture & Domain Modeling with Go Kit https://www.gophercon.com/agenda/session/16822 GopherCon 2018 Pre-Conference Workshop:

Slide 4

Slide 4 text

Speaker ● Mr. Peter Bourgon ● https://twitter.com/peterbourgon ● Distributed System Engineer ● Fastly

Slide 5

Slide 5 text

Workshopの内容 ● Microservicesについて ● Go kitの紹介 ● https://github.com/peterbourgon/sympatico を使った演習

Slide 6

Slide 6 text

Microservicesについて

Slide 7

Slide 7 text

Microservicesは組織の課題を解決する Microservicesは技術的な課題を生み出す

Slide 8

Slide 8 text

● 大きな組織が効率的に作業できるようになる ● 他のチームにブロックされなくなる ● コミュニケーションコストを下げる 解決する課題

Slide 9

Slide 9 text

生み出される課題 ● サービス境界を上手く定義する必要がある ● 各サービスのモニタリング・分散トレーシング etc...

Slide 10

Slide 10 text

生み出される課題 ● サービス境界を上手く定義する必要がある ○ DDD, Event Storming ● 各サービスのモニタリング・分散トレーシング etc… ○ Go kit

Slide 11

Slide 11 text

DDD (ドメイン駆動設計) ● データではなくドメインモデルを中 心とした設計 ● 境界付けられたコンテキストに従っ てサービスを分割する Sales Context Opportunity Support Context Territory Customer Product Pipeline Ticket Customer Product 境界付けられたコンテキスト : モデルが有効な範囲

Slide 12

Slide 12 text

Event Storming ● モデリング手法 ● ビジネス内で発生するイベントを洗 い出す ○ TicketCreated ○ ProductSold ● イベントの関連が理解しやすいよ うなモデルを構築する https://www.slideshare.net/aloyer/event-storming-notes

Slide 13

Slide 13 text

Go kit

Slide 14

Slide 14 text

Go kit ● https://github.com/go-kit/kit ● マイクロサービスのためのツールキット ● いくつものコンポーネントとのアダプタを提供 ○ Open Census, Zipkin, Prometheus, Graphite etc… ● ScalaのFinagleに近い思想

Slide 15

Slide 15 text

Finagleの思想 Service Filter Filter Req Res Req Res Req Res

Slide 16

Slide 16 text

Service Service Finagleの思想 Filter Filter Req Res Req Res Req Res

Slide 17

Slide 17 text

Go kitの思想

Slide 18

Slide 18 text

Go kitの思想 ● Service ○ Business logicを書くところ ● Endpoint ○ Serviceを抽象化するところ ● Transport ○ HTTPやgRPCからEndpointを呼び出すところ

Slide 19

Slide 19 text

Service ● 通常のGoのinterfaceとして定義する type Service interface { Sum(ctx context.Context, a, b int) (int, error) Concat(ctx context.Context, a, b string) (string, error) }

Slide 20

Slide 20 text

Endpoint ● Go kitが提供しているinterface ● RequestとResponseを interface{} で抽象化している type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error) type Middleware func(Endpoint) Endpoint

Slide 21

Slide 21 text

Transport ● HTTP, gRPC, JSON-RPCなどが提供されている ● DecoderとEncoderを実装するとEndpointを呼び出してくれ る

Slide 22

Slide 22 text

Transport (HTTP) type DecodeRequestFunc func(context.Context, *http.Request) (request interface{}, err error) type EncodeResponseFunc func(context.Context, http.ResponseWriter, interface{}) error func NewService( e endpoint.Endpoint, dec DecodeRequestFunc, enc EncodeResponseFunc, options ...ServerOption, ) *Server // implements http.Handler

Slide 23

Slide 23 text

Transport (gRPC) type DecodeRequestFunc func(context.Context, interface{}) (request interface{}, err error) type EncodeResponseFunc func(context.Context, interface{}) (response interface{}, err error) func NewService( e endpoint.Endpoint, dec DecodeRequestFunc, enc EncodeResponseFunc, options ...ServerOption, ) *Server

Slide 24

Slide 24 text

Example https://github.com/go-kit/kit/tree/master/examples/addsvc/pkg

Slide 25

Slide 25 text

Sympatico https://github.com/peterbourgon/sympatico Workshop Exercise:

Slide 26

Slide 26 text

Sympaticoを使った演習 ● SympaticoはDNAを管理するサービス ● 演習の解答が1 commitずつpushしてある ○ DNAのバリデーションを追加せよ ○ Prometheusを導入せよ etc... ● 1プロセスを2プロセスのマイクロサービスに分割 ● Go kitを導入

Slide 27

Slide 27 text

Sympaticoの感想 ● 2パッケージを1プロセスから2プロセスにした感じなのであ まりマイクロサービス化の参考にはならない ● Go kitを使うためのサンプルとしてならよさそう ● Goの書き方として面白い部分があったので紹介

Slide 28

Slide 28 text

パッケージ構成 ❏ cmd ❏ internal ❏ auth ❏ service.go ❏ endpoints.go ❏ transport.go ❏ dna ❏ ctxlog ❏ usage ● main以外をinternalパッケー ジに突っ込んでいる ○ 別のプロジェクトからは参照不 可 ○ IDEなどの補完にも出ない ● Flat package ○ 境界づけられたコンテキスト ○ authにserviceからtransportまで 入っている

Slide 29

Slide 29 text

ブロックで初期化 ● 初期化したい変数を定義 ● ブロックを作って初期化 ● 一時変数を閉じ込める ○ ブロック ⇔ 関数 var authrepo *auth.SQLiteRepository { var err error authrepo, err = auth.NewSQLiteRepository(*authURN) if err != nil { logger.Log("during", "auth.NewSQLiteRepository", "err", err) os.Exit(1) } } var authsvc *auth.Service { authsvc = auth.NewService(authrepo, authEventsTotal) } var api http.Handler { r := mux.NewRouter() r.PathPrefix("/auth/").Handler(http.StripPrefix("/auth", auth.NewHTTPTransport(authsvc))) api = ctxlog.NewHTTPMiddleware(r, logger) }

Slide 30

Slide 30 text

まとめ ● マイクロサービス化にあたって ○ DDD, Event Stormingでモデリング ○ Go kitで実装 ● 個人的には interface{} はできるだけ避けたいので Go kitは使わなさそう...

Slide 31

Slide 31 text

● Architecture & Domain Modeling with Go Kit ○ https://gophers.slack.com/archives/CCF41LFDW/p1535410195000100 ● Go kit ○ https://github.com/go-kit/kit ● Go kit - Architecture and design ○ https://gokit.io/faq/#design-mdash-how-is-a-go-kit-microservice-modeled ● Sympatico ○ https://github.com/peterbourgon/sympatico 参考資料