ساخت پروژه با معماری مایکروسرویس، زبان گولنگ، اندپوینت رست، کوبرنتیز و... (قسمت سوم)

این مطلب ادامه قسمت دوم است. در قسمت قبل اندپوینت رست به سرویس gRPC اضافه کردیم، تو این قسمت میخوایم middleware به سرویس gRPC و REST اضافه کنیم.می‌تونید سورس کد قسمت سوم از اینجا دریافت کنید.

قدم اول: اضافه کردن Uber zap logger

قدم اول اینه اوبر زب با لاگ استاندارد گولنگ عوض کنیم، چون فریمورک میدلور gRPC زب رو پشتیبانی میکنه.

فایل logger.go در پوشه “pkg/logger” همراه با محتوای زیر ایجاد کنید:

https://gist.github.com/amsokol/70ed47cd4c32bc658f8c726e5f51f94e

فایل “pkg/cmd/server.go” برای اضافه کردن زب آپدیت کنید:

https://gist.github.com/amsokol/a655142929103438214e8d75c8766146

لاگ استاندارد در فایل “pkg/protocol/grpc/server.go” رو با زب عوض کنید، تغییرات رو از اینجا ببینید.

لاگ استاندارد در فایل “pkg/protocol/rest/server.go” رو با زب عوض کنید، تغییرات رو از اینجا ببینید.


قدم دوم: اضافه کردن میدلور logging/tracing به سرویس gRPC

این لایبرری برای اضافه کردن میدلور به gRPC عالیه:

https://github.com/grpc-ecosystem/go-grpc-middleware

میخوایم اینو برای logging/tracing استفاده کنیم.

فایل logger.go در پوشه “pkg/protocol/grpc/middleware” همراه با محتوای پایین ایجاد کنید:

https://gist.github.com/amsokol/f41dc65c68eba00fcf66be616adb019e

فایل “pkg/protocol/grpc/server.go” با محتوای پایین جهت اضافه کردن logging/tracing به سرور gRPC عوض کنید:

https://gist.github.com/amsokol/0c8b5fcee7c725f0e15f4eef5dfcf80c

ساختار پروژه‌تون باید شبیه به این شده باشه:

خب امتحان کنیم سیستم لاگ‌مون چطور کار می‌کنه.

سرور gRPC با لاگ لول دیباگ (-log-level=-1) اجرا می‌کنیم:

cd cmd/server 
go build . 
server.exe -grpc-port=9090 -http-port=8080 -db-host=<HOST>:3306 -db-user=<USER> -db-password=<PASSWORD> -db-schema=<SCHEMA> -log-level=-1 -log-time-format=2006-01-02T15:04:05.999999999Z07:00

یه ترمینال دیگه باز میکنم تا سرویس گیرنده gRPC اجرا کنیم:

cd cmd/client-rest 
go build . 
client-rest.exe -server=http://localhost:8080

برگردیم به سرور gRPC و به خروجی ترمینال نگاه میکنیم، اگه چیزی شبیه این بود یعنی همه چی به درستی کار میکنه:

API server listening at: 127.0.0.1:2345
{"level":"info","ts":"2018-09-16T09:54:16.8474966+03:00","msg":"starting HTTP/REST gateway..."}
{"level":"info","ts":"2018-09-16T09:54:16.8484985+03:00","msg":"starting gRPC server..."}
{"level":"info","ts":"2018-09-16T09:54:16.8554788+03:00","msg":"pickfirstBalancer: HandleSubConnStateChange: 0xc00016c060, READY","system":"grpc","grpc_log":true}
{"level":"debug","ts":"2018-09-16T09:54:28.5287447+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:49838","grpc.start_time":"2018-09-16T09:54:28+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Create","peer.address":"[::1]:49838","grpc.code":"OK","grpc.time_ms":99.84400177001953}
{"level":"debug","ts":"2018-09-16T09:54:28.6258332+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:49838","grpc.start_time":"2018-09-16T09:54:28+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Read","peer.address":"[::1]:49838","grpc.code":"OK","grpc.time_ms":38.01499938964844}
{"level":"debug","ts":"2018-09-16T09:54:28.6695219+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:49838","grpc.start_time":"2018-09-16T09:54:28+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Update","peer.address":"[::1]:49838","grpc.code":"OK","grpc.time_ms":42.224998474121094}
{"level":"debug","ts":"2018-09-16T09:54:28.6873289+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:49838","grpc.start_time":"2018-09-16T09:54:28+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"ReadAll","peer.address":"[::1]:49838","grpc.code":"OK","grpc.time_ms":16.808000564575195}
{"level":"debug","ts":"2018-09-16T09:54:28.7319168+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:49838","grpc.start_time":"2018-09-16T09:54:28+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Delete","peer.address":"[::1]:49838","grpc.code":"OK","grpc.time_ms":41.12799835205078}


قدم سوم: اضافه کردن میدلور به رست

می‌خوایم ۲ تا میدلور به رست اضافه کنیم:

  • Request-ID
  • Logging/Tracing

میدلور Request-ID یک آیدی یونیک به ریکوئست HTTP اضافه میکنه. میدلور Logging/Tracing در قسمت بررسی لاگ‌های سرور به ما کمک میکنه تا ریکوئست‌های هر کاربر را از دیگر کاربران متمایز کنیم و مورد بررسی قرار بدیم.

فایل request-id.go در پوشه “pkg/protocol/rest/middleware” همراه با محتوای زیر ایجاد کنید:

https://gist.github.com/amsokol/249c338c73a8cfac7cd9bba80f755e17

حالا فایل logger.go در پوشه “pkg/protocol/rest/middleware” همراه با محتوای زیر ایجاد کنید:

https://gist.github.com/amsokol/ed20b0e79cb02c41945575071f64ef94

محتوای فایل با “pkg/protocol/rest/server.go”محتوای زیر جایگزین کنید:

https://gist.github.com/amsokol/bfcce2cdc0dcfc59b3fac0358556e924

ساختار پروژه باید به شکل زیر باشد:

بریم چک کنیم کدها چطور کار می‌کنند.

سرور gRPC با لاگ لول (-log-level=-1) اجرا کنید:

cd cmd/server 
go build . 
server.exe -grpc-port=9090 -http-port=8080 -db-host=<HOST>:3306 -db-user=<USER> -db-password=<PASSWORD> -db-schema=<SCHEMA> -log-level=-1 -log-time-format=2006-01-02T15:04:05.999999999Z07:00

یه ترمینال دیگه باز کنید و کلاینت rest اونجا اجرا کمید:

cd cmd/client-rest 
go build . 
client-rest.exe -server=http://localhost:8080

برگردید به تریمنالی که توش سرور gRPC اجرا کرده بودید، خروجی باید همچین چیزی باشه:

API server listening at: 127.0.0.1:2345
{"level":"info","ts":"2018-09-16T10:28:30.0875991+03:00","msg":"starting HTTP/REST gateway..."}
{"level":"info","ts":"2018-09-16T10:28:30.0886057+03:00","msg":"starting gRPC server..."}
{"level":"info","ts":"2018-09-16T10:28:30.0936242+03:00","msg":"pickfirstBalancer: HandleSubConnStateChange: 0xc000052070, READY","system":"grpc","grpc_log":true}
{"level":"debug","ts":"2018-09-16T10:28:42.3320283+03:00","msg":"request started","request-id":"PC/5P2xo0mYah-000001","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"POST","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo"}
{"level":"debug","ts":"2018-09-16T10:28:42.4345359+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:50178","grpc.start_time":"2018-09-16T10:28:42+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Create","peer.address":"[::1]:50178","grpc.code":"OK","grpc.time_ms":100.51200103759766}
{"level":"debug","ts":"2018-09-16T10:28:42.4345359+03:00","msg":"request completed","request-id":"PC/5P2xo0mYah-000001","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"POST","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo","elapsed-ms":102.5076}
{"level":"debug","ts":"2018-09-16T10:28:42.5072257+03:00","msg":"request started","request-id":"PC/5P2xo0mYah-000002","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"GET","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/29"}
{"level":"debug","ts":"2018-09-16T10:28:42.5457395+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:50178","grpc.start_time":"2018-09-16T10:28:42+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Read","peer.address":"[::1]:50178","grpc.code":"OK","grpc.time_ms":37.51100158691406}
{"level":"debug","ts":"2018-09-16T10:28:42.5457395+03:00","msg":"request completed","request-id":"PC/5P2xo0mYah-000002","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"GET","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/29","elapsed-ms":38.5138}
{"level":"debug","ts":"2018-09-16T10:28:42.5467358+03:00","msg":"request started","request-id":"PC/5P2xo0mYah-000003","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"PUT","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/29"}
{"level":"debug","ts":"2018-09-16T10:28:42.590229+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:50178","grpc.start_time":"2018-09-16T10:28:42+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Update","peer.address":"[::1]:50178","grpc.code":"OK","grpc.time_ms":42.492000579833984}
{"level":"debug","ts":"2018-09-16T10:28:42.590229+03:00","msg":"request completed","request-id":"PC/5P2xo0mYah-000003","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"PUT","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/29","elapsed-ms":43.4932}
{"level":"debug","ts":"2018-09-16T10:28:42.5913265+03:00","msg":"request started","request-id":"PC/5P2xo0mYah-000004","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"GET","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/all"}
{"level":"debug","ts":"2018-09-16T10:28:42.6090751+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:50178","grpc.start_time":"2018-09-16T10:28:42+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"ReadAll","peer.address":"[::1]:50178","grpc.code":"OK","grpc.time_ms":17.74799919128418}
{"level":"debug","ts":"2018-09-16T10:28:42.6111404+03:00","msg":"request completed","request-id":"PC/5P2xo0mYah-000004","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"GET","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/all","elapsed-ms":19.8139}
{"level":"debug","ts":"2018-09-16T10:28:42.6121388+03:00","msg":"request started","request-id":"PC/5P2xo0mYah-000005","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"DELETE","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/29"}
{"level":"debug","ts":"2018-09-16T10:28:42.6541939+03:00","msg":"finished unary call with code OK","peer.address":"[::1]:50178","grpc.start_time":"2018-09-16T10:28:42+03:00","system":"grpc","span.kind":"server","grpc.service":"v1.ToDoService","grpc.method":"Delete","peer.address":"[::1]:50178","grpc.code":"OK","grpc.time_ms":42.05500030517578}
{"level":"debug","ts":"2018-09-16T10:28:42.6541939+03:00","msg":"request completed","request-id":"PC/5P2xo0mYah-000005","http-scheme":"http","http-proto":"HTTP/1.1","http-method":"DELETE","remote-addr":"[::1]:50181","user-agent":"Go-http-client/1.1","uri":"http://localhost:8080/v1/todo/29","elapsed-ms":42.055ghwio


خلاصه قسمت سوم

تمام این برای قسمت سوم بود. ما میدلور برای هردوسرویس gRPC و REST اضافه کردیم.

سورس کد قسمت سوم از اینجا در دسترس شماست.

تو قسمت چهارم توضیح میدیم چطور کوبرنتیز برای این پروژه کانفیگ کنیم و روی گوگل کلاد اجراش کنیم.