سؤال

لقد قمت مؤخرًا باستكشاف إطار عمل الويب Tornado لخدمة الكثير من الاتصالات المتسقة بواسطة العديد من العملاء المختلفين.

لدي معالج طلب يأخذ بشكل أساسي سلسلة مشفرة بـ RSA ويفك تشفيرها.النص الذي تم فك تشفيره هو عبارة عن سلسلة XML يتم تحليلها بواسطة معالج مستندات SAX الذي قمت بكتابته.كل شيء يعمل بشكل جيد وكان وقت التنفيذ (لكل طلب HTTP) حوالي 100 مللي ثانية (مع فك التشفير والتحليل).

يحتوي XML على تجزئة اسم المستخدم وكلمة المرور للمستخدم.أريد الاتصال بخادم MySQL للتحقق من تطابق اسم المستخدم مع تجزئة كلمة المرور التي يوفرها التطبيق.

عندما أقوم بإضافة الكود التالي بشكل أساسي:

conn = MySQLdb.connect (host = "192.168.1.12",
                user = "<useraccount>",
                passwd = "<Password>",
                db = "<dbname>")
    cursor = conn.cursor()

    safe_username = MySQLdb.escape_string(XMLLoginMessage.username)
    safe_pass_hash = MySQLdb.escape_string(XMLLoginMessage.pass_hash)

    sql = "SELECT * FROM `mrad`.`users` WHERE `username` = '" + safe_username + "' AND `password` = '" + safe_pass_hash + "' LIMIT 1;"

    cursor.execute(sql)

            cursor.close()
    conn.close()

الوقت المستغرق لتنفيذ طلب HTTP يصل إلى 4 - 5 ثوانٍ!أعتقد أن هذا يحدث في الوقت الذي يستغرقه الاتصال بخادم قاعدة بيانات MySql نفسه.

سؤالي هو كيف يمكنني تسريع هذا؟هل يمكنني الإعلان عن اتصال MySQL في النطاق العام والوصول إليه في معالجات الطلب عن طريق إنشاء مؤشر جديد، أم أن ذلك سيواجه مشكلات في التزامن بسبب التصميم غير المتزامن لـ Tornado؟

في الأساس، كيف لا يمكنني إجراء اتصال جديد بخادم MySQL في كل طلب Http، لذلك يستغرق تنفيذه جزءًا من الثانية فقط بدلاً من عدة ثوانٍ.

يرجى أيضًا ملاحظة أن خادم SQL موجود فعليًا على نفس الجهاز الفعلي مثل مثيل Tornado Web Server

تحديث

لقد قمت للتو بإجراء استعلام MySQL بسيط من خلال ملف تعريف، وهو نفس الكود أدناه.

الدعوة إلى "connections.py" فيه استغرق تنفيذ الوظيفة 4.944 ثانية بمفردها.هذا لا يبدو صحيحا، أليس كذلك؟

تحديث 2

أعتقد أن التشغيل باستخدام اتصال واحد (أو حتى عدد قليل باستخدام مجموعة اتصال DB بسيطة جدًا) سيكون سريعًا بما يكفي للتعامل مع الإنتاجية التي أتوقعها لكل مثيل لخادم ويب تورنادو.

إذا احتاج 1000 عميل إلى الوصول إلى استعلام، وتكون أوقات الاستعلام النموذجية بآلاف الثواني، فلن يتعين على العميل الأقل حظًا سوى الانتظار ثانية واحدة لاسترداد البيانات.

هل كانت مفيدة؟

المحلول

يعتبر SQLAlchemy, ، والذي يوفر تجريدًا أفضل عبر DBAPI ويوفر أيضًا تجميع الاتصال، وما إلى ذلك.(يمكنك بسعادة تجاهل ORM الخاص به واستخدام مجموعة أدوات SQL فقط)

(أيضًا، أنت لا تقوم بحظر مكالمات قاعدة البيانات في معالجات الطلب غير المتزامنة؟)

نصائح أخرى

يجب ألا يستغرق اتصال SQL 5 ثوانٍ.حاول عدم إصدار استعلام ومعرفة ما إذا كان ذلك سيؤدي إلى تحسين أدائك - وهو ما ينبغي أن يحدث.

تحتوي وحدة Mysqldb على مؤشر ترابط آمن "1"، مما يعني أن الوحدة آمنة لمؤشر الترابط، ولكن لا يمكن مشاركة الاتصالات بين سلاسل الرسائل.يمكنك تنفيذ تجمع اتصال كبديل.

وأخيرًا، تحتوي واجهة برمجة تطبيقات DB-API على نموذج استبدال المعلمات للاستعلامات التي لا تتطلب تسلسل الاستعلام يدويًا وإلغاء المعلمات:

cur.execute("SELECT * FROM blach WHERE x = ? AND y = ?", (x,y))

قم بتعريفه في المعالج الأساسي، وسيتم استدعاؤه مرة واحدة لكل تطبيق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top