Hlavné vlajky s pružinou

1. Prehľad

V tomto článku stručne definujeme príznaky funkcií a navrhneme namyslený a pragmatický prístup k ich implementácii v aplikáciách Spring Boot. Potom sa pustíme do zložitejších iterácií využívajúcich výhody rôznych funkcií Spring Boot.

Budeme diskutovať o rôznych scenároch, ktoré môžu vyžadovať označovanie funkcií, a hovoríme o možných riešeniach. Urobíme to pomocou ukážkovej aplikácie Bitcoin Miner.

2. Príznaky funkcií

Príznaky funkcií - niekedy nazývané prepínače funkcií - sú mechanizmom, ktorý nám umožňuje povoliť alebo zakázať konkrétne funkcie našej aplikácie bez toho, aby sme museli upravovať kód alebo v ideálnom prípade znova nasadzovať našu aplikáciu.

V závislosti na dynamike požadovanej daným príznakom funkcie bude možno potrebné nakonfigurovať ich globálne, na inštanciu aplikácie alebo podrobnejšie - možno na používateľa alebo požiadavku.

Rovnako ako v mnohých situáciách v softvérovom inžinierstve, aj v tomto prípade je dôležité pokúsiť sa použiť najpriamejší prístup, ktorý rieši daný problém bez zbytočnej zložitosti.

Príznaky funkcií sú silným nástrojom, ktorý pri rozumnom použití môže priniesť spoľahlivosť a stabilitu nášho systému. Ak sú však zneužívané alebo nedostatočne udržiavané, môžu sa rýchlo stať zdrojmi zložitosti a bolesti hlavy.

Existuje veľa scenárov, kedy by sa vám mohli hodiť príznaky funkcií:

Kmeňový vývoj a netriviálne funkcie

Pri vývoji založenom na hlavných sieťach, najmä keď chceme pokračovať v integrácii často, by sme sa mohli ocitnúť nie sú pripravení uvoľniť určitý kúsok funkčnosti. Príznaky funkcií sa môžu hodiť, aby sme ich mohli naďalej vydávať bez toho, aby boli naše zmeny k dispozícii až do dokončenia.

Konfigurácia špecifická pre dané prostredie

Mohli by sme zistiť, že vyžadujeme určité funkcie na vynulovanie našej databázy pre testovacie prostredie E2E.

Prípadne možno budeme musieť použiť inú konfiguráciu zabezpečenia pre mimoprodukčné prostredia, ako je konfigurácia použitá v produkčnom prostredí.

Preto by sme mohli využiť príznaky funkcií na prepnutie správneho nastavenia v správnom prostredí.

A / B testovanie

Uvoľnenie viacerých riešení pre ten istý problém a meranie dopadu je presvedčivá technika, ktorú by sme mohli implementovať pomocou príznakov funkcií.

Kanárske púšťanie

Pri nasadzovaní nových funkcií by sme sa mohli rozhodnúť postupovať postupne, počnúc malou skupinou používateľov a rozšírením ich prijatia, keď overíme správnosť jeho správania. Príznaky funkcií nám to umožňujú dosiahnuť.

V nasledujúcich častiach sa pokúsime poskytnúť praktický prístup k riešeniu vyššie uvedených scenárov.

Poďme si rozdeliť rôzne stratégie označovania funkcií, počnúc najjednoduchším scenárom a potom prejsť na podrobnejšie a zložitejšie nastavenie.

3. Príznaky funkcií na úrovni aplikácie

Ak potrebujeme vyriešiť ktorýkoľvek z prvých dvoch prípadov použitia, príznaky funkcií na úrovni aplikácie sú jednoduchým spôsobom, ako uviesť veci do činnosti.

Jednoduchý príznak funkcie by zvyčajne zahŕňal vlastnosť a určitú konfiguráciu na základe hodnoty tejto vlastnosti.

3.1. Príznaky funkcií pomocou profilov pružiny

Na jar môžeme využívať výhody profilov. Profily nám pohodlne umožňujú selektívne konfigurovať určité fazule. S niekoľkými konštrukciami okolo nich môžeme rýchlo vytvoriť jednoduché a elegantné riešenie pre príznaky funkcií na úrovni aplikácie.

Predstierajme, že budujeme ťažobný systém BitCoin. Náš softvér je už v produkcii a máme za úlohu vytvoriť experimentálny vylepšený algoritmus ťažby.

V našom JavaConfig mohli by sme profilovať naše komponenty:

@Configuration public class ProfiledMiningConfig {@Bean @Profile ("! Experimental-miner") public BitcoinMiner defaultMiner () {návrat nového DefaultBitcoinMiner (); } @Bean @Profile ("experimental-miner") public BitcoinMiner experimentalMiner () {return new ExperimentalBitcoinMiner (); }}

Potom, s predchádzajúcou konfiguráciou stačí zahrnúť náš profil, aby sme sa prihlásili pre našu novú funkčnosť. Existuje veľa spôsobov, ako nakonfigurovať našu aplikáciu všeobecne a najmä povoliť profily. Rovnako existujú testovacie nástroje, ktoré nám uľahčujú život.

Pokiaľ je náš systém dostatočne jednoduchý, potom by sme mohli vytvoriť konfiguráciu založenú na prostredí, aby sme určili, ktoré príznaky funkcií sa majú použiť a ktoré ignorovať.

Poďme si predstaviť, že spolu s predchádzajúcim experimentálnym baníkom máme namiesto tabuliek nové používateľské rozhranie založené na kartách.

Chceli by sme povoliť obe funkcie v našom akceptovacom prostredí (UAT). Mohli by sme vytvoriť application-uat.yml spis:

jar: profily: zahŕňajú: experimentálny baník, ui-karty # Viac konfigurácie tu

Po vytvorení predchádzajúceho súboru by sme potrebovali iba povoliť profil UAT v prostredí UAT, aby sme získali požadovanú sadu funkcií.

Je tiež dôležité pochopiť, ako využiť výhody jar.profily.zahrnúť. V porovnaní s spring.profiles.active, prvý z nich nám umožňuje zahrnúť profily aditívnym spôsobom.

V našom prípade chceme uat profil tiež obsahuje experimentálne baníky a ui-karty.

3.2. Príznaky funkcií pomocou vlastných vlastností

Profily sú skvelým a jednoduchým spôsobom, ako dokončiť svoju prácu. Profily však môžeme vyžadovať na iné účely. Alebo možno budeme chcieť vybudovať štruktúrovanejšiu infraštruktúru funkcií.

Pre tieto scenáre môžu byť žiaduce vlastné vlastnosti.

Prepíšeme náš predchádzajúci príklad a využijme výhody @ConditionalOnProperty a náš menný priestor:

@Configuration verejná trieda CustomPropsMiningConfig {@Bean @ConditionalOnProperty (name = "features.miner.experimental", matchIfMissing = true) verejný BitcoinMiner defaultMiner () {vrátiť nový DefaultBitcoinMiner (); } @Bean @ConditionalOnProperty (name = "features.miner.experimental") public BitcoinMiner experimentalMiner () {return new ExperimentalBitcoinMiner (); }}

Predchádzajúci príklad vychádza z podmienenej konfigurácie Spring Boot a konfiguruje jeden alebo druhý komponent v závislosti od toho, či je vlastnosť nastavená na pravda alebo nepravdivé (alebo úplne vynechané).

Výsledok je veľmi podobný výsledku v 3.1, ale teraz máme náš menný priestor. Vlastný priestor mien nám umožňuje vytvárať zmysluplné súbory YAML / vlastnosti:

# [...] Niektoré funkcie jarnej konfigurácie: miner: experimentálne: true ui: karty: true # [...] Ďalšie príznaky funkcií

Toto nové nastavenie nám tiež umožňuje predponu príznakov našich funkcií - v našom prípade pomocou Vlastnosti predpona.

Mohlo by sa to zdať ako malý detail, ale s rastom našej aplikácie a zvyšovaním zložitosti nám táto jednoduchá iterácia pomôže udržať naše príznaky funkcií pod kontrolou.

Hovorme o ďalších výhodách tohto prístupu.

3.3. Použitím @ConfigurationProperties

Hneď ako dostaneme predponu vlastností, môžeme vytvoriť POJO zdobený @ConfigurationProperties a získať programový popisovač v našom kóde.

Podľa nášho prebiehajúceho príkladu:

@Component @ConfigurationProperties (prefix = "features") verejná trieda ConfigProperties {súkromný miner MinerProperties; súkromné ​​UIPvlastnosti ui; // štandardné getre a setre verejné statické triedy MinerProperties {private boolean experimental; // standard geters and setters} public static class UIProperties {private boolean cards; // štandardní zakladatelia a zakladatelia}}

Umiestnením stavu našich vlajok funkcií do súdržnej jednotky otvárame nové možnosti, ktoré nám umožňujú ľahko sprístupniť tieto informácie iným častiam nášho systému, napríklad používateľskému rozhraniu, alebo následným systémom.

3.4. Konfigurácia exponovaných funkcií

Náš systém ťažby bitcoinov dostal vylepšenie používateľského rozhrania, ktoré ešte nie je úplne pripravené. Z tohto dôvodu sme sa rozhodli túto funkciu označiť. Mohli by sme mať jednostránkovú aplikáciu používajúcu React, Angular alebo Vue.

Bez ohľadu na technológiu potrebujeme vedieť, aké funkcie sú povolené, aby sme mohli zodpovedajúcim spôsobom vykresliť našu stránku.

Vytvorme jednoduchý koncový bod, ktorý bude slúžiť našej konfigurácii, aby naše používateľské rozhranie mohlo v prípade potreby dopytovať back-end:

@RestController verejná trieda FeaturesConfigController {súkromné ​​vlastnosti ConfigProperties; // constructor @GetMapping ("/ feature-flags") public ConfigProperties getProperties () {return properties; }}

Mohli by existovať sofistikovanejšie spôsoby poskytovania týchto informácií, napríklad vytváranie vlastných koncových bodov aktuátora. Ale v záujme tejto príručky sa koncový bod radiča cíti ako dosť dobré riešenie.

3.5. Udržiavajte tábor v čistote

Aj keď to môže znieť očividne, akonáhle budeme naše vlajky funkcií implementovať premyslene, je rovnako dôležité zostať disciplinovaní a zbaviť sa ich, keď už ich nebudeme potrebovať.

Príznaky funkcií pre prvý prípad použitia - vývoj na základe kufra a netriviálne funkcie - sú zvyčajne krátkodobé. To znamená, že sa budeme musieť uistiť, že naše ConfigProperties, našu konfiguráciu Java a našu YAML súbory zostanú čisté a aktuálne.

4. Podrobnejšie vlajky funkcií

Niekedy sa ocitneme v zložitejších scenároch. Pokiaľ ide o testovanie A / B alebo vypúšťanie kanárikov, náš predchádzajúci prístup jednoducho nestačí.

Aby sme dostali príznaky funkcií na podrobnejšej úrovni, bude možno potrebné vytvoriť naše riešenie. Môže to zahŕňať prispôsobenie našej používateľskej entity tak, aby obsahovala informácie špecifické pre jednotlivé funkcie, alebo možno rozšírenie nášho webového rámca.

Znečisťovanie našich používateľov príznakmi funkcií nemusí byť pre všetkých lákavým nápadom a existujú aj ďalšie riešenia.

Ako alternatívu by sme mohli využiť niektoré vstavané nástroje, napríklad Togglz. Tento nástroj pridáva na zložitosti, ale ponúka pekné riešenie pripravené na použitie a poskytuje prvotriednu integráciu s programom Spring Boot.

Togglz podporuje rôzne aktivačné stratégie:

  1. Užívateľské meno: Príznaky spojené s konkrétnymi používateľmi
  2. Postupné zavádzanie: Príznaky povolené pre percento používateľskej základne. Je to užitočné napríklad pre verzie Canary, keď chceme overiť správanie našich funkcií
  3. Dátum vydania: Mohli by sme naplánovať povolenie príznakov na určitý dátum a čas. To môže byť užitočné pri uvedení produktu na trh, koordinovanom vydaní alebo pri ponukách a zľavách
  4. IP klienta: Označené funkcie založené na IP adresách klientov. Tieto by sa mohli hodiť pri aplikácii konkrétnej konfigurácie na konkrétnych zákazníkov, pretože majú statické adresy IP
  5. IP servera: V takom prípade sa na určenie, či má alebo nemá byť funkcia povolená, používa adresa IP servera. To by mohlo byť užitočné aj pre kanárikové verzie, s mierne odlišným prístupom ako postupné zavádzanie - napríklad keď chceme v našich prípadoch posúdiť vplyv na výkon.
  6. ScriptEngine: Príznaky funkcií by sme mohli povoliť na základe ľubovoľných skriptov. Toto je pravdepodobne najpružnejšia možnosť
  7. Vlastnosti systému: Mohli by sme nastaviť určité vlastnosti systému, aby sme určili stav príznaku funkcie. To by bolo dosť podobné tomu, čo sme dosiahli našim najpriamejším prístupom

5. Zhrnutie

V tomto článku sme mali možnosť hovoriť o príznakoch funkcií. Ďalej sme diskutovali o tom, ako by nám jar mohla pomôcť dosiahnuť niektoré z týchto funkcií bez pridania nových knižníc.

Začali sme definíciou, ako nám tento vzor môže pomôcť v niekoľkých bežných prípadoch použitia.

Ďalej sme vytvorili niekoľko jednoduchých riešení pomocou nástrojov Spring and Spring Boot out-of-the-box. S tým sme prišli s jednoduchou, ale výkonnou konštrukciou označovania funkcií.

Nižšie sme porovnali niekoľko alternatív. Prechod od jednoduchšieho a menej flexibilného riešenia k zložitejšiemu, aj keď zložitejšiemu vzoru.

Nakoniec sme stručne poskytli niekoľko pokynov na vytvorenie robustnejších riešení. Je to užitočné, keď potrebujeme vyšší stupeň podrobnosti.