首頁  >  文章  >  web前端  >  Grafana Kheat 表:性能工程師應該知道的一切

Grafana Kheat 表:性能工程師應該知道的一切

Patricia Arquette
Patricia Arquette原創
2024-10-26 11:26:02675瀏覽

Grafana K6 備忘單:效能工程師應該了解的一切(包含範例和最佳實務)

1.Grafana K6簡介

Grafana K6 是一款專為效能測試而設計的開源工具。它非常適合大規模測試 API、微服務和網站,讓開發人員和測試人員深入了解系統效能。本備忘單將涵蓋每位性能工程師開始使用 Grafana K6 時應了解的關鍵面向。

什麼是 Grafana K6?

Grafana K6 是一款面向開發人員和測試人員的現代負載測試工具,它使效能測試變得簡單、可擴展,並且易於整合到 CI 管道中。

什麼時候使用它?

  • 負載測試
  • 壓力測試
  • 峰值測試
  • 效能瓶頸偵測
  • API 檢定
  • 瀏覽器測試
  • 混沌工程

2. Grafana K6 備忘單:基本面

2.1.安裝

透過 Homebrew 或 Docker 安裝 Grafana K6:

brew install k6
# Or with Docker
docker run -i grafana/k6 run - <script.js

2.2.使用公共 REST API 進行基本測試

以下是如何使用公用 REST API 來執行簡單測試。

import http from "k6/http";
import { check, sleep } from "k6";

// Define the API endpoint and expected response
export default function () {
  const res = http.get("https://jsonplaceholder.typicode.com/posts/1");

  // Define the expected response
  const expectedResponse = {
    userId: 1,
    id: 1,
    title:
      "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto",
  };

  // Assert the response is as expected
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response is correct": (r) =>
      JSON.stringify(JSON.parse(r.body)) === JSON.stringify(expectedResponse),
  });

  sleep(1);
}
2.2.1 運行Web儀表板的測試和使用

要執行測試並在 Web 儀表板中查看結果,我們可以使用以下命令:

K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=html-report.html k6 run ./src/rest/jsonplaceholder-api-rest.js

這將在報告資料夾中產生一個名為 html-report.html 的報告。

但我們也可以透過造訪以下 URL 在 Web 儀表板中查看結果:

http://127.0.0.1:5665/

Grafana Kheat sheet: everything a performance engineer should know

存取 URL 後,我們可以在 Web 儀表板中即時查看測試結果。

Grafana Kheat sheet: everything a performance engineer should know

2.3.使用公共 GraphQL API 進行測試

使用公用 GraphQL API 的範例。

如果您不知道什麼是 GraphQL API,可以存取以下網址:什麼是 GraphQL? 。

有關我們將要使用的 GraphQL API 的更多信息,您可以訪問以下 URL 的文檔:GraphQL Pokémon。

有關如何測試 GraphQL API 的更多信息,您可以訪問以下網址:GraphQL 測試。

這是一個簡單的測試,用於透過名稱獲取寶可夢並檢查回應是否成功。

import http from "k6/http";
import { check } from "k6";

// Define the query and variables
const query = `
  query getPokemon($name: String!) {
    pokemon(name: $name) {
      id
      name
      types
    }
  }`;

const variables = {
  name: "pikachu",
};

// Define the test function
export default function () {
  const url = "https://graphql-pokemon2.vercel.app/";
  const payload = JSON.stringify({
    query: query,
    variables: variables,
  });

  // Define the headers
  const headers = {
    "Content-Type": "application/json",
  };

  // Make the request
  const res = http.post(url, payload, { headers: headers });

  // Define the expected response
  const expectedResponse = {
    data: {
      pokemon: {
        id: "UG9rZW1vbjowMjU=",
        name: "Pikachu",
        types: ["Electric"],
      },
    },
  };

  // Assert the response is as expected
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response is correct": (r) =>
      JSON.stringify(JSON.parse(r.body)) === JSON.stringify(expectedResponse),
  });
}

3. 建構績效項目的最佳實踐

3.1.集中配置

在一個地方定義全域設定選項,例如效能閾值、虛擬使用者 (VU) 數量和持續時間,以便於修改。

brew install k6
# Or with Docker
docker run -i grafana/k6 run - <script.js

3.2.程式碼模組化

3.2.1. REST API 的常數和請求

將程式碼分離成可重複使用的模組,例如,將常數和請求與測試邏輯分開。

對於我們的 REST API 範例,我們可以建立一個 Constants.js 檔案來儲存 API 的基本 URL,並建立一個 requests-jsonplaceholder.js 檔案來儲存與 API 互動的函數。

import http from "k6/http";
import { check, sleep } from "k6";

// Define the API endpoint and expected response
export default function () {
  const res = http.get("https://jsonplaceholder.typicode.com/posts/1");

  // Define the expected response
  const expectedResponse = {
    userId: 1,
    id: 1,
    title:
      "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto",
  };

  // Assert the response is as expected
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response is correct": (r) =>
      JSON.stringify(JSON.parse(r.body)) === JSON.stringify(expectedResponse),
  });

  sleep(1);
}

現在我們可以建立 requests-jsonplaceholder.js 檔案來儲存與 API 互動的函數。

K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=html-report.html k6 run ./src/rest/jsonplaceholder-api-rest.js

3.2.2. REST API 測試腳本中請求的集成

最後,我們可以建立測試腳本 jsonplaceholder-api-rest.js 來使用我們在 requests-jsonplaceholder.js 檔案中建立的函數。

http://127.0.0.1:5665/

我們的腳本程式碼現在更容易理解,並且如果 URL、參數發生變化或需要添加新方法,則需要進行更改的位置會集中起來,從而使我們的解決方案更易於擴展隨著時間的推移。

我們可以透過創建更多的原子函數來進一步改進我們的腳本,如果有必要,我們可以重複使用這些原子函數來創建更複雜的場景,這樣就更容易理解我們的測試腳本的作用。例如,如果我們想測試貼文是否存在,我們可以建立一個取得貼文並回傳回應的函數,然後我們可以在測試腳本 jsonplaceholder-api-rest.js 中使用此函數。

import http from "k6/http";
import { check } from "k6";

// Define the query and variables
const query = `
  query getPokemon($name: String!) {
    pokemon(name: $name) {
      id
      name
      types
    }
  }`;

const variables = {
  name: "pikachu",
};

// Define the test function
export default function () {
  const url = "https://graphql-pokemon2.vercel.app/";
  const payload = JSON.stringify({
    query: query,
    variables: variables,
  });

  // Define the headers
  const headers = {
    "Content-Type": "application/json",
  };

  // Make the request
  const res = http.post(url, payload, { headers: headers });

  // Define the expected response
  const expectedResponse = {
    data: {
      pokemon: {
        id: "UG9rZW1vbjowMjU=",
        name: "Pikachu",
        types: ["Electric"],
      },
    },
  };

  // Assert the response is as expected
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response is correct": (r) =>
      JSON.stringify(JSON.parse(r.body)) === JSON.stringify(expectedResponse),
  });
}

3.2.3. GraphQL API 的常數和請求

我們可以修改constants.js檔案以新增GraphQL API的基本URL和我們需要使用的標頭。

// ./src/config/options.js
export const options = {
  stages: [
    { duration: '1m', target: 100 }, // ramp up to 100 VUs
    { duration: '5m', target: 100 }, // stay at 100 VUs for 5 mins
    { duration: '1m', target: 0 },   // ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'], // 95% of requests should complete in under 500ms
  },
};

現在我們可以建立 requests-graphql-pokemon.js 檔案來儲存與 GraphQL API 互動的函式。

// ./src/utils/constants.js
export const BASE_URLS = {
  REST_API: 'https://jsonplaceholder.typicode.com',
};

3.2.4. GraphQL API 測試腳本中的請求集成

此時我們可以建立測試腳本來使用我們在 requests-graphql-pokemon.js 檔案中建立的函數。我們將創建一個簡單的測試腳本,用於獲取口袋妖怪的數據並檢查響應是否成功。

// ./src/utils/requests-jsonplaceholder.js
import { BASE_URLS } from './constants.js';
import http from 'k6/http';

export function getPosts() {
    return http.get(`${BASE_URLS.REST_API}/posts`);
}

export function getPost(id) {
    return http.get(`${BASE_URLS.REST_API}/posts/${id}`);
}

export function createPost(post) {
    return http.post(`${BASE_URLS.REST_API}/posts`, post);
}

export function updatePost(id, post) {
    return http.put(`${BASE_URLS.REST_API}/posts/${id}`, post);
}

export function deletePost(id) {
    return http.del(`${BASE_URLS.REST_API}/posts/${id}`);
}

與api rest 的範例相同,我們可以透過創建更多原子函數來改進我們的腳本,如果需要的話,我們可以重複使用這些原子函數來創建更複雜的場景,這樣就更容易理解我們的測試腳本的內容是的。

還有更好的方法來優化並對回應和請求結果進行更好的參數化,您認為我們可以做什麼?

3.3.動態數據和參數化

使用動態資料來模擬更真實的場景並載入不同的資料集。 K6 允許我們使用共享數組從檔案載入資料。共享數組是一種儲存資料的方式,所有 VU 都可以存取。

我們可以建立一個 users-config.js 檔案來從 JSON 檔案 users.json 載入使用者資料。

brew install k6
# Or with Docker
docker run -i grafana/k6 run - <script.js
import http from "k6/http";
import { check, sleep } from "k6";

// Define the API endpoint and expected response
export default function () {
  const res = http.get("https://jsonplaceholder.typicode.com/posts/1");

  // Define the expected response
  const expectedResponse = {
    userId: 1,
    id: 1,
    title:
      "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto",
  };

  // Assert the response is as expected
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response is correct": (r) =>
      JSON.stringify(JSON.parse(r.body)) === JSON.stringify(expectedResponse),
  });

  sleep(1);
}

然後我們可以在測試腳本 jsonplaceholder-api-rest.js 中使用它。

K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=html-report.html k6 run ./src/rest/jsonplaceholder-api-rest.js

4. 項目結構

組織良好的專案結構有助於維護和擴展您的測試。以下是建議的資料夾結構:

http://127.0.0.1:5665/

這種結構有助於保持專案組織有序、可擴展且易於維護,避免專案根目錄混亂。

另一種選擇是按功能將測試腳本分組到資料夾中,您可以測試和比較對您的上下文最有意義的內容。例如,如果您的專案是關於進行交易的錢包,您可以為每種類型的交易(存款、提款、轉帳等)建立一個資料夾,並且在每個資料夾內您可以擁有該特定交易的測試腳本。

import http from "k6/http";
import { check } from "k6";

// Define the query and variables
const query = `
  query getPokemon($name: String!) {
    pokemon(name: $name) {
      id
      name
      types
    }
  }`;

const variables = {
  name: "pikachu",
};

// Define the test function
export default function () {
  const url = "https://graphql-pokemon2.vercel.app/";
  const payload = JSON.stringify({
    query: query,
    variables: variables,
  });

  // Define the headers
  const headers = {
    "Content-Type": "application/json",
  };

  // Make the request
  const res = http.post(url, payload, { headers: headers });

  // Define the expected response
  const expectedResponse = {
    data: {
      pokemon: {
        id: "UG9rZW1vbjowMjU=",
        name: "Pikachu",
        types: ["Electric"],
      },
    },
  };

  // Assert the response is as expected
  check(res, {
    "status is 200": (r) => r.status === 200,
    "response is correct": (r) =>
      JSON.stringify(JSON.parse(r.body)) === JSON.stringify(expectedResponse),
  });
}

在第二個範例中,我們有一個更複雜的資料結構,但我們仍然可以重複使用為第一個範例建立的相同請求函數。

結論

K6 效能測試對於識別瓶頸和確保應用程式可擴展性至關重要。透過遵循模組化程式碼、集中配置和使用動態資料等最佳實踐,工程師可以建立可維護和可擴展的效能測試腳本。

大大的擁抱。

查理自動化

以上是Grafana Kheat 表:性能工程師應該知道的一切的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn