Il-komunità tal-iżviluppaturi Raiffeisenbank .NET tkompli tirrevedi fil-qosor il-kontenut ta' ViennaNET. Dwar kif u għaliex wasalna għal dan,
F'dan l-artikolu, se ngħaddu minn libreriji li għad iridu jiġu kkunsidrati biex naħdmu ma' tranżazzjonijiet, kjuwijiet u databases distribwiti, li jistgħu jinstabu fir-repożitorju GitHub tagħna (
ViennaNET.Sagas
Meta proġett jaqleb għal DDD u arkitettura ta 'mikroservizz, allura meta l-loġika tan-negozju titqassam f'servizzi differenti, tqum problema relatata mal-ħtieġa li jiġi implimentat mekkaniżmu ta' tranżazzjoni distribwita, minħabba li ħafna xenarji ħafna drabi jaffettwaw diversi oqsma f'daqqa. Tista' ssir familjari ma' mekkaniżmi bħal dawn f'aktar dettall, pereżempju,
Fil-proġetti tagħna, implimentajna mekkaniżmu sempliċi iżda utli: saga, jew aħjar saga bbażata fuq l-orkestrazzjoni. L-essenza tagħha hija kif ġej: hemm ċertu xenarju tan-negozju li fih huwa meħtieġ li jitwettqu b'mod sekwenzjali operazzjonijiet f'servizzi differenti, u jekk jinqalgħu xi problemi fi kwalunkwe pass, huwa meħtieġ li tissejjaħ il-proċedura ta 'rollback għall-passi preċedenti kollha, fejn ikun ipprovdut. Għalhekk, fl-aħħar tas-saga, irrispettivament mis-suċċess, nirċievu dejta konsistenti fl-oqsma kollha.
L-implimentazzjoni tagħna għadha ssir fil-forma bażika tagħha u mhijiex marbuta mal-użu ta’ xi metodi ta’ interazzjoni ma’ servizzi oħra. Mhuwiex diffiċli biex tużah: agħmel dixxendent tal-klassi astratta bażi SagaBase<T>, fejn T hija l-klassi tal-kuntest tiegħek li fiha tista 'taħżen id-dejta inizjali meħtieġa biex is-saga taħdem, kif ukoll xi riżultati intermedji. L-istanza tal-kuntest se tiġi mgħoddija lill-passi kollha matul l-eżekuzzjoni. Saga nnifisha hija klassi mingħajr stat, għalhekk l-istanza tista 'titqiegħed f'DI bħala Singleton biex tikseb id-dipendenzi meħtieġa.
Eżempju ta' reklam:
public class ExampleSaga : SagaBase<ExampleContext>
{
public ExampleSaga()
{
Step("Step 1")
.WithAction(c => ...)
.WithCompensation(c => ...);
AsyncStep("Step 2")
.WithAction(async c => ...);
}
}
Eżempju ta' sejħa:
var saga = new ExampleSaga();
var context = new ExampleContext();
await saga.Execute(context);
Eżempji sħaħ ta' implimentazzjonijiet differenti jistgħu jitqiesu
ViennaNET.Orm.*
Sett ta’ libreriji biex taħdem ma’ diversi databases permezz ta’ Nhibernate. Aħna nużaw l-approċċ DB-First billi nużaw Liquibase, għalhekk hemm biss funzjonalità biex naħdmu mad-dejta f'database lesta.
ViennaNET.Orm.Seedwork и ViennaNET.Orm
– assemblaġġi ewlenin li fihom interfaces bażiċi u l-implimentazzjonijiet tagħhom, rispettivament. Ejja nħarsu lejn il-kontenut tagħhom f'aktar dettall.
Interface IEntityFactoryService
u l-implimentazzjoni tagħha EntityFactoryService
huma l-punt tat-tluq ewlieni għall-ħidma mad-database, peress li l-Unità tax-Xogħol, repożitorji għal ħidma ma 'entitajiet speċifiċi, kif ukoll eżekuturi ta' kmandi u mistoqsijiet diretti SQL huma maħluqa hawn. Xi drabi huwa konvenjenti li tillimita l-kapaċitajiet ta 'klassi biex taħdem ma' database, pereżempju, biex tipprovdi l-abbiltà li taqra d-dejta biss. Għal każijiet bħal dawn IEntityFactoryService
hemm antenat - interface IEntityRepositoryFactory
, li jiddikjara biss metodu għall-ħolqien ta' repożitorji.
Biex taċċessa direttament id-database, jintuża l-mekkaniżmu tal-fornitur. Kull DBMS li nużaw fit-timijiet tagħna għandu l-implimentazzjoni tiegħu stess: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql
.
Fl-istess ħin, diversi fornituri jistgħu jiġu rreġistrati f'applikazzjoni waħda fl-istess ħin, li tippermetti, pereżempju, fi ħdan il-qafas ta' servizz wieħed, mingħajr ebda spiża għall-modifika tal-infrastruttura, li jwettqu migrazzjoni pass pass minn DBMS wieħed għal ieħor. Il-mekkaniżmu għall-għażla tal-konnessjoni meħtieġa u, għalhekk, il-fornitur għal klassi ta’ entità speċifika (li għaliha huwa miktub l-immappjar tat-tabelli tad-database) huwa implimentat permezz tar-reġistrazzjoni tal-entità fil-klassi BoundedContext (fih metodu għar-reġistrazzjoni ta’ entitajiet ta’ dominju) jew is-suċċessur tagħha ApplicationContext (fih metodi għar-reġistrazzjoni ta' entitajiet tal-applikazzjoni , talbiet diretti u kmandi), fejn l-identifikatur tal-konnessjoni mill-konfigurazzjoni huwa aċċettat bħala argument:
"db": [
{
"nick": "mssql_connection",
"dbServerType": "MSSQL",
"ConnectionString": "...",
"useCallContext": true
},
{
"nick": "oracle_connection",
"dbServerType": "Oracle",
"ConnectionString": "..."
}
],
Eżempju Applikazzjoni Kuntest:
internal sealed class DbContext : ApplicationContext
{
public DbContext()
{
AddEntity<SomeEntity>("mssql_connection");
AddEntity<MigratedSomeEntity>("oracle_connection");
AddEntity<AnotherEntity>("oracle_connection");
}
}
Jekk l-ID tal-konnessjoni ma jkunx speċifikat, allura l-konnessjoni msejħa "default" se tintuża.
L-immappjar dirett ta' entitajiet għal tabelli ta' database huwa implimentat bl-użu ta' għodod standard ta' NHibernate. Tista 'tuża d-deskrizzjoni kemm permezz ta' fajls xml kif ukoll permezz ta 'klassijiet. Għal kitba konvenjenti ta 'repożitorji stub fit-testijiet tal-Unità, hemm librerija ViennaNET.TestUtils.Orm
.
Eżempji sħaħ tal-użu ta' ViennaNET.Orm.* jistgħu jinstabu
ViennaNET.Messaging.*
Sett ta’ libreriji biex taħdem bil-kjuwijiet.
Biex taħdem bil-kjuwijiet, intgħażel l-istess approċċ bħal ma 'diversi DBMSs, jiġifieri, l-approċċ unifikat massimu possibbli f'termini ta' ħidma mal-librerija, irrispettivament mill-maniġer tal-kju użat. Librerija ViennaNET.Messaging
huwa preċiżament responsabbli għal din l-unifikazzjoni, u ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue и ViennaNET.Messaging.KafkaQueue
fihom implimentazzjonijiet ta' adapter għal IBM MQ, RabbitMQ u Kafka, rispettivament.
Meta taħdem bil-kjuwijiet, hemm żewġ proċessi: li tirċievi messaġġ u tibgħatu.
Ikkunsidra li tirċievi. Hemm 2 għażliet hawnhekk: għal smigħ kontinwu u biex tirċievi messaġġ wieħed. Biex tisma 'l-kju kontinwament, l-ewwel trid tiddeskrivi l-klassi tal-proċessur li wiret minnha IMessageProcessor
, li se tkun responsabbli għall-ipproċessar tal-messaġġ li jkun dieħel. Sussegwentement, għandu jkun "konness" ma 'kju speċifiku dan isir permezz ta' reġistrazzjoni; IQueueReactorFactory
li jindika l-identifikatur tal-kju mill-konfigurazzjoni:
"messaging": {
"ApplicationName": "MyApplication"
},
"rabbitmq": {
"queues": [
{
"id": "myQueue",
"queuename": "lalala",
...
}
]
},
Eżempju ta’ kif tibda tisma’:
_queueReactorFactory.Register<MyMessageProcessor>("myQueue");
var queueReactor = queueReactorFactory.CreateQueueReactor("myQueue");
queueReactor.StartProcessing();
Imbagħad, meta s-servizz jibda u l-metodu jissejjaħ biex jibda jisma, il-messaġġi kollha mill-kju speċifikat se jmorru għall-proċessur korrispondenti.
Biex tirċievi messaġġ wieħed f'interface tal-fabbrika IMessagingComponentFactory
hemm metodu CreateMessageReceiver
li se joħloq riċevitur jistenna messaġġ mill-kju speċifikat lilu:
using (var receiver = _messagingComponentFactory.CreateMessageReceiver<TestMessage>("myQueue"))
{
var message = receiver.Receive();
}
Biex tibgħat messaġġ għandek bżonn tuża l-istess IMessagingComponentFactory
u oħloq min jibgħat il-messaġġ:
using (var sender = _messagingComponentFactory.CreateMessageSender<MyMessage>("myQueue"))
{
sender.SendMessage(new MyMessage { Value = ...});
}
Hemm tliet għażliet lesti għas-serializing u deserializing messaġġ: test biss, XML u JSON, iżda jekk meħtieġ, tista 'faċilment tagħmel l-implimentazzjonijiet tal-interface tiegħek stess. IMessageSerializer и IMessageDeserializer
.
Aħna ppruvajna nippreservaw il-kapaċitajiet uniċi ta’ kull maniġer tal-kju, eż. ViennaNET.Messaging.MQSeriesQueue
jippermettilek li tibgħat mhux biss test, iżda wkoll messaġġi byte, u ViennaNET.Messaging.RabbitMQQueue
jappoġġja r-rotot u l-kju on-the-fly. It-tgeżwir tal-adapter tagħna għal RabbitMQ jimplimenta wkoll xi semblanza ta 'RPC: nibagħtu messaġġ u nistennew rispons minn kju temporanju speċjali, li jinħoloq biss għal messaġġ ta' rispons wieħed.
Hawnhekk
ViennaNET.CallContext
Aħna nużaw kjuwijiet mhux biss għall-integrazzjoni bejn sistemi differenti, iżda wkoll għall-komunikazzjoni bejn mikroservizzi tal-istess applikazzjoni, pereżempju, fi ħdan saga. Dan wassal għall-ħtieġa li flimkien mal-messaġġ tiġi trażmessa tali data awżiljarja bħall-login tal-utent, l-identifikatur tat-talba għal illoggjar minn tarf sa tarf, l-indirizz IP tas-sors u d-dejta tal-awtorizzazzjoni. Biex nimplimentaw it-trażmissjoni ta’ din id-dejta, żviluppajna librerija ViennaNET.CallContext
, li jippermettilek taħżen data minn talba li tidħol fis-servizz. F'dan il-każ, il-mod kif saret it-talba, permezz ta' kju jew permezz ta' Http, ma jimpurtax. Imbagħad, qabel ma tintbagħat it-talba jew il-messaġġ li joħroġ, id-dejta tittieħed mill-kuntest u titqiegħed fl-intestaturi. Għalhekk, is-servizz li jmiss jirċievi d-dejta awżiljarja u jimmaniġġjaha bl-istess mod.
Grazzi għall-attenzjoni tiegħek, nistennew bil-ħerqa l-kummenti tiegħek u t-talbiet tiegħek!
Sors: www.habr.com