Медленное время отклика сокета при использовании нескольких запросов - PullRequest
1 голос
/ 28 марта 2020

Я использую сервер сокетов, который использует ThreadingMixIn, чтобы сделать его неблокирующим. Сервер работает хорошо, он может обрабатывать сотни соединений одновременно без каких-либо проблем. Моя проблема начинается с SqlAlchemy, который помогает запрашивать и обновлять мою базу данных. После того, как клиент отправляет сообщение (каждую секунду) на мой сервер, я должен сделать два запроса и одно обновление в моей базе данных. Два запроса очень просты, а таблица небольшая, обновление более проблематично c, здесь я должен обновить по Id (Id таблицы проиндексирован в моей базе данных), и таблица содержит тысячи строк. Проблема возникает, когда 200 клиентов подключаются к моему серверу, хотя мой сценарий может обрабатывать как чтение, так и запись, но после 200 подключений простаивает и время отклика начинает замедляться. Я отслеживаю его с помощью tcptrack и вижу, что среднее время простоя увеличивается с 0-1 с до 2-3 с. Мои запросы и обновления выполняются быстро, но после 200 соединений эти запросы замедляются . Я также измеряю время выполнения в коде, и я заметил, что t1 увеличивается до 2 с пару раз от среднего 0,005 с. Я прилагаю свой упрощенный код.

Пример моего краткого кода:

from config_file import *
import os
import sys
from http.server import BaseHTTPRequestHandler, HTTPServer
import socketserver
import select    
from models import Users, Model1, Model2
from base_db import Session, engine, Base, conn

class MyHandler(BaseHTTPRequestHandler):

    def __init__(self, request, address, server):
        BaseHTTPRequestHandler.__init__(self, request, address, server)

    def do_GET(self):
        while True:
            readable, writable, exceptional = select.select([self.rfile], [self.wfile], [self.rfile, self.wfile])
            try:
                for s in readable:
                    s.readline()
                    try: 
                        t0 = time.time()
                        session = Session()
                        model_data_1 = session.query(Model1).filter_by(id=1)
                        model_data_2 = session.query(Model2).filter_by(foo=False).all()
                        session.query(Users).filter_by(id=111).update({'test1' : 21, 'test2': 0, 'test3': "FIX", "timstamp": datetime.datetime.utcnow() }) 
                        t1 = time.time() - t0
                    except:
                        session.rollback()
                    finally:
                        session.close()

                for s in writable:
                    session = Session()
                    try:
                         self.model_data_2 = session.query(Model2).filter_by(type="test").first()
                    except:
                        session.rollback()
                    finally:
                        session.close()
                    if self.model_data_2:
                        time.sleep(1)
                        s.write(self.model_data_2.data)
            except Exception as e:
                print (e)

class MyServer(socketserver.ThreadingMixIn, HTTPServer):
    pass

if __name__ == '__main__':  
    httpd = MyServer((HOST, PORT), MyHandler)
    try:
        httpd.allow_reuse_address = True
        httpd.serve_forever() 
    except KeyboardInterrupt:
        pass

    httpd.server_close()
    conn.close()

По конфигурации базы данных:

import sqlalchemy as db
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
from config_file import *

engine = db.create_engine("postgresql://" + DB_AUTH_USER +
                          ":" + DB_AUTH_PASSWD + "@" + DB_HOST_PORT + "/" + DB_NAME)
conn = engine.connect()
session_factory = sessionmaker(bind=engine)
Session = scoped_session(session_factory)
Base = declarative_base()

Мой вопрос почему замедляется среднее время выполнения после 200 соединений? Мои запросы быстрые, но по какой-то причине они начинают замедляться, или мои потоки делают это замедление? Заранее большое спасибо!

1 Ответ

0 голосов
/ 04 апреля 2020

Наконец я перешел с SqlAlchemy на vanilla psycopg2, что в итоге и решило мою проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...