Berapa banyak permintaan bersamaan yang diterima oleh satu proses Flask?

138

Saya membangun aplikasi dengan Flask, tapi saya tidak tahu banyak tentang WSGI dan ini adalah basis HTTP, Werkzeug. Ketika saya mulai melayani aplikasi Flask dengan gunicorn dan 4 proses pekerja, apakah ini berarti saya dapat menangani 4 permintaan bersamaan?

Maksud saya permintaan bersamaan, dan bukan permintaan per detik atau apa pun.

Carson
sumber

Jawaban:

183

Saat menjalankan server pengembangan - yaitu apa yang Anda dapatkan dengan menjalankan app.run(), Anda mendapatkan satu proses sinkron, yang berarti paling banyak 1 permintaan sedang diproses pada satu waktu.

Dengan menempelkan Gunicorn di depannya dalam konfigurasi default dan hanya meningkatkan jumlah --workers, yang Anda dapatkan pada dasarnya adalah sejumlah proses (dikelola oleh Gunicorn) yang masing-masing berperilaku seperti app.run()server pengembangan. 4 pekerja == 4 permintaan bersamaan. Ini karena Gunicorn menggunakan synctipe pekerja yang disertakan secara default.

Penting untuk dicatat bahwa Gunicorn juga termasuk pekerja yang tidak sinkron, yaitu eventletdan gevent(dan juga tornado, tapi itu paling baik digunakan dengan kerangka kerja Tornado, tampaknya). Dengan menentukan salah satu pekerja async ini dengan --worker-classbendera, yang Anda dapatkan adalah Gunicorn mengelola sejumlah proses async, yang masing-masing mengelola konkurensi sendiri. Proses ini tidak menggunakan utas, melainkan coroutine. Pada dasarnya, dalam setiap proses, masih hanya 1 hal yang dapat terjadi pada satu waktu (1 utas), tetapi objek dapat 'dihentikan sementara' ketika mereka menunggu proses eksternal untuk diselesaikan (pikirkan permintaan basis data atau menunggu di jaringan I / O).

Ini berarti, jika Anda menggunakan salah satu pekerja async Gunicorn, setiap pekerja dapat menangani lebih dari satu permintaan pada satu waktu. Berapa banyak pekerja yang terbaik tergantung pada sifat aplikasi Anda, lingkungannya, perangkat keras yang digunakannya, dll. Rincian lebih lanjut dapat ditemukan di halaman desain Gunicorn dan mencatat bagaimana gevent bekerja pada halaman intro-nya.

Ryan Artecona
sumber
4
Gunicorn sekarang mendukung utas "nyata" sejak versi 19. Lihat ini dan ini .
Filipe Correia
2
Bagaimana cara melacak sumber daya mana yang dibagikan (dan bagaimana) dan mana yang sepenuhnya terpisah antara utas / proses? Sebagai contoh, bagaimana saya menangani situasi di mana saya ingin berbagi struktur data yang besar antara beberapa proses yang ditangani oleh Gunicorn dan digunakan dalam penangan Flask?
Johann Petrak
Apa yang Anda tanyakan pada @Johsm seperti menanyakan cara berbagi data antara berbagai proses dalam sistem operasi. Jawabannya dapat menjawab pertanyaan Anda, Anda harus menggunakan penyimpanan eksternal karena proses tidak membagi ingatannya dengan proses lain. Gunicorn di sini hanya untuk memanfaatkan arsitektur CPU multiprosesing tetapi tidak menangani masalah tersebut.
adkl
Bagaimana dengan Hawa? Apakah ini berlaku untuk Hawa juga?
Eswar
2
server pengembangan labu menggunakan utas secara default sejak v1.0 ( github.com/pallets/flask/pull/2529 )
hychou
40

Saat ini ada solusi yang jauh lebih sederhana daripada yang sudah disediakan. Saat menjalankan aplikasi Anda, Anda hanya harus meneruskan threaded=Trueparameter ke app.run()panggilan, seperti:

app.run(host="your.host", port=4321, threaded=True)

Opsi lain sesuai dengan apa yang dapat kita lihat di dokumen werkzeug , adalah menggunakan processesparameter, yang menerima angka> 1 yang menunjukkan jumlah maksimum proses bersamaan untuk ditangani:

  • berulir - haruskah proses menangani setiap permintaan di utas terpisah?
  • proses - jika lebih besar dari 1 maka menangani setiap permintaan dalam proses baru hingga jumlah maksimum proses bersamaan ini.

Sesuatu seperti:

app.run(host="your.host", port=4321, processes=3) #up to 3 processes

Info lebih lanjut tentang run()metode di sini , dan posting blog yang mengarahkan saya untuk menemukan solusi dan referensi api.


Catatan: pada dokumen Flask mengenai run()metode ini menunjukkan bahwa menggunakannya dalam Lingkungan Produksi tidak disarankan karena ( kutipan ): "Meskipun ringan dan mudah digunakan, server bawaan Flask tidak cocok untuk produksi karena tidak skala dengan baik . "

Namun, mereka menunjuk ke halaman Opsi Penempatan mereka untuk cara yang disarankan untuk melakukan ini ketika pergi untuk produksi.

DarkCygnus
sumber
5
Terimakasih atas infonya. Penting untuk dicatat bahwa dokumen untuk menjalankan menyatakan bahwa itu tidak boleh digunakan dalam lingkungan produksi yang menyatakan itu tidak memenuhi persyaratan keamanan atau kinerja.
Coffee_fan
1
@Coffee_fan kamu benar. Bahkan pada 1.1.x terbaru mereka menolak itu, dan sebaliknya menyarankan untuk memeriksa halaman mereka pada Opsi Penempatan ketika pergi untuk produksi. Termasuk pengamatanmu yang berharga dalam jawabannya :)
DarkCygnus
33

Labu akan memproses satu permintaan per utas pada saat yang sama. Jika Anda memiliki 2 proses dengan masing-masing 4 utas, itu adalah 8 permintaan bersamaan.

Labu tidak menelurkan atau mengelola utas atau proses. Itulah responsabilitas gateway WSGI (mis. Gunicorn).

jd.
sumber
9

Tidak - Anda pasti bisa menangani lebih dari itu.

Penting untuk diingat bahwa jauh di lubuk hati, dengan asumsi Anda menjalankan mesin inti tunggal, CPU benar-benar hanya menjalankan satu instruksi * pada satu waktu.

Yaitu, CPU hanya dapat menjalankan satu set instruksi yang sangat terbatas, dan tidak dapat menjalankan lebih dari satu instruksi per clock tick (banyak instruksi bahkan membutuhkan lebih dari 1 tick).

Oleh karena itu, sebagian besar konkurensi yang kita bicarakan dalam ilmu komputer adalah konkurensi perangkat lunak. Dengan kata lain, ada lapisan implementasi perangkat lunak yang mengabstraksi CPU tingkat bawah dari kami dan membuat kami berpikir kami menjalankan kode secara bersamaan.

"Hal-hal" ini dapat berupa proses, yang merupakan unit kode yang dijalankan secara bersamaan dalam arti bahwa setiap proses berpikir prosesnya berjalan di dunianya sendiri dengan ingatannya sendiri yang tidak dibagi.

Contoh lain adalah utas, yang merupakan unit kode di dalam proses yang memungkinkan konkurensi juga.

Alasan 4 proses pekerja Anda dapat menangani lebih dari 4 permintaan adalah bahwa mereka akan mematikan utas untuk menangani lebih banyak dan lebih banyak permintaan.

Batas permintaan aktual tergantung pada server HTTP yang dipilih, I / O, OS, perangkat keras, koneksi jaringan dll.

Semoga berhasil!

* Instruksi adalah perintah yang sangat mendasar yang dapat dijalankan CPU. contoh - tambahkan dua angka, lompat dari satu instruksi ke instruksi lainnya

pengguna1094786
sumber
1
Apakah itu gunicorn yang memunculkan benang atau Labu? Saya tidak menemukan bukti yang mendukung kemungkinan tersebut.
jd.
1
Tentu, saya mengerti tentang prosesnya, tetapi jawabannya mengatakan lebih banyak utas muncul sesuai kebutuhan. Untuk itulah saya ingin mendapat konfirmasi.
jd.
4
"jauh di lubuk hati, dengan asumsi Anda menjalankan mesin inti tunggal, CPU benar-benar hanya menjalankan satu instruksi * pada satu waktu" Ini tidak benar pada mesin modern. Sebagian besar CPU modern adalah pipelined dan superscalar , di mana bahkan satu core memiliki beberapa unit eksekusi dan decoder instruksi yang mengubah "kode mesin" dilihat dari sisi perangkat lunak menjadi mikro-ops perangkat keras aktual yang dikirim ke unit-unit eksekusi individual.
Michael Geary
1
Untuk memperjelas, jalan kembali pada hari itu, CPU benar-benar secara langsung menjalankan instruksi numerik dalam sebuah executable - kode mesin. Setiap referensi CPU memiliki diagram timing instruksi yang menunjukkan berapa banyak siklus clock yang diambil oleh setiap instruksi termasuk referensi memori. Jadi, Anda bisa menambahkan waktu untuk mengetahui berapa lama potongan kode akan memakan waktu. CPU modern tidak seperti itu sama sekali. Satu pengecualian yang menarik adalah BeagleBone yang memiliki prosesor ARM superscalar modern dan dua prosesor "PRU" kuno dengan timing instruksi yang tetap.
Michael Geary
1
Dan untuk mengklarifikasi itu , ketika saya mengatakan "modern" saya menggunakannya sebagai singkatan untuk prosesor seperti chip ARM / Intel / AMD - pipeline, superscalar, dll. Tentu saja ada juga prosesor modern yang bekerja dengan cara lama dengan pengaturan waktu tetap per instruksi, seperti PRU BeagleBone yang saya sebutkan dan berbagai mikrokontroler baru. (Dan sekarang kembali ke Gunicorn!)
Michael Geary