ViennaNET: Backend үчүн китепканалардын жыйындысы. 2 бөлүк

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

Бул макалада биз GitHub репозиторийибизден (булактар ​​бул жерде), жана Nuget пакеттери бул жерде.

ViennaNET: Backend үчүн китепканалардын жыйындысы. 2 бөлүк

ViennaNET.Sagas

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

Биздин долбоорлордо биз жөнөкөй, бирок пайдалуу механизмди ишке ашырдык: дастан, тагыраак айтканда, оркестрге негизделген дастан. Анын маңызы төмөндөгүдөй: белгилүү бир бизнес сценарий бар, анда ар кандай кызматтарда операцияларды ырааттуу аткаруу зарыл жана кандайдыр бир кадамда кандайдыр бир көйгөйлөр пайда болсо, бардык мурунку кадамдар үчүн артка кайтаруу процедурасын чакыруу керек. каралган. Ошентип, дастандын аягында, ийгиликке карабастан, биз бардык домендерде ырааттуу маалыматтарды алабыз.

Биздин ишке ашыруу дагы эле анын негизги түрүндө жүргүзүлөт жана башка кызматтар менен өз ара аракеттенүүнүн кандайдыр бир ыкмаларын колдонуу менен байланышкан эмес. Аны колдонуу кыйын эмес: жөн гана SagaBase<T> базалык абстракттуу классынын тукумун түзүңүз, мында T - сиздин контексттик классыңыз, анда сиз дастандын иштеши үчүн зарыл болгон баштапкы маалыматтарды, ошондой эле кээ бир аралык натыйжаларды сактай аласыз. Контексттик инстанция аткаруу учурунда бардык кадамдарга өткөрүлөт. Saga өзү жарандыгы жок класс, ошондуктан керектүү көз карандылыктарды алуу үчүн инстанцияны 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": "..."
  }
],

Мисал ApplicationContext:

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

Эгер туташуу ID көрсөтүлбөсө, анда "демейки" деп аталган байланыш колдонулат.

Объекттерди маалымат базасынын таблицаларына түз карталоо стандарттык NHibernate куралдарын колдонуу менен ишке ашырылат. Сүрөттөмөлөрдү xml файлдары аркылуу да, класстар аркылуу да колдоно аласыз. Unit тесттеринде stub репозиторийлерин ыңгайлуу жазуу үчүн китепкана бар ViennaNET.TestUtils.Orm.

ViennaNET.Orm.* колдонуунун толук мисалдарын тапса болот бул жерде.

ViennaNET.Messaging.*

Кезектер менен иштөө үчүн китепканалардын жыйындысы.

Кезектер менен иштөө үчүн ар кандай МББлардагыдай эле ыкма тандалган, тактап айтканда, колдонулган кезек менеджерине карабастан китепкана менен иштөө боюнча максималдуу мүмкүн болгон бирдиктүү ыкма. Китепкана 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 аркылуу жасалганы маанилүү эмес. Андан кийин, чыгуучу суроо-талапты же билдирүүнү жөнөтүүдөн мурун, маалыматтар контексттен алынып, баш саптарга жайгаштырылат. Ошентип, кийинки кызмат жардамчы маалыматтарды кабыл алат жана ошол эле жол менен башкарат.

Көңүл бурганыңыз үчүн рахмат, комментарийлериңизди жана суранычыңызды күтөбүз!

Source: www.habr.com

Комментарий кошуу