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

داستان از اونجایی شروع شد که دنبال شغل تو کشورای دیگه گشتم، به عنوان گولنگ دولوپر اقدام کردم، تقریبا هر شرکتی که به گولنگ کار میکرد مایکروسرویس هم کار میکرد پس یه گوگل کردم و به این مطلب توی مدیوم رسیدم، دیدم جالبه گفتم ترجمه کنم تا بهتر تو ذهنم بمونه، این آموزش قرار نیست توضیح بده مایکروسرویس چیه یا چطور کار میکنه و کجا به درد شما میخوره، این مطلب فقط توضیح میده چطور پیاده سازی کنیم. خیلی خب توضیح بسته بریم سراغ متن اصلی نویسنده.تو اینترنت کلی مطلب درباره ساخت سرویس رست‌فول با معماری مایکروسرویس توسط زبان گولنگ وجود داره، دنبال بهترین شیوه برای شرکتم بودم و بیشتر این مطالب رو خوندم، بالاخره بهترین شیوه برای پیاده سازی معماری مایکروسرویس پیدا کردم، این شیوه توسط فریمورک protobuf/gRPC که گوگل توسعه میده پیاده سازی میشه، مطمئنم همه درباره‌ش خوندید یا بعضی‌ها همین الآن دارید از این شیوه استفاده می‌کنید، ولی فکر میکنم کمتر کسی تجربه توسعه رست‌فول با معماری مایکروسرویس توسط فریمورک protobuf/gRPC داشته باشه، من فقط یه مطلب تو مدیوم در این باره پیدا کردم: https://medium.com/@thatcher/why-choose-between-grpc-and-rest-bc0d351f2f84 من نمیخوام دوباره این مطلب رو توضیح بدم، میخوام قدم به قدم توضیح بدم چطور یک اپلیکیشن "To Do list" با معماری مایکروسرویس، gRPC و اندپوینت‌های رست توسعه بدید. می‌خوام نشون بدم چطور تو معماری مایکروسرویس تست و میدلور (request-ID and logging/tracing) بنویسید. همچنین با مثال توضیح میدم چطور این اپلیکیشن را بیلد بگیرید و در انتها روی کوبرنتیز دپلوی کنید.این آموزش ۴ قسمت خواهد داشت:قسمت یک: چطور یک سرویس‌دهنده و سرویس‌گیرنده gRPC بنویسیم.قسمت دو: چطور اندپوینت‌های رست رو به سرویس gRPC اضافه کنیم.قسمت سه: چطور میدلور (logging/tracing) به سرویس gRPC و رست اضافه کنیم.قسمت چهار: چطور کوبرنتیز رو کانفیگ کنید و health check اضافه کنیم. (احتمالا این قسمت رو ترجمه نمیکنم میتونید از وبلاگ اصلی بخونید)پیش‌نیازها:این آموزش زبان گولنگ نیست، شما باید از قبل کد زدن با گولنگ رو بلد باشید.باید گولنگ ورژن ۱.۱۱ یا بالاتر رو نصب کنید، ما می‌خوایم از قابلیت ماژول گولنگ استفاده کنیم که از این ورژن در دسترسه.شما باید نصب و راه‌اندازی MySQL بلد باشید، ما برای ذخیره اطلاعات از این دیتابیس استفاده می‌کنیم.ا- API firstاین یعنی چی؟ (این قسمت سادس و ترجمه‌ش واقعا بی‌معنی میشد)API definition MUST be language-, protocol-, transport- neutralAPI definition and API implementation MUST be loosely coupledAPI versioningI need to exclude manual work to sync API definition, API implementation and API documentation. I need API implementation stubs/skeleton and API documentation are generated from API definition automatically.در طول آموزش این نکات رو بیشتر باز میکنم.اپلیکیشن ToDo list با معماری مایکروسرویساین اپلیکیشن باید تسک‌هارو مدیریت کنه، پس جدولمون باید این فیلدهارو داشته باشه:ID (unique integer identifier)Title (text)Description (text)Reminder (timestamp)اپلیکیشن todo به طور معمول شامل اندپوینت‌های ایجاد، دریافت، اصلاح، حذف و همچین دریافت همه تسک‌ها می‌شود.قسمت اول: ایجاد سرویس gRPC CRUDقدم اول: تعریف API توسط protoقسمت یک درباره چگونگی ساخت توسعه سرویس‌دهنده gRPC CRUD و سرویس‌‌گیرنده‌ش برای تست است.سورس کد قسمت یک از اینجا در دسترس‌تونه https://github.com/amsokol/go-grpc-http-rest-microservice-tutorial/tree/part1 قبل اینکه شروع کنیم نیاز داریم تا ساختار پروژه رو تعریف کنیم.این یه الگوی خوب برای پروژه‌های گولنگه: https://github.com/golang-standards/project-layout لطفا این رو همونطوری که من استفاده کردم استفاده کنید.من از ویندوز ۱۰ ۶۴ بیت استفاده کردم، با این اوصاف فکر نمیکنم مشکلی برای تبدیل این دستورات برای مک یا لینوکس داشته باشید.در مرحله اول یک پوشه درجایی از کامپیوتر (برای اینکه بتونیم از گو ماژول استفاده کنیم باید خارج از GOPATH پوشه رو بسازیم) برای ایجاد پروژه بسازید. حالا پروژه رو مقدار دهی اولیه میکنیم:mkdir go-grpc-http-rest-microservice-tutorial cd go-grpc-http-rest-microservice-tutorial go mod init github.com/<you>/go-grpc-http-rest-microservice-tutorialحالا پوشه‌ای برای تعریف API ها میسازیم:mkdir -p api\proto\v1پوشه v1 برای ورژن یک API ساخته شده.درباره API ورژنینگ: این شیوه من برای ساخت ورژن‌های مختلف از API است، هر ورژن داخل فولدری با اسم خودش ساخته میشه.مرحله بعد ساخت فایل todo-service.proto داخل پوشه api\proto\v1 و اضافه کردن متد ایجادِ ToDoService برای شروع. https://gist.github.com/amsokol/bce8ddf48b834bd1d4689dc8b9ceb45c شما میتونید از لینک زیر بیشتر درمورد proto بخونید: https://developers.google.com/protocol-buffers/docs/proto3 حالا Proto compiler binaries از اینجا دانلود کنید: https://github.com/protocolbuffers/protobuf/releases محتوای پوشه bin رو خارج کنید و آدرسش رو به path های environment variable سیستمون اضافه کنید.پوشه “third_party” داخل روت اصلی پروژه بسازیدمحتوای پوشه “include” داخل پوشه “third_party” کپی کنید.ساختار پروژه باید شبیه این باشدحالا کد جنریتور Proto نصب کنیدgo get -u github.com/golang/protobuf/protoc-gen-goفایل protoc-gen.cmd داخل پوشه “third_party” بسازید. برای مک و لینوکس فایل protoc-gen.sh بسازید و محتوای زیر رو در آن کپی کنید:protoc --proto_path=api/proto/v1 --proto_path=third_party --go_out=plugins=grpc:pkg/api/v1 todo-service.protoفولدری برای خروجی کدهای ساخته شده توسط کد ایجاد میکنیم:mkdir -p pkg/api/v1مطمئن بشید تو پوشه go-grpc-http-rest-microservice-tutorial هستید و دستور زیر را اجرا کنید:// for windows .\third_party\protoc-gen.cmd // for mac/linux ./third_party/protoc-gen.shاین دستور فایل todo-service.pb.go داخل فولدر “pkg/model/v1” میسازه.در نتیجه خروجی باید چیزی شبیه این باشهنتیجه جالب بود. حالا بیاید بقیه متدهای todo service اضافه کنیم و کامپایلش کنیم https://gist.github.com/amsokol/9a4cdd4d53f7f32757cc06d34d2c6097 و دوباره کامپایلر پروتو اجرا کنیم تا کدها آپدیت بشه:// for windows .\third_party\protoc-gen.cmd // for mac/linux ./third_party/protoc-gen.shاین فایل ها باید داخل CI/CD ساخته بشه و به صورت دستی اجراش نکنید.تموم شد! API ها رو تعریف کردیم.قدم دوم: توسعه API توسط گولنگمن از MySQL استفاده میکنم، شما میتونید هر دیتابیسی که باهاش راحت ترید انتخاب کنید.با استفاده از کوئری پایین جدول ToDo می‌سازیم: https://gist.github.com/amsokol/245f734d10a410bf2701e4c9482c9ceb تو این پست توضیح ندادم چطور MySQL نصب کنید یا چطور دیتابیس توش ایجاد کنید و کوئری بزنید، انتظار دارم اینارو بلد باشید یا تو اینترنت سرچ کنید.فایل “pkg/service/v1/todo-service.go” با محتوای زیر ایجاد می‌کنید: https://gist.github.com/amsokol/bb7987f6247bdca80eec65ecf21a9b31 ساختار پروژه باید شبیه به این شده باشهو تمام.قدم سوم: نوشتن تست برای API مهم نیست داریم چی رو توسعه میدیم، باید تست بنویسیم، این یه قانونه.این یه لایبرری خوب برای ماک کردن دیتابیس‌های SQL هستش. https://github.com/DATA-DOG/go-sqlmock از این برای نوشتن تست سرویس تودولیست استفاده میکنم.این فایل رو در فولدر “pkg/service/v1” ذخیره کنید، پروژه تون باید شبیه عکس پایین شده باشه:تمام.قدم چهارم: ایجاد سرور gRPCفایل “pkg/protocol/grpc/server.go” همراه با محتوایات پایین بسازید: https://gist.github.com/amsokol/e52d2c3e601b128e9d02a2a5f1ad1fd5 فانکشن RunServer یک سرویس ToDo میسازه و سرور gRPC اجرا میکنه.در واقعیت شما باید TLS برای gRPC کانفیگ کنید، اینجا میتونید با یک مثال ببینید چطور باید این کارو انجام بدید.حالا فایل “pkg/cmd/server.go” همراه با محتوای پایین ایجاد کنید: https://gist.github.com/amsokol/46d5f4794c8d3b8122d93352ac074969 این فانکشن RunServer پارامترهای کامندلاین موقع اجرای برنامه دریافت میکنه، با سرور MySQL ارتباط برقرار میکنه، یک سرویس ToDo ایجاد میکنه و فانکشن RunServer قبلی رو از سرور gRPC اجرا میکنه.در آخر فایل “cmd/server/main.go” با محتوای زیر بسازید: https://gist.github.com/amsokol/7f27b64aeaa4a81541eb9c00f77f3f90 این تمام چیزی بود که سمت سرور اتفاق میفته، در آخر پروژه باید به این شکل باشه:قدم پنجم: ساخت کلاینت gRPCفایل “cmd/client-grpc/main.go” همراه با محتوای زیر بسازید: https://gist.github.com/amsokol/fa4c6046b8bc7d3dcc19329355e60173 این تمام اتفاقیه که سمت کلاینت میفته، خروجی پروژه‌تون باید شبیه عکس پایین باشه.قدم ششم: اجرای سرور و کلاینت gRPCاین قدم آخره تا اطمینان پیدا کنیم سرور gRPC درست کار میکنه.با استفاده از ترمینال سرور gRPC بیلد میگیریم و اجرا می‌کنیم (پارامترهای دیتابیس رو باتوجه به کانفیگ خودتون تغییر بدید)cd cmd/server go build . server.exe -grpc-port=9090 -db-host=<HOST>:3306 -db-user=<USER> -db-password=<PASSWORD> -db-schema=<SCHEMA>اگر همچین خروجی مشاهده کردید:2018/10/13 12:17:23 starting gRPC server...این یعنی سرور اجرا شده.حالا یه ترمینال دیگه باز میکنیم و کلاینت رو بیلد میگیریم و اجرا میکنیمcd cmd/client-grpc go build . client-grpc.exe -server=localhost:9090اگر خروجی شبیه این بود:2018/10/13 12:22:18 Create result: <api:"v1" id:2 > 2018/10/13 12:22:18 Read result: <api:"v1" toDo:<id:2 title:"title (2018-10-13T08:52:18.373811Z)" description:"description (2018-10-13T08:52:18.373811Z)" reminder:<seconds:1539420738 > > > 2018/10/13 12:22:18 Update result: <api:"v1" updated:1 > 2018/10/13 12:22:18 ReadAll result: <api:"v1" toDos:<id:2 title:"title (2018-10-13T08:52:18.373811Z)" description:"description (2018-10-13T08:52:18.373811Z) + updated" reminder:<seconds:1539420738 > > > 2018/10/13 12:22:18 Delete result: <api:"v1" deleted:1 >یعنی همه چی به خوبی کار میکنه.خلاصه قسمت اولتمام این قسمت اول بود، ما سرویس دهنده و سرویس گیرنده gRPC توسعه دادیم.سورس کد قسمت اول از اینجا در دسترس‌تونه.قسمت دوم اختصاص پیدا میکنه به چگونگی اضافه کردن اندپوینت‌های رست به سرویس gRPC که امروز توسعه دادیم.