
Kuweka magogo ni chombo muhimu sana cha msanidi programu, lakini wakati wa kuunda mifumo iliyosambazwa, inakuwa jiwe ambalo linahitaji kuwekwa kwenye msingi wa programu yako, vinginevyo ugumu wa kuendeleza huduma ndogo utachukua haraka.
.Net Core 3 ameongeza vyema , kwa hivyo ikiwa programu zako zitatumia simu za moja kwa moja za HTTP kwa mawasiliano kati ya huduma, basi unaweza kuchukua fursa ya utendakazi huu wa nje ya kisanduku. Walakini, ikiwa usanifu wako wa nyuma unahusisha mwingiliano kupitia wakala wa ujumbe (RabbitMQ, Kafka, n.k.), basi bado unahitaji kuwa na wasiwasi juu ya kupitisha muktadha wa uunganisho kupitia ujumbe huu mwenyewe.
Katika makala hii tutachukua maombi rahisi ya mtandao-api na kuandaa ukataji miti, ambayo itakuwa
kudumisha uunganisho wa mwisho hadi mwisho kati ya kumbukumbu za huduma huru ili uweze kutazama kwa urahisi shughuli zote ambazo zilisababishwa na ombi maalum kutoka kwa mteja.
kuwa na sehemu moja ya kuingilia yenye uchanganuzi unaofaa, ili hata Usaidizi uweze kutumia zana ya ukataji miti, ambayo maswali kama "Nilipata hitilafu katika programu na kitambulisho kama hicho na kama vile" inaweza kutumika.
Kwanza, tunahitaji kuamua juu ya mtoa huduma wa kukata miti kwa ajili ya maombi yetu. Mahitaji makuu ya ukataji wa kisasa ni muundo, i.e. hatupaswi kufanya kazi na ujumbe wa maandishi gorofa, lakini kwa vitu. Shukrani kwa kumbukumbu kama hizo, tunaweza kuunda maoni ya ujumbe wetu kwa urahisi kutoka kwa mitazamo tofauti na kufanya uchanganuzi.
Kwa maombi yetu tutatumia kifurushi cha Serilog, ambacho kina usaidizi bora wa ukataji miti uliopangwa na mfumo tajiri wa kuongeza. Nitaruka hatua za msingi za kuiweka (unaweza kupata idadi kubwa ya vifungu kwenye mada hii) na kufanya dhana kwamba
Serilog tayari imesanidiwa na ndiyo kiweka kumbukumbu chaguo-msingi kwa mtoaji wako wa sindano ya utegemezi
usanidi wake unajumuisha uboreshaji wa ujumbe wenye sifa za muktadha (Enrich.FromLogContext)
Hatua inayofuata ni kuchagua ni mfumo gani wa kati wa kukusanya kumbukumbu wa kutuma ujumbe kutoka kwa Serilog hadi. Labda chaguo la kawaida la chanzo wazi leo ni stack ya ELK (Elasticsearch, Logstash na Kibana), basi hebu tuchukue. Ili kufanya hivyo, tutatumia toleo kutoka - baada ya kujiandikisha kwa mpango wa bure, tuna uwezo wote wa injini ya utafutaji ya Lucene mikononi mwetu.
Tunachotakiwa kufanya ni kuongeza kifurushi kwenye mradi wetu
Install-Package Serilog.Sinks.Logzio
Na ongeza kiboreshaji kinacholingana kwenye usanidi wa logger yetu, ukilisha ishara ya ufikiaji
LoggerConfiguration loggerConfig = new LoggerConfiguration();
loggerConfig.WriteTo.Logzio(secrets.LogzioToken, 10, TimeSpan.FromSeconds(10), null, LogEventLevel.Debug);
Kwa kuzindua programu, tutaweza kutazama ujumbe wetu sio tu kwenye koni, bali pia katika Kibana.

Interfaces

Katika programu ya aina ya huduma, tunaweza kutofautisha miingiliano miwili kuu kwa mwingiliano wake na ulimwengu wa nje, wacha tuichague kama wima na mlalo. Kiolesura cha wima ni API ya wavuti ambayo simu kutoka kwa programu ya mteja hufika. Mlalo ni wakala wa ujumbe ambao hutumiwa kubadilishana data na huduma zingine za ndani.
Wacha tuzingatie hatua za kuanzisha uunganisho kwenye kila moja ya violesura hivi.
Uwiano katika maombi ya HTTP
Ili kupata taarifa nyingi iwezekanavyo, tunahitaji kuzalisha kitambulisho cha uunganisho karibu iwezekanavyo na mwanzo wa shughuli, i.e. kwenye lango au moja kwa moja kwenye mteja (simu ya rununu au wavuti). Kwa kuwa leo tunashughulika na maombi ya nyuma, tutaonyesha tu juu yake mahitaji ya kichwa cha lazima cha "X-Correlation-ID" katika maombi yote kwa API ya wavuti.
Kuongeza kifurushi , ambayo kazi yake ni kuchukua thamani kutoka kwa kichwa tunachohitaji
Install-Package CorrelationID
Hebu tuiongeze kwenye bomba la usindikaji wa ombi
public class Startup
{
public void Configure(IApplicationBuilder application)
{
application
.UseCorrelationId(new CorrelationIdOptions
{
Header = "X-Correlation-ID",
IncludeInResponse = false,
UpdateTraceIdentifier = false,
UseGuidForCorrelationId = false
});
}
}
Sasa tutaitumia kuunda kichujio rahisi cha vitendo:
public sealed class ApiRequestFilter : ActionFilterAttribute
{
public ApiRequestFilter(IApiRequestTracker apiRequestTracker, ICorrelationContextAccessor correlationContextAccessor)
{
_correlationContextAccessor = correlationContextAccessor ?? throw new ArgumentNullException(nameof(correlationContextAccessor));
}
private readonly ICorrelationContextAccessor _correlationContextAccessor;
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!Guid.TryParse(_correlationContextAccessor.CorrelationContext.CorrelationId, out Guid correlationId))
{
context.Result = new BadRequestResult();
return;
}
await next.Invoke();
}
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
await next.Invoke();
}
}
Na uiongeze kwa mtawala
[Route("[controller]")]
[ApiController]
[ServiceFilter(typeof(ApiRequestFilter))]
public class CarsController : ControllerBase
{
}
Matokeo yake, mtawala ataonyesha ombi 400 Mbaya kwa maombi yote bila kichwa na kitambulisho sambamba.
Baada ya kuanza kupokea kitambulisho kutoka kwa mteja, lazima tuiongeze kwenye muktadha wa ukataji miti, tutafanya safu ya kutunga kwa hili:
public class CorrelationIdContextLogger
{
public CorrelationIdContextLogger(RequestDelegate next)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
}
readonly RequestDelegate _next;
public async Task InvokeAsync(HttpContext httpContext, ILogger<CorrelationIdContextLogger> logger, ICorrelationContextAccessor correlationContextAccessor)
{
if (Guid.TryParse(correlationContextAccessor.CorrelationContext.CorrelationId, out Guid correlationId))
{
using (logger.BeginScopeWith(("CorrelationId", correlationId)))
{
await _next(context);
}
}
else
{
await _next(context);
}
}
}
Katika programu yetu, tunatumia ILogger ya kawaida kutoka kwa kifurushi cha Microsoft.Extensions.Logging.Abstractions, kwa hivyo tutaongeza thamani kwa kutumia kiendelezi rahisi kwake.
public static IDisposable BeginScopeWith(this ILogger logger, params (string key, object value)[] keys)
{
return logger.BeginScope(keys.ToDictionary(x => x.key, x => x.value));
}
Tunaongeza safu kwenye bomba la usindikaji wa ombi na kupata matokeo yaliyohitajika.
public class Startup
{
public void Configure(IApplicationBuilder application)
{
application.UseMiddleware<CorrelationIdContextLogger>();
}
}
Sasa shughuli zote zinazotolewa na maombi kwa API yetu ya wavuti zina kitambulisho cha uunganisho ambacho zinaweza kuunganishwa kwa urahisi.

Uwiano katika ujumbe wa wakala
Hatua inayofuata ni kusanidi usambazaji na upokeaji wa kitambulisho cha uunganisho kupitia wakala wa ujumbe. Katika mfano wetu, tutatumia RabbitMQ, na kuchukua mfumo wa MassTransit kama mteja. Tena, hebu turuke usanidi wa awali wa kufanya kazi na MassTransit na twende moja kwa moja ili kusanidi ukataji miti.
Kuanza, tunaweza kujumuisha kumbukumbu za MassTransit yenyewe; kwa hili tutaongeza kifurushi kwenye programu yetu
Install-Package MassTransit.SerilogIntegration
Sasa baada ya kuongeza logger kwenye mipangilio ya MassTransit, tutaweza kuona kumbukumbu za mfumo.
services
.AddSingleton(provider =>
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.UseSerilog();
});
});
Ruhusu ombi letu lijibu ombi la POST kwa kutuma tukio la SomethingDoneMessage lenye thamani "imefanywa". Mkataba wa ujumbe kama huo unaweza kuelezewa kama ifuatavyo:
namespace MbMessages
{
public interface ISomethingDoneMessageV1
{
string Value { get; }
}
}
Ujumbe wa MassTransit kimsingi ni bahasha ambayo ujumbe wa wakala huambatanishwa. Bahasha inaonekana kama hii:
{
"messageId": "59020000-5dba-0015-10b8-08d77ec28593",
"requestId": "59020000-5dba-0015-5674-08d77ec28592",
"conversationId": "59020000-5dba-0015-bca8-08d77ec28594",
"destinationAddress": "rabbitmq://bear.rmq.cloudamqp.com/aelzlsta/ya.servicetemplate.receiveendpoint",
"headers": {},
"messageType": [
"urn:message:MbMessages:ISomethingDoneMessageV1"
],
"message": {
"value": "done"
}
}
Ujumbe unaonyesha nyanja za huduma ambazo ni muhimu kwa uendeshaji wa mfumo yenyewe, lakini tuna uwezo wa kuongeza mali zetu za ziada kwenye bahasha hii. Kwa kuongezea, MassTransit ina zana zilizojumuishwa za kufanya kazi na sehemu zingine za hiari, inayovutia zaidi ambayo ni kitambulisho cha uunganisho cha CorrelationId.
Wacha tuongeze kiolesura cha CorrelatedB kwenye mkataba wa ujumbe:
namespace MbMessages
{
public interface ISomethingDoneMessageV1 : CorrelatedBy<Guid>
{
string Value { get; }
}
}
Wacha tuitekeleze na tupe thamani kwa mali ya CorrelationId wakati wa kuunda ujumbe:
internal class SomethingDoneMessageV1 : ISomethingDoneMessageV1
{
internal SomethingDoneMessageV1(Guid correlationId, string value)
{
CorrelationId = correlationId;
Value = value;
}
public Guid CorrelationId { get; private set; }
public string Value { get; private set; }
}
Ikiwa tunatazama ujumbe uliosasishwa, tutaona kwamba kitambulisho cha uunganisho kimekuwa sio sehemu ya ujumbe wetu tu, bali pia sehemu ya bahasha - kitambulisho hiki sasa kitatumika pia katika kumbukumbu zote za MassTransit, ambayo inamaanisha itakuwa rahisi zaidi. ili tushughulikie matatizo katika kiwango cha wakala wa ujumbe.
{
"messageId": "59020000-5dba-0015-10b8-08d77ec28593",
"requestId": "59020000-5dba-0015-5674-08d77ec28592",
"conversationId": "59020000-5dba-0015-bca8-08d77ec28594",
"correlationId": "c7ff562a-b639-415b-9add-c9e524a727cc",
"destinationAddress": "rabbitmq://bear.rmq.cloudamqp.com/aelzlsta/ya.servicetemplate.receiveendpoint",
"headers": {},
"messageType": [
"urn:message:MbMessages:ISomethingDoneMessageV1"
],
"message": {
"correlationId": "c7ff562a-b639-415b-9add-c9e524a727cc",
"value": "Hello"
}
}
Tunachotakiwa kufanya ni kusanidi uwekaji kumbukumbu wa sifa hizi za huduma za ujumbe; kwa hili tutaongeza kifurushi kwenye mradi. . Kifurushi kinaongeza kichujio kwenye bomba la kuchakata ujumbe wa MassTransit ambalo huweka muktadha wa ujumbe kwenye safu salama ya uzi. Serilog inasoma muktadha kutoka kwa rafu na inaongeza sifa hizi za ziada kwa vitu vyetu vya kumbukumbu.
Install-Package Serilog.Enrichers.MassTransitMessage
Katika MassTransit tunaingiza chujio
services
.AddSingleton(provider =>
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.UseSerilog();
cfg.UseSerilogMessagePropertiesEnricher();
});
});
Na katika usanidi wa Serilog tunaongeza mtunzaji
Log.Logger = new LoggerConfiguration()
.Enrich.FromMassTransitMessage()
.CreateLogger();
Kwa kuwa programu inayopokea ujumbe kutoka kwa foleni ya RabbitMQ ina ufikiaji wa mali yote ya bahasha ya MassTransit, tunaweza kutumia kitambulisho cha uunganisho kinachotokea ndani ya programu inayotumia, na pia kuipitisha zaidi kwenye mnyororo wa simu.
Kama matokeo, kumbukumbu zetu zilianza kuwa na CorrelationId sio tu ndani ya huduma moja, lakini pia wakati wa kuingiliana na programu zingine.

Kwa hivyo, mfumo unaotokana wa ukataji miti katika programu za .Net huturuhusu kuunganisha kumbukumbu kutoka kwa huduma ndogo tofauti bila matatizo yoyote - hata zile zinazofanya kazi kupitia wakala wa ujumbe. Na kwa usaidizi wa Elasticsearch, tunaweza kuchambua kumbukumbu kwa haraka na kwa urahisi kwa kujenga dashibodi tunazohitaji huko Kibana (mfano unaonyeshwa kwenye picha kwa chapisho).
Bila shaka, kuingia katika fomu hii haitashughulikia mwingiliano mgumu kati ya huduma zako na mifumo mbalimbali ya nje, lakini kuanzisha utaratibu huo mwanzoni mwa maendeleo ya mradi ni mojawapo ya mambo ambayo utajishukuru zaidi ya mara moja.
Unaweza kuelewa msimbo wa chanzo wa mfumo unaosababisha katika mradi:
Chanzo: mapenzi.com
