API Load Testing ve Uvicorn Workerları hk

Selamlar. FastAPI ile yazdığım bir API’ım var. Şu an Ubuntu serverda aktif olarak çalışıyor ve bu api’a basit bir load test yapmak istiyorum. Sadece ‘acaba aynı anda kaç request’e cevap verebiliyor’ sorusunun cevabını arıyorum ve bunun için şöyle basit bir kod yazdım

import requests
import threading
import os


failed = 0

api_url = os.getenv("API_URL")

def do_request():
    payload = {"test_col": "sent from python script with requests"}
    try:
        r = requests.post(f"{api_url}/icreate", json=payload)
        print(r.status_code)
    except Exception as e:
        print(e)
        global failed
        failed+=1

threads = []
count = 600

for i in range(count):
    t = threading.Thread(target=do_request)
    t.daemon = True
    threads.append(t)

for i in range(count):
    threads[i].start()

for i in range(count):
    threads[i].join()

print(failed)

Basit bir load testing için bu yaklaşım doğru mudur? JMeter gibi programları araştırdım fakat çok karmaşık olduğu için şimdilik girmek istemedim açıkçası.

Uvicorn workerları hakkındaki sorum da bununla bağlantılı. API tek workerla çalıştığında yukarıdaki kodda oluşturduğum 600 threadin ortalama 70’i Target machine refuses connection hatası veriyor. hatta çok fazla yüklenirsem API tamamen yanıt veremez hale geliyor ve restart gerektiriyor.
Worker sayısını 4 yaptığımda threadi 2500 e kadar çıkarıyorum ve hiçbiri failed olmuyor. Bunun üzerine biraz araştırma yaptım ama teknik eksikliğim nedeniyle araştırmalarımdan pek bir anlam çıkaramadım. Worker sayısını 20-30 gibi bir sayı yapsam bunun olumsuz etkisi ne olur? Worker sayısı tamamen API’ın deploy edildiği makinenin spec’i ile mi orantılıdır?

Soru Uvicorn’a daha yakin bir noktaya sorulmasi gerekecek kadar ozellesmis. Ben sadece benzeri sistemler uzerine bilgimi kullanarak genel cevaplayabilirim:

Gerekli load’u olusturabiliyorsa dogrudur.
Ben python’un thread’ler arasi gereksiz interaksiyon (GIL) ihtimaline karsi baska bir dilde yazardim herhalde. Nasilsa kod “dili yeni ogreniyorum” kodu gibi.

ICMP hata mesaji donuyor gibi. Worker soketinin 500’luk backlog’u mu var?

Test kodu disinda kalan herhangi normal bir kullanici icin, degil mi?
Cunku sistemde stres olusturan bir kod kullaniyoruz. Ayni stres client tarafinda da olusabilir. (Hatta dusunursen, ihtimali server tarafinda olusmasindan daha yuksek.)

Baski bittikten sonra sistemin eski haline geri donmesi lazim. Donmezse bug olabilir.

Client hizini bilmiyorum, ama 4 worker’in da 530*4 client desteklemesi lazim mantiken. Stres testi yapan alet (client) process limitlerine veya kutuphane limitasyonlarina takiliyor olabilir. Veya basitce non-linear yavaslama goruyor olabilir. (Soyle dusun: 100,000 thread olsa sadece 100k kat yavaslamayacak.)

Evet, ve istenilen parametrelere.

Ortalama veya pik CPU ve hafiza kullanimlarina gore belirlenebilir sayilari.
Veya bir degerle baslanip duruma gore artirilip azaltilabilir. (Uvicorn’un tuning guide’i yok mu?)

1 Beğeni

hocam garip bir şekilde threading ile değil de asenkron http kütüphaneleriyle istek attığımda bir sorunla karşılaşmıyorum. zaten logları incelediğimde de herhangi bir hata göremiyordum server tarafında. Ayrıca bir de Go ile yazmayı deneyeceğim bakalım ne değişecek.

evet test dışında direkt kullanıcının kullanacağı api’ı test ettim. bu sorun client tarafında da oluşabilir.

Ben de öyle düşünüyordum fakat tamamen kullanılamaz hale gelmesi beni çok şaşırttı. acaba bazı threadlerdeki istekler hala yanıt mı bekliyor diye bakayım dedim ama öyle bir durum da yok. loglara bakıyorum herhangi bir hata göremiyorum. yani client tarafında target machine refuses connection
hatası alırken serverda her şey yolunda gözüküyor.

burayı nedense anlayamadım. mantıken sistemde çok fazla yük varsa yeni gelen istekleri sıraya alıp onları bekletmesi gerekmez mi? bu acaba nginx’in işi mi fastapi’ın işi mi bunu araştırmam gerek sanırım. nginx ile load balancing’i vs öğrenmem gerekecek. ben dümdüz deploy ettim.

zaten başlarda pek user olmayacağından şimdilik 2 workerla başlayacağım. saniyede 500 küsür isteğe yanıt verebiliyor olması benim için yeterli zaten. ayrıca kubernetes öğrenmeye çalışıyorum bu aralar. k8s ile de çözebilirim diye düşünüyorum bu problemi.

İyi çalışmalar.

2 Beğeni

Istekler “istek” olmadan once TCP baglantilarinin kurulabilmesi lazim. Onun icin network paketlerinin bilumum katmandan gecmesi lazim. Incelemeye asagidan baslaman gerekebilir.

nginx FastAPI ile nasil konusuyor? Mesela Flask’ta araya uWSGI gibi bir WSGI sunucusu girmesi gerekiyor. Katmanlar ve incelenmesi gereken seyler daha da karisiyor…
Ama neyse ki bu arada katmanda calisan cogu programin derdi efficiency, hiz, vs. O yuzden kaynak bulmak cok zor olmayabilir.

Oy, bi turlu sonemedi su Kubernetes bubble’i.
Ogrenmeye calisanlara saygim sonsuz tabi.

Nginx, Gunicorn ile konuşuyor hocam.

#!/bin/bash

NAME=fastapi-app
DIR=/home/fastapi-user/fastapi-nginx-gunicorn
USER=fastapi-user
GROUP=fastapi-user
WORKERS=3
WORKER_CLASS=uvicorn.workers.UvicornWorker
VENV=$DIR/.venv/bin/activate
BIND=unix:$DIR/run/gunicorn.sock
LOG_LEVEL=error

cd $DIR
source $VENV

exec gunicorn main:app \
  --name $NAME \
  --workers $WORKERS \
  --worker-class $WORKER_CLASS \
  --user=$USER \
  --group=$GROUP \
  --bind=$BIND \
  --log-level=$LOG_LEVEL \
  --log-file=-

bir siteden bulmuştum ama bulamadım siteyi. worker class olarak uvicorn kullanmak istedim.

hocam aslında öğrenmek gibi bir derdim yoktu çok da gereksiz geliyordu bana. K8s’in kendisi gereksiz değil, benim ufak tefek projelerim için gereksiz görünüyordu ancak kariyerim için önemli şu an kubernetes. 3-4 ay kadar k8s çalışıp giriş seviyesi bilgiye sahip olmam gerek.
Yine de çok merak ettim, neden balon olduğunu düşünüyorsunuz?

Cunku Turkiye’de Kubernetes gerektirecek buyuklukte is yapan yok. Ama kullanan sayisi 0’dan fazla…

Administrate etmek bir kisinin full-time isi olmasa (veya kullananlar bu kaynagi ayirsalar) bu kadar abartmayacagim belki…

Veya ne bileyim, en azindan AWS’deki cluster ucreti ucuz gelmeli kullananlara.

Daha yapacagi is tanimlanmamisken microservice-based olacagi bilinen sistemi getiriyor aklima onceki islerimden. Benim yaram veya kor noktam da olabilir.