iT邦幫忙

2022 iThome 鐵人賽

DAY 27
3
DevOps

淺談DevOps與Observability系列 第 27

模擬微服務架構的三本柱假資料產生器 - Synthetic Load Generator

  • 分享至 

  • xImage
  •  

Synthetic Load Generator

某天自己在學習Grafana Tempo的時候, 看到它的範例有一個image叫做Synthetic Load Generator
好奇心驅使我來學習看看這是什麼?

官方定義

The synthetic load generator is a utility to generate synthetic operational data (traces, metrics, logs, events) for a simulated microservice-based application. The application is modeled through its topology and operation models for each of the components within the topology.

其中有一句話讓我感到興趣, 模擬微服務架構的應用程式其產生的(traces, metrics, logs, events)
就決定來玩看看
但我發現它目前只有traces :(
因為他的model只有定義了trace model連結 :(

Configuration

整個配置檔案是JSON格式, 檔案中會描述各種服務以及路由方向, 來描述完整的拓樸關係.

建議先在腦海裡想一下...要多少節點跟行為.

主要定義的是topology這拓樸描述物件, 裡面會包含services和rootRoutes

{
    "topology": {
        "services": [
            {
                xxx
            }
        ],
        "rootRoutes": [
            {
              xxx  
            }
        ]
    }
}

rootRoute表示拓樸中的root span, tracesPerHour還能設定每小時要發送的request數量.
這裡的service, 是對應到每個服務節點的名稱.
route則是打到該服務節點的API Path或RPC method的概念

昨天的範例, 就是說每小時打2880個請求到frontend/product.

    "rootRoutes": [
      {
        "service": "frontend",
        "route": "/product",
        "tracesPerHour": 2880
      },
      {
        "service": "frontend",
        "route": "/cart",
        "tracesPerHour": 14400
      }
    ]

接著是services內每個service物件的定義.
每個service物件內會有

  • serviceName : An unique service name
  • tagSets : 定義在該service的屬性, 會被套用到各route上
  • routes : 定義route
    • route : API path
    • downstreamCalls : 該route會去調用哪個服務的route
    • tagSets : 能定義一些route的tag屬性以及一些權重
      • tag : 其實就是OTel Span上的Tag屬性
      • weight : 權重, 當有多個tag同名時, 可以用權重比重的方式隨機出一個, 數字越大, 權重越高, 出現機率越高
      • tagGenerators, 隨機產生出tag key與value
        • numTags : 生成幾個tag
        • numVals : 生成的隨機數的最大值
        • numLength : 需要生成的隨機串位數
      • maxLatency : 該route能設定最大的latency time, 單位是millisecond,
      • inherit: 能指定從上游繼承哪些tag
  • instances
    • 一個服務節點在微服務架構中能佈署成Cluster mode,多機, 這裡就是給像是container id或node id的概念.
  • random : 只支援符合高斯分佈的隨機數
    能夠對每個service或每個route添增自己的tags
        {
          "serviceName": "adservice",
          "tagSets": [
            {
              "tags": {},
              "tagGenerators": [],
              "inherit": [],
              "maxLatency": 500
            }
          ],
          "routes": [
            {
              "route": "/AdRequest",
              "downstreamCalls": {},
              "tagSets": []
            },
            {
              "route": "/Ad",
              "downstreamCalls": {},
              "tagSets": []
            }
          ],
          "instances": [
            "adservice-6b654dbf57-zq8dt",
            "adservice-d847fdcf5-j6s2f"
          ],
          "random": {
            "seed": 22694143111805,
            "nextNextGaussian": 0,
            "haveNextNextGaussian": false
          }
        }

在service設定的tags, 會被套用到該service的所有route;
若tags只被配置在route上, 那就只有該route會被套用.

Examples

First Demo

先來個暖身, 讓前端打login, 會隨機取得某一個tag

{
    "topology": {
      "services": [
        {
            "serviceName": "plateform",
            "tagSets": [
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-2"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 2,
                "tags": {
                  "version": "v126",
                  "region": "us-west-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 110
              }
            ],
            "routes": [
              {
                "route": "/Login",
                "downstreamCalls": { },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "account": "雷N"
                    },
                    "tagGenerators": [
                    ],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Virginia"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Nathan"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  }
                ]
              }
            ],
            "instances": [
              "plateform-001",
              "plateform-002"
            ],
            "random": {
              "seed": 187004238864083,
              "nextNextGaussian": 0,
              "haveNextNextGaussian": false
            }
          }
      ]
    },
    "rootRoutes": [
        {
          "service": "plateform",
          "route": "/Login",
          "tracesPerHour": 120
        }
      ]
}

可以比較一下Tag內容的不同

調用鏈路也是如預期, 單純到炸

Second Demo

新增一個Product服務
讓root, 可以偶爾打plateform/login, 偶爾打product/GetProduct

{
    "topology": {
      "services": [
        {
            "serviceName": "plateform",
            "tagSets": [
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-2"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 2,
                "tags": {
                  "version": "v126",
                  "region": "us-west-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 110
              }
            ],
            "routes": [
              {
                "route": "/Login",
                "downstreamCalls": { },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "account": "雷N"
                    },
                    "tagGenerators": [
                    ],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Virginia"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Nathan"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  }
                ]
              }
            ],
            "instances": [
              "plateform-001",
              "plateform-002"
            ],
            "random": {
              "seed": 187004238864083,
              "nextNextGaussian": 0,
              "haveNextNextGaussian": false
            }
          },
          {
            "serviceName": "product",
            "tagSets": [
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-2"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 2,
                "tags": {
                  "version": "v126",
                  "region": "us-west-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 110
              }
            ],
            "routes": [
              {
                "route": "/GetProducts",
                "downstreamCalls": { },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "account": "雷N"
                    },
                    "tagGenerators": [
                    ],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Virginia"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Nathan"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  }
                ]
              }
            ],
            "instances": [
              "product-001",
              "product-002"
            ],
            "random": {
              "seed": 187004238864083,
              "nextNextGaussian": 0,
              "haveNextNextGaussian": false
            }
          }
      ]
    },
    "rootRoutes": [
        {
          "service": "plateform",
          "route": "/Login",
          "tracesPerHour": 120
        },
        {
            "service": "product",
            "route": "/GetProducts",
            "tracesPerHour": 1200
        }
      ]
}


Final Demo


來玩一下downstream
讓product/GetProducts會去呼叫Recommendations/GetRecommendations

順便繼承GetProducts帶來的product tag
也順便測試出錯的話會怎辦?
在product蘋果那裡, 讓它噴錯error: true, 回應http.status_code: 404
其他則正常

{
    "topology": {
      "services": [
        {
            "serviceName": "plateform",
            "tagSets": [
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-2"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 2,
                "tags": {
                  "version": "v126",
                  "region": "us-west-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 110
              }
            ],
            "routes": [
              {
                "route": "/Login",
                "downstreamCalls": { },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "account": "雷N"
                    },
                    "tagGenerators": [
                    ],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Virginia"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  },
                  {
                    "weight": 1,
                    "tags": {
                      "account": "Nathan"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  }
                ]
              }
            ],
            "instances": [
              "plateform-001",
              "plateform-002"
            ],
            "random": {
              "seed": 187004238864083,
              "nextNextGaussian": 0,
              "haveNextNextGaussian": false
            }
          },
          {
            "serviceName": "product",
            "tagSets": [
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-2"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 100
              },
              {
                "weight": 2,
                "tags": {
                  "version": "v126",
                  "region": "us-west-1"
                },
                "tagGenerators": [],
                "inherit": [],
                "maxLatency": 110
              }
            ],
            "routes": [
              {
                "route": "/GetProducts",
                "downstreamCalls": {
                    "recommendations": "/GetRecommendations"
                 },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "product": "檸檬"
                    },
                    "tagGenerators": [
                    ],
                    "inherit": []
                  },
                  {
                    "weight": 5,
                    "tags": {
                        "product": "蘋果",
                        "error": true,
                        "http.status_code": 404
                    },
                    "tagGenerators": [],
                    "inherit": []
                  },
                  {
                    "weight": 2,
                    "tags": {
                        "product": "芭樂"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  }
                ]
              },
              {
                "route": "/GetCart",
                "downstreamCalls": {
                 },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "product": "檸檬"
                    },
                    "tagGenerators": [
                    ],
                    "inherit": []
                  },
                  {
                    "weight": 5,
                    "tags": {
                        "product": "蘋果",
                        "error": true,
                        "http.status_code": 404
                    },
                    "tagGenerators": [],
                    "inherit": []
                  },
                  {
                    "weight": 2,
                    "tags": {
                        "product": "芭樂"
                    },
                    "tagGenerators": [],
                    "inherit": []
                  }
                ]
              }
            ],
            "instances": [
              "product-001",
              "product-002"
            ],
            "random": {
              "seed": 187004238864083,
              "nextNextGaussian": 0,
              "haveNextNextGaussian": false
            }
          },
          {
            "serviceName": "recommendations",
            "tagSets": [
              {
                "weight": 1,
                "tags": {
                  "version": "v127",
                  "region": "us-east-1"
                },
                "tagGenerators": [],
                "inherit": ["product"],
                "maxLatency": 100
              }
            ],
            "routes": [
              {
                "route": "/GetRecommendations",
                "downstreamCalls": { },
                "tagSets": [
                  {
                    "weight": 1,
                    "tags": {
                      "query": "雷N"
                    },
                    "tagGenerators": [
                        {
                          "rand": {
                            "seed": 179867746078676,
                            "nextNextGaussian": 0,
                            "haveNextNextGaussian": false
                          },
                          "tagGen": {},
                          "valLength": 16,
                          "numTags": 50,
                          "numVals": 3000
                        }
                      ],
                    "inherit": [],
                    "maxLatency": 2800
                  }
                ]
              }
            ],
            "instances": [],
            "random": {
              "seed": 187004238864083,
              "nextNextGaussian": 0,
              "haveNextNextGaussian": false
            }
          }
      ]
    },
    "rootRoutes": [
        {
          "service": "plateform",
          "route": "/Login",
          "tracesPerHour": 120
        },
        {
            "service": "product",
            "route": "/GetProducts",
            "tracesPerHour": 800
        }
        ,
        {
            "service": "product",
            "route": "/GetCart",
            "tracesPerHour": 600
        }
      ]
}

正常的情況跟請求鍊結, 且有繼承product tag資料

出錯的情況跟請求鍊結

甚至還能做儀表板, 看看各服務的API log成長速率
搭配前幾天分享的LogQL Metric Queries

sum by (service, api) (rate({compose_service="synthetic-load-generator"}  | json | line_format "{{.message}}" | __error__ = "" | regexp ".*service (?P<service>\\w+) route (?P<api>[\\w|/]+)" [1h]))

今日小心得

有這套生成器, 很快的就能模擬出一個微服務架構的拓樸.
連error都能模擬真的是很讚!
用來練習LogQL更是方便多了XD

參考資料

Synthetic Load Generator


上一篇
Grafana - 為Log與Trace搭起一座鵲橋
下一篇
淺談Grafana K6 - 網路服務的測試神器
系列文
淺談DevOps與Observability36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
Calvin
iT邦新手 3 級 ‧ 2022-09-27 23:15:05

我還在寫!!!

我要留言

立即登入留言