Net-Base Iris

06.06.2026

Freastalaí Ardfheidhmíochta REST i Delphi: Teorainneacha Iarratais, Pool Snáithithe agus iompar glan i gcás ró-ualach (sleachta foinse)

Freastalaí ardfheidhmíochta REST i Delphi ní bhíonn gasta toisc ‘JSON tapa’ amháin; tá sé gasta mar thoradh ar chomhthráthúlacht rialaithe, amanna scoir docht agus iompar glan faoi ró-ualaigh. Taispeánann an t-alt seo geata comhthráthúchais praiticiúil le Semaphore agus freagraí 429/503...

06.06.2026

Ó théama an iris go cleachtas tionscadail

Leathanaigh seirbhíse agus teicniúla oiriúnacha don alt

Cén fáth a theipeann ar „High Performance“ i REST i Delphi go minic de bharr comhthráthachta

Is annamh a bhíonn freastalaí High Performance REST Delphi teoranta sa chleachtas do thréimhse CPU ghlan in aghaidh an iarratais; go minic bíonn sé teoranta de bharr comhthráthachta neamhrialaithe: iomarca iarratas ag teacht ag an am céanna, iomarca fiosruithe bunachar sonraí ag rith go comhuaineach nó I/O bacach (comhad, líonra, bunachar sonraí). Ní bhíonn an toradh díreach ‘níos mo moill’; tá sé cosúil le imoibriú slabhra: níos mó snáithíní, níos mó scuaine, titim sa phóil nasc, méadú ar moilleanna, time-outs ar thaobh an chliaint agus, sa deireadh, freastalaí atá fós “beo” ach nach soláthraíonn freagraí seasmhacha.

Ní hé tráchtas aonair an leigheas, ach iompar ró-ualach atá smachtaithe: nuair a shroicheann an freastalaí a theorainneacha, ní mór dó iarratais a dhiúltú go luath agus go dírithe (go tipiciúil HTTP 429 nó 503), seachas iad a ligean isteach i scuaine gan teorainn. Dá réir sin tá an píosa cód seo beartaithe: geata comhthráthachta éadrom (Semaphore) le timeouts, atá in-infheidhmithe i ndeighiltí REST atá ann cheana — is cuma an bhfuil tú ag úsáid Indy, WebBroker, Horse nó do chiseal HTTP féin.

Architekturidee: Concurrency-Gate vor dem „teuren Teil“

Is simplí an smaoineamh bunúsach: roimh an gcuid chostasach (ceangal le bunachar sonraí, tuarascálacha casta, freagraí móra JSON) áirítear tógáil token ó Semaphore. Mura bhfuil token ar fáil, tugtar freagra rialaithe láithreach. Tá sé tábhachtach: caithfear an geata seo a scaoileadh go muiníneach (try/finally), agus caithfear é a chur sa marcód a dhéanann an obair chostasach i ndáiríre — ní hamháin ag tús an request-handler má tá parser/router/deimhniú le rith ina dhiaidh sin.

Leis seo ní bhíonn an ualach “easnamhach” ach tá sé beartaithe: freagraíonn an freastalaí níos lú iarratas ag an am céanna, ach le moilleanna níos seasmhaí. I bhfeidhmchláir ghnó saincheaptha is minice an rogha seo níos tairbhiúla ná amanna barr shórtacha i mbunchlochchláir thástála shintéiseacha.

Source-Schnipsel: Request-Limiter mit Timeout, 429/503 und Telemetrie-Hooks

Tá an cód Delphi thíos ag cur i bhfeidhm geata comhthráthachta mar rang TRestRequestGate. Tá sé bunaithe ar TSemaphore (as System.SyncObjs; is comhaireora é Semaphore do rochtain chomhthráthach teoranta). Soláthraíonn glao an gheata nó dúil «Lease»-réada (RAII-ähnantach: scaoileadh sa Destructor) nó socraíonn sé freagra láithreach um ró-ualach. Tá hooks breise ann do logging/monitóireacht ionas go bhfeicfidh tú i mbeartas an chláir cén fáth ar dhiúltaíodh iarratais.

unit RESTRequestGate;

interface

uses
System.SysUtils,
System.Classes,
System.SyncObjs,
System.Diagnostics;

type
// Comhthéacs íosta le haghaidh logging/tracing; is féidir é a leathnú, m.sh. le User/Route.
TRESTGateContext = record
RequestId: string;
Route: string;
RemoteIp: string;
end;

TRESTOverloadDecision = (odAccepted, odRejectedBusy, odRejectedTimeout);

// Hook do theiliméireacht oibríochta (m.sh. chuig comhad, Syslog, Prometheus-Exporter, srl.)
TRESTGateEvent = reference to procedure(const Ctx: TRESTGateContext;
Decision: TRESTOverloadDecision;
WaitedMs: Integer;
InFlight: Integer);

// Réad léasa: scaoileadh an Token sa Destructor.
TRESTGateLease = class
private
FSemaphore: TSemaphore;
FInFlightCounter: PInteger;
FReleased: Boolean;
public
constructor Create(ASem: TSemaphore; ACounter: PInteger);
destructor Destroy; override;
procedure Release;
end;

TRESTRequestGate = class
private
FSem: TSemaphore;
FMaxInFlight: Integer;
FInFlight: Integer;
FOnEvent: TRESTGateEvent;
public
constructor Create(AMaxInFlight: Integer);
destructor Destroy; override;

// TimeoutMs = 0: gan aon fanacht, láithreach 429/503
function TryAcquire(const Ctx: TRESTGateContext; TimeoutMs: Cardinal;
out Lease: TRESTGateLease;
out WaitedMs: Integer;
out Decision: TRESTOverloadDecision): Boolean;

property OnEvent: TRESTGateEvent read FOnEvent write FOnEvent;
property MaxInFlight: Integer read FMaxInFlight;
function InFlight: Integer;
end;

implementation

uses
System.Math;

{ TRESTGateLease }

constructor TRESTGateLease.Create(ASem: TSemaphore; ACounter: PInteger);
begin
inherited Create;
FSemaphore := ASem;
FInFlightCounter := ACounter;
FReleased := False;
end;

destructor TRESTGateLease.Destroy;
begin
Release;
inherited;
end;

procedure TRESTGateLease.Release;
begin
if FReleased then
Exit;
FReleased := True;

// Ar dtús laghdaigh an comhaireamh, ansin scaoil an Semaphore.
TInterlocked.Decrement(FInFlightCounter^);
FSemaphore.Release;
end;

{ TRESTRequestGate }

constructor TRESTRequestGate.Create(AMaxInFlight: Integer);
begin
inherited Create;
if AMaxInFlight <= 0 then
raise EArgumentException.Create(‚Ní mór go mbeadh AMaxInFlight > 0‘);

FMaxInFlight := AMaxInFlight;
FInFlight := 0;

// InitialCount = MaxCount = AMaxInFlight
FSem := TSemaphore.Create(nil, AMaxInFlight, AMaxInFlight, “);
end;

destructor TRESTRequestGate.Destroy;
begin
FSem.Free;
inherited;
end;

function TRESTRequestGate.InFlight: Integer;
begin
Result := TInterlocked.CompareExchange(FInFlight, 0, 0);
end;

function TRESTRequestGate.TryAcquire(const Ctx: TRESTGateContext; TimeoutMs: Cardinal;
out Lease: TRESTGateLease; out WaitedMs: Integer; out Decision: TRESTOverloadDecision): Boolean;
var
Sw: TStopwatch;
WaitRes: TWaitResult;
CurrentInFlight: Integer;
begin
Lease := nil;
WaitedMs := 0;
Decision := odRejectedBusy;

Sw := TStopwatch.StartNew;
if TimeoutMs = 0 then
WaitRes := FSem.WaitFor(0)
else
WaitRes := FSem.WaitFor(TimeoutMs);

WaitedMs := Integer(Min(Sw.ElapsedMilliseconds, High(Integer)));

case WaitRes of
wrSignaled:
begin
CurrentInFlight := TInterlocked.Increment(FInFlight);
Lease := TRESTGateLease.Create(FSem, @FInFlight);
Decision := odAccepted;
Result := True;

if Assigned(FOnEvent) then
FOnEvent(Ctx, Decision, WaitedMs, CurrentInFlight);
end;

wrTimeout:
begin
// wrTimeout le TimeoutMs > 0: fanacht sonraithe, ach teorannaithe.
Decision := odRejectedTimeout;
Result := False;
if Assigned(FOnEvent) then
FOnEvent(Ctx, Decision, WaitedMs, InFlight);
end;
else
begin
// wrAbandoned/cásanna earráide: diúltaigh go coimeádach
Decision := odRejectedBusy;
Result := False;
if Assigned(FOnEvent) then
FOnEvent(Ctx, Decision, WaitedMs, InFlight);
end;
end;
end;

end.

Cuspóir: Seasmhacht faoi ualach in ionad „gach rud ag an am céanna“

Le MaxInFlight sonraítear cé mhéad requests is féidir dul ag an „ghné chostasach“ ag an am céanna. Ní hé seo go comhfhiosach an „líon núicléas CPU“, ach paraiméadar oibriúcháin. Ag endpoints atá trom le bunachar sonraí bíonn sé minic loighciúil MaxInFlight a shocrú i gcaidreamh leis an DB-Connection-Pool (m.sh. Pool = 20, MaxInFlight = 12 go 16), ionas nach mbacfaidh gach request ceangal agus go leanfaidh snáitheanna eile i ndiaidh.

Coinníollacha teorannacha agus piolláin

  • Try/Finally é riachtanach: Caithfear an Lease a scaoileadh go cinnte. Má tá eisceachtaí sa endpoint, déanann sin an geata „leachtach“ agus fanfaidh an freastalaí buan ar „busy“.
  • Socraigh Timeout go ciallmhar: TimeoutMs=0 is teorainn chrua í (diúltaítear láithreach). Cuireann Timeout gearr (de ghnáth 50 go 150 ms) na buaicphointí i gceart, gan sraitheanna feithimh a thógáil.
  • Ná cuir an geata ró-luath: D’fhéadfadh fíordheimhniú (m.sh. Bearer/JWT) nó routing a bheith saor; ba chóir go ngníomhódh an semaphore roimh an rannóg atá fíor-chostasach. Ar an lámh eile: má bhíonn an Auth costasach (m.sh. i gcoinne córas aitheantais seachtrach), caithfear é a theorannú freisin.
  • 429 vs 503: Tá HTTP 429 („Too Many Requests“) oiriúnach nuair ba chóir do chliaint iarracht athdhéanach a dhéanamh go dírithe. Tá 503 („Service Unavailable“) oiriúnach nuair nach bhfuil an tseirbhís, go sealadach, in ann iarratais a ghlacadh ar bhealach bríúil. I mbeideanna cásanna moltar ceannlíne Retry-After.

Comhtháthú i REST-Handler: Indy/WebBroker/Horse pragmatach

Tá an sliocht seo deartha go heisiach neodrach ó thaobh framework de. Níl uait ach áit amháin ina rachaidh requests „tríd“. Go minic bíonn singleton domhanda nó geata in aghaidh grúpa bealaigh (m.sh. „/reports“ níos lú, „/health“ gan geata). Samplaí d’fhionnachtain mar phatrún:

  • Líon an comhthéacs (RequestId, Route, RemoteIp)
  • TryAcquire le Timeout gairid
  • Má dhiúltaítear scríobh freagra láithreach (429/503) agus críochnaigh
  • Maireann an Lease sa scóp go dtí tar éis an chuid chostasaí

I Horse (Middleware) tá an geata gar do ghrúpa bealaigh. I WebBroker is féidir leat oibriú sa Action-Handler cuí. I Indy braitheann sé ar an méid má tá snáithe agat in aghaidh an request; oibríonn an geata fós, chomh fada agus a bhíonn na codanna costasacha teoranta go glan.

Ard-Feidhmíochta REST Freastalaí Delphi: Freagraí ró-ualaithe nach nimhíonn cliaint

Ní hamháin cód-stáit iad freagraí ró-ualaithe. Má dhéanann cliaint iarracht athdhéanach láithreach go fíochmhar ar 429/503, cruthaíonn sin stoirm athdhéanach. I dtimpeallachtaí córais ilchineálacha (Aipeanna Soghluaiste, C# Services, Legacy-Clients) cuidíonn iompar comhsheasmhach:

  • Retry-After: mar shampla 1 go 3 soicind, ag brath ar an endpoint. Is tagaire ama soiléir é sin.
  • Corp gearr: Tá JSON beag cosúil le {"error":"server_busy","requestId":"..."} leordhóthanach. Caithfidh réada earréada móra CPU agus bandaleithead breise.
  • Health-Endpoint gan teorannú: Ba chóir don monatóireacht sonraí a sholáthar fiú faoi ualach (más gá le bratach „degraded“).

Mura bhfuil, má chuireann tú reverse proxy cosúil le nginx os comhair an aip: comhréitigh am-amaí agus buffering ann. Is féidir le proxy ualach a laghdú (TLS-Termination, Keep-Alive), ach is féidir leis ualach a aistriú freisin (m.sh. corpanna iarratais móra a choinneáil i mbuffer). Sa chleachtas oibriúcháin tá sé riachtanach go bhfuil na teorainneacha comhsheasmhach: Proxy-Timeout > App-Timeout, murach sin feicfidh cliaint „Gateway Timeout“, cé go bhféadfadh an aip a bheith tar éis diúltú go glan.

Snáithithe, poill DB agus Keep-Alive: Cá a bhriseann sé síos sa chleachtas

Réitíonn an Gate an fhadhb „an iomarca ag an am céanna“, ach ní chuireann sé cosc go huathoibríoch ar iarratas aonair acmhainní iomarcacha a ghabháil. Tarlaíonn trí phointe imeartha tipiciúla ó thionscadail Delphi go beacht ag na comhéadan idir snáithithe, bunachar sonraí agus naisc HTTP:

  • Blocálann iarratas il-acmhainní teanntachta: Ar dtús nasc DB, ansin glao HTTP seachtrach, ansin rochtain ar chomhad. Má tharlaíonn seo go léir sa snáithe iarratais céanna, méadaítear an t-am blocála iolrach. Cé go gcuireann an Gate teorainn leis an iolraitheacht, laghdaíonn an ráta aschuir go mór. Tá sé úsáideach anseo spleáchais a dhíchomhcheangal (m.sh. glaonna seachtracha a dhéanamh asíncrónach, réamhghnó a ríomh trí Job-Queue).
  • BDE-athsholáthar le nasc dúchasach – Pooling und Transaktionen: BDE-Ablosung mit nativer Anbindung is féidir leis nascanna a phooláil, ach coinneoidh idirbheart „fada“ (m.sh. toisc go mbíonn cruthú JSON nó seiceálacha gnó idir StartTransaction agus Commit) an nasc gan ghá. Cleachtas glan is ea an t-idirbheart chomh gar agus is féidir a chur timpeall na ráitis iarbhír agus an t-éadáil nó an bhailíochtú a dhéanamh lasmuigh den idirbheart, más féidir ó thaobh an ghnó.
  • HTTP Keep-Alive mar eatóir cuimhne i bhfolach: Cuireann Keep-Alive laghdú ar handshakeanna, ach d’fhéadfadh sé go dtiocfadh go leor sockets oscailte de bharr go leor cliant i mbun folmhaithe. Go háirithe i Windows- agus Linux-seirbhísí ní fheictear ansin “CPU ardaigh”, ach “Handles/FDs lán” nó méadú ar RAM de bharr buidéil/puffers. Cabhraíonn amanna idle soiléire ar an fhreastalaí agus ar an Reverse Proxy, agus teorainn in aghaidh IP-cliant má ligeann an timpeallacht é.

An toradh: MaxInFlight níl sé ina luach statach. Braithfidh sé ar do acmhainn is moille agus is tanaí (DB, córais seachtracha, stóráil) agus ar cé chomh maith agus a choinníonn iarratas na hacmhainní sin le chéile.

Slonn feidhmíochta in aice leis an Gate: Ná measc JSON, DB agus I/O

Cobhsaíonn an Gate an chórais, ach ní dhéanann sé ionadaíocht ar eacnamaíocht shoiléir na ndeisiúir. Tá trí bhacchéim i bhfreastalaithe Delphi REST a thagann chun cinn go minic:

  • Tógáil JSON le sliseanna idirmheánacha neamh-riachtanacha: Go minic cruthaítear ualach de bharr go leor stríocanna Unicode sealadacha. Má tá sé indéanta, tóg an JSON go treoshuíomh srutha (Writer/Stream) seachas rudaí idirmheánacha ollmhóra, go háirithe ag endpointeanna liosta.
  • Rochtain ar an mbunachar sonraí „in aghaidh an mhíre“: Is é an N+1-queries agus lookups in aghaidh an róla an clasaiceach. Is fearr joins dírithe, batch-queries agus comhthógáil ar an bhfreastalaí. I gcás torthaí an-mhóra bíonn pagináil le sórtáil seasta úsáideach (ionas nach ‘scaoilfidh’ na leathanaigh).
  • I/O blocálach sa snáithe iarratais: Ba chóir rochtain comhaid nó glaonna HTTP seachtracha a theorannú go docht nó a aistriú chuig píplíne asíncrónach. Murach sin, bhlocálfaidh tú snáitheanna costasacha díreach ag fanacht.

Do réitigh fiontraíochta digiteacha atá fhorbartha de réir a chéile is minic gurb é seo an pointe buailte: cuirtear endpoint leis “go tapa” agus oibríonn sé go dtí go dtagann ualach réalaíoch agus toirte sonraí. Ansin léirítear an bhfuil teorainneacha ailtireachta tarraingthe go soiléir (sraith rochtana sonraí, caching, straitéisí bulk, timeouts soiléire).

Diancheardlárú agus Oibriú: Cad ba chóir duit a thomhas

Tá an Hook OnEvent deartha go huafásach simplí. Sa chleachtas ba chóir duit ar a laghad na luachanna seo a leanas a thaifeadadh:

  • InFlight (paraléilte reatha ar an Gate)
  • WaitedMs (cé mhéad „Queueing“ atá tú ag ligean)
  • Decision (accepted/busy/timeout)
  • Route/RemoteIp (anailís ghinearálta ar chúiseanna, gan neamhaird a dhéanamh ar chosaint sonraí)

Le seo gheobhaidh tú comhartha an bhfuil na teorainneacha ró-dhian (an iomarca 429) nó ró-éadrom (WaitedMs ard, moill ag méadú). Agus feicfidh tú an bhfuil bealaí aonair ag smachtú. Tá sé seo cinntitheach do Windows- agus Linux-Services sa ghnáthshaol: gan teleiméireacht, éiríonn fadhb feidhmíochta go tapa ina chluiche tomhais idir an líonra, an bunachar sonraí, an proxy agus an iarratas.

Aisteach, ach an-úsáideach: „WaitedMs“ mar tháscaire réamhfhógra

Téann go leor foirne i ngnách díreach chuig an am freagartha agus an CPU. WaitedMs is minic an táscaire níos fearr, toisc go léiríonn sé go bhfuil iarratais ag fanacht cheana roimh an obair iarbhír. Má mhéadaíonn WaitedMs agus fanann an CPU i leibhéal measartha, ní hé an CPU de ghnáth an acmhainn gann ach pool (nascanna bunachar sonraí), lock i loighic an ghnó nó seirbhís downstream seachtrach. Sábhálann sé sin am san anailís chúiseanna, toisc gur féidir leat díriú níos spriocdhírithe ar „Pool/Lock/I/O“ in ionad „barrfheabhsú comhipiléir“.

Eagsúlachtaí: Geataí in aghaidh bealaí, tosaíochtaí agus „Fast Lane“

Tá geata amháin do gach rud simplí, ach ní hamháin idéalach i gcónaí. Eagsúlachtaí le breithmheas:

  • Geata do ghrúpa bealaí: „/reports“ dian, „/api/orders“ measartha, „/health“ oscailte. Mar sin seachnaítear go gcuirfeadh iarratais tuarascála costasacha isteach ar phróisis lárnacha.
  • Fast Lane do Riarachán/Monatóireacht: Geata ar leith le paralelacht bheag, ionas go mbeidh gníomhaíochtaí oibríochta indéanta fiú faoi ualach.
  • Teorainneacha bunaithe ar bhuiséad: Má athraíonn méideanna freagra go mór, d’fhéadfadh buiséad byte breise cabhrú (m.sh. uasmhéid X MB ag an am céanna le linn giniúna). Tá sé sin níos casta, ach réalaíoch do íosluchtuithe móra.

Tábhachtach: is éasca a dhéanamh de thosaíocht mar rud polaitiúil („tá mo dheireadhphointe níos tábhachtaí“). Fanann sé seasmhach ó thaobh teicniúil má tá tosaíochtaí nasctha le próisis (m.sh. fáiltiú ordú roimh tuarascáil), ní le róil nó roinnte.

Conclúid: An fiú an Geata — agus cá ndéanann an cur chuige teip?

Is eilimint phraiticiúil é Concurrency-Gate do fheidhmighneach ard-fheidhmíochta REST freastalaí i Delphi, toisc go gcuireann sé cumas bainistithe ar Overload agus go coinníonn sé do chórais seasmhach faoi ualach buaic. Tá sé an-úsáideach go háirithe má tá deireadhphointí nasctha le bunachar sonraí agat, má tá Reverse Proxy os comhair, nó má ghineann iliomad cliant (Legacy, Portale, Services) ualach i dtonnta.

Tá na teorainneacha soiléir: má tá an obair féin in aghaidh gach iarratais ró-chostasach (ceisteanna neamhéifeachtacha, réada JSON móra, córais seachtracha a bhacann), ní chuirfidh an geata ach i bhfolach na comharthaí. Sa chás sin, ní mór rochtain sonraí, straitéisí taisceála, ama-amanna freagartha agus, más gá, próiseáil asíncrónach (Queue/Job-System) a chur i bhfeidhm. Mar chrios sábháilteachta i mbainistíocht, is minic gurb é an geata an difríocht idir ’seal réasúnta‘ agus ‚go hiomlán neamhúsáidte‘.

Mura dteastaíonn uait iompar Overload a ionchorprú i Delphi REST-API agus REST-Server atá ann cheana, nó más mian leat teorainneacha a chothromú go néata le timeouts bunachar sonraí agus proxy: pléigh an tionscadal nó an tionscnamh athnuachana le Net-Base.

I dtimpeallacht shaineolaíoch, imríonn Thread-Pool Delphi agus Http 429 Too Many Requests ról tábhachtach freisin, má tá gá le comhtháthú slán idir sruthanna sonraí, comhtháthaithe agus forás aontaithe.

Pléigh tionscadal nó tionscnamh athnuachana le Net-Base.

Céim eile

Nuair a éiríonn an t-ábhar seo ina thionscadal fíor, ba chóir ailtireacht, an córas reatha agus an t-oibriú a mheas le chéile go luath.

Ní hamháin go dtacaímid le ceisteanna aonair, ach freisin nuair is gá ó shlisíní cód foinse, ó ábhair legacy nó ó smaointe portail tionscadal corparáideach iontaofa a fhorbairt.

  • Measúnítear an staid reatha, an stát sprioc agus na rioscaí teicniúla le chéile.
  • Ní chuirfear REST, rochtain ar shonraí, portalí agus Rollout siar mar iarmhairtí.
  • Feiceann sibh go luath cé acu an cosán atá inbhuanaithe ó thaobh eacnamaíochta agus oibríochta.

Roinn an post

Roinn an t-alt seo go díreach

Tá LinkedIn, X, XING, Facebook, WhatsApp agus ríomhphost ar fáil láithreach. Do Instagram ullmhaímid nasc agus téacs gairid láithreach.

Ríomhphost

Osclaítear Instagram i gcluaisín nua. Cóipeáiltear an nasc agus an téacs gairid roimh ré isteach sa ghearrthaisce.