ميكروسيرفيسات بلغة Go: هندسة معمارية وممارسة متقدمة

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

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

ابدأ الدورة

ميكروسيرفيسات بلغة Go: هندسة معمارية وممارسة متقدمة



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



1. الأنماط المعمارية: CQRS و Event Sourcing بلغة Go



بالنسبة للنماذج المجالية المعقدة، غالبًا ما يكون نمط CRUD التقليدي غير كافٍ. تسمح أنماط CQRS (فصل مسؤولية الأوامر والاستعلامات) و Event Sourcing بفصل عمليات الكتابة والقراءة، بالإضافة إلى تخزين تاريخ تغييرات الحالة.



تنفيذ CQRS في Go

نقوم بتقسيم النموذج إلى أوامر (تغيير الحالة) واستعلامات (قراءة). على سبيل المثال، لنأخذ خدمة إدارة الطلبات.



// commands.gopackage orders

type CreateOrderCommand struct { UserID string Items []OrderItem}

type OrderCommandHandler struct { repo OrderRepository bus EventBus}

func (h *OrderCommandHandler) Handle(ctx context.Context, cmd CreateOrderCommand) error { order := NewOrder(cmd.UserID, cmd.Items) if err := h.repo.Save(ctx, order); err != nil { return err } h.bus.Publish(ctx, OrderCreatedEvent{ OrderID: order.ID, UserID: order.UserID, }) return nil}

// queries.gotype OrderQueryHandler struct { readRepo OrderReadRepository}

func (h *OrderQueryHandler) GetOrderByID(ctx context.Context, orderID string) (*OrderView, error) { return h.readRepo.FindByID(ctx, orderID)}


بالنسبة لـ Event Sourcing، استخدم المكتبة github.com/looplab/eventhorizon أو اكتب تنفيذك الخاص بناءً على قنوات Go.



2. نمط Saga: المعاملات الموزعة



في عالم الميكروسيرفيسات، المعاملات ACID عبر خدمات متعددة غير ممكنة. يحل نمط Saga هذه المشكلة من خلال سلسلة من المعاملات المحلية مع إجراءات تعويضية.



التصميم التنسيقي (Choreography) مقابل التنسيق المركزي (Orchestration)

هناك نهجان: التصميم التنسيقي (تتواصل الخدمات عبر الأحداث) والتنسيق المركزي (منسق مركزي). لمشاريع Go، غالبًا ما يتم اختيار التصميم التنسيقي بسبب لامركزيته.



// saga.gopackage saga

type SagaStep struct { Name string Action func(ctx context.Context) error Compensate func(ctx context.Context) error}

type Saga struct { steps []SagaStep}

func (s *Saga) Execute(ctx context.Context) error { executed := []SagaStep{} for _, step := range s.steps { if err := step.Action(ctx); err != nil { // تعويض جميع الخطوات المنفذة for i := len(executed) - 1; i >= 0; i-- { executed[i].Compensate(ctx) } return err } executed = append(executed, step) } return nil}

// مثال على الاستخدام:func CreateOrderSaga(ctx context.Context) error { saga := Saga{ steps: []SagaStep{ {Name: "ReserveInventory", Action: reserveInventory, Compensate: releaseInventory}, {Name: "ChargePayment", Action: chargePayment, Compensate: refundPayment}, {Name: "SendEmail", Action: sendEmail, Compensate: noop}, }, } return saga.Execute(ctx)}


لوسطاء الرسائل، استخدم RabbitMQ أو NATS - فهما يتكاملان بشكل ممتاز مع Go عبر الحزم github.com/streadway/amqp و github.com/nats-io/nats.go.



3. gRPC والتفاعل بين الخدمات



غالبًا ما تصبح واجهات REST API عنق زجاجة في الميكروسيرفيسات بسبب التنسيق النصي و

المدونات

توصيات الكتب