Афинитет на сесията
Афинитетът на сесията е механизъм за обвързване (афинитизиране) на причинно свързана последователност от заявки с
Концепция
Афинитетът на сесията е механизъм за обвързване (афинитизиране) на причинно свързана последователност от заявки с дестинацията, обработила първата заявка, когато натоварването се разпределя между няколко дестинации. Той е полезен в сценарии, при които повечето заявки в дадена последователност работят с едни и същи данни, а разходът за достъп до данните се различава за различните възли (дестинации), обработващи заявките. Най-честият пример е временното кеширане (например в паметта), при което първата заявка извлича данни от по-бавно постоянно хранилище в бърз локален кеш, а останалите заявки работят само с кешираните данни, което увеличава пропускателната способност.
Конфигурация
Регистриране на услуги и middleware
Услугите за афинитет на сесията се регистрират автоматично в DI контейнера от AddReverseProxy() . Middleware компонентът UseSessionAffinity() е включен по подразбиране в метода MapReverseProxy без параметри. Ако персонализирате конвейера на прокси сървъра, поставете този middleware преди добавянето на UseLoadBalancing() .
Пример:
C# app.MapReverseProxy(proxyPipeline =>
{
proxyPipeline.UseSessionAffinity();
proxyPipeline.UseLoadBalancing();
});
Note Some session affinity implementations depend on Data Protection, which will require
additional configuration for scenarios like multiple proxy instances. See Key Protection for
details.Конфигурация на клъстера
Афинитетът на сесията се конфигурира за всеки клъстер поотделно, съгласно следната конфигурационна схема.
JSON"ReverseProxy": {
"Clusters": {
"<cluster-name>": {
"SessionAffinity": {
"Enabled": "(true|false)", // defaults to 'false'
"Policy": "(HashCookie|ArrCookie|Cookie|CustomHeader)", // defaults to
'HashCookie'
"FailurePolicy": "(Redistribute|Return503Error)", // defaults to
'Redistribute'
"AffinityKeyName": "Key1",
"Cookie": {
"Domain": "localhost",
"Expiration": "03:00:00",
"HttpOnly": true,
"IsEssential": true,
"MaxAge": "1.00:00:00",
"Path": "mypath",
"SameSite": "Strict",
"SecurePolicy": "Always"
}
}
}
}
}Конфигурация на cookie
Атрибутите за конфигуриране на бисквитката (cookie), използвана с политиките HashCookie, ArrCookie и Cookie, могат да се задават чрез SessionAffinityCookieConfig . Свойствата могат да се зададат като JSON конфигурация, както по-горе, или в код, както е показано по-долу:
C#new ClusterConfig
{
ClusterId = "cluster1",
SessionAffinity = new SessionAffinityConfig
{
Enabled = true,
FailurePolicy = "Return503Error",
Policy = "HashCookie",
AffinityKeyName = "Key1",
Cookie = new SessionAffinityCookieConfig
{
Domain = "mydomain",
Expiration = TimeSpan.FromHours(3),
HttpOnly = true,
IsEssential = true,
MaxAge = TimeSpan.FromDays(1),
Path = "mypath",
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
SecurePolicy =
Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest
}
}
}Ключ на афинитета
Афинитетът между заявка и дестинация се установява чрез ключ на афинитета, идентифициращ целевата дестинация. Този ключ може да се съхранява в различни части на заявката в зависимост от конкретната имплементация на афинитета на сесията, но всяка заявка не може да има повече от един такъв ключ. Точната семантика на ключа зависи от имплементацията, но вградените политики понастоящем използват DestinationId като ключ на афинитета.
Настоящият дизайн не изисква ключът да идентифицира еднозначно единствена афинитизирана дестинация. Позволено е установяването на афинитет към група от дестинации. В този случай точната дестинация, която ще обработи дадената заявка, се определя от балансиращото натоварването.
Установяване на нов афинитет или разрешаване на съществуващ
Когато пристигне заявка и бъде маршрутизирана към клъстер с включен афинитет на сесията, прокси сървърът автоматично решава дали трябва да се установи нов афинитет, или да се разреши съществуващ, въз основа на наличието и валидността на ключ на афинитета в заявката, както следва:
Заявката не съдържа ключ. Разрешаването се пропуска и се установява нов афинитет към дестинацията, избрана от балансиращото натоварването.
В заявката е намерен валиден ключ на афинитета. Механизмът за афинитет се опитва да намери всички здрави дестинации, отговарящи на ключа, и ако намери такива, предава заявката надолу по конвейера. Ако бъдат намерени няколко отговарящи дестинации, се извиква балансиращото натоварването, за да избере единствената целева дестинация. Ако бъде намерена само една отговаряща дестинация, балансиращото натоварването не извършва действие.
Ключът на афинитета е невалиден или не е намерена нито една здрава афинитизирана дестинация. Това се третира като неуспех, който се обработва от политика при неуспех, описана по-долу.
Ако за заявката е установен нов афинитет, ключът на афинитета се прикачва към отговора, като точното представяне и местоположение на ключа зависи от имплементацията. В момента съществуват две вградени политики, които съхраняват ключа в бисквитка или в персонализирано заглавие. След като отговорът бъде
доставен на клиента, отговорност на клиента е да прикачва ключа към всички следващи заявки в
рамките на същата сесия. Освен това, когато следващата заявка, носеща ключа, пристигне при прокси сървъра, той
разрешава съществуващия афинитет, но ключът на афинитета не се прикачва отново към отговора. Така,
само първият отговор носи ключа на афинитета.
Съществуват четири вградени политики за афинитет, които форматират и съхраняват ключа по различен начин в заявките и отговорите. Политиката по подразбиране е HashCookie .
HashCookie , ArrCookie и Cookie съхраняват ключа като бисквитка, съответно хеширана или криптирана - вижте Защита на ключа по-долу. Ключът на заявката се предава като бисквитка с конфигурираното име и задава същата бисквитка чрез заглавието Set-Cookie в първия отговор от афинитизираната последователност. Името на бисквитката трябва да се зададе изрично чрез SessionAffinityConfig.AffinityKeyName . Другите свойства на бисквитката могат да се конфигурират чрез SessionAffinityCookieConfig . CustomHeader съхранява ключа като криптирано заглавие. Тя очаква ключът на афинитета да се предава в персонализирано заглавие с конфигурираното име и задава същото заглавие в първия отговор от афинитизираната последователност. Името на заглавието трябва да се зададе чрез SessionAffinityConfig.AffinityKeyName .
AffinityKeyName трябва да бъде уникално за всички клъстери с включен афинитет на сесията, за да се избегнат конфликти.
Защита на ключа
Политиката HashCookie използва хеш алгоритъма XxHash64, за да получи бърз, компактен и прикрит формат за стойността на бисквитката.
Политиката ArrCookie използва хеш алгоритъма SHA-256, за да получи прикрит изход за стойността на бисквитката, който съответства на формата на бисквитката за афинитет на IIS ARR. ARR използва името на хоста на дестинацията като входна стойност, така че идентификаторите на дестинациите в YARP трябва да бъдат конфигурирани по съответен начин, ако се използват заедно с ARR.
HashCookie и ArrCookie не осигуряват силна защита на поверителността и чувствителни данни не бива да се включват в идентификаторите на дестинациите. Тези политики също не скриват общия брой уникални дестинации зад прокси сървъра и не бива да се използват, ако това е проблем.
Политиките Cookie и CustomHeader криптират ключа чрез Data Protection. Това осигурява силна защита на поверителността на ключа, но изисква допълнителна конфигурация, когато се използва повече от един екземпляр на прокси сървъра.
Политика при неуспешен афинитет
Ако ключът на афинитета не може да бъде декодиран или не е намерена здрава дестинация, това се счита за
неуспех и се извиква политика при неуспешен афинитет, за да го обработи. Политиката има пълен достъп до
HttpContext и може сама да изпрати отговор на клиента. Тя връща булева стойност, показваща
дали обработката на заявката може да продължи надолу по конвейера, или трябва да бъде прекратена.
Съществуват две вградени политики при неуспех. Политиката по подразбиране е Redistribute .
Redistribute - опитва се да установи нов афинитет към една от наличните здрави дестинации, като пропуска стъпката за търсене на афинитет и предава всички здрави дестинации на балансиращото натоварването по същия начин, както се прави при заявка без афинитет. Обработката на заявката продължава. Това е реализирано от RedistributeAffinityFailurePolicy .
Return503Error - изпраща обратно на клиента отговор 503 и обработката на заявката се прекратява. Това е реализирано от Return503ErrorAffinityFailurePolicy
Конвейер на заявките
Механизмите за афинитет на сесията се реализират от услугите (споменати по-горе) и следните два middleware компонента:
SessionAffinityMiddleware - координира процеса на разрешаване на афинитета за заявката. Първо извиква политиката, зададена за дадения клъстер чрез свойството ClusterConfig.SessionAffinity.Policy. След това проверява статуса на разрешаването на афинитета, върнат от политиката, и при неуспех извиква политика за обработка на грешки, зададена чрез ClusterConfig.SessionAffinity.FailurePolicy. Трябва да бъде добавен в конвейера преди балансиращото натоварването.
AffinitizeTransform - задава ключа в отговора, ако за заявката е установен нов афинитет. В противен случай, ако заявката следва съществуващ афинитет, не прави нищо. Добавя се автоматично като трансформация на отговора.
Тази статия е създадена от автора с помощта на изкуствен интелект. Научете повече