有了自動化測試、測試環境等等多層保護之後,我們可以很有信心,線上問題要突破這些狀況,出現到線上正式環境的機率已經很低了。
不過,即使我們已經做了這麼多安全措施,總是會有一些線上問題出現的機會。到這個階段,我們能做到的事情,就是縮短線上問題出現的時間,盡可能的減輕線上問題所帶來的影響。
今天我們來聊什麼是 Feature Flags,他怎麼保護我們減輕線上問題的危害,以及怎麼用 Laravel Pennant 這個套件來實作 Feature Flags。
Feature Flags,或者說功能旗標,是一種軟體開發技術,用來控制某個功能是否啟用,而不需要重新部署程式碼。
也就是說,可能我們上傳的程式包含了某一個新功能,我們可以根據某個開關,控制這個功能是否公布給使用者,甚至可以控制公布給哪一些使用者。
利用這個方式,
Laravel Pennant 是官方建立,用來實作 Feature Flags 的套件
首先我們安裝 Laravel Pennant
composer require laravel/pennant
安裝好之後,我們要生成對應的設定檔和遷移
php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"
建立好之後執行一次 migrate
php artisan migrate
到這邊,我們的環境就安裝好了,基本上可以開始建立新的 Feature Flag 了
假設我們原本有一個舊的 API,想要改寫成新的
Route::get('/legacy', function () {
return 'old api';
});
首先,我們用指令建立一個新的 Feature
php artisan pennant:feature NewApi
INFO Feature [app/Features/NewApi.php] created successfully.
我們看看 app/Features/NewApi.php
,可以看到預設是設置為 false
的
<?php
namespace App\Features;
use Illuminate\Support\Lottery;
class NewApi
{
/**
* Resolve the feature's initial value.
*/
public function resolve(mixed $scope): mixed
{
return false;
}
}
利用這個類別,我們將上面改寫成
if (Feature::active(NewApi::class)) {
Route::get('/legacy', function () {
return 'new api';
});
} else {
Route::get('/legacy', function () {
return 'old api';
});
}
這時候我們進到 http://127.0.0.1:8000/api/legacy,會看到依舊是「old api」
不過,如果我們進到資料庫,調整 name
為 App\Features\NewApi
的資料,將其 value
改成 true
這時候我們再次進到 http://127.0.0.1:8000/api/legacy,就會看到是「new api」了!
上面我們展示了簡單的對所有使用者開關功能的方式。
不過延續這個作法,我們可以有各式各樣不同的發布邏輯。
下面介紹幾種
這個名稱來自過去的礦工,會習慣性的在進入礦坑時,帶一隻金絲雀一起進去。
一旦進去之後發現金絲雀不叫或者暈倒了,那麼礦工就知道出現了危險,可以儘早撤退。
我們在部署新的功能時,也可以根據這樣的作法,先面對一批少量的用戶開放新功能,如果出現問題,就立刻切換回舊功能。
如果這批用戶使用過後沒有問題,我們再切換成所有用戶均使用新功能。
在新功能尚未確定是否穩定階段,我們可以先只針對公司內員工發布新功能,如果公司內員工測試過沒有問題之後,才對外發布。
和金絲雀部署類似,不過為了避免少量用戶可能沒辦法發現的問題,我們將階段做的更加細緻。
第一階段是針對少量用戶,比方說 1% 用戶進行發布。如果順利,下一階段可以對 10% 用戶進行發布,接著是 50%,最後是 100%。
這樣的作法比起金絲雀發布,花費的時間更多,不過也能更加減少出現問題時影響的用戶數量。
今天的部分就提到這邊,我們明天見!