2016-09-28 54 views
16

ile Flask çalışırken istekleri olmayan bir istekte bulunmayan bir istek yapın Flask uygulamasına bir istek, biraz işlem yaptıktan sonra yanıt vermek için 5 saniye süren yavaş bir dış uç noktaya bir istekte bulunun. Gevent ile Gunicorn'un çalıştırılması, bu yavaş isteklerin çoğunun aynı anda ele alınmasına izin verecek gibi görünüyor. Aşağıdaki örnek, görünümü engellememek için nasıl değiştirebilirim?Tabanca ve Gevent

import requests 

@app.route('/do', methods = ['POST']) 
def do(): 
    result = requests.get('slow api') 
    return result.content 
gunicorn server:app -k gevent -w 4 
+1

Burada ne beklersiniz? Eğer henüz almadıysanız istemciye bir şey geri dönemezsiniz –

+0

Ben async yapmak için bekliyordum böylece süper yavaş api için beklerken cpu gücü potansiyel olarak gidebilecek diğer gelen istekleri işlemek için kullanılabilir diğer yola. (Bu uygulamanın birçok farklı gelen istekleri alacağını farz ettiğimden) – JLTChiu

+1

Bu, sizin düşündüğünüz anlamına gelmez. Ve Gunicorn * bunu sizin için halletmeli, sadece bir "time.sleep (30)" ekleyerek emin olmak için test edebilirsiniz, sanırım. Reaktör kalıbı denir, ancak Gunicorn müşterinin bağlanmasına izin verir ve ardından talebi bir işçiye aktarır. İşçi bittiğinde, çalışandan veriyi döndürür ve sonra tekrar havuza geri koyar. Yine de, eğer mevcut olanlar meşgulse, yeni bir işçiyi çalıştırırsa emin değilim. –

cevap

6

Öncelikle biraz arka plan, Bir kilitleme soketi varsayılan türden bir yuvadır, bir kez uygulamanızı okumaya başladığınızda veya iş parçacığı gerçekten okunana kadar kontrole geri dönmez veya bağlantınız kesilir. python-requests, varsayılan olarak bu şekilde çalışır. Engelleme olmayan okumalar sağlayan grequests adı verilen bir sıkma var.

Önemli mekanik fark, herhangi bir şey yapmadan göndermek, yeniden bağlamak, bağlanmak ve kabul etmektir. Seçtiğiniz bir numaranız var. Dönüş kodunu ve hata kodlarını kontrol edebilir ve genellikle kendiniz çıldırırsınız. Bana inanmıyorsanız, denemek bazen

Kaynak: https://docs.python.org/2/howto/sockets.html

Ayrıca söylemeye devam ediyor:

en hızlı priz kod kullandığı şüphe yok engellenmeyen soketler ve onları çoğaltmak için seçin. 'u bir LAN bağlantısını, CPU'yu zorlamadan doyurabilecek bir şey koyabilirsiniz. Sorun şu ki, bu şekilde yazılmış bir uygulama 'dan başka bir şey yapamaz. Bu, tüm kez baytları karıştırmaya hazır olmalıdır.

ise kendi yumurtası onu alarak uygulama aslında parçacığı optimal çözüm

olduğunu, daha fazla bir şey yapmak gerekiyordu Ama görünümünüze karmaşıklık bir sürü eklemek ister misiniz olduğunu varsayarsak İş Parçacığı. Özellikle ne zaman guneycorn async workers?

Asenkron işçiler Greenlets'e dayanmaktadır ( Eventlet ve Gevent aracılığıyla). Greenlets, Python için kooperatif çoklu iş parçacığının bir uygulamasıdır. Genel olarak, bir uygulama bu işçi sınıflarını hiçbir değişiklik yapmadan kullanmak için yapmalıdır.davranış

ve

bazı örnekler asenkron işçi gerektiren: Uzun engelleme aramaları (Yani, dış web hizmetleri)

yapma Uygulamaları Yani kısa uzun bir hikaye kesmek için, Don' Bir şeyi değiştir! Sadece olsun. Herhangi bir değişiklik yaparsanız, önbelleğe almayı tanıtmak olsun. Python istek geliştiricileri tarafından önerilen bir uzantıyı Cache-control kullanmayı düşünün.

2

Sen grequests kullanabilirsiniz. İstek yapılırken diğer yeşilliklerin çalışmasına izin verir. requests kitaplığı ile uyumludur ve requests.Response nesnesini döndürür.

import grequests 

@app.route('/do', methods = ['POST']) 
def do(): 
    result = grequests.map([grequests.get('slow api')]) 
    return result[0].content 

Edit: kullanım aşağıdaki gibidir ben de test eklenmiş ve gunicorn en gevent işçisi zaten başlatılmış olan maymun-yama gerçekleştirir beri zaman grequests fayda görmediği gördü ettik: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/ggevent.py#L65

6

Flask uygulamanızı tabanca ile dağıtıyorsanız, zaten engellenmiyordur. Bir müşteri, görüşlerinizden birinden yanıt beklerse, başka bir müşteri bir sorun olmadan aynı görünüme istekte bulunabilir. Birden çok isteği aynı anda işlemek için birden fazla işçi olacak. Bunun çalışması için kodunuzu değiştirmenize gerek yok. Bu aynı zamanda her Flask dağıtım seçeneği için de geçerli.

+0

Bu durumda OP, görüşünün içinden başka bir engelleme ağı araması yapmaktan bahsediyor. Cevabınızdaki senaryodan farklı olanı. – e4c5

+0

OP sorgusu "Görüntülemeyi engellememek için aşağıdaki örneği nasıl değiştirebilirim?" Görünüm zaten blokajsız. Elbette 'requests.get 'engeller, ancak bu eylem başka bir müşterinin OP'nin ana endişesi olduğuna inandığım aynı görüşe erişebileceği şekilde olur. Api çağrısını da nonbloke edebilirsin, ama bu işe yaramaz çünkü bir şekilde tamamlanana kadar müşteriye bir şey veremezsin. – sytech

+0

Gerçekten mi? belki de sorumu yanlış anladım. Anlayışım, – e4c5