يوم في حياة مطور Go: كود، خدمات مصغرة، وهدوء في الإنتاج

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: الأساطير والواقع لمبرمج Go

\n\n

في مجتمع تكنولوجيا المعلومات، هناك رأيان متعارضان حول عمل مطور Go. يقول البعض إنها جنة للمثالي: كتابة صارمة للأنواع، عدم وجود وراثة للفئات، وترجمة فائقة السرعة. ويقول آخرون إنها عبارة عن if err != nil لا نهاية لها وكفاح مع الأدوية العامة (على الرغم من إضافتها بالفعل).

\n\n

أين الحقيقة؟ كيف يبدو يوم عمل مطور Go في شركة متوسطة تكتب خدمات مصغرة عالية التحميل؟ اليوم سأفتح باب واقعي. لا ماء - فقط كود وأدوات وحالات حقيقية.

\n\n

أعمل في شركة منتجات حيث Golang هي اللغة الأساسية للواجهة الخلفية. مجموعتنا التقنية: gRPC، PostgreSQL، Kafka، Kubernetes. قصة نموذجية لـ التطوير بلغة Go. لنبدأ.

\n\n

08:30 - الصباح: الخطة ومراجعة الكود

\n\n

لا يبدأ اليوم بالقهوة، بل بتصفح الإشعارات في GitLab وSlack. بينما يكون العقل منتعشًا، هذا هو أفضل وقت لمراجعة طلبات الدمج للزملاء.

\n\n

الروتين الصباحي: ما الذي أتحقق منه أولاً؟

\n
    \n
  • أخطاء CI/CD - إذا فشل البناء ليلاً، فهذه هي المهمة الأولى.
  • \n
  • تعليقات على كودي - في Go، من المعتاد إجراء مراجعات مفصلة.
  • \n
  • رسوم بيانية للمراقبة - هل انخفض زمن الاستجابة بعد النشر أمس؟
  • \n
\n\n

بالمناسبة، عن مراجعة الكود. هناك قاعدة غير مكتوبة في مجتمع Go: يجب أن يكون الكود بسيطًا. إذا كتبت شيئًا معقدًا، سترفض مراجعتك. مثال على تعليق نموذجي من كبير المطورين:

\n\n
// سيء: تجريد مفرط\ntype Processor interface {\n    Process(ctx context.Context, data []byte) ([]byte, error)\n}\n\n// جيد: مجرد دالة\nfunc Process(ctx context.Context, data []byte) ([]byte, error) {\n    // منطق\n}\n
\n\n

في الساعة 09:00 - الاجتماع اليومي. لا نضيع الوقت في قصص طويلة. الشكل: ماذا فعلت أمس، ماذا سأفعل اليوم، هل هناك عوائق. لا "كيف كان مساؤك".

\n\n

09:30 - الغوص في الكود: كتابة خدمة مصغرة بلغة Go

\n\n

اليوم على جدول الأعمال - تحسين خدمة الإشعارات. هذه خدمة مصغرة بلغة Go كلاسيكية تستقبل الأحداث من Kafka وترسل بريدًا إلكترونيًا/دفعًا. المهمة: إضافة دعم للقوالب.

\n\n

أولاً، أفتح هيكل المشروع. في Go، من المعتاد استخدام شجرة مجلدات بسيطة:

\n\n
notifier/\n├── cmd/\n│   └── server/\n│       └── main.go\n├── internal/\n│   ├── handler/\n│   ├── service/\n│   └── repository/\n├── pkg/\n│   └── models/\n└── go.mod\n
\n\n

أبدأ بنموذج البيانات. في Go، للعمل مع قاعدة البيانات، غالبًا ما يستخدمون Go ORM (مثل GORM) أو استعلامات SQL نقية عبر sqlx. أنا أفضل sqlx - سحر أقل، تحكم أكثر.

\n\n
type Template struct {\n    ID      int64  `db:"id"`\n    Name    string `db:"name"`\n    Content string `db:"content"`\n    CreatedAt time.Time `db:"created_at"`\n}\n\nfunc (r *Repository) GetTemplateByName(ctx context.Context, name string) (*Template, error) {\n    var t Template\n    err := r.db.GetContext(ctx, &t, "SELECT * FROM templates WHERE name = $1", name)\n    if err != nil {\n        return nil, fmt.Errorf("get template: %w", err)\n    }\n    return &t, nil\n}\n
\n\n

لاحظ معالجة الأخطاء. في Golang لا يوجد try-catch. يتم التحقق من كل استدعاء دالة بحثًا عن الأخطاء. هذا ليس خطأ، بل ميزة - يصبح الكود قابلاً للتنبؤ. في 5 سنوات من العمل، لم أواجه أبدًا مؤشرًا فارغًا غير متوقع في الإنتاج.

\n\n

11:00 - التكامل مع gRPC

\n\n

المرحلة التالية - إضافة نقطة نهاية gRPC للوحة الإدارة. في التطوير بلغة Go الحديث، أصبح gRPC معيارًا للخدمات الداخلية. إنه أسرع من REST ويولد العملاء تلقائيًا.

\n\n

أولاً، أصف ملف proto:

\n\n
syntax = "proto3";\n\npackage notifier;\n\nservice TemplateService {\n    rpc CreateTemplate (CreateTemplateRequest) returns (TemplateResponse);\                

المدونات

توصيات الكتب