Go में CQRS और Event Sourcing: जटिल सिस्टम के लिए आर्किटेक्चर

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

जब सामान्य CRUD पर्याप्त नहीं है: CQRS और Event Sourcing से परिचय

\n

कल्पना करें कि आप एक टिकट बुकिंग सिस्टम बना रहे हैं। जब तक दस उपयोगकर्ता हैं, सब कुछ सरल है। लेकिन जब वे एक हज़ार हो जाते हैं, और फिर एक मिलियन, समस्याएँ शुरू हो जाती हैं: डेटाबेस लॉक हो जाते हैं, क्वेरीज़ संघर्ष करती हैं, और परिवर्तनों का इतिहास पुनर्स्थापित करना असंभव हो जाता है। परिचित स्थिति?

\n

Go-डेवलपमेंट की दुनिया में, जहाँ प्रदर्शन और समानता हमारा सब कुछ है, दो आर्किटेक्चरल पैटर्न इन समस्याओं को हल करने में मदद करते हैं: CQRS (Command Query Responsibility Segregation) और Event Sourcing। आज हम उन्हें व्यवहार में समझेंगे — कोड, उदाहरणों और वास्तविक उपयोग परिदृश्यों के साथ।

\n\n

सरल शब्दों में CQRS क्या है?

\n

CQRS कमांड (लेखन) और क्वेरीज़ (पढ़ना) के बीच जिम्मेदारी का विभाजन है। क्लासिक CRUD में, एक डेटा मॉडल निर्माण और पढ़ने दोनों के लिए जिम्मेदार होता है। CQRS में, हम दो अलग-अलग मॉडल बनाते हैं:

\n
    \n
  • Command model — स्थिति बदलने के लिए जिम्मेदार (निर्माण, अद्यतन, हटाना)
  • \n
  • Query model — केवल डेटा पढ़ने के लिए जिम्मेदार
  • \n
\n

यह प्रत्येक पक्ष को स्वतंत्र रूप से अनुकूलित करने की अनुमति देता है: लेखन सख्ती से मान्य हो सकता है, जबकि पढ़ना डीनॉर्मलाइज़्ड और तेज़ हो सकता है। Go में, गोरूटीन और चैनलों के कारण यह विशेष रूप से प्रभावी है।

\n\n

Go पर CQRS का सरल उदाहरण

\n

चलिए ऑर्डर प्रबंधन के लिए एक बुनियादी सिस्टम बनाते हैं। कमांड से शुरू करते हैं:

\n\n
type CreateOrderCommand struct {\n    OrderID   string\n    UserID    string\n    ProductID string\n    Amount    float64\n}\n\ntype CommandHandler struct {\n    repo *OrderRepository\n}\n\nfunc (h *CommandHandler) HandleCreateOrder(ctx context.Context, cmd CreateOrderCommand) error {\n    order := Order{\n        ID:        cmd.OrderID,\n        UserID:    cmd.UserID,\n        ProductID: cmd.ProductID,\n        Amount:    cmd.Amount,\n        Status:    "pending",\n        CreatedAt: time.Now(),\n    }\n    return h.repo.Save(ctx, order)\n}
\n\n

अब पढ़ने के लिए एक अलग मॉडल बनाते हैं:

\n\n
type OrderQuery struct {\n    repo *ReadRepository\n}\n\ntype OrderView struct {\n    OrderID    string\n    UserName   string\n    ProductName string\n    Total      float64\n    Status     string\n}\n\nfunc (q *OrderQuery) GetOrderSummary(ctx context.Context, orderID string) (*OrderView, error) {\n    return q.repo.GetOrderView(ctx, orderID)\n}
\n\n

ध्यान दें: OrderView में पहले से ही डीनॉर्मलाइज़्ड डेटा (उपयोगकर्ता का नाम, उत्पाद का नाम) है, जो विभिन्न स्रोतों से एकत्र किया गया है। यह पढ़ने को दस गुना तेज़ बनाता है।

\n\n

Event Sourcing: स्थिति नहीं, बल्कि घटनाएँ रिकॉर्ड करना

\n

Event Sourcing डेटा भंडारण के दृष्टिकोण को बदलता है: किसी वस्तु की वर्तमान स्थिति को संग्रहीत करने के बजाय, हम उन घटनाओं का क्रम संग्रहीत करते हैं जो उस स्थिति तक ले गईं। यह एक सुपरपावर देता है: परिवर्तनों का पूरा इतिहास और स्थिति को पीछे "रिवाइंड" करने की क्षमता।

\n\n

Go में Event Sourcing का कार्यान्वयन

\n

चलिए बुनियादी घटना प्रकारों से शुरू करते हैं:

\n\n
type Event struct {\n    ID        string\n    AggregateID string\n    Type      string\n    Data      []byte\n    Timestamp time.Time\n    Version   int\n}\n\ntype EventStore interface {\n    Save(ctx context.Context, events []Event) error\n    Load(ctx context.Context, aggregateID string) ([]Event, error)\n}
\n\n

अब हम एग्रीगेट को लागू करते हैं — एक ऑब्जेक्ट जो घटनाओं से अपनी स्थिति पुनर्स्थापित करता है:

\n\n
type OrderAggregate struct {\n    ID     string\n    Status string\n    Items  []OrderItem\n    Version int\n}\n\nfunc (a *OrderAggregate) Apply(event Event) {\n    switch event.Type {\n    case "OrderCreated":\n        var data OrderCreatedData\n        json.Unmarshal(event.Data, &data)\n        a.ID = data.OrderID\n        a.Status = "created"\n    case "OrderConfirmed":\n        a.Status = "confirmed"\n    case "OrderShipped":\n        a.Stat                

ब्लॉग

पुस्तक अनुशंसाएँ