سؤال
أنا أملك تطبيق Python قديمًا مكتوبًا باسم CGI.حتى الآن يعمل هذا بشكل جيد، ولكن عدد المستخدمين المتزامنين سوف يتزايد بشكل كبير في المستقبل القريب جدًا.هنا على SO قرأت:"تعتبر CGI رائعة لمواقع الويب ذات الزيارات المنخفضة، ولكنها تعاني من بعض مشكلات الأداء لأي شيء آخر".أعلم أنه كان من الأفضل أن نبدأ بطريقة أخرى، لكن CGI هو ما هو عليه الآن.
هل يمكن لأي شخص أن يرشدني إلى كيفية الحفاظ على أداء CGI، دون الحاجة إلى إعادة كتابة كل التعليمات البرمجية؟
المحلول
لا يتم توسيع نطاق CGI لأن كل طلب يؤدي إلى عملية خادم جديدة تمامًا.انها الكثير من النفقات العامة.تتجنب mod_wsgi العبء الزائد عن طريق تفرع عملية واحدة وتسليم الطلبات لتلك العملية الجارية.
لنفترض أن التطبيق هو أسوأ أنواع CGI.
أسوأ الحالات هي أنه يحتوي على ملفات مثل هذه.
my_cgi.py
import cgi
print "status: 200 OK"
print "content-type: text/html"
print
print "<!doctype...>"
print "<html>"
etc.
يمكنك محاولة "تغليف" ملفات CGI الأصلية لجعلها wsgi.
wsgi.py
import cStringIO
def my_cgi( environ, start_response ):
page = cStringIO.StringIO()
sys.stdout= page
os.environ.update( environ )
# you may have to do something like execfile( "my_cgi.py", globals=environ )
execfile( "my_cgi.py" )
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/html')] # HTTP Headers
start_response(status, headers)
return page.getvalue()
هذه خطوة أولى لإعادة كتابة تطبيق CGI الخاص بك في إطار عمل مناسب.يتطلب هذا القليل من العمل، وسيجعل CGI الخاص بك أكثر قابلية للتطوير، نظرًا لأنك لن تبدأ عملية CGI جديدة لكل طلب.
الخطوة الثانية هي إنشاء mod_wsgi
الخادم الذي يستخدمه Apache بدلاً من جميع نصوص CGI النصية.يجب على هذا الخادم (1) تحليل عناوين URL، (2) استدعاء وظائف مختلفة مثل my_cgi
وظيفة المثال.كل وظيفة سوف execfile
البرنامج النصي CGI القديم دون التفرع عن عملية جديدة.
ينظر الى com.werkzeug للمكتبات المفيدة.
إذا كانت نصوص CGI الخاصة بتطبيقك تحتوي على بعض البنية (الوظائف، والفئات، وما إلى ذلك) فمن المحتمل أن تتمكن من استيرادها والقيام بشيء أكثر ذكاءً بكثير مما سبق.هذه طريقة أفضل.
wsgi.py
from my_cgi import this_func, that_func
def my_cgi( environ, start_response ):
result= this_func( some_args )
page_text= that_func( result, some_other_args )
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/html')] # HTTP Headers
start_response(status, headers)
return page_text
يتطلب هذا المزيد من العمل لأنه يتعين عليك فهم التطبيق القديم.ومع ذلك، فإن هذا له ميزتان.
نصائح أخرى
FastCGI . إذا فهمت FastCGI بشكل صحيح، يمكنك أن تفعل ما تريد عن طريق كتابة برنامج بيثون بسيط جدا التي تقع بين خادم الويب ورمز الإرث الخاص بك.