یه دولوپر که سعی میکنه عمیق و کم هزینه باشه، از هرچیزی که بلدم مینویسم تا مطمئنشم درست یادش گرفتم.
ساخت پروژه با معماری مایکروسرویس، زبان گولنگ، اندپوینت رست، کوبرنتیز و... (قسمت اول)
داستان از اونجایی شروع شد که دنبال شغل تو کشورای دیگه گشتم، به عنوان گولنگ دولوپر اقدام کردم، تقریبا هر شرکتی که به گولنگ کار میکرد مایکروسرویس هم کار میکرد پس یه گوگل کردم و به این مطلب توی مدیوم رسیدم، دیدم جالبه گفتم ترجمه کنم تا بهتر تو ذهنم بمونه، این آموزش قرار نیست توضیح بده مایکروسرویس چیه یا چطور کار میکنه و کجا به درد شما میخوره، این مطلب فقط توضیح میده چطور پیاده سازی کنیم. خیلی خب توضیح بسته بریم سراغ متن اصلی نویسنده.
تو اینترنت کلی مطلب درباره ساخت سرویس رستفول با معماری مایکروسرویس توسط زبان گولنگ وجود داره، دنبال بهترین شیوه برای شرکتم بودم و بیشتر این مطالب رو خوندم، بالاخره بهترین شیوه برای پیاده سازی معماری مایکروسرویس پیدا کردم، این شیوه توسط فریمورک protobuf/gRPC که گوگل توسعه میده پیاده سازی میشه، مطمئنم همه دربارهش خوندید یا بعضیها همین الآن دارید از این شیوه استفاده میکنید، ولی فکر میکنم کمتر کسی تجربه توسعه رستفول با معماری مایکروسرویس توسط فریمورک protobuf/gRPC داشته باشه، من فقط یه مطلب تو مدیوم در این باره پیدا کردم:
من نمیخوام دوباره این مطلب رو توضیح بدم، میخوام قدم به قدم توضیح بدم چطور یک اپلیکیشن "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- neutral
- API definition and API implementation MUST be loosely coupled
- API versioning
- I 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 و سرویسگیرندهش برای تست است.
سورس کد قسمت یک از اینجا در دسترستونه
قبل اینکه شروع کنیم نیاز داریم تا ساختار پروژه رو تعریف کنیم.
این یه الگوی خوب برای پروژههای گولنگه:
لطفا این رو همونطوری که من استفاده کردم استفاده کنید.
من از ویندوز ۱۰ ۶۴ بیت استفاده کردم، با این اوصاف فکر نمیکنم مشکلی برای تبدیل این دستورات برای مک یا لینوکس داشته باشید.
در مرحله اول یک پوشه درجایی از کامپیوتر (برای اینکه بتونیم از گو ماژول استفاده کنیم باید خارج از 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 برای شروع.
شما میتونید از لینک زیر بیشتر درمورد proto بخونید:
- حالا Proto compiler binaries از اینجا دانلود کنید:
- محتوای پوشه 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 اضافه کنیم و کامپایلش کنیم
و دوباره کامپایلر پروتو اجرا کنیم تا کدها آپدیت بشه:
// for windows
.\third_party\protoc-gen.cmd
// for mac/linux
./third_party/protoc-gen.sh
این فایل ها باید داخل CI/CD ساخته بشه و به صورت دستی اجراش نکنید.
تموم شد! API ها رو تعریف کردیم.
قدم دوم: توسعه API توسط گولنگ
من از MySQL استفاده میکنم، شما میتونید هر دیتابیسی که باهاش راحت ترید انتخاب کنید.
با استفاده از کوئری پایین جدول ToDo میسازیم:
تو این پست توضیح ندادم چطور MySQL نصب کنید یا چطور دیتابیس توش ایجاد کنید و کوئری بزنید، انتظار دارم اینارو بلد باشید یا تو اینترنت سرچ کنید.
فایل “pkg/service/v1/todo-service.go” با محتوای زیر ایجاد میکنید:
و تمام.
قدم سوم: نوشتن تست برای API
مهم نیست داریم چی رو توسعه میدیم، باید تست بنویسیم، این یه قانونه.
این یه لایبرری خوب برای ماک کردن دیتابیسهای SQL هستش.
از این برای نوشتن تست سرویس تودولیست استفاده میکنم.
این فایل رو در فولدر “pkg/service/v1” ذخیره کنید، پروژه تون باید شبیه عکس پایین شده باشه:
تمام.
قدم چهارم: ایجاد سرور gRPC
فایل “pkg/protocol/grpc/server.go” همراه با محتوایات پایین بسازید:
فانکشن RunServer یک سرویس ToDo میسازه و سرور gRPC اجرا میکنه.
در واقعیت شما باید TLS برای gRPC کانفیگ کنید، اینجا میتونید با یک مثال ببینید چطور باید این کارو انجام بدید.
حالا فایل “pkg/cmd/server.go” همراه با محتوای پایین ایجاد کنید:
این فانکشن RunServer پارامترهای کامندلاین موقع اجرای برنامه دریافت میکنه، با سرور MySQL ارتباط برقرار میکنه، یک سرویس ToDo ایجاد میکنه و فانکشن RunServer قبلی رو از سرور gRPC اجرا میکنه.
در آخر فایل “cmd/server/main.go” با محتوای زیر بسازید:
این تمام چیزی بود که سمت سرور اتفاق میفته، در آخر پروژه باید به این شکل باشه:
قدم پنجم: ساخت کلاینت gRPC
فایل “cmd/client-grpc/main.go” همراه با محتوای زیر بسازید:
این تمام اتفاقیه که سمت کلاینت میفته، خروجی پروژهتون باید شبیه عکس پایین باشه.
قدم ششم: اجرای سرور و کلاینت 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 که امروز توسعه دادیم.
مطلبی دیگر از این انتشارات
ترکیب به جای وراثت در زبان Go
مطلبی دیگر از این انتشارات
راست در مقابل Go , کدام را انتخاب کنیم؟
مطلبی دیگر از این انتشارات
پیاده سازی یک سرویس قابل تست در Golang - قسمت ۱