[로드 테스트] API 서버를 Locust로 공격하고 Prometheus + Grafana로 모니터링
Prometheus
Grafana
Locust
부하 시험의 기초 지식
이 두 가지를 가르쳐 달라고 읽었습니다. 좋았습니다! 특히 책쪽.
웹 애플리케이션 부하 시험 실습 입문 : ↑의 저자에 의해 읽을 수있는 슬라이드
이 기사에서 할 일은?
실제로 수중에서 공격 & 감시를 해보자! 라는 것은 없다.
모든 소스 코드는 GitHub에 있습니다.
htps : // 기주 b. 코 m / 센 수이칸 1973 / st rs_ st_ st mp ぇ
할 일
언어나 미들웨어는 무엇이든 좋지만 이번에는
Go + MySQL에서 매우 간단한 API 서버를 구축하고 Locust로 공격하고 Prometheus + Grafana로 부하를 모니터링합니다.
하지 않는 것
모니터링을 위해 자체 쿼리를 작성하지 않습니다. 또, 본제가 아닌 부분은 편하게 잡하게 실장합니다.
1. 환경 구축
Install Docker for Mac에서 Docker를 설치하고 docker-compose로 빌드했습니다.
주로 이하 2개의 기사를 참고로 했습니다.
디렉토리 구성
전부 내용 쓰면 길어지므로, 자세한 것은 htps : // 기주 b. 코 m / 센 수이칸 1973 / st rs_ st_ st mp ぇ를 봐 주세요.
그래서 yml이나 Dockerfile 같은 이야기는 생략하고 바로 docker를 시작합니다.
$ docker-compose build && docker-compose up
http://localhost:9090/targets에서 Prometheus의 Targets를 확인하면 이런 느낌이 들 것입니다.
Grafana에 데이터 소스 추가
http://localhost:3000에 admin : admin으로 로그인하십시오.
Prometheus
MySQL
Grafana에 Dashboard 추가
왼쪽의 + 아이콘에서 import를 선택하고,
아래의 3가지를 추가하고 각각 환경에 맞춘 설정을 하면,
3개의 그래프를 손에 넣을 수 있습니다. (이것은 Mysql-Prometheus의 예)
2. Locust로 공격
공격 대상 API 서버
Go에 쓴 이것.
극히 단순(그리고 텍토)인 것입니다만, DB 의 write/read 양쪽이 있기 때문에, 부하의 모니터링 예로서 좋은 느낌인가라고 생각합니다.
hello.go
package main
import (
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
_ "github.com/go-sql-driver/mysql"
)
// Greeting : record of greetings table
type Greeting struct {
ID int `json:"id"`
Text string `json:"text"`
}
func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/greetings", func(w http.ResponseWriter, req *http.Request) {
db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/sample_for_qiita")
if err != nil {
panic(err.Error())
}
defer db.Close()
if req.Method == "GET" {
rows, err := db.Query("SELECT * FROM greetings ORDER BY RAND() LIMIT 1")
if err != nil {
panic(err.Error())
}
for rows.Next() {
greeting := Greeting{}
err := rows.Scan(&greeting.ID, &greeting.Text)
if err != nil {
panic(err.Error())
}
fmt.Fprintf(w, greeting.Text)
}
}
if req.Method == "POST" {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
panic(err.Error())
}
var greeting Greeting
error := json.Unmarshal(body, &greeting)
if error != nil {
log.Fatal(error)
}
_, err = db.Exec("insert into greetings (text) values (?)", greeting.Text)
if err != nil {
panic(err.Error())
}
}
})
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe failed.", err)
}
}
github.com/prometheus/client_golang/prometheus/promhttp
를 사용합니다. 막상 공격
이런 느낌의 간단한 시나리오를 쓰고,
locustfile.py
from locust import HttpLocust, TaskSet, task
import random
import string
class GreetingTaskSet(TaskSet):
def on_start(self):
self.client.headers = {'Content-Type': 'application/json; charset=utf-8'}
@task
def fetch_greeting(self):
self.client.get("/greetings")
@task
def create_greeting(self):
# 雑にランダム文字列で済ませちゃう。 (注: random.choices は 3.6 以降でしか使えません)
self.client.post("/greetings", json={"text": ''.join(random.choices(string.ascii_letters, k=10))})
class GreetingLocust(HttpLocust):
task_set = GreetingTaskSet
min_wait = 100
max_wait = 1000
부하를 걸어 간다
# ローカルを発射台として攻撃する
$ locust -f locustfile.py --no-web -H http://localhost:8080
3. Prometheus + Grafana로 모니터링
공격하면서 그래프를 바라보면 부하의 고조를 느낄 수 있어서 기쁘다! ! ! ! ! !
병목 현상을 확인합시다.
오시마
참고
Reference
이 문제에 관하여([로드 테스트] API 서버를 Locust로 공격하고 Prometheus + Grafana로 모니터링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sensuikan1973/items/b766b60933a84edc5416텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)