Nkag mus rau hauv .Net microservice ib puag ncig hauv kev xyaum

Nkag mus rau hauv .Net microservice ib puag ncig hauv kev xyaum

Kev sau ntawv yog ib qho cuab yeej tseem ceeb rau cov neeg tsim khoom, tab sis thaum tsim cov kab ke faib tawm, nws dhau los ua lub hauv paus tseem ceeb uas yuav tsum tau muab tso rau hauv lub hauv paus ntawm koj daim ntawv thov, txwv tsis pub qhov nyuaj ntawm kev tsim kho microservices yuav pom tseeb sai sai.

.Net Core 3 ntxiv ib qho feature zoo heev lub peev xwm los dhau cov ntsiab lus sib raug zoo hauv HTTP headers, yog li ntawd, yog tias koj cov ntawv thov siv HTTP hu ncaj qha rau kev sib txuas lus interservice, koj tuaj yeem siv qhov zoo ntawm qhov kev ua haujlwm tawm ntawm lub thawv no. Txawm li cas los xij, yog tias koj lub backend architecture xav tau kev sib txuas lus los ntawm tus neeg xa xov (RabbitMQ, Kafka, thiab lwm yam), koj tseem yuav tsum tau ua haujlwm hloov pauv ntawm cov ntsiab lus sib raug zoo los ntawm cov lus no koj tus kheej.

Hauv tsab xov xwm no, peb yuav siv ib daim ntawv thov web API yooj yim thiab teeb tsa kev sau npe uas yuav

  • tswj kev sib raug zoo ntawm cov cav ntawm cov kev pabcuam ywj pheej kom koj tuaj yeem saib tau txhua yam haujlwm uas tau tshwm sim los ntawm kev thov tshwj xeeb los ntawm tus neeg siv khoom.

  • Muaj ib qho chaw nkag uas yooj yim rau kev tshuaj xyuas kom txawm tias Cov Neeg Pabcuam, uas tau txais cov lus nug zoo li "Kuv tau txais qhov yuam kev hauv daim ntawv thov nrog tus lej thov zoo li no," tuaj yeem siv cov cuab yeej sau npe.

Ua ntej, peb yuav tsum txiav txim siab seb puas muaj tus neeg muab kev pab sau ntawv rau peb daim ntawv thov. Qhov tseem ceeb tshaj plaws rau kev sau ntawv niaj hnub no yog cov qauv, uas txhais tau tias peb yuav tsum ua haujlwm nrog cov khoom es tsis yog cov lus ntawv tiaj tiaj. Ua tsaug rau cov cav no, peb tuaj yeem yooj yim tsim cov lus sawv cev ntawm peb cov lus hauv ntau qhov sib txawv thiab ua kev tshuaj xyuas.

Rau peb daim ntawv thov, peb yuav siv pob Serilog, uas muaj kev txhawb nqa zoo heev rau kev teev cia cov qauv thiab lub kaw lus plugin nplua nuj. Kuv yuav hla cov kauj ruam teeb tsa yooj yim (koj tuaj yeem nrhiav tau ntau tsab xov xwm ntawm lub ncauj lus no) thiab xav tias

  • Seriallog twb tau teeb tsa lawm thiab yog lub cim logger rau koj tus neeg muab kev pabcuam txhaj tshuaj.

  • nws qhov kev teeb tsa suav nrog kev txhim kho cov lus nrog cov khoom ntsiab lus (Enrich.FromLogContext)

Kauj ruam tom ntej yog xaiv lub kaw lus sau cav uas yuav xa cov lus los ntawm Serilog mus rau. Tej zaum qhov kev xaiv qhib qhov chaw feem ntau niaj hnub no yog ELK stack (Elasticsearch, Logstash, thiab Kibana), yog li peb yuav siv qhov ntawd. Rau qhov no, peb yuav siv kev daws teeb meem los ntawm Logz.IO — Tom qab sau npe rau txoj kev npaj dawb, lub zog tag nrho ntawm Lucene search engine nyob ntawm koj cov ntiv tes.

Txhua yam uas peb tseem tshuav yog ntxiv ib pob rau peb qhov project. Serilog.Sinks.Logzio

Install-Package Serilog.Sinks.Logzio

Thiab ntxiv cov enreacher sib xws rau peb qhov kev teeb tsa logger, pub nws nkag mus rau token

LoggerConfiguration loggerConfig = new LoggerConfiguration();
loggerConfig.WriteTo.Logzio(secrets.LogzioToken, 10, TimeSpan.FromSeconds(10), null, LogEventLevel.Debug);

Los ntawm kev tso tawm daim ntawv thov, peb yuav pom peb cov lus tsis yog hauv lub console xwb, tab sis kuj nyob hauv Kibana.

Nkag mus rau hauv .Net microservice ib puag ncig hauv kev xyaum

Interfaces

Nkag mus rau hauv .Net microservice ib puag ncig hauv kev xyaum

Ib daim ntawv thov hom kev pabcuam muaj ob lub interfaces tseem ceeb nrog lub ntiaj teb sab nraud, uas peb yuav hu ua ntsug thiab kab rov tav. Lub interface ntsug yog lub web API uas cov xov tooj los ntawm daim ntawv thov tus neeg siv khoom tuaj txog. Lub interface kab rov tav yog tus neeg xa xov, uas yog siv los pauv cov ntaub ntawv nrog lwm cov kev pabcuam sab hauv.

Cia peb xav txog cov theem ntawm kev siv kev sib raug zoo ntawm txhua qhov interfaces no.

Kev sib raug zoo hauv HTTP cov kev thov

Yuav kom tau txais cov ntaub ntawv ntau li ntau tau, peb yuav tsum tsim kom muaj tus lej sib raug zoo ze rau qhov pib ntawm qhov kev ua ub no li ntau tau, piv txwv li, ntawm lub rooj vag lossis ncaj qha rau ntawm tus neeg siv khoom (mobile lossis web). Txij li thaum peb tab tom cuam tshuam nrog daim ntawv thov backend hnub no, peb tsuas yog xav tau lub taub hau "X-Correlation-ID" uas yuav tsum tau ua hauv txhua qhov kev thov web API.

Ntxiv ib pob khoom Kev Sib Txheeb Xyuas, lub luag haujlwm uas yog coj tus nqi los ntawm lub header uas peb xav tau

Install-Package CorrelationID

Cia peb ntxiv nws rau hauv qhov kev thov ua cov txheej txheem

public class Startup
{
    public void Configure(IApplicationBuilder application)
    {
        application
	    .UseCorrelationId(new CorrelationIdOptions
        {
            Header = "X-Correlation-ID",
            IncludeInResponse = false,
            UpdateTraceIdentifier = false,
            UseGuidForCorrelationId = false
        });
    }
}

Tam sim no cia peb siv nws los tsim ib qho kev lim dej yooj yim:

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();
    }
}

Thiab cia peb ntxiv nws rau tus maub los

[Route("[controller]")]
[ApiController]
[ServiceFilter(typeof(ApiRequestFilter))]
public class CarsController : ControllerBase
{

}

Yog li ntawd, tus maub los yuav tso tawm 400 Qhov kev thov tsis zoo rau txhua qhov kev thov yam tsis muaj lub header nrog tus cim qhia sib xws.

Tom qab peb pib tau txais tus cim los ntawm tus neeg siv khoom, peb yuav tsum ntxiv nws rau hauv cov ntsiab lus sau cia. Peb yuav tsim ib txheej txheej rau qhov no:

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);
        }
    }
}

Hauv peb daim ntawv thov, peb siv tus qauv ILogger los ntawm pob Microsoft.Extensions.Logging.Abstractions, yog li peb yuav ntxiv tus nqi siv kev txuas ntxiv yooj yim rau nws.

public static IDisposable BeginScopeWith(this ILogger logger, params (string key, object value)[] keys)
{
    return logger.BeginScope(keys.ToDictionary(x => x.key, x => x.value));
}

Peb ntxiv ib txheej rau hauv qhov kev thov ua cov kav dej thiab tau txais qhov tshwm sim xav tau.

public class Startup
{
    public void Configure(IApplicationBuilder application)
    {
        application.UseMiddleware<CorrelationIdContextLogger>();
    }
}

Tam sim no txhua yam kev ua ub no uas tsim los ntawm kev thov rau peb lub web API muaj tus cim qhia txog kev sib raug zoo uas lawv tuaj yeem txuas tau yooj yim.

Nkag mus rau hauv .Net microservice ib puag ncig hauv kev xyaum

Kev sib raug zoo hauv cov lus ntawm tus neeg ua lag luam

Kauj ruam tom ntej yog teeb tsa kev xa thiab txais cov cim sib raug zoo los ntawm tus neeg xa xov. Hauv peb qhov piv txwv, peb yuav siv RabbitMQ, thiab lub moj khaum MassTransit ua tus neeg siv khoom. Dua li no, peb yuav hla qhov teeb tsa thawj zaug ntawm MassTransit thiab txav mus ncaj qha rau kev sau cia.

Ua ntej tshaj, peb tuaj yeem pab kom cov cav ntawm MassTransit nws tus kheej, rau qhov no peb yuav ntxiv ib pob rau peb daim ntawv thov MassTransit.Serilog Kev Sib Koos Ua Ke

Install-Package MassTransit.SerilogIntegration

Tam sim no, tom qab ntxiv lub logger rau hauv MassTransit settings, peb yuav pom tau cov framework cav.

services
    .AddSingleton(provider =>
        {
            return Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                cfg.UseSerilog();
            });
        });

Cia peb hais tias peb daim ntawv thov xa ib qho xwm txheej SomethingDoneMessage nrog tus nqi "done" ua lus teb rau POST thov. Daim ntawv cog lus rau cov lus zoo li no tuaj yeem piav qhia raws li hauv qab no:

namespace MbMessages
{
    public interface ISomethingDoneMessageV1
    {
        string Value { get; }
    }
}

Cov lus ntawm MassTransit yog cov ntawv xa ntawv uas muaj cov lus xa los ntawm cov neeg sawv cev. Lub ntawv xa ntawv zoo li no:

{
  "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"
  }
}

Cov lus qhia txog cov teb kev pabcuam uas xav tau rau lub framework nws tus kheej, tab sis peb kuj tuaj yeem ntxiv peb cov khoom ntxiv rau lub hnab ntawv no. Tsis tas li ntawd, MassTransit muaj cov cuab yeej ua tiav rau kev tswj hwm qee qhov teb xaiv tau, qhov nthuav tshaj plaws yog CorrelationId.

Cia peb ntxiv CorrelatedBy interface rau daim ntawv cog lus:

namespace MbMessages
{
    public interface ISomethingDoneMessageV1 : CorrelatedBy<Guid>
    {
        string Value { get; }
    }
}

Cia peb siv nws thiab muab tus nqi rau CorrelationId khoom thaum tsim cov lus:

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; }
}

Yog tias peb saib cov lus tshiab, peb yuav pom tias tus cim sib raug zoo tam sim no tsis yog ib feem ntawm peb cov lus xwb, tab sis kuj yog ib feem ntawm lub hnab ntawv - tus cim no tam sim no kuj yuav siv rau hauv txhua lub cav MassTransit, uas txhais tau tias nws yuav yooj yim dua rau peb los daws cov teeb meem ntawm qib tus neeg xa xov.

{
  "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"
  }
}

Peb tseem yuav tsum teeb tsa kev sau cov khoom siv pabcuam no ntawm cov lus. Yuav ua li no, peb yuav ntxiv ib pob rau hauv qhov project. Serilog.Enrichers.MassTransitMessageLub pob ntxiv ib lub lim rau MassTransit cov lus ua cov pipeline, uas tso cov ntsiab lus ntawm cov lus rau ntawm ib qho thread-safe stack. SerialLog nyeem cov ntsiab lus los ntawm lub stack thiab ntxiv cov khoom ntxiv no rau peb cov cav tov.

Install-Package Serilog.Enrichers.MassTransitMessage

Ntxig ib lub lim rau hauv MassTransit

services
    .AddSingleton(provider =>
        {
            return Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                cfg.UseSerilog();
                cfg.UseSerilogMessagePropertiesEnricher();
            });
        });

Thiab nyob rau hauv Serilog configuration peb ntxiv Enricher

Log.Logger = new LoggerConfiguration()
    .Enrich.FromMassTransitMessage()
    .CreateLogger();

Vim tias daim ntawv thov uas tau txais cov lus los ntawm RabbitMQ queue muaj kev nkag mus rau txhua yam khoom ntawm MassTransit envelope, peb tuaj yeem siv tus cim sib raug zoo hauv daim ntawv thov siv thiab tseem xa nws mus rau hauv qab txoj saw hlau.

Yog li ntawd, peb cov cav tau pib muaj CorrelationId tsis yog hauv ib qho kev pabcuam xwb, tab sis kuj thaum cuam tshuam nrog lwm cov ntawv thov.

Nkag mus rau hauv .Net microservice ib puag ncig hauv kev xyaum

Yog li, qhov system logging uas tshwm sim rau .Net daim ntawv thov tso cai rau peb kom yooj yim sib txuas cov cav los ntawm cov microservices sib txawv kiag li - txawm tias cov uas khiav los ntawm tus neeg xa xov. Thiab nrog Elasticsearch, peb tuaj yeem tshuaj xyuas cov cav sai thiab yooj yim los ntawm kev tsim cov dashboards tsim nyog hauv Kibana (ib qho piv txwv tau pom hauv daim duab txuas nrog rau qhov ntawv tshaj tawm).

Tau kawg, kev nkag mus rau hauv daim foos no yuav tsis suav nrog kev sib cuam tshuam nyuaj ntawm koj cov kev pabcuam thiab ntau yam kev siv sab nraud, tab sis kev tsim kom muaj hom kev txiav txim no thaum pib ntawm kev txhim kho qhov project yog ib qho ntawm cov khoom uas koj yuav ua tsaug rau koj tus kheej ntau zaus.

Koj tuaj yeem tshawb nrhiav cov lej ntawm qhov system tshwm sim hauv qhov project: github.com/a-postx/YA.ServiceTemplate

Tau qhov twg los: www.hab.com

Yuav txhim khu kev qha hosting rau cov chaw nrog DDoS tiv thaiv, VPS VDS servers 🔥 Yuav lub vev xaib hosting txhim khu kev qha nrog kev tiv thaiv DDoS, VPS VDS servers | ProHoster