Надвор од функционалните знаменца: инженеринг за приспособливост во време на извршување
Ознаките за функционалности често се воведуваат како безбедносен механизам: обвиткајте ризична промена, распоредете ја во неактивна состојба и вклучете ја кога тимот е подготвен. Тоа е вредно, но е само мал дел од поширока инженерска способност: приспособливост при извршување.
Бекенд што може безбедно да се приспособува при извршување може да го менува однесувањето без секоја одлука да стане распоредување. Тој може да го контролира опсегот на воведување, да одговори на зависности што откажуваат, да ја прилагоди скапата обработка, внимателно да воведе нови API договори и брзо да поништи лош оперативен избор. Разликата е важна бидејќи самата ознака не го прави системот приспособлив. Таа исто толку лесно може да стане трајна гранка, недокументиран прекинувач за конфигурација и уште еден извор на нејаснотии во продукција.
Размислувајте во одлуки, не во булови вредности
Наједноставната ознака одговара на едно прашање: вклучено или исклучено. На реалните системи обично им треба попрецизно прашање. Кои клиенти треба да добијат нов облик на одговор? Што треба да се случи ако надворешен давател е бавен? Колку задачи смее закупец да извршува истовремено? Дали заобиколувањето на кешот е соодветно за време на инцидент?
Моделирајте ја одлуката експлицитно. Воведувањето може да зависи од закупец, регион, пакет на сметка, тип на барање или стабилен процентуален сегмент. Политиката за отпорност може да зависи од неодамнешните стапки на грешки и латентноста. Поставката за перформанси може да зависи од големината на оптоварувањето. Ова се одделни грижи и не треба да се кријат зад единствено if ($flag).
final class SearchPolicy
{
public function useNewRankingFor(RequestContext $context): bool
{
if ($context->tenantId === 'internal') {
return true;
}
return $this->bucket($context->tenantId) < 10;
}
private function bucket(string $value): int
{
return abs(crc32($value)) % 100;
}
}
Ова и понатаму е едноставно, но има важно својство: клиентот останува во истиот сегмент за воведување. Случајниот избор за секое барање создава неконзистентно однесување, збунувачки случаи за поддршка и ненадежни споредби.
Изградете граница за конфигурација
Однесувањето при извршување треба да се контролира преку тесна граница со јасна одговорност. Кодот на апликацијата треба да побара одлука од услуга за политики или конфигурација, наместо низ целиот код да чита променливи на околината, редови од базата на податоци и далечинска конфигурација директно.
Во PHP, таа граница може да биде интерфејс инјектиран во услугите. Таа може да обезбеди типизирани методи како searchPolicy->useNewRankingFor($context) наместо насекаде да изложува произволни клучеви од низи. Имплементацијата може да почне со статична конфигурација и подоцна да чита од база на податоци или услуга за конфигурација без да наметне преработка на целото складиште.
Чувајте ги податоците за конфигурација одделно од правилата што ги толкуваат. Вредност како new_ranking_rollout_percentage=10 е податок. Валидацијата, сегментирањето, проверките за подобност и резервното однесување се правила на апликацијата. Мешањето на тие одговорности ги прави оперативните промени измамно опасни.
Валидирајте пред да се промени однесувањето
Конфигурацијата е влез во продукција. Третирајте ја со истото сомневање што му се дава на API товар. Валидирајте опсези, задолжителни полиња, дозволени региони и меѓусебно исклучиви опции. Ако невалидна конфигурација стигне до активен процес, изберете позната безбедна стандардна вредност и емитувајте корисен сигнал за операторите.
Ова е особено важно со Docker распоредувања. Променливите на околината се погодни за непроменливи поставки во моментот на распоредување, но тие не се инхерентно контроли при извршување. Промената на околината на контејнерот обично значи замена на контејнерот. Користете ги за стандардни вредности и детали за поврзување; користете намерен механизам за конфигурација кога целта е непосредна оперативна промена.
Вградете повратност во API-ја и бази на податоци
Приспособливоста при извршување е највредна кога е споена со компатибилни практики за испорака. Функционалноста не може безбедно да се исклучи ако нејзината миграција на базата на податоци веќе ја направила старата кодна патека невозможна.
За промени во шемата, претпочитајте низа на проширување и повлекување:
- Додајте ја новата табела, колона или индекс без да ја отстраните старата структура.
- Распоредете код што може да ја чита старата претстава и да ја запишува новата кога е соодветно.
- Пополнете ги податоците наназад во контролирани серии, со контролни точки и видлив напредок.
- Префрлете го читањето откако новите податоци ќе бидат доверливи.
- Отстранете ги старата патека и шема дури откако ќе заврши преодниот период.
Колона што дозволува null често е побезбедна од новозадолжителна колона. Нова верзија на крајна точка или опционално поле во одговорот обично е побезбедно од промена на значењето на постојно поле. Повратната компатибилност не е неволност за подобрување; таа овозможува распоредувањата, повторните обиди, редиците и повеќе верзии на апликацијата да коегзистираат без изданието да се претвори во синхронизиран настан.
Работата со базата на податоци заслужува особена воздржаност. Кодна ознака може да го пренасочи сообраќајот за секунди, но голема миграција или градење индекс може да има многу различни оперативни карактеристики. Планирајте ги операциите со шемата како независно набљудливи промени, а не како невидлива последица од промена на однесувањето на апликацијата.
Користете приспособливи контроли за патеките на откажување
Ознаките за функционалности најчесто се користат за воведување на производи, но оперативните контроли се подеднакво важни. Услуга што повикува зависност за плаќања, пребарување или пораки има потреба од јасно однесување кога таа зависност ќе стане бавна или недостапна.
Корисни контроли вклучуваат буџети за истекување време, ограничувања на повторни обиди, конкурентност на редиците, TTL вредности на кешот и резервни режими. Секоја треба да има разумна стандардна вредност, цврста безбедносна граница и сопственик. Неограничениот повторен обид не е отпорност; често е начин да се умножи оптоварувањето за време на прекин.
Повторните обиди треба да се резервираат за откажувања што веројатно се привремени, како прекин на врската или експлицитно одговор што дозволува повторен обид. Тие треба да бидат ограничени и спарени со идемпотентност. За API за запишување, клуч за идемпотентност може да му овозможи на повикувачот безбедно да повтори барање без создавање дупликатна работа. За асинхрони задачи, запишете стабилен идентитет на задачата и направете обработувачот да толерира повторна обработка.
Кога зависноста е деградирана, намереното резервно однесување може да биде подобро од целосен прекин. Тоа може да значи враќање кеширани резултати со нивната вообичаена семантика на свежина, одложување несуштинско збогатување или прифаќање работа во трајна редица. Не враќајте тивко погрешни податоци само за да зачувате успешен HTTP статус.
Набљудливоста ја претвора флексибилноста во контрола
Секоја значајна одлука при извршување има потреба од набљудлива трага. Ако воведувањето е овозможено за десет проценти од закупците, операторите треба да можат да ги споредат стапката на грешки, латентноста и деловно релевантните исходи за старите и новите патеки. Ако се активира резервно однесување, дневниците и метриките треба да наведат зошто, колку често и колку долго.
Ограничете ги ознаките. Метрика означена со секој ID на корисник или ID на барање може да го преоптовари системот за надзор. Претпочитајте димензии како име на функционалност, исход, регион или рута, а деталните идентификатори ставајте ги во структурирани дневници или траги каде што е соодветно.
Важна е и проверливоста. Запишете кој променил поставка при извршување, кога е променета, старите и новите вредности и секое истекување. Дневникот на промени го претвора инцидентот од „нешто се промени“ во конкретна временска линија.
Направете ги привремените контроли навистина привремени
Долгорочниот трошок на приспособливоста при извршување е ширењето на одлуките. Ознаките се натрупуваат, конфигурацијата станува противречна и никој не знае кои патеки сè уште се активни. Решението е управување соодветно на системот: јасен сопственик, цел, стандардна вредност, опсег на воведување и датум на отстранување за секоја контрола.
- Користете контроли за издание за краткотрајно воведување и враќање назад.
- Користете оперативни контроли за внимателно ограничен одговор на инциденти.
- Користете конфигурација на производот само кога однесувањето навистина треба да остане конфигурирано.
- Редовно прегледувајте ги застарените контроли и целосно бришете ги повлечените патеки.
Целта не е секое однесување да стане променливо. На стабилните системи им требаат стабилни стандардни вредности, јасни договори и код што може да се распореди. Целта е да се препознаат малкуте одлуки каде што се очекува промена, ризикот е реален или времето за опоравување е важно — и тие одлуки да се проектираат така што ќе бидат видливи, ограничени и повратни.
Тоа е чекорот надвор од ознаките за функционалности: не повеќе прекинувачи, туку подобра контрола над тоа како системот се однесува кога реалноста се менува побрзо од циклусот на издание.