SlideShare une entreprise Scribd logo
1  sur  32
Télécharger pour lire hors ligne
KAI CHU CHUNG
Cloud GDE
GDG Cloud Taipei co-organizers
@CageChung
https://kaichu.io
如何透過 Go-kit 快速搭建微服務架
構應用程式實戰
KAI CHU CHUNG
Cloud GDE
GDG Cloud Taipei co-organizers
QNAP
@CageChung
https://kaichu.io
https://www.facebook.com/groups/GCPUG.TW
Agenda
● Go-kit
● Layout
● Test
● Toolchain
Toolkit for microservices
Go-kit
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Hello Gophercon TW 2020")
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":8888", nil)
}
Scenario 1
type Addsvc interface {
sum(a, b int64) (int64, error)
}
type SumRequest struct {
A int64 `json:"a"`
B int64 `json:"b"`
}
type addService struct{}
func (s *addService) sum(a, b int64) (int64, error) {
return a + b, nil
}
Scenario 2
Service
Define method and
implementation
func (s *addService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
var req SumRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if res, err := s.sum(req.A, req.B); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} else {
fmt.Fprint(w, res)
}
}
}
func main() {
http.ListenAndServe(":8888", &addService{})
}
Scenario 2
type Endpoint func(request) (response)
type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)
func MakePostSumEndpoint(s addService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (response interface{}, err error) {
p := request.(SumRequest)
return s.sum(p.A, p.B)
}
}
Endpoint
Endpoint is the fundamental building block of servers and clients. It represents a single RPC
method.
func EncodeJSONRequest(c context.Context, r *http.Request, request interface{}) error
func EncodeJSONResponse(_ context.Context, w http.ResponseWriter, response interface{}) error
func decodeHTTPSquareRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req SumRequest
err := json.NewDecoder(r.Body).Decode(&req)
return req, err
}
func encodeJSONResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
Transport
DecodeRequestFunc / EncodeResponseFunc
● EncodeJSONRequest is an EncodeRequestFunc that serializes the request as a JSON object to the
Request body
● EncodeJSONResponse is a EncodeResponseFunc that serializes the response as a JSON object to the
ResponseWriter
func NewServer(
e endpoint.Endpoint,
dec DecodeRequestFunc,
enc EncodeResponseFunc,
options ...ServerOption,
) *Server { ... }
postSum := httptransport.NewServer(e, decodeHTTPSumRequest, httptransport.EncodeJSONResponse)
r := mux.NewRouter()
r.Methods(http.MethodPost).Handler(postSum)
log.Printf("listening on :8888")
log.Fatal(http.ListenAndServe(":8888", r))
Transport
Go kit comes with handy HTTP transport.NewServer constructs a new server, which
implements http.Handler and wraps the provided endpoint.
type Server struct {
e Endpoint
dec DecodeRequestFunc
enc EncodeResponseFunc
}
func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
request, err := s.dec(ctx, r)
if err != nil {
return
}
response, err := s.e(ctx, request)
if err != nil {
return
}
if err := s.enc(ctx, w, response); err != nil {
return
}
}
Scenario 3
How is a Go-kit microservice modeled?
Transport
Endpoint
Service
https://gokit.io/faq/#design-mdash-how-is-a-go-kit-microservice-modeled
Go-kit Endpoint
Go + microservices = Go kit - Speaker Deck - https://speakerdeck.com/peterbourgon/go-plus-microservices-equals-go-kit?slide=78
.
├── auth
├── circuitbreaker
├── cmd
├── endpoint
├── examples
├── log
├── metrics
├── ratelimit
├── sd
├── tracing
├── transport
├── util
├── .build.yml
├── .gitignore
├── .travis.yml
Go-kit components
Authentication: Basic, casbin, JWT.
Circuit Breaker: Hystrix, GoBreaker, and HandyBreaker.
Logging: Provide an interface for structured logging. Recognizes that logs
are data. They need context and semantics to be useful for analysis.
Supported formats are logfmt and JSON.
Metrics: Provides uniform interfaces for service instrumentation. Comes
with counters, gauges, and histograms. Has adapters for CloudWatch,
Prometheus, Graphite, DogStatsD, StatsD, expvar, and more.
Rate Limit: Uses Go's token bucket implementation.
Service Discovery: Consul, DNS SRV, etcd, Eureka, ZooKeeper, and more.
Tracing: OpenCensus, OpenTracing, and Zipkin.
Transport: AMQP, AWS Lambda, gRPC, HTTP, NATS, Thrift.
Go-kit microservice
Golang UK Conference 2015 - Peter Bourgon - Go Kit A Toolkit for Microservices - https://youtu.be/aL6sd4d4hxk?t=1022
Go-kit microservice + Istio
Golang UK Conference 2015 - Peter Bourgon - Go Kit A Toolkit for Microservices - https://youtu.be/aL6sd4d4hxk?t=1022
Go-kit simple
workshop
https://github.com/cage1016/gokit-workshop
- Simple tutorial from http/net
to Gokit skeleton
Project layout
Layout
.
├── cmd
│ ├── add
│ ├── ...
│ └── tictac
├── internal
│ ├── app
│ │ ├── add
│ │ ├── ...
│ │ └── tictac
│ └── pkg
│ ├── account
│ ├── ...
│ ├── errors
│ ├── jwt
│ ├── responses
│ └── version
├── pb
│ ├── add
│ └── tictac
Layout
● Every service put at internal/app/<service-name>
● cmd/<service-name> is service entry point
● internal/app/<shared-pkg> is shared pkg for other service
● pb/<service-name> for external usage
├── internal
│ ├── app
│ │ ├── add
│ │ │ ├── endpoints
│ │ │ │ ├── endpoints.go
│ │ │ │ ├── middleware.go
│ │ │ │ ├── requests.go
│ │ │ │ └── responses.go
│ │ │ ├── service
│ │ │ │ ├── logging.go
│ │ │ │ ├── service.go
│ │ │ │ └── version.go
│ │ │ └── transports
│ │ │ ├── grpc
│ │ │ └── http
│ │ └── tictac
│ │ ├── endpoints
│ │ ├── ...
│ │ ├── model
│ │ │ └── count.go
│ │ ├── postgres
│ │ │ ├── init.go
│ │ │ └── postgres.go
│ │ ├── service
│ │ └── transports
Layout
Single service
● Each service at least contain Endpoints, Service,
Transports
● Service: provide expose service method for serving
● Endpoints: handle decode/encode request between service
and transport
● Transports: implement support transports for service
● Other associated request components
├── deployments
│ ├── docker
│ └── helm
├── Makefile
├── README.md
├── CHANGELOG.md
├── cloudbuild.yaml
├── gk.json
├── go.mod
├── go.sum
└── skaffold.yaml
Layout
● Basic workflow components
○ Skaffold.yaml
○ Cloudbuild.yaml
● README.md, CHANGELOG.md etc documentation.
● Deployment workflow like docker, helm put at
deployments
Go-kit Microservice
demo
https://github.com/cage1016/ms-demo
- Go-kit base
- GRPC/HTTP
- Service
- Add
- TicTac
- Kubernetes/Istio
- Sakffold support
A little copying is better than a little
dependency.
Proverbs from @rob_pike
Test
func setupXTestCase(_ *testing.T) (xTestSuit, func(t *testing.T)) {
s := xTestSuit{}
return s, func(t *testing.T) { }
}
func TestAddOrganization(t *testing.T) {
_, teardownTestCase := setupXTestCase(t)
defer teardownTestCase(t)
cases := []struct {
...
}{
{
desc: "A",
setupSubTest: func(t *testing.T) func(t *testing.T) {
return func(t *testing.T) { }
},
},
}
for _, tc := range cases {
t.Run(tc.desc, func(t *testing.T) {
teardownSubTest := tc.setupSubTest(t)
defer teardownSubTest(t)
// test code
})
}
Unitest skeleton
=== RUN TestAddOrganization
test start
=== RUN
TestAddOrganization/A
sub test start
sub test teardown
test teardown
--- PASS: TestAddOrganization
(0.00s)
--- PASS:
TestAddOrganization/A (0.00s)
PASS
● Cloudbuild pipeline does not support docker in docker,
mock required interface object before test
○ // +build !integration unit
○ // +build integration
● Data layer
○ postgres
● Services
● Transports
○ HTTP/GRPC
Unitest
.
├── mocks
│ ├── account.go
│ ├── authz.go
│ ├── commons.go
│ ├── context.go
│ ├── fixture.go
│ ├── idp.go
│ ├── organization.go
│ └── users.go
├── postgres
│ ├── database.go
│ ├── init.go
│ ├── users.go
│ └── users_test.go
├── service
│ ├── ...
│ ├── service.go
│ ├── service_test.go
│ └── version.go
└── transports
├── grpc.go
├── grpc_test.go
├── http.go
├── http_test.go
└── nats.go
Toolchain
A generator for go-kit that helps you create/update boilerplate code
Usage:
gk [flags]
gk [command]
Available Commands:
add Use to add additional transports to a service
help Help about any command
init Initiates a service
new A set of generators used to create new
cmd/services/transports/middlewares
update Use to update service
Flags:
-d, --debug If you want to se the debug logs.
--folder string If you want to specify the base folder of the
project.
-f, --force Force overwrite existing files without asking.
-h, --help help for gk
--testing If testing the generator.
Use "gk [command] --help" for more information about a command.
gk
https://github.com/cage1016
/gk/tree/feature/gokitconsul
k8sistio
Go-kit generator
hello:
curl localhost:8180/hello | jq
generate:
go mod init github.com/cage1016/gophercon-tw
gk n s hellogophercon
sed -i "" 's|Foo(ctx context.Context, s string) (res string, err error)|Hello(ctx context.Context) (res
string, err error)|g' internal/app/hellogophercon/service/service.go
sed -i "" 's|method=post,expose=true|method=get,expose=true|g'
internal/app/hellogophercon/service/service.go
gk init hellogophercon
sed -i "" 's|return res, err|return "Hello Gophercon TW 2020", err|g'
internal/app/hellogophercon/service/service.go
gk add grpc hellogophercon
cd pb/hellogophercon && ./compile.sh
gk init grpc hellogophercon
gk new cmd hellogophercon
go run cmd/hellogophercon/main.go
Makefile
Build/Test Store Deploy Monitor
workflow
KAI CHU CHUNG
GDE Cloud
GDG Cloud Taipei co-organizers
@CageChung
https://kaichu.io
Q & A

Contenu connexe

Tendances

Tendances (20)

GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
GDG Cloud Taipei: Meetup #52 - Istio Security: API AuthorizationGDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
 
Velero search &amp; practice 20210609
Velero search &amp; practice 20210609Velero search &amp; practice 20210609
Velero search &amp; practice 20210609
 
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
PuppetConf 2016: Running Puppet Software in Docker Containers – Gareth Rushgr...
 
How to debug the pod which is hard to debug (디버그 하기 어려운 POD 디버그 하기)
How to debug the pod which is hard to debug (디버그 하기 어려운 POD 디버그 하기)How to debug the pod which is hard to debug (디버그 하기 어려운 POD 디버그 하기)
How to debug the pod which is hard to debug (디버그 하기 어려운 POD 디버그 하기)
 
[Image Results] Java Build Tools: Part 2 - A Decision Maker's Guide Compariso...
[Image Results] Java Build Tools: Part 2 - A Decision Maker's Guide Compariso...[Image Results] Java Build Tools: Part 2 - A Decision Maker's Guide Compariso...
[Image Results] Java Build Tools: Part 2 - A Decision Maker's Guide Compariso...
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 
Docker workshop 0507 Taichung
Docker workshop 0507 Taichung Docker workshop 0507 Taichung
Docker workshop 0507 Taichung
 
開放運算&GPU技術研究班
開放運算&GPU技術研究班開放運算&GPU技術研究班
開放運算&GPU技術研究班
 
PuppetConf 2016: Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
PuppetConf 2016:  Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...PuppetConf 2016:  Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
PuppetConf 2016: Docker, Mesos, Kubernetes and...Puppet? Don't Panic! – Deep...
 
Continuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPContinuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCP
 
Paris container day june17
Paris container day   june17Paris container day   june17
Paris container day june17
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extreme
 
Docker remote-api
Docker remote-apiDocker remote-api
Docker remote-api
 
Docker deploy
Docker deployDocker deploy
Docker deploy
 
手把手帶你學Docker 03042017
手把手帶你學Docker 03042017手把手帶你學Docker 03042017
手把手帶你學Docker 03042017
 
CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)CI : the first_step: Auto Testing with CircleCI - (MOSG)
CI : the first_step: Auto Testing with CircleCI - (MOSG)
 
Android presentation - Gradle ++
Android presentation - Gradle ++Android presentation - Gradle ++
Android presentation - Gradle ++
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and docker
 
Advanced Task Scheduling with Amazon ECS (June 2017)
Advanced Task Scheduling with Amazon ECS (June 2017)Advanced Task Scheduling with Amazon ECS (June 2017)
Advanced Task Scheduling with Amazon ECS (June 2017)
 

Similaire à 如何透過 Go-kit 快速搭建微服務架構應用程式實戰

服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Qiangning Hong
 
Google Developer Fest 2010
Google Developer Fest 2010Google Developer Fest 2010
Google Developer Fest 2010
Chris Ramsdale
 

Similaire à 如何透過 Go-kit 快速搭建微服務架構應用程式實戰 (20)

GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes with ...
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes  with ...GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes  with ...
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes with ...
 
用 Go 語言打造多台機器 Scale 架構
用 Go 語言打造多台機器 Scale 架構用 Go 語言打造多台機器 Scale 架構
用 Go 語言打造多台機器 Scale 架構
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Protobuf & Code Generation + Go-Kit
Protobuf & Code Generation + Go-KitProtobuf & Code Generation + Go-Kit
Protobuf & Code Generation + Go-Kit
 
Using Groovy to empower WebRTC Network Systems
Using Groovy to empower WebRTC Network SystemsUsing Groovy to empower WebRTC Network Systems
Using Groovy to empower WebRTC Network Systems
 
Plone deployment made easy
Plone deployment made easyPlone deployment made easy
Plone deployment made easy
 
How to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita GalkinHow to make a high-quality Node.js app, Nikita Galkin
How to make a high-quality Node.js app, Nikita Galkin
 
Metrics with Ganglia
Metrics with GangliaMetrics with Ganglia
Metrics with Ganglia
 
Improving go-git performance
Improving go-git performanceImproving go-git performance
Improving go-git performance
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
 
Monitoring Kafka w/ Prometheus
Monitoring Kafka w/ PrometheusMonitoring Kafka w/ Prometheus
Monitoring Kafka w/ Prometheus
 
Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010Building Web Apps Sanely - EclipseCon 2010
Building Web Apps Sanely - EclipseCon 2010
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Google Developer Fest 2010
Google Developer Fest 2010Google Developer Fest 2010
Google Developer Fest 2010
 
The Ring programming language version 1.5.3 book - Part 8 of 184
The Ring programming language version 1.5.3 book - Part 8 of 184The Ring programming language version 1.5.3 book - Part 8 of 184
The Ring programming language version 1.5.3 book - Part 8 of 184
 
The Ring programming language version 1.5.4 book - Part 8 of 185
The Ring programming language version 1.5.4 book - Part 8 of 185The Ring programming language version 1.5.4 book - Part 8 of 185
The Ring programming language version 1.5.4 book - Part 8 of 185
 
Skydive 5/07/2016
Skydive 5/07/2016Skydive 5/07/2016
Skydive 5/07/2016
 
The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180
 
JBoss World 2010
JBoss World 2010JBoss World 2010
JBoss World 2010
 
Kubernetes internals (Kubernetes 해부하기)
Kubernetes internals (Kubernetes 해부하기)Kubernetes internals (Kubernetes 해부하기)
Kubernetes internals (Kubernetes 해부하기)
 

Plus de KAI CHU CHUNG

Plus de KAI CHU CHUNG (16)

Devfest 2023 - Service Weaver Introduction - Taipei.pdf
Devfest 2023 - Service Weaver Introduction - Taipei.pdfDevfest 2023 - Service Weaver Introduction - Taipei.pdf
Devfest 2023 - Service Weaver Introduction - Taipei.pdf
 
DevFest 2022 - Skaffold 2 Deep Dive Taipei.pdf
DevFest 2022 - Skaffold 2 Deep Dive Taipei.pdfDevFest 2022 - Skaffold 2 Deep Dive Taipei.pdf
DevFest 2022 - Skaffold 2 Deep Dive Taipei.pdf
 
DevFest 2022 - Cloud Workstation Introduction TaiChung
DevFest 2022 - Cloud Workstation Introduction TaiChungDevFest 2022 - Cloud Workstation Introduction TaiChung
DevFest 2022 - Cloud Workstation Introduction TaiChung
 
COSCUP 2020 Google 技術 x 公共參與 x 開源 口罩地圖技術開源
COSCUP 2020 Google 技術 x 公共參與 x 開源 口罩地圖技術開源COSCUP 2020 Google 技術 x 公共參與 x 開源 口罩地圖技術開源
COSCUP 2020 Google 技術 x 公共參與 x 開源 口罩地圖技術開源
 
Global GDG Leaders Summit, Google I/O 2018 經驗分享
Global GDG Leaders Summit, Google I/O 2018 經驗分享Global GDG Leaders Summit, Google I/O 2018 經驗分享
Global GDG Leaders Summit, Google I/O 2018 經驗分享
 
Google apps script introduction
Google apps script introductionGoogle apps script introduction
Google apps script introduction
 
Screenshot as a service
Screenshot as a serviceScreenshot as a service
Screenshot as a service
 
Nas 也可以揀土豆
Nas 也可以揀土豆Nas 也可以揀土豆
Nas 也可以揀土豆
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
 
Django oscar introduction
Django oscar introductionDjango oscar introduction
Django oscar introduction
 
Google apps script introduction
Google apps script introductionGoogle apps script introduction
Google apps script introduction
 
Gae managed vm introduction
Gae managed vm introductionGae managed vm introduction
Gae managed vm introduction
 
Google app engine (gae) 演進史
Google app engine (gae) 演進史Google app engine (gae) 演進史
Google app engine (gae) 演進史
 
痞客趴趴走 Waldo
痞客趴趴走   Waldo痞客趴趴走   Waldo
痞客趴趴走 Waldo
 
Waldo-gcp
Waldo-gcpWaldo-gcp
Waldo-gcp
 
Introduction to chrome extension development
Introduction to chrome extension developmentIntroduction to chrome extension development
Introduction to chrome extension development
 

Dernier

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Dernier (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 

如何透過 Go-kit 快速搭建微服務架構應用程式實戰

  • 1. KAI CHU CHUNG Cloud GDE GDG Cloud Taipei co-organizers @CageChung https://kaichu.io 如何透過 Go-kit 快速搭建微服務架 構應用程式實戰
  • 2. KAI CHU CHUNG Cloud GDE GDG Cloud Taipei co-organizers QNAP @CageChung https://kaichu.io
  • 4. Agenda ● Go-kit ● Layout ● Test ● Toolchain
  • 6. package main import ( "fmt" "net/http" ) func hello(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Hello Gophercon TW 2020") } func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8888", nil) } Scenario 1
  • 7. type Addsvc interface { sum(a, b int64) (int64, error) } type SumRequest struct { A int64 `json:"a"` B int64 `json:"b"` } type addService struct{} func (s *addService) sum(a, b int64) (int64, error) { return a + b, nil } Scenario 2 Service Define method and implementation
  • 8. func (s *addService) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodPost: var req SumRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if res, err := s.sum(req.A, req.B); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } else { fmt.Fprint(w, res) } } } func main() { http.ListenAndServe(":8888", &addService{}) } Scenario 2
  • 9. type Endpoint func(request) (response) type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error) func MakePostSumEndpoint(s addService) endpoint.Endpoint { return func(_ context.Context, request interface{}) (response interface{}, err error) { p := request.(SumRequest) return s.sum(p.A, p.B) } } Endpoint Endpoint is the fundamental building block of servers and clients. It represents a single RPC method.
  • 10. func EncodeJSONRequest(c context.Context, r *http.Request, request interface{}) error func EncodeJSONResponse(_ context.Context, w http.ResponseWriter, response interface{}) error func decodeHTTPSquareRequest(_ context.Context, r *http.Request) (interface{}, error) { var req SumRequest err := json.NewDecoder(r.Body).Decode(&req) return req, err } func encodeJSONResponse(_ context.Context, w http.ResponseWriter, response interface{}) error { return json.NewEncoder(w).Encode(response) } Transport DecodeRequestFunc / EncodeResponseFunc ● EncodeJSONRequest is an EncodeRequestFunc that serializes the request as a JSON object to the Request body ● EncodeJSONResponse is a EncodeResponseFunc that serializes the response as a JSON object to the ResponseWriter
  • 11. func NewServer( e endpoint.Endpoint, dec DecodeRequestFunc, enc EncodeResponseFunc, options ...ServerOption, ) *Server { ... } postSum := httptransport.NewServer(e, decodeHTTPSumRequest, httptransport.EncodeJSONResponse) r := mux.NewRouter() r.Methods(http.MethodPost).Handler(postSum) log.Printf("listening on :8888") log.Fatal(http.ListenAndServe(":8888", r)) Transport Go kit comes with handy HTTP transport.NewServer constructs a new server, which implements http.Handler and wraps the provided endpoint.
  • 12. type Server struct { e Endpoint dec DecodeRequestFunc enc EncodeResponseFunc } func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() request, err := s.dec(ctx, r) if err != nil { return } response, err := s.e(ctx, request) if err != nil { return } if err := s.enc(ctx, w, response); err != nil { return } } Scenario 3
  • 13. How is a Go-kit microservice modeled? Transport Endpoint Service https://gokit.io/faq/#design-mdash-how-is-a-go-kit-microservice-modeled
  • 14. Go-kit Endpoint Go + microservices = Go kit - Speaker Deck - https://speakerdeck.com/peterbourgon/go-plus-microservices-equals-go-kit?slide=78
  • 15. . ├── auth ├── circuitbreaker ├── cmd ├── endpoint ├── examples ├── log ├── metrics ├── ratelimit ├── sd ├── tracing ├── transport ├── util ├── .build.yml ├── .gitignore ├── .travis.yml Go-kit components Authentication: Basic, casbin, JWT. Circuit Breaker: Hystrix, GoBreaker, and HandyBreaker. Logging: Provide an interface for structured logging. Recognizes that logs are data. They need context and semantics to be useful for analysis. Supported formats are logfmt and JSON. Metrics: Provides uniform interfaces for service instrumentation. Comes with counters, gauges, and histograms. Has adapters for CloudWatch, Prometheus, Graphite, DogStatsD, StatsD, expvar, and more. Rate Limit: Uses Go's token bucket implementation. Service Discovery: Consul, DNS SRV, etcd, Eureka, ZooKeeper, and more. Tracing: OpenCensus, OpenTracing, and Zipkin. Transport: AMQP, AWS Lambda, gRPC, HTTP, NATS, Thrift.
  • 16. Go-kit microservice Golang UK Conference 2015 - Peter Bourgon - Go Kit A Toolkit for Microservices - https://youtu.be/aL6sd4d4hxk?t=1022
  • 17. Go-kit microservice + Istio Golang UK Conference 2015 - Peter Bourgon - Go Kit A Toolkit for Microservices - https://youtu.be/aL6sd4d4hxk?t=1022
  • 20. . ├── cmd │ ├── add │ ├── ... │ └── tictac ├── internal │ ├── app │ │ ├── add │ │ ├── ... │ │ └── tictac │ └── pkg │ ├── account │ ├── ... │ ├── errors │ ├── jwt │ ├── responses │ └── version ├── pb │ ├── add │ └── tictac Layout ● Every service put at internal/app/<service-name> ● cmd/<service-name> is service entry point ● internal/app/<shared-pkg> is shared pkg for other service ● pb/<service-name> for external usage
  • 21. ├── internal │ ├── app │ │ ├── add │ │ │ ├── endpoints │ │ │ │ ├── endpoints.go │ │ │ │ ├── middleware.go │ │ │ │ ├── requests.go │ │ │ │ └── responses.go │ │ │ ├── service │ │ │ │ ├── logging.go │ │ │ │ ├── service.go │ │ │ │ └── version.go │ │ │ └── transports │ │ │ ├── grpc │ │ │ └── http │ │ └── tictac │ │ ├── endpoints │ │ ├── ... │ │ ├── model │ │ │ └── count.go │ │ ├── postgres │ │ │ ├── init.go │ │ │ └── postgres.go │ │ ├── service │ │ └── transports Layout Single service ● Each service at least contain Endpoints, Service, Transports ● Service: provide expose service method for serving ● Endpoints: handle decode/encode request between service and transport ● Transports: implement support transports for service ● Other associated request components
  • 22. ├── deployments │ ├── docker │ └── helm ├── Makefile ├── README.md ├── CHANGELOG.md ├── cloudbuild.yaml ├── gk.json ├── go.mod ├── go.sum └── skaffold.yaml Layout ● Basic workflow components ○ Skaffold.yaml ○ Cloudbuild.yaml ● README.md, CHANGELOG.md etc documentation. ● Deployment workflow like docker, helm put at deployments
  • 23. Go-kit Microservice demo https://github.com/cage1016/ms-demo - Go-kit base - GRPC/HTTP - Service - Add - TicTac - Kubernetes/Istio - Sakffold support
  • 24. A little copying is better than a little dependency. Proverbs from @rob_pike
  • 25. Test
  • 26. func setupXTestCase(_ *testing.T) (xTestSuit, func(t *testing.T)) { s := xTestSuit{} return s, func(t *testing.T) { } } func TestAddOrganization(t *testing.T) { _, teardownTestCase := setupXTestCase(t) defer teardownTestCase(t) cases := []struct { ... }{ { desc: "A", setupSubTest: func(t *testing.T) func(t *testing.T) { return func(t *testing.T) { } }, }, } for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { teardownSubTest := tc.setupSubTest(t) defer teardownSubTest(t) // test code }) } Unitest skeleton === RUN TestAddOrganization test start === RUN TestAddOrganization/A sub test start sub test teardown test teardown --- PASS: TestAddOrganization (0.00s) --- PASS: TestAddOrganization/A (0.00s) PASS
  • 27. ● Cloudbuild pipeline does not support docker in docker, mock required interface object before test ○ // +build !integration unit ○ // +build integration ● Data layer ○ postgres ● Services ● Transports ○ HTTP/GRPC Unitest . ├── mocks │ ├── account.go │ ├── authz.go │ ├── commons.go │ ├── context.go │ ├── fixture.go │ ├── idp.go │ ├── organization.go │ └── users.go ├── postgres │ ├── database.go │ ├── init.go │ ├── users.go │ └── users_test.go ├── service │ ├── ... │ ├── service.go │ ├── service_test.go │ └── version.go └── transports ├── grpc.go ├── grpc_test.go ├── http.go ├── http_test.go └── nats.go
  • 29. A generator for go-kit that helps you create/update boilerplate code Usage: gk [flags] gk [command] Available Commands: add Use to add additional transports to a service help Help about any command init Initiates a service new A set of generators used to create new cmd/services/transports/middlewares update Use to update service Flags: -d, --debug If you want to se the debug logs. --folder string If you want to specify the base folder of the project. -f, --force Force overwrite existing files without asking. -h, --help help for gk --testing If testing the generator. Use "gk [command] --help" for more information about a command. gk https://github.com/cage1016 /gk/tree/feature/gokitconsul k8sistio Go-kit generator
  • 30. hello: curl localhost:8180/hello | jq generate: go mod init github.com/cage1016/gophercon-tw gk n s hellogophercon sed -i "" 's|Foo(ctx context.Context, s string) (res string, err error)|Hello(ctx context.Context) (res string, err error)|g' internal/app/hellogophercon/service/service.go sed -i "" 's|method=post,expose=true|method=get,expose=true|g' internal/app/hellogophercon/service/service.go gk init hellogophercon sed -i "" 's|return res, err|return "Hello Gophercon TW 2020", err|g' internal/app/hellogophercon/service/service.go gk add grpc hellogophercon cd pb/hellogophercon && ./compile.sh gk init grpc hellogophercon gk new cmd hellogophercon go run cmd/hellogophercon/main.go Makefile
  • 31. Build/Test Store Deploy Monitor workflow
  • 32. KAI CHU CHUNG GDE Cloud GDG Cloud Taipei co-organizers @CageChung https://kaichu.io Q & A