本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
教學︰使用 Evidently 範例應用程式進行 A/B 測試
本節提供了如何使用 Amazon 進行 A/B 測 CloudWatch 試的教程。本教學將介紹 Evidently 範例應用程式,這是一個簡單的回應應用程式。範例應用程式將設定為顯示或不顯示 showDiscount
功能。若是對使用者顯示功能,在購物網站上顯示的價格會以 20% 的折扣顯示。
除了對某些使用者顯示折扣,對其他使用者則不顯示,在本教學中,您可以設定 Evidently 從這兩個變體中收集頁面載入時間指標。
警告
此案例需要具有程式設計存取和長期認證的IAM使用者,這會帶來安全性風險。為了減輕此風險,我們建議您僅向這些使用者提供執行工作所需的權限,並在不再需要這些使用者時移除這些使用者。如有必要,可更新存取金鑰。如需詳細資訊,請參閱《IAM使用指南》中的〈更新存取金鑰〉。
步驟 1:下載範例應用程式
首先下載 Evidently 範例應用程式。
下載範例應用程式
從以下 Simple Storage Service (Amazon S3) 儲存貯體下載範例應用程式︰
https://evidently-sample-application.s3.us-west-2.amazonaws.com/evidently-sample-shopping-app.zip
解壓縮套件。
步驟 2:新增 Evidently 端點並設定憑證
接著,將 Evidently 的區域和端點新增至範例應用程式套件中 src
目錄的 config.js
檔案,如以下範例所示:
evidently: { REGION: "us-west-2", ENDPOINT: "https://evidently.us-west-2.amazonaws.com (https://evidently.us-west-2.amazonaws.com/)", },
您還必須確保應用程序有權調用「 CloudWatch 顯而易見」。
授予範例應用程式呼叫 Evidently 的許可
聯合到您的 AWS 帳戶。
建立IAM使用者並將AmazonCloudWatchEvidentlyFullAccess策略附加至此使用者。
記下IAM用戶的訪問密鑰 ID 和秘密訪問密鑰,因為您在下一步中將需要它們。
在之前於本節中修改的同一個
config.js
檔案中,輸入存取金鑰 ID 和機密存取金鑰的值,如以下範例所示:credential: { accessKeyId: "
Access key ID
", secretAccessKey: "Secret key
" }重要
我們使用此步驟讓範例應用程式儘可能簡單,以便您嘗試。我們不建議您將IAM使用者憑證放入實際的生產應用程式中。建議您改為使用 Amazon Cognito 進行身分驗證。如需詳細資訊,請參閱將 Amazon Cognito 與 Web 和行動應用程式整合。
步驟 3:設定功能評估的程式碼
當您使用「 CloudWatch 顯而易見」來評估特徵時,您必須使用此EvaluateFeature作業為每個使用者作業階段隨機選取特徵變化。此操作會根據您在實驗中指定的百分比,將使用者工作階段指派給功能的每個變化。
設定書店示範應用程式的功能評估程式碼
將用戶端建置器新增至
src/App.jsx
檔案,以便範例應用程式呼叫 Evidently。import Evidently from 'aws-sdk/clients/evidently'; import config from './config'; const defaultClientBuilder = ( endpoint, region, ) => { const credentials = { accessKeyId: config.credential.accessKeyId, secretAccessKey: config.credential.secretAccessKey } return new Evidently({ endpoint, region, credentials, }); };
將以下項目新增至
const App
程式碼區段以啟動用戶端。if (client == null) { client = defaultClientBuilder( config.evidently.ENDPOINT, config.evidently.REGION, );
透過新增以下程式碼建構
evaluateFeatureRequest
。此程式碼會預先填寫我們在本教學後面推薦的專案名稱和功能名稱。只要您還在 Evidently 主控台中指定這些專案和功能名稱,則可以替換自己的專案名稱和功能名稱。const evaluateFeatureRequest = { entityId: id, // Input Your feature name feature: 'showDiscount', // Input Your project name' project: 'EvidentlySampleApp', };
新增可呼叫 Evidently 進行進行功能評估的程式碼。傳送請求時,Evidently 會隨機指派使用者工作階段是否查看
showDiscount
功能。client.evaluateFeature(evaluateFeatureRequest).promise().then(res => { if(res.value?.boolValue !== undefined) { setShowDiscount(res.value.boolValue); } getPageLoadTime() })
步驟 4:設定實驗指標的程式碼
對於自定義指標,請使用「顯而易見」將指標結果發送PutProjectEvents
API給「顯而易見」。下方範例會介紹如何設定自訂指標,以及如何將實驗資料傳送到 Evidently。
新增以下函數來計算頁面載入時間並使用 PutProjectEvents
將指標值傳送到 Evidently。將以下函數添加到Home.tsx
並在中調用此函數 EvaluateFeature
API:
const getPageLoadTime = () => { const timeSpent = (new Date().getTime() - startTime.getTime()) * 1.000001; const pageLoadTimeData = `{ "details": { "pageLoadTime": ${timeSpent} }, "UserDetails": { "userId": "${id}", "sessionId": "${id}"} }`; const putProjectEventsRequest = { project: 'EvidentlySampleApp', events: [ { timestamp: new Date(), type: 'aws.evidently.custom', data: JSON.parse(pageLoadTimeData) }, ], }; client.putProjectEvents(putProjectEventsRequest).promise(); }
以下是您下載檔案時完成所有編輯後的 App.js
檔案狀態。
import React, { useEffect, useState } from "react"; import { BrowserRouter as Router, Switch } from "react-router-dom"; import AuthProvider from "contexts/auth"; import CommonProvider from "contexts/common"; import ProductsProvider from "contexts/products"; import CartProvider from "contexts/cart"; import CheckoutProvider from "contexts/checkout"; import RouteWrapper from "layouts/RouteWrapper"; import AuthLayout from "layouts/AuthLayout"; import CommonLayout from "layouts/CommonLayout"; import AuthPage from "pages/auth"; import HomePage from "pages/home"; import CheckoutPage from "pages/checkout"; import "assets/scss/style.scss"; import { Spinner } from 'react-bootstrap'; import Evidently from 'aws-sdk/clients/evidently'; import config from './config'; const defaultClientBuilder = ( endpoint, region, ) => { const credentials = { accessKeyId: config.credential.accessKeyId, secretAccessKey: config.credential.secretAccessKey } return new Evidently({ endpoint, region, credentials, }); }; const App = () => { const [isLoading, setIsLoading] = useState(true); const [startTime, setStartTime] = useState(new Date()); const [showDiscount, setShowDiscount] = useState(false); let client = null; let id = null; useEffect(() => { id = new Date().getTime().toString(); setStartTime(new Date()); if (client == null) { client = defaultClientBuilder( config.evidently.ENDPOINT, config.evidently.REGION, ); } const evaluateFeatureRequest = { entityId: id, // Input Your feature name feature: 'showDiscount', // Input Your project name' project: 'EvidentlySampleApp', }; // Launch client.evaluateFeature(evaluateFeatureRequest).promise().then(res => { if(res.value?.boolValue !== undefined) { setShowDiscount(res.value.boolValue); } }); // Experiment client.evaluateFeature(evaluateFeatureRequest).promise().then(res => { if(res.value?.boolValue !== undefined) { setShowDiscount(res.value.boolValue); } getPageLoadTime() }) setIsLoading(false); },[]); const getPageLoadTime = () => { const timeSpent = (new Date().getTime() - startTime.getTime()) * 1.000001; const pageLoadTimeData = `{ "details": { "pageLoadTime": ${timeSpent} }, "UserDetails": { "userId": "${id}", "sessionId": "${id}"} }`; const putProjectEventsRequest = { project: 'EvidentlySampleApp', events: [ { timestamp: new Date(), type: 'aws.evidently.custom', data: JSON.parse(pageLoadTimeData) }, ], }; client.putProjectEvents(putProjectEventsRequest).promise(); } return ( !isLoading? ( <AuthProvider> <CommonProvider> <ProductsProvider> <CartProvider> <CheckoutProvider> <Router> <Switch> <RouteWrapper path="/" exact component={() => <HomePage showDiscount={showDiscount}/>} layout={CommonLayout} /> <RouteWrapper path="/checkout" component={CheckoutPage} layout={CommonLayout} /> <RouteWrapper path="/auth" component={AuthPage} layout={AuthLayout} /> </Switch> </Router> </CheckoutProvider> </CartProvider> </ProductsProvider> </CommonProvider> </AuthProvider> ) : ( <Spinner animation="border" /> ) ); }; export default App;
每當使用者存取範例應用程式時,自訂指標會傳送至 Evidently 進行分析。Evidently 會分析每個指標,並在 Evidently 儀表板上即時顯示結果。以下範例顯示了指標酬載:
[ {"timestamp": 1637368646.468, "type": "aws.evidently.custom", "data": "{\"details\":{\"pageLoadTime\":2058.002058},\"userDetails\":{\"userId\":\"1637368644430\",\"sessionId\":\"1637368644430\"}}" } ]
步驟 5:建立專案、功能和實驗
接下來,您可以在 CloudWatch Eviated 控制台中創建項目,功能和實驗。
為此教學課程建立專案、功能和實驗
在開啟 CloudWatch 主控台https://console.aws.amazon.com/cloudwatch/
。 在導航窗格中,選擇應用程序信號,顯而易見。
選擇 Create project (建立專案) 並填寫欄位。您必須使用
EvidentlySampleApp
,以使範例的專案名稱正常工作。針對評估事件儲存,選擇不存放評估事件。填寫完欄位後,選擇 Create Project (建立專案)。
如需詳細資訊,請參閱建立新專案。
專案建立之後,在該專案中建立功能。命名功能
showDiscount
。在此功能中,建立Boolean
類型的兩個變化。命名具有False
值的第一個變化disable
並命名第二個具有True
值的第二個變化enable
。如需建立功能的詳細資訊,請參閱 將功能新增至專案。
完成建立功能後,請在專案中建立實驗。命名實驗
pageLoadTime
。此實驗將使用稱為
pageLoadTime
的自訂指標,測量正在測試之頁面的頁面載入時間。實驗的自訂指標是使用 Amazon 建立的 EventBridge。有關更多信息 EventBridge,請參閱什麼是 Amazon EventBridge? 。若要建立該自訂指標,請在建立實驗時執行下列動作:
在 Metrics (指標) 下,對於 Metric source (指標來源),選擇 Custom metrics (自訂指標)。
對於 Metric name (指標名稱),輸入
pageLoadTime
。對於 Goal (目標),選擇 Decrease (降低)。這表示我們想要以此指標的較低值來表示功能的最佳變化。
對於 Metric rule (指標規則),輸入下列內容:
針對 Entity ID (實體 ID),輸入
UserDetails.userId
。對於 Value key (值索引鍵),輸入
details.pageLoadTime
。對於 Unit (單位),輸入
ms
。
選擇 Add metric (新增指標)。
對於 Audiences (受眾),選取 100%,以便將所有使用者輸入實驗中。將變化之間的流量分割設定為每個 50%。
之後,請選擇 Create experiment (建立實驗) 來建立實驗。建立後,在您讓 Evidently 啟動前,它不會啟動。
步驟 6: CloudWatch 明顯地開始實驗和測試
最後的步驟是開始實驗並啟動範例應用程式。
開始教學課程實驗
在開啟 CloudWatch 主控台https://console.aws.amazon.com/cloudwatch/
。 在導航窗格中,選擇應用程序信號,顯而易見。
選擇EvidentlySampleApp專案。
選擇 Experiments (實驗) 索引標籤。
選擇旁邊的按鈕,pageLoadTime然後選擇操作,開始實驗。
選擇實驗結束的時間。
選擇 Start experiment (開始實驗)。
實驗會即刻開始。
接著,使用以下命令啟動 Evidently 範例應用程式:
npm install -f && npm start
應用程式啟動之後,系統會將您指派給正在測試的兩個功能變體之一。一個變體顯示「20% 的折扣」,另一個則不顯示。繼續重新整理頁面以查看不同的變體。
注意
Evidently 具有黏性評估。功能評估是確定性的,意味著針對相同的 entityId
和功能,使用者將始終收到相同的變體指派。變體指派變更僅發生在將實體新增至撥號的覆寫或實驗流量時。
但是,為了讓您輕鬆使用範例應用程式教學,Evidently 每次在您重新整理頁面時,都會重新指派範例應用程式功能評估,以便您可以體驗這兩種變體,而無需新增覆寫。
疑難排解
我們建議您使用 npm
6.14.14 版。如果您看到有關建置或啟動範例應用程式的任何錯誤,並且您使用不同版本的 npm,請執行以下操作。
安裝 npm
6.14.14 版
下載 node-v14.17.5.pkg
並執行此 pkg 來安裝 npm。 如果您看到
webpack not found
錯誤,請導覽至evidently-sample-shopping-app
資料夾並嘗試以下操作:刪除
package-lock.json
刪除
yarn-lock.json
刪除
node_modules
從
package.json
刪除 Webpack 相依項執行下列命令:
npm install -f && npm