ميكروسيرفيسات بلغة Go: الهندسة والممارسة من الألف إلى الياء

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

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

ابدأ الدورة

مقدمة: لماذا Go هي اللغة المثالية للميكروسيرفيسات؟

\n\n

أصبحت هندسة الميكروسيرفيسات المعيار الفعلي لبناء التطبيقات الحديثة القابلة للتوسع. لغة Go (Golang)، التي تم إنشاؤها في مختبرات Google، مثالية لهذه المهمة بفضل بساطتها وأدائها ودعمها المدمج للتوازي. في هذه المقالة، سنقوم بتحليل الدورة الكاملة لإنشاء ميكروسيرفيس بلغة Go: من تصميم الهندسة المعمارية إلى النشر في بيئة الإنتاج.

\n\n

تقدم Go ترجمة سريعة، واستهلاكًا ضئيلًا للذاكرة، وعملًا أصليًا مع الـ Goroutines - الخيوط خفيفة الوزن. وهذا يجعلها خيارًا ممتازًا للأنظمة الموزعة عالية التحميل. سنناقش المفاهيم الأساسية، ونكتب أمثلة على الكود، ونناقش أفضل الممارسات.

\n\n

1. تصميم هندسة الميكروسيرفيس بلغة Go

\n\n

1.1. مبادئ هندسة الميكروسيرفيسات

\n\n

قبل كتابة الكود، من الضروري تحديد حدود الميكروسيرفيسات. المبادئ الأساسية:

\n\n
    \n
  • المسؤولية الواحدة (Single Responsibility) — كل خدمة مسؤولة عن وظيفة تجارية واحدة.
  • \n
  • استقلالية النشر — يمكن تحديث كل ميكروسيرفيس دون إيقاف النظام بأكمله.
  • \n
  • الاقتران الضعيف (Loose Coupling) — تتواصل الخدمات عبر واجهات برمجة تطبيقات (API) محددة بوضوح.
  • \n
  • لامركزية إدارة البيانات — كل خدمة لها قاعدة البيانات الخاصة بها.
  • \n
\n\n

1.2. هيكل مشروع Go للميكروسيرفيس

\n\n

هيكل المجلدات الموصى به لميكروسيرفيس بلغة Go:

\n\n
my-service/\n├── cmd/\n│   └── server/\n│       └── main.go          # نقطة الدخول\n├── internal/\n│   ├── handler/             # معالجات HTTP/gRPC\n│   ├── service/             # منطق الأعمال\n│   ├── repository/          # العمل مع قاعدة البيانات\n│   └── model/               # هياكل البيانات\n├── pkg/\n│   └── api/                 # ملفات proto المشتركة (gRPC)\n├── config/\n│   └── config.go            # الإعدادات\n├── migrations/              # ترحيلات قاعدة البيانات\n├── Dockerfile\n└── go.mod
\n\n

1.3. مثال على ميكروسيرفيس بسيط

\n\n

لنقم بإنشاء ميكروسيرفيس HTTP أساسي لإدارة المستخدمين. نبدأ بتعريف النموذج والمستودع:

\n\n
// internal/model/user.go\npackage model\n\ntype User struct {\n    ID    int64  `json:"id"`\n    Name  string `json:"name"`\n    Email string `json:"email"`\n}\n\n// internal/repository/user_repo.go\npackage repository\n\nimport (\n    "context"\n    "my-service/internal/model"\n)\n\ntype UserRepository interface {\n    GetByID(ctx context.Context, id int64) (*model.User, error)\n    Create(ctx context.Context, user *model.User) (int64, error)\n}\n\ntype inMemoryRepo struct {\n    users map[int64]*model.User\n    nextID int64\n}\n\nfunc NewInMemoryRepo() UserRepository {\n    return &inMemoryRepo{\n        users:  make(map[int64]*model.User),\n        nextID: 1,\n    }\n}\n\nfunc (r *inMemoryRepo) GetByID(ctx context.Context, id int64) (*model.User, error) {\n    user, ok := r.users[id]\n    if !ok {\n        return nil, fmt.Errorf("user not found")\n    }\n    return user, nil\n}\n\nfunc (r *inMemoryRepo) Create(ctx context.Context, user *model.User) (int64, error) {\n    user.ID = r.nextID\n    r.users[user.ID] = user\n    r.nextID++\n    return user.ID, nil\n}
\n\n

2. التواصل بين الميكروسيرفيسات: REST و gRPC وقوائم الانتظار

\n\n

2.1. REST API بلغة Go

\n\n

للتفاعل المتزامن، غالبًا ما يتم استخدام REST أو gRPC. لنلقِ نظرة على وحدة تحكم REST باستخدام المكتبة القياسية net/http والموجه chi:

\n\n
// internal/handler/user_handler.go\npackage handler\n\nimport (\n    "encoding/json"\n    "net/http"\n    "strconv"\n    "my-service/internal/service"\n    "github.com/go-chi/chi/v5"\n)\n\ntype UserHandler struct {\n    svc *service.UserService\n}\n\nfunc NewUserHandler(svc *service.UserService) *UserHandler {\n                

المدونات

توصيات الكتب