Хоризонтално скалирање
cMind скале са минималним напором оператора. Два без жичиног терета — покренути/тест извршавања, копирање-трговање — обе користе базу као координацију тачка, тако додавање репа требају без vanjske координатора (не ZooKeeper, не лидер избор).
Копирање-трговање (само-оздрављивање лизе)
Сваки чвор трчи CopyEngineSupervisor (гатирано на App:Copy:Enabled). Сваки помирба цикл,
надзорник:
- Захтева сваки радни профил неодељен или лизе-истекао, у једном атомском
UPDATE— два трча надзорника никад обе захтева исти профил, тако профил копира од управо један чвор (не двоструке наруџбе). - Обнови лизе на профилима се домаћин.
- Домаћин доељени профили, гура приступ-токен ротације трчаћој домаћин на месту (не токен-ток падају).
Чвор пада → zaustavляет обнови; једном App:Copy:LeaseTtl пролаза, сваки преживи чвор захтева
његови профили следећи цикл, обнови стање из помирба без дупцирања трговине. Скалирање
изван = додај репе; неодељен/слободни профили подигнути аутоматски.
Милостива скала-у / увођена освежавање (S1) = на SIGTERM, CopyEngineSupervisor.StopAsync
отпусти овај чвор лизе (AssignedNode/LeaseExpiresAt → null) тако преживи захтева их
његова врло следећа помирба цикл — не после потпуног LeaseTtl. Само хард пада чека TTL.
Копирање-агент terminationGracePeriodSeconds (подразумевано 30) даје отпусти време до завршки пред
под убијен.
Опреме (App:Copy)
| Постављање | Подразумевано | Напомене |
|---|---|---|
Enabled | false | Укључи копирање домаћина за чвор. |
ReconcileInterval | 30s | Колико често чвор захтева/обнови/помирба. |
LeaseTtl | 120s | Милост пред тихо чвор профили захтева. Задржи неколико помирба интервала тако спор цикл не узрокује лажно уручињена. |
NodeName | име машине | Поставити одликованО када двоје надзорника деле домаћина. |
На Kubernetes копирање надзорници трче као Deployment; поставити replicas на жељену паралелизма. Сваки
под добиј стабилна NodeName (подразумевано: под име домаћина), тако лизе атрибутирано по поду. База је
једна извора истине — не лепљиве сеансе, не по-под стање за премештај.
Балансирана дистрибуција (S4): поставити App:Copy:MaxProfilesPerNode > 0 за ограничење колико покренути
профили чвор домаћин. Сваки надзорник тада захтева на већину су преостали простор преко атомског
FOR UPDATE SKIP LOCKED ограничена захтева, тако профили ширење преко репа уместо прво
надзорник граба свега — не једна врућа под / SPOF. Пропусти-закључан захтева задржи "управо један чвор
за профил" гарантија (не двоструко-домаћина) чак и под истовремена захтева. 0 (подразумевано) =
неограничена (један чвор домаћин свега, без промена).
У скали (S7/S8): сваки под јектора помирба од до 20% од ReconcileInterval
(CopyEngineSupervisor.JitteredInterval) тако N репе не стрела захтева/обнови UPDATE
истовремено (Postgres грмећа-крда). Када copyAgent.replicas > 1 графикон такође ширења
репе преко чворова (topologySpreadConstraints) и додаје PodDisruptionBudget (minAvailable: 1)
тако цев/надград никад не узима копирање капацитета на нулу.
Покрени/тест извршавања
NodeScheduler бира најмање-учитава подобан чвор хоноры MaxInstances; удален чвор агенти
само-регистрирају и пулс (App:Discovery), NodeHeartbeatMonitor означава чвор недостижан
када пулс прелази Discovery:HeartbeatTtl. Додај чвор агенти да додате извршавања капацитета;
мртав агент маршрута око аутоматски.
Миграције на скала-изван / увођена развој
Свака Web/MCP репа трче OwnerSeeder при покретању, која примени EF миграције и семена властитељ.
Да то буде безбедно када N репе почињу одједном, мигрирати + семена трче унутар Postgres сеансе
водиљу лок (MigrationLock.RunExclusiveAsync, кључ DatabaseDefaults.MigrationAdvisoryLockKey):
прва репа да захтева то мигрирати и семена; остатак блок на лок, тада пронађе миграције
већ примењено (не-оп) и властитељ већ присутна. Нема одвојене миграције посла или лидер избор је
потребна. Ако додате прво-трчи сејање, пустите то унутар исти чувана блок тако то једна-писац.
Чвор-агент HTTP отпорност
Главни чвор разговара сваке CtraderCliNode агент преко HTTP кроз три намена-раздељена клијенти тако
лабава чвор или мрежа никад не причини покаљена стање:
- читати (
status/report/stats) — идемпотент GETs, поново покушава на пролазне неуспехе (експоненцијална простирања + јектор,NodeAgentHttp.ReadRetryCount) са по-покушај и укупна времена. - пиши (
start/stop/clean) — не-идемпотент POSTs, тајм изван али никад поново покушава: а поново покушаваstartмогао двоструко-поклопити контејнер. - ток (
logs) — дугоживиdocker logs -fток добиј бесконачно тајм и не отпорност цевовод, тако раздирање је никад пре.
Чвор који остаје недостижан је обрађен од пулса + осиромашена-инстанце захтева; HTTP слој само глачава пролазне брљоте.
Без жичиног слоја
Web (Blazor Server + API) и MCP сервер су без жичиног позади база, репликирају слободно. Auth је колачиће-базирана; скала Web хоризонтално позади оптерећење балансера. MCP сервер је одвојено процес/Deployment тако то скале независно од Web.
База везни отпорност
Сваки домаћин који отвара база користи а поново покушава извршавања стратегија тако пролазна одвајање или управљан-Postgres неуспех (RDS / Flexible Server закрпу) је поново покушава уместо површина као грешке кориснику:
- Web и MCP регистрирају контекст кроз Aspire Npgsql компоненту са
DisableRetry=falseи изричитиCommandTimeout(DatabaseDefaults.CommandTimeoutSeconds). - CopyAgent (не-Aspire) регистрирају преко
UseAppNpgsql, која примени истиEnableRetryOnFailure(MaxRetryCount, MaxRetryDelay)+ команда тајм одDatabaseDefaults.
Све пише су једна SaveChanges / једна ExecuteUpdate / једна ExecuteSql исказе, тако
поново покушава стратегија је безбедна (не мулти-исказ трансакција требава ручну strategy.ExecuteAsync
мотање). Ако додате а ручна трансакција или мулти SaveChanges у једна логичка операција, обавезно
то у db.Database.CreateExecutionStrategy().ExecuteAsync(...) — инач то хвата под поново покушава.
Чеклиста за скалирање изван
- Postgres величине за додано везни терет (свака Web/MCP/чвор репа отвара базену).
-
App:Copy:Enabled=trueна сваки чвор која требава домаћин копирање профили. - Одликовано
App:Copy:NodeNameпо суседству надзорника (K8s: подразумевано по-под добро). -
LeaseTtl≥ 3×ReconcileInterval. - Чвор агенти развојена где привилегирани Docker доступна (AKS/EKS/EC2/VM, не Fargate).
- Мулти-репа Web: поставити
signalrвезни низ (Redis позадина) и омогући улаз сеансе афинитета (лепљиве сеансе) тако Blazor кругови препознај до живо под. А компонента исключење је хватена одMainLayoutErrorBoundary(пријатно поново покушава, кругови остају живо).