Dapatkah saya melayani beberapa klien menggunakan hanya Flask app.run () sebagai standalone?

202

Saya tahu saya dapat menautkan Flask dengan Apache atau server web lainnya. Tapi, saya berpikir untuk menjalankan Flask sebagai server mandiri yang melayani banyak klien secara bersamaan.

Apakah ini mungkin? Apakah saya harus menangani pemunculan banyak utas dan mengelolanya?

ATOzTOA
sumber

Jawaban:

295

flask.Flask.runmenerima argumen kata kunci tambahan ( **options) yang diteruskan ke werkzeug.serving.run_simple- dua argumen tersebut adalah threaded(boolean) dan processes(yang dapat Anda atur ke nomor lebih besar dari satu agar werkzeug menelurkan lebih dari satu proses untuk menangani permintaan).

threadeddefaultnya Truesebagai pada Flask 1.0, jadi untuk versi Flask terbaru, server pengembangan default akan dapat melayani banyak klien secara bersamaan secara default. Untuk versi Flask yang lebih lama, Anda dapat secara eksplisit meneruskan threaded=Trueuntuk mengaktifkan perilaku ini.

Misalnya, Anda bisa melakukannya

if __name__ == '__main__':
    app.run(threaded=True)

untuk menangani beberapa klien menggunakan utas dengan cara yang kompatibel dengan versi Flask lama, atau

if __name__ == '__main__':
    app.run(threaded=False, processes=3)

untuk memberitahu Werkzeug untuk menelurkan tiga proses untuk menangani permintaan yang masuk, atau adil

if __name__ == '__main__':
    app.run()

untuk menangani beberapa klien menggunakan utas jika Anda tahu bahwa Anda akan menggunakan Flask 1.0 atau yang lebih baru.

Yang sedang berkata, Werkzeug's serving.run_simplemembungkus wsgirefpaket perpustakaan standar - dan paket itu berisi implementasi referensi WSGI, bukan server web siap produksi. Jika Anda akan menggunakan Flask dalam produksi (dengan asumsi bahwa "produksi" bukan aplikasi internal lalu lintas rendah dengan tidak lebih dari 10 pengguna secara bersamaan) pastikan untuk menahannya di belakang server web nyata (lihat bagian dokumen Flask yang berjudul Opsi Penerapan untuk beberapa metode yang disarankan).

Sean Vieira
sumber
2
Bagaimana jika saya melihat maksimal 100 pengguna? Bisakah saya menetapkan processes=100dan senang dengan itu? Dalam kasus saya, saya hanya perlu file statis, tidak ada metode HTTP Post. Persyaratan saya adalah, saya ingin menjalankan semua utas Flask sebagai bagian dari aplikasi induk saya, sehingga semuanya dapat berbagi variabel.
ATOzTOA
4
Terkekeh - @ATOzTOA - tidak, itu mungkin akan sangat tidak produktif (Prosesnya relatif mahal, dan kecuali jika Anda melakukan banyak pekerjaan di setiap permintaan, tidak ada alasan mengapa 4 atau 8 proses tidak cukup). Yang mengatakan, jika Anda hanya menampilkan konten statis, Anda akan lebih baik dengan server yang dioptimalkan untuk melakukan itu (Apache, ngnix, IIS).
Sean Vieira
2
Selain itu, Anda biasanya tidak perlu membagi variabel di seluruh permintaan - jika Anda melakukannya, Anda harus membatasi diri pada satu proses atau menggunakan beberapa komunikasi out-of-band (Redis, database, sistem file, dll.) Sehingga bahwa setiap proses Anda tetap disinkronkan.
Sean Vieira
3
@ATOzTOA - jika Anda tidak dapat memutar server yang lebih baik maka saya hanya akan berputar dan melihat apa yang terjadi. Jika tidak bekerja dengan baik di bawah beban, Anda dapat menggunakannya di server web yang berbeda.
Sean Vieira
2
@ATOzTOA, mengenai pertanyaan Anda tentang mengapa Anda tidak dapat menentukan 'ulir' dan 'proses' secara bersamaan, lihat kode di sini: werkzeug.readthedocs.org/en/latest/_modules/werkzeug/serving
pyrho
62

Menggunakan yang sederhana app.run()dari dalam Flask menciptakan server sinkron tunggal pada utas tunggal yang hanya mampu melayani satu klien pada satu waktu. Ini dimaksudkan untuk digunakan dalam lingkungan terkontrol dengan permintaan rendah (yaitu pengembangan, debugging) untuk alasan ini.

Memunculkan thread dan mengelolanya sendiri mungkin tidak akan membuat Anda terlalu jauh, karena Python GIL .

Yang mengatakan, Anda masih memiliki beberapa opsi bagus. Gunicorn adalah server WSGI yang solid dan mudah digunakan yang akan membuat Anda menelurkan banyak pekerja (proses terpisah, sehingga tidak ada kekhawatiran GIL), dan bahkan dilengkapi dengan pekerja asinkron. yang akan mempercepat aplikasi Anda (dan membuatnya lebih aman) dengan sedikit tidak berfungsi pada bagian Anda (terutama dengan Flask).

Tetap saja, bahkan Gunicorn mungkin tidak boleh langsung diekspos secara publik. Dalam produksi, itu harus digunakan di belakang server HTTP yang lebih kuat; nginx cenderung cocok dengan Gunicorn dan Flask.

Ryan Artecona
sumber
17
tidak terlalu. Gunicorn adalah python, nginx tidak. itu bukan bagaimana Anda akan menggunakannya. Gunicorn akan membiarkan Anda menjalankan aplikasi sebagai gunicorn app:app 127.0.0.1:8080gantinya python app.py. Nginx akan bertindak sebagai layanan publik yang mengekspos aplikasi Gunicorn-run pribadi Anda (proxy-terbalik) , menyembunyikan segala macam detail implementasi HTTP tingkat rendah, mungkin melayani file statis secara langsung, dll.
Ryan Artecona
Flask dengan app.run (berulir = Benar) berjalan sangat bagus di Apache2 menggunakan mod_wsgi flask.palletsprojects.com/en/1.1.x/deploying/mod_wsgi
MortenB