در Grab ، ما بسیار بر روی یک monorepo Go بزرگ برای توسعه پشتیبانی می کنیم ، که مزایایی مانند قابلیت استفاده مجدد کد و قابلیت کشف را ارائه می دهد. با این حال ، با رشد ما ادامه داده و مدیریت یک monorepo بزرگ چالش های منحصر به فرد خود را به همراه می آورد.
به عنوان یک مثال ، استفاده از دستورات Go مانند go get و go list هنگام بازیابی ماژول های Go که در یک مخزن چند ماژول قرار دارند ، بسیار آهسته است. این کندی بر روی بهره وری توسعه دهندگان ، سیستم های CI و میزبان سیستم کنترل نسخه GitLab ما تأثیر می گذارد.
در این نوشته وبلاگ ، ما نحوه کمک Athens، یک پروکسی ماژول Go را برای بهبود تجربه کلی توسعه دهندگان موتور های چرخشی به Go از یک monorepo Go بزرگ در Grab مورد بررسی قرار می دهیم.
نکات کلیدی
- ما زمان اجرای دستور go get را از حدود 18 دقیقه به 12 ثانیه کاهش دادیم زمانی که ماژول های Go monorepo را بازیابی می کردیم. ما با استفاده از حالت fallback network در Athens و GOVCS mode Golang همراه با صرفه جویی در هزینه و بهبود کارایی ، کل اسکلت Athens خود را 70 درصد تنظیم کردیم.
مشکلات و راه حل ها
1. عملکرد بسیار کند دستورات Go
خلاصه مشکل: اجرای دستور go get در monorepo ما زمان قابل توجهی را می گیرد و می تواند منجر به کاهش عملکرد در سیستم کنترل نسخه ما شود.
وقتی با زبان برنامه نویسی Go کار می کنید ، هر روز از دستور go get بسیار متداولی استفاده می کنید. علاوه بر برنامه نویسان ، این دستور همچنین توسط سیستم های CI استفاده می شود.
چه کاری انجام می دهد؟
دستور go get برای دانلود و نصب بسته ها و وابستگی هایشان در Go استفاده می شود. توجه کنید که بسته به اینکه در حالت GOPATH سنتی یا حالت module-aware اجرا می شود ، به طور متفاوت عمل می کند. در Grab ، ما از حالت module-aware در تنظیمات یک مخزن چند ماژول استفاده می کنیم.
هر بار که go get اجرا می شود ، از دستورات Git مانند git ls-remote ، git tag ، git fetch و غیره برای جستجو و دانلود worktree کل استفاده می کند. استفاده بیش از حد از این دستورات Git در monorepo ما به طولانی شدن زمان پردازش کمک می کند و می تواند به سیستم کنترل نسخه ما زحمت بیاورد.
اندازه monorepo ما چقدر است؟
برای به درک کامل از چالش هایی که تیم های مهندسی ما با آن روبرو هستند ، تحت تأثیر گذاشتن git-sizer بر روی monorepo ما بسیار حائز اهمیت است.
در کلانترین دارایی ما ، مانورپو دارای حجم کل 69.3 گیبایت تجزیه نشده است ، عددی کاملا قابل توجه است. برای آنکه به مقایسه برسید ، مخزن هسته Linux ، شناخته شده به خاطر وسعت آن ، در حال حاضر 55.8 گیبایت است.
- حجم کلاناندازه گیری مخزن: مجموع حجم ناسازگار مخزن حجم مجموعی 69.3 گیبایت است ، عددی کاملا حائز اهمیت است.
برای مقایسه ، به گزارش git-sizer مخزن Linux مراجعه کنید.
چقدر “کند” است؟
برای توضیح این مشکل بیشتر ، زمان لازم برای بازیابی ماژول های مختلف در monorepo ما با سرعت دانلود 10 مگابایت بر ثانیه را مقایسه خواهیم کرد.
این یک مثال از نحوه ساختاربندی یک ماژول در monorepo ما است:
در این مثال ، استفاده از go get برای بازیابی یک ماژول بیش از 18 دقیقه طول کشید. اگر ما نیاز داشته باشیم بیش از یک ماژول را در monorepo ما بازیابی کنیم ، ممکن است زمانبر باشد.
چرا در monorepo کند است؟
پیامدها: کاهش بهره وری و فشرده کردن سیستم ها
توسعه دهندگان و CI
هنگامی که عملکرد دستورات Go مانند go get کند است ، باعث تأخیرهای قابل توجه و نارسایی هایی در جریان کارهای توسعه نرم افزاری می شود. این منجر به کاهش بهره وری و ترغیب توسعه دهندگان می شود.
بهینه سازی سرعت عملیات دستورات Go برای اطمینان از جریان کاری کارآمد و تولید نرم افزار با کیفیت است.
همچنین شایان ذکر است که استفاده بیش از حد از دستورات go get همچنین می تواند منجر به مشکلات عملکرد برای VCS شود. وقتی بسته های Go به سرعت با استفاده از go get دانلود می شوند ، مشاهده کردیم که باعث ایجاد یک مانع در خوشه VCS ما می شود که می تواند باعث کاهش عملکرد یا حتی ایجاد مشکلات صف محدودیت نرخ شود.
این منجر به کاهش عملکرد زیرساخت VCS ما می شود و باعث تأخیر یا گاهی اوقات عدم دسترسی برای برخی کاربران و CI می شود.
راه حل: Athens + حالت fallbackNetwork + GOVCS + راه حل تازه بارگذاری سفارشی حافظه نهان
خلاصه مشکل: افزایش سرعت دستور go get با دانلود از VCS ما
با استفاده از Athens، یک سرور proxy برای ماژول های Go (درباره پروتکل GOPROXY بیشتر بخوانید) ، ما به مشکل سرعت را حل کردیم.
نحوه کار Athens چگونه است؟
Athens از یک سیستم ذخیره سازی برای بسته های ماژول Go استفاده می کند ، که همچنین می تواند پیکربندی شود برای استفاده از انواع مختلفی از سیستم های ذخیره سازی مانند Amazon S3 و Google Cloud Storage و غیره.
با کش کردن این بسته های ماژول در ذخیره سازی ، Athens می تواند بسته ها را مستقیماً از ذخیره سازی ارائه دهد به جای درخواست آنها از VCS مربوطه هنگام ارائه دستورات Go مانند go
|
|