ViennaNET: арын хэсэгт зориулсан номын сангийн багц. 2-р хэсэг

Raiffeisenbank .NET хөгжүүлэгчийн нийгэмлэг ViennaNET-ийн агуулгыг товчхон хянаж үзсээр байна. Бид яаж, яагаад ийм байдалд хүрсэн тухай, та эхний хэсгийг уншиж болно.

Энэ нийтлэлд бид GitHub репозитороос олж болох тархсан гүйлгээ, дараалал, мэдээллийн сантай ажиллах хараахан болоогүй номын сангуудыг үзэх болно.эх сурвалжууд энд байна), ба Nuget багцууд энд байна.

ViennaNET: арын хэсэгт зориулсан номын сангийн багц. 2-р хэсэг

ViennaNET.Sagas

Төсөл DDD болон микро үйлчилгээний архитектур руу шилжих үед бизнесийн логикийг өөр өөр үйлчилгээнүүдэд хуваарилах үед олон хувилбарууд нэг дор хэд хэдэн домэйнд нөлөөлдөг тул хуваарилагдсан гүйлгээний механизмыг хэрэгжүүлэх хэрэгцээтэй холбоотой асуудал үүсдэг. Та ийм механизмтай илүү дэлгэрэнгүй танилцаж болно, жишээлбэл, "Бичил үйлчилгээний загвар" номонд Крис Ричардсон.

Төсөлдөө бид энгийн боловч ашигтай механизмыг хэрэгжүүлсэн: сага, эс тэгвээс оркестрт суурилсан сага. Үүний мөн чанар нь дараах байдалтай байна: янз бүрийн үйлчилгээнд дараалсан үйлдлүүдийг хийх шаардлагатай бизнесийн тодорхой хувилбар байдаг бөгөөд хэрэв ямар нэгэн алхам дээр асуудал гарвал өмнөх бүх алхмуудыг буцаах процедурыг дуудах шаардлагатай болно. өгсөн. Тиймээс, домайн төгсгөлд амжилтаас үл хамааран бид бүх домэйн дээр тогтмол өгөгдлийг хүлээн авдаг.

Бидний хэрэгжилт нь үндсэн хэлбэрээр хийгдсэн хэвээр байгаа бөгөөд бусад үйлчилгээтэй харилцах ямар ч аргыг ашиглахтай холбоогүй болно. Үүнийг ашиглахад тийм ч хэцүү биш: зүгээр л SagaBase<T> үндсэн хийсвэр ангийн удамшлыг үүсгээрэй, T нь таны контекст анги бөгөөд энэ нь дасан дээр ажиллахад шаардлагатай анхны өгөгдөл, мөн зарим завсрын үр дүнг хадгалах боломжтой. Гүйцэтгэлийн явцад контекст жишээг бүх үе шатанд дамжуулна. Сага өөрөө харьяалалгүй анги тул шаардлагатай хамаарлыг авахын тулд жишээг DI-д Singleton хэлбэрээр байрлуулж болно.

Жишээ зар:

public class ExampleSaga : SagaBase<ExampleContext>
{
  public ExampleSaga()
  {
    Step("Step 1")
      .WithAction(c => ...)
      .WithCompensation(c => ...);
	
    AsyncStep("Step 2")
      .WithAction(async c => ...);
  }
}

Жишээ дуудлага:

var saga = new ExampleSaga();
var context = new ExampleContext();
await saga.Execute(context);

Төрөл бүрийн хэрэгжилтийн бүрэн жишээг харж болно энд болон хамт угсарч байна туршилтууд.

ViennaNET.Orm.*

Nhibernate-ээр дамжуулан янз бүрийн мэдээллийн сантай ажиллахад зориулсан номын сангийн багц. Бид Liquibase ашиглан DB-First аргыг ашигладаг тул зөвхөн бэлэн мэдээллийн сан дахь өгөгдөлтэй ажиллах функц байдаг.

ViennaNET.Orm.Seedwork и ViennaNET.Orm – үндсэн интерфейсүүд болон тэдгээрийн хэрэгжилтийг агуулсан үндсэн угсралтууд. Тэдний агуулгыг илүү нарийвчлан авч үзье.

интерфэйс IEntityFactoryService болон түүний хэрэгжилт EntityFactoryService Эдгээр нь мэдээллийн сантай ажиллах үндсэн эхлэл юм, учир нь энд Ажлын хэсэг, тодорхой байгууллагуудтай ажиллах репозиторууд, түүнчлэн командын гүйцэтгэгчид болон шууд SQL асуулга бий болно. Заримдаа өгөгдлийн сантай ажиллах ангийн чадварыг хязгаарлах нь тохиромжтой байдаг, жишээлбэл, зөвхөн өгөгдлийг унших боломжийг олгодог. Ийм тохиолдлын хувьд IEntityFactoryService өвөг дээдсийн интерфейс байдаг IEntityRepositoryFactory, энэ нь зөвхөн репозитор үүсгэх аргыг тунхагладаг.

Өгөгдлийн санд шууд хандахын тулд үйлчилгээ үзүүлэгч механизмыг ашигладаг. Манай багуудад ашигладаг DBMS бүр өөрийн гэсэн хэрэгжилттэй байдаг. ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql.

Үүний зэрэгцээ хэд хэдэн үйлчилгээ үзүүлэгчийг нэгэн зэрэг нэг програмд ​​​​бүртгүүлэх боломжтой бөгөөд энэ нь жишээлбэл, нэг үйлчилгээний хүрээнд дэд бүтцийг өөрчлөхөд ямар ч зардалгүйгээр, шат дараалсан шилжилт хөдөлгөөн хийх боломжийг олгодог. нэг DBMS-ээс нөгөө рүү. Шаардлагатай холболт, тиймээс тодорхой аж ахуйн нэгжийн ангиллын үйлчилгээ үзүүлэгчийг сонгох механизм нь (өгөгдлийн сангийн хүснэгтэд зураглал бичих) аж ахуйн нэгжийг BoundedContext ангид (домэйн нэгж бүртгэх аргыг агуулсан) эсвэл түүний залгамжлагчийг бүртгэх замаар хэрэгжүүлдэг. ApplicationContext (програмын нэгж, шууд хүсэлт, командыг бүртгэх аргуудыг агуулсан), тохиргооны холболтын танигчийг аргумент болгон хүлээн авдаг:

"db": [
  {
    "nick": "mssql_connection",
    "dbServerType": "MSSQL",
    "ConnectionString": "...",
    "useCallContext": true
  },
  {
    "nick": "oracle_connection",
    "dbServerType": "Oracle",
    "ConnectionString": "..."
  }
],

Хэрэглээний контекст жишээ:

internal sealed class DbContext : ApplicationContext
{
  public DbContext()
  {
    AddEntity<SomeEntity>("mssql_connection");
    AddEntity<MigratedSomeEntity>("oracle_connection");
    AddEntity<AnotherEntity>("oracle_connection");
  }
}

Хэрэв холболтын ID-г заагаагүй бол "өгөгдмөл" нэртэй холболтыг ашиглана.

Өгөгдлийн сангийн хүснэгтэд байгууллагуудын шууд зураглалыг стандарт NHibernate хэрэгслийг ашиглан хэрэгжүүлдэг. Та тайлбарыг xml файлууд болон классуудаар дамжуулан ашиглаж болно. Unit tests дахь stub репозиторуудыг бичихэд тохиромжтой номын сан байдаг ViennaNET.TestUtils.Orm.

ViennaNET.Orm.* ашиглах бүрэн жишээг олж болно энд.

ViennaNET.Messaging.*

Дараалалтай ажиллах номын сангийн багц.

Дараалалтай ажиллахын тулд янз бүрийн DBMS-тэй ижил хандлагыг сонгосон, тухайлбал, ашигласан дарааллын менежерээс үл хамааран номын сантай ажиллахад хамгийн их боломжтой нэгдсэн арга барилыг сонгосон. Номын сан ViennaNET.Messaging энэ нэгдлийг яг таг хариуцаж, мөн ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue и ViennaNET.Messaging.KafkaQueue IBM MQ, RabbitMQ болон Kafka-д зориулсан адаптерийн хэрэгжилтийг агуулна.

Дараалалтай ажиллахдаа мессеж хүлээн авах, илгээх гэсэн хоёр үйл явц байдаг.

Хүлээн авах талаар бодож үзээрэй. Энд 2 сонголт байна: тасралтгүй сонсох, нэг мессеж хүлээн авах. Дарааллыг байнга сонсохын тулд эхлээд удамшсан процессорын ангиллыг тайлбарлах хэрэгтэй IMessageProcessor, энэ нь ирж буй мессежийг боловсруулах үүрэгтэй. Дараа нь энэ нь тодорхой дараалалд "холбогдсон" байх ёстой бөгөөд үүнийг бүртгүүлэх замаар хийдэг IQueueReactorFactory тохиргооноос дарааллын тодорхойлогчийг зааж:

"messaging": {
    "ApplicationName": "MyApplication"
},
"rabbitmq": {
    "queues": [
      {
        "id": "myQueue",
        "queuename": "lalala",
        ...
      }
    ]
},

Сонсож эхлэх жишээ:

_queueReactorFactory.Register<MyMessageProcessor>("myQueue");
var queueReactor = queueReactorFactory.CreateQueueReactor("myQueue");
queueReactor.StartProcessing();

Дараа нь үйлчилгээ эхэлж, сонсож эхлэх аргыг дуудах үед заасан дарааллын бүх мессежүүд холбогдох процессор руу очно.

Үйлдвэрийн интерфейс дээр нэг мессеж хүлээн авах IMessagingComponentFactory арга бий CreateMessageReceiverЭнэ нь түүнд заасан дарааллаас мессеж хүлээж буй хүлээн авагчийг үүсгэх болно:

using (var receiver = _messagingComponentFactory.CreateMessageReceiver<TestMessage>("myQueue"))
{
    var message = receiver.Receive();
}

Зурвас илгээхийн тулд Та мөн адил ашиглах хэрэгтэй IMessagingComponentFactory мөн мессеж илгээгч үүсгэх:

using (var sender = _messagingComponentFactory.CreateMessageSender<MyMessage>("myQueue"))
{
    sender.SendMessage(new MyMessage { Value = ...});
}

Мессежийг цуваа болгох, цувралаас гаргах гурван бэлэн сонголт байдаг: зүгээр л текст, XML болон JSON, гэхдээ шаардлагатай бол та өөрийн интерфэйсийн хэрэгжилтийг хялбархан хийж болно. IMessageSerializer и IMessageDeserializer.

Бид дарааллын менежер бүрийн өвөрмөц чадварыг хадгалахыг хичээсэн, жишээлбэл. ViennaNET.Messaging.MQSeriesQueue танд зөвхөн текст төдийгүй байт мессеж илгээх боломжийг олгодог ViennaNET.Messaging.RabbitMQQueue чиглүүлэлт болон шууд дарааллыг дэмждэг. RabbitMQ-д зориулсан бидний адаптер боодол нь RPC-ийн зарим дүр төрхийг хэрэгжүүлдэг: бид мессеж илгээж, зөвхөн нэг хариу мессежийн хувьд үүсгэгдсэн тусгай түр зуурын дарааллаас хариу хүлээж байна.

энд үндсэн холболтын нюанс бүхий дарааллыг ашиглах жишээ.

ViennaNET.CallContext

Бид дарааллыг зөвхөн өөр өөр системүүдийн хооронд нэгтгэхийн тулд төдийгүй ижил програмын микро үйлчилгээ, жишээлбэл, домог доторх харилцаа холбоог ашигладаг. Энэ нь хэрэглэгчийн нэвтрэлт, төгсгөлийн бүртгэлд зориулсан хүсэлтийн танигч, эх сурвалжийн IP хаяг, зөвшөөрлийн өгөгдөл зэрэг туслах өгөгдлийг мессежийн хамт дамжуулах шаардлагатай болсон. Энэ мэдээллийг дамжуулах ажлыг хэрэгжүүлэхийн тулд бид номын сан байгуулсан ViennaNET.CallContext, энэ нь үйлчилгээнд орж буй хүсэлтийн өгөгдлийг хадгалах боломжийг олгодог. Энэ тохиолдолд дараалал эсвэл Http-ээр дамжуулан хүсэлтийг хэрхэн хийсэн нь хамаагүй. Дараа нь гарч буй хүсэлт эсвэл мессежийг илгээхийн өмнө контекстээс өгөгдлийг авч толгой хэсэгт байрлуулна. Тиймээс дараагийн үйлчилгээ нь туслах өгөгдлийг хүлээн авч, ижил аргаар удирддаг.

Анхаарал тавьсанд баярлалаа, бид таны сэтгэгдэл, хүсэлтийг хүлээж байна!

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх