یه دولوپر که سعی میکنه عمیق و کم هزینه باشه، از هرچیزی که بلدم مینویسم تا مطمئنشم درست یادش گرفتم.
ساخت پروژه با معماری مایکروسرویس، زبان گولنگ، اندپوینت رست، کوبرنتیز و... (قسمت سوم)
این مطلب ادامه قسمت دوم است. در قسمت قبل اندپوینت رست به سرویس gRPC اضافه کردیم، تو این قسمت میخوایم middleware به سرویس gRPC و REST اضافه کنیم.میتونید سورس کد قسمت سوم از اینجا دریافت کنید.
قدم اول: اضافه کردن Uber zap logger
قدم اول اینه اوبر زب با لاگ استاندارد گولنگ عوض کنیم، چون فریمورک میدلور gRPC زب رو پشتیبانی میکنه.
فایل logger.go در پوشه “pkg/logger” همراه با محتوای زیر ایجاد کنید:
فایل “pkg/cmd/server.go” برای اضافه کردن زب آپدیت کنید:
لاگ استاندارد در فایل “pkg/protocol/grpc/server.go” رو با زب عوض کنید، تغییرات رو از اینجا ببینید.
لاگ استاندارد در فایل “pkg/protocol/rest/server.go” رو با زب عوض کنید، تغییرات رو از اینجا ببینید.
قدم دوم: اضافه کردن میدلور logging/tracing به سرویس gRPC
این لایبرری برای اضافه کردن میدلور به gRPC عالیه:
میخوایم اینو برای logging/tracing استفاده کنیم.
فایل logger.go در پوشه “pkg/protocol/grpc/middleware” همراه با محتوای پایین ایجاد کنید:
فایل “pkg/protocol/grpc/server.go” با محتوای پایین جهت اضافه کردن logging/tracing به سرور gRPC عوض کنید:
ساختار پروژهتون باید شبیه به این شده باشه:
خب امتحان کنیم سیستم لاگمون چطور کار میکنه.
سرور 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” همراه با محتوای زیر ایجاد کنید:
حالا فایل logger.go در پوشه “pkg/protocol/rest/middleware” همراه با محتوای زیر ایجاد کنید:
محتوای فایل با “pkg/protocol/rest/server.go”محتوای زیر جایگزین کنید:
ساختار پروژه باید به شکل زیر باشد:
بریم چک کنیم کدها چطور کار میکنند.
سرور 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 اضافه کردیم.
سورس کد قسمت سوم از اینجا در دسترس شماست.
تو قسمت چهارم توضیح میدیم چطور کوبرنتیز برای این پروژه کانفیگ کنیم و روی گوگل کلاد اجراش کنیم.
مطلبی دیگر از این انتشارات
کتابخانه های استاندارد در Go (بخش دوم)
مطلبی دیگر از این انتشارات
گروهبندی سریع کاربران با استفاده از Consistent Hashing
مطلبی دیگر از این انتشارات
مقدمه ایی بر فریم ورک gin (gin-gonic web framework)