From 9de9bd414fb4e651f3ec6bf53085fb073b38bfed Mon Sep 17 00:00:00 2001 From: naeel Date: Tue, 18 Aug 2026 08:49:35 +0400 Subject: [PATCH] =?UTF-8?q?LoadTest=20v2:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D1=80=D0=B8=D1=91=D0=BC=D0=B0=20=D0=A1?= =?UTF-8?q?=D0=9E=D0=9E=D0=91=D0=A9=D0=95=D0=9D=D0=98=D0=99=20(/messages,?= =?UTF-8?q?=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D0=B9=D0=BD=D0=BE=D0=B5=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D0=BC=D0=BE=D0=B5=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/app.py | 48 ++++++++++ site/templates/index.html | 192 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) diff --git a/site/app.py b/site/app.py index ccb64ec..27aef84 100644 --- a/site/app.py +++ b/site/app.py @@ -86,6 +86,54 @@ def upload(): return jsonify(result) +@app.route("/messages", methods=["POST"]) +def messages(): + """Приём СООБЩЕНИЯ в память (для проверки очередей/ИоТ). + + От клиента приходит сырое тело запроса (raw body) нужного размера. + Задача - проверить, ДОХОДИТ ли сообщение нужного размера до бэкенда + (в отличие от /upload здесь нет multipart - только тело, как в очередях). + """ + t0 = time.time() + + meta = { + "server_start": time.strftime("%Y-%m-%d %H:%M:%S"), + "remote_addr": request.remote_addr or "", + # Заголовки, которые обычно шлёт очередь/ИоТ-клиент. + "content_length_header": request.headers.get("Content-Length", ""), + "content_type_header": request.headers.get("Content-Type", ""), + "user_agent": request.headers.get("User-Agent", ""), + "x_amz_sns_message_type": request.headers.get("X-Amz-Sns-Message-Type", ""), + "ce_specversion": request.headers.get("Ce-Specversion", ""), + } + + # Читаем ВСЁ сырое тело сообщения в память и замеряем время. + t_read = time.time() + data = request.get_data() # сырое тело без разбора (как в SQS/IoT) + read_s = time.time() - t_read + + size = len(data) # сколько байт РЕАЛЬНО дошло до бэкенда + total_s = time.time() - t0 + + result = { + "ok": True, + "message": { + "size_bytes": size, + "size_kb": round(size / 1024, 3), + "size_mb": round(size / (1024 * 1024), 3), + "prefix": data[:64].decode("utf-8", "replace"), # первые 64 байта для наглядности + }, + "server": { + "read_ms": round(read_s * 1000, 2), + "total_ms": round(total_s * 1000, 2), + "speed_mb_s": round(size / (1024 * 1024) / read_s, 3) if read_s > 0 else 0, + }, + "md5": hashlib.md5(data).hexdigest(), # контрольная сумма принятых байт + "meta": meta, + } + return jsonify(result) + + if __name__ == "__main__": # ОБЯЗАТЕЛЬНО для платформы: `python site/app.py` должен стартовать сервер. # debug=False - прод-режим, без reloader (иначе поднимается второй процесс). diff --git a/site/templates/index.html b/site/templates/index.html index 0a5518c..b21aebb 100644 --- a/site/templates/index.html +++ b/site/templates/index.html @@ -39,8 +39,200 @@

+
+    
+    
+    
+    
+ +

Сообщение (очередь / ИоТ)

+

+ Задайте размер сообщения (в байтах). Содержимое - случайное. + Проверяется, ДОХОДИТ ли тело сообщения нужного размера до бэкенда (без multipart, как в очереди). +

+ +
+ + + +
+ + + + + +
+ + +

   
 
+  
+