Saya membangun generator beban dasar dan mulai mengalami batasan deskriptor file, saya belum melihat dokumentasi apa pun yang berkaitan dengan cara melepaskan sumber daya, jadi entah saya salah melakukannya dan dokumen perlu diperbarui, atau permintaan membocorkan deskriptor file di suatu tempat (tanpa dukungan untuk keepalive saya sedikit bingung mengapa ada file yang dibiarkan terbuka sama sekali)
Di mana Anda menggunakan requests.async
?
tidak, semua permintaan adalah requests.get / requests.post biasa saja, saya masih melihat beberapa di sana
$ lsof | grep localhost | wc -l
110
semua kecuali 4/5 di antaranya dalam format
Python 82117 daleharvey 123u IPv4 0xffffff800da304e0 0t0 TCP localhost:61488->localhost:http (CLOSE_WAIT)
Saya agak bingung dengan ini, jujur saja.
Hah saya akan mengambil bidikan lain untuk mereproduksinya dengan andal, jika saya tidak bisa menutupnya
Saya telah melihat ini terjadi pada saya, tetapi hanya ketika saya menggunakan modul async dengan 200+ koneksi simultan.
Hai,
Saya mendapat masalah yang persis sama menggunakan request dan monkey patching dengan gevent: beberapa koneksi tetap berada di CLOSE_WAIT.
Mungkin masalah dengan gevent gitu.
Ini mungkin masalah ulimit -n. Coba dengan nilai yang lebih tinggi.
"Terlalu banyak file yang terbuka" adalah hasil dari bug yang disebabkan oleh soket yang tetap berada di CLOSE_WAIT.
Jadi ulimit tidak akan memperbaiki hanya membuat solusi.
@tamiel bagaimana kita memperbaikinya?
Saya akan melakukan lebih banyak tes secepatnya dan mencoba memperbaikinya.
Saya telah memeriksanya, dan tampaknya ada masalah dengan semua pustaka yang menggunakan httplib.HTTPSConnection.
Memposting contoh di sini:
Saya baru saja menemukan kesalahan yang sangat mirip menggunakan kumpulan asinkron dengan hanya koneksi HTTP - Saya masih menyelidiki tetapi meneruskan ukuran kolam ke async.map membuat kesalahan berkembang biak dengan cepat.
Ada perbaikan untuk ini? Ini membuat Permintaan tidak dapat digunakan dengan gevent ..
Ini semua tentang CLOSE_WAIT
s. Hanya harus menutupnya. Saya tidak yakin mengapa mereka masih buka.
Apakah ini masalah urllib3? Harus menutup ini sendiri bukanlah ide bagus yang kurasa.
Ini lebih merupakan masalah umum. Kita bisa tetap mengobrol disini.
Ok hanya untuk memberi Anda perspektif, kami mencoba untuk beralih dari httplib2 ke permintaan, dan kami tidak melihat masalah ini dengan httplib2. Jadi ini bukan masalah umum yang pasti.
Secara umum, maksud saya ini adalah masalah yang sangat serius yang mempengaruhi semua orang yang terlibat.
jadi bagaimana kita mengatasi ini? kami benar-benar ingin menggunakan permintaan + tidur untuk bergerak maju
Saya ingin tahu jawabannya.
Kebocoran ini tampaknya disebabkan oleh penanganan pengalihan internal, yang menyebabkan permintaan baru dibuat sebelum tanggapan yang tertunda dikonsumsi. Dalam pengujian acdha @ 730c0e2e2bef77968a86962f9d5f2bebba4d19ec memiliki
Ini memerlukan perubahan di dua tempat yang membuat saya ingin sedikit merefaktor antarmuka tetapi saya kehabisan waktu untuk melanjutkan saat ini.
Saya mengalami masalah yang sama saat menggunakan async - mengurung solusi dengan memotong permintaan dan menghapus tanggapan / memanggil gc.collect
Saya yakin saya mengalami hal ini hari ini untuk menghubungkan ke server berlisensi yang hanya memungkinkan 5 koneksi.
Dengan menggunakan async, saya hanya dapat MENDAPATKAN 4 hal sebelum berhenti selama 60 detik.
Menggunakan GET normal dengan konsumsi saya dapat mengambil sekitar 150 hal secara berurutan dalam waktu kurang dari 40 detik.
Belum membuat kludge saya karena saya melihat masalah ini.
Baru saja mendapat kesalahan ini saat menggunakan ipython dan mendapat pesan ini. Ini hanya membuat setiap permintaan satu per satu, tetapi saya rasa saya mendapatkan sesuatu yang serupa saat menggunakan async.
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/IPython/core/ultratb.py", line 756, in structured_traceback
File "/Library/Python/2.7/site-packages/IPython/core/ultratb.py", line 242, in _fixed_getinnerframes
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 1035, in getinnerframes
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 995, in getframeinfo
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 456, in getsourcefile
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 485, in getmodule
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 469, in getabsfile
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.py", line 347, in abspath
OSError: [Errno 24] Too many open files
Unfortunately, your original traceback can not be constructed.
Anehnya, saya pikir ketika hanya menggunakan interpreter Python biasa saya mendapatkan "Max Retries Error" tetapi saya pikir itu adalah masalah lain dengan saya melakukan permintaan pada semua domain yang sama, tetapi tidak yakin.
Saya mengalami ini pada proyek pertama yang saya miliki di mana allow_redirects adalah True; hal itu tampaknya disebabkan oleh objek respons yang bocor rantai pengalihan yang tidak dirilis bahkan dengan prefetch = True. Ini memperbaikinya dalam pengujian awal saya:
[i.raw.release_conn() for i in resp.history]
resp.raw.release_conn()
Hmmm..
@acdha pengaturan:
requests.defaults.defaults['allow_redirects'] = False
sebelum saya membuat permintaan apa pun masih menghasilkan kesalahan yang sama, tetapi saya pikir ini bukan opsi untuk implementasi saya karena semua permintaan yang saya buat akan memerlukan pengalihan = /
@dalanmiller Bagaimana Anda memproses tanggapan Anda? Saya sebelumnya menggunakan async.map
dengan hook respon dan _appears_ menjadi lebih stabil menggunakan loop sederhana di atas async.imap
:
for resp in requests.async.imap(reqs, size=8):
try:
print resp.status_code, resp.url
finally:
[i.raw.release_conn() for i in resp.history]
resp.raw.release_conn()
@haditsku
Saya baru saja menggunakan for loop melalui daftar url dan melakukan request.get pada masing-masing dengan pengaturan saya dan semacamnya.
for u in urls:
response_list.append(requests.get(u))
Saya mencoba menggunakan pasta Anda dan itu bekerja untuk sekitar 50 permintaan dalam daftar panjang 900 saya, sampai saya mulai mendapatkan "kesalahan coba lagi maks melebihi dengan url" untuk sisanya. Ini adalah kesalahan standar yang cukup untuk memukul domain yang sama berulang kali, bukan?
Hei, saya sedang merayapi daftar besar url, 35k, dan mendapatkan kesalahan yang sama pada _some_ permintaan.
Saya mendapatkan url dalam potongan 10, seperti ini:
responses = requests.async.map([requests.async.get(u, params=self.params()) for u in chunk]) # chunk is a list of 10
Di suatu tempat dalam kisaran 20k saya mulai mendapatkan kesalahan 24, lalu ok melalui 30k dan kemudian lagi.
Ada info lebih lanjut yang Anda tertarik untuk mempersempitnya?
requests.async
hilang. Anda mungkin ingin mempertimbangkan untuk pindah ke grequests.
Baiklah terima kasih. Akan lebih baik untuk menyebutkan ini di dokumen.
Semacam noob ketika datang ke Permintaan Tarik dan dokumentasi penulisan tapi saya mencobanya dan mengirimkannya. Mohon komentar atau kritik :)
Oke, ini terjadi bahkan tanpa menggunakan asinkron, hanya dengan requests.get, setelah 6 ribu permintaan.
Saya curiga.
Bagi saya, kesalahan 'Terlalu banyak file yang terbuka' terjadi setelah mengunduh persis 1k file. Solusi saya adalah menonaktifkan properti keep-hidup, yang pernah mendapatkan permintaan dalam jumlah banyak ( @acdha terima kasih atas petunjuknya). lsof -p PID | wc -l
menunjukkan jumlah koneksi yang tidak meningkat selama eksekusi.
rsess = requests.session()
rsess.config['keep-alive'] = False
rs = [grequests.get(l, session=rsess) for l in links]
for s in chunks(rs,100):
responses = grequests.map(s, size=concurrency)
for r in responses:
try:
print(r.status_code, r.url)
finally:
r.raw.release_conn()
[1] memotong: http://stackoverflow.com/a/312464
Menutup sambil menunda perbaikan urllib3.
@kennethreitz Berapa nomor terbitan urllib3?
Sepertinya ini masalahnya http://bugs.python.org/issue16298
@silvexis bisa jadi terkait dengan bug urllib3, sekarang saya hanya berharap seseorang menjawab @ piotr-dobrogost: P
Apakah ada orang lain yang masih mengalami masalah ini?
Saya belum mendengar laporan apapun tentang itu. Apakah kamu?
Ini masalah konfigurasi kotak, bukan kerangka kerjanya. Lihat konfigurasi kernel OS Anda. Di BSD ini disebut kern.maxfiles
. Ada utas tentang ulimit
di sistem Linux: http://stackoverflow.com/questions/34588/how-do-i-change-the-number-of-open-files-limit-in-linux
Semoga membantu, dan saya tidak tahu cara mengubah parameter ini di Windows.
Dengan peringatan bahwa kami masih menjalankan permintaan versi lama, kami memiliki kode berikut, mengerikan, untuk menangani ini:
if self._current_response is not None:
# Requests doesn't have a clean API to actually close the
# socket properly. Dig through multiple levels of private APIs
# to close the socket ourselves. Icky.
self._current_response.raw.release_conn()
if self._current_response.raw._fp.fp is not None:
sock = self._current_response.raw._fp.fp._sock
try:
logger.debug('Forcibly closing socket')
sock.shutdown(socket.SHUT_RDWR)
sock.close()
except socket.error:
pass
(Saya pikir self._current_response adalah objek respons permintaan)
Hmm, di mana rantai penutupnya putus? Kami memiliki metode Response.close()
yang memanggil release_conn()
, jadi apa yang perlu dilakukan dalam release_conn()
agar ini berfungsi?
@Lukasa ini pasti sudah diperbaiki di urllib3 karena saya adalah bagian dari diskusi. Dengan kecenderungan konservatif dalam perkiraan saya, saya akan mengatakan itu ada sejak permintaan 1.2.x jika bukan 1.1.x.
Ya, saya pikir ini sudah diperbaiki. Kecuali kita melihat sesuatu di 1.2.3, saya akan terus menganggap ini sudah diperbaiki.
Saya melihat kebocoran CLOSE_WAIT dengan 2.0.2, apakah Anda memiliki pengujian unit untuk memastikan tidak ada regresi pada topik?
Tidak, kami tidak. AFAIK urllib3 juga tidak. Dapatkah Anda mereproduksi kebocoran Anda dengan mudah?
Kami menggunakan permintaan di aplikasi internal kami sejak hari Senin, dan mencapai 1024 file maks hari ini ..
2 jam setelah reboot, kami memiliki 40 CLOSE_WAIT seperti yang diceritakan oleh lsof.
Jadi saya pikir kita bisa mereproduksi di lingkungan pengembang, ya. Saya akan tetap berhubungan dengan Anda
@tardyp juga, bagaimana Anda menginstal permintaan? Saya pikir semua pengelola paket OS menghapus urllib3. Jika mereka tidak terus memperbaruinya dan Anda menggunakan versi lama, itu bisa menjadi penyebabnya. Jika Anda menggunakan pip, silakan membuka masalah baru untuk melacaknya alih-alih menambahkan diskusi ke masalah ini.
Saya menginstal dengan pip, tetapi saya menggunakan python 2.6, saya telah melihat perbaikan pada python2.7 untuk
bug ini. Apakah Anda monkeypatch untuk versi yang lebih lama?
Pierre
Pada hari Jumat, 29 Nov 2013 jam 17:33, Ian Cordasco [email protected] :
@tardyp https://github.com/tardyp juga, bagaimana Anda menginstal permintaan? saya
pikir semua pengelola paket OS menghapus urllib3. Jika tidak
tetap perbarui itu dan Anda menggunakan versi lama, itu mungkin
menyebabkan sebagai gantinya. Jika Anda menggunakan pip, jangan ragu untuk membuka edisi baru
lacak ini dengan alih-alih menambahkan diskusi ke yang ini.-
Balas email ini secara langsung atau lihat di Gi tHubhttps: //github.com/kennethreitz/requests/issues/239#issuecomment -29526302
.
@tardyp tolong buka masalah baru sedetail mungkin termasuk apakah permintaan yang Anda buat memiliki pengalihan dan apakah Anda menggunakan gevent. Juga, setiap detail tentang sistem operasi dan contoh bagaimana mereproduksinya akan sangat luar biasa.
FYI https://github.com/shazow/urllib3/issues/291 telah dikembalikan karena bug.
Haruskah kita membukanya kembali?
Saya mengalami masalah yang sama!
@polvoazul Tidak mungkin ini adalah masalah yang sama, yang awalnya dilaporkan pada tahun 2011, jadi menurut saya membuka kembali tidak benar. Namun, jika Anda menjalankan rilis permintaan saat ini (2.4.3) dan dapat mereproduksi masalah, membuka masalah baru akan menjadi benar.
@ Lukas saya butuh bantuan Anda。 saya menggunakan eventlet + permintaan, yang selalu membuat begitu banyak kaus kaki yang tidak dapat mengidentifikasi protokol。 permintaan saya adalah 2.4.3, apakah eventlet + permintaan menyebabkan masalah ini?
Maaf @mygoda , tapi tidak mungkin mengetahuinya. Jika Anda tidak membatasi jumlah permintaan yang dapat beredar pada satu waktu maka itu pasti mungkin, tetapi itu adalah masalah arsitektural di luar pengiriman permintaan.
Mengalami masalah yang sama sekarang, menjalankan 120 utas, menyebabkan 100000+ file dibuka, ada solusi apa sekarang?
@mygoda kamu menggunakan periode yang luar biasa。
@ 1a1a11a _File_ apa yang Anda buka? Itu akan menjadi langkah pertama yang berguna untuk memahami masalah ini.
@ 1a1a11a versi permintaan apa yang Anda gunakan? Versi python apa? Sistem operasi apa? Bisakah kita mendapatkan informasi apapun?
Saya menggunakan request 2.9.1, python 3.4, ubuntu 14.04, pada dasarnya saya menulis crawler menggunakan 30 utas dengan proxy untuk merayapi beberapa situs web. Saat ini saya telah menyesuaikan batas file per proses menjadi 655350, jika tidak maka akan melaporkan kesalahan.
Saya masih menerima pesan kesalahan "Gagal membuat koneksi baru: [Errno 24] Terlalu banyak file terbuka" dari requests.packages.urllib3.connection.VerifiedHTTPSConnection. "Saya menggunakan Python 3.4, permintaan 2.11.1 dan permintaan-futures 0.9.7. Saya menghargai permintaan-futures adalah pustaka yang terpisah, tetapi sepertinya kesalahan berasal dari permintaan. Saya mencoba membuat 180k permintaan asinkron melalui SSL. Saya telah membagi permintaan itu menjadi segmen 1000, jadi saya hanya pindah ke 1000 berikutnya setelah semua objek masa depan telah diselesaikan. Saya menjalankan Ubuntu 16.04.2 dan batas file terbuka default saya adalah 1024. Akan lebih baik untuk memahami alasan yang mendasari kesalahan ini. Apakah perpustakaan permintaan membuat file terbuka untuk setiap permintaan individu? Dan jika demikian, mengapa? Apakah ini file sertifikat SSL? Dan apakah pustaka permintaan secara otomatis menutup file yang terbuka itu ketika objek di masa mendatang diselesaikan?
Permintaan membuka banyak file. Beberapa file tersebut dibuka untuk sertifikat, tetapi dibuka oleh OpenSSL dan bukan oleh Permintaan, jadi file tersebut tidak dipertahankan. Selain itu, Permintaan juga akan membuka, jika diperlukan, file .netrc
, file host, dan banyak lainnya.
Anda akan mendapatkan layanan terbaik dengan menggunakan alat seperti strace
untuk menentukan file mana yang dibuka. Ada daftar ketat panggilan sistem yang mengarah ke deskriptor file yang dialokasikan, jadi Anda harus dapat dengan cepat menghitungnya. Itu juga akan memberi tahu Anda apakah ada masalah atau tidak. Tapi, ya, saya berharap jika Anda secara aktif membuat 1000 koneksi melalui HTTPS maka pada beban puncak kita dapat dengan mudah menggunakan lebih dari 1000 FD.
Saya berjuang dengan masalah ini juga dan menemukan bahwa menggunakan opensnoop
pada OS X bekerja sangat baik untuk membiarkan saya melihat apa yang terjadi jika ada yang mengalami masalah yang sama.
Saya juga sering melihat kesalahan ini ketika berulang kali memanggil requests.post(url, data=data)
ke server HTTP
(bukan HTTPS). Berjalan di Ubuntu 16.04.3, Python 3.5.2, meminta 2.9.1
Apakah data
?
Beberapa ratus kb teks
Bukan objek file?
Tidak, saya membentuk kueri besar di memori.
Apakah Anda menjalankan kode ini di beberapa utas?
Tidak, utas tunggal, memposting ke localhost
Tampaknya hampir tidak mungkin bagi kita untuk membocorkan FD sebanyak itu: kita harus berulang kali menggunakan koneksi TCP yang sama atau menutupnya secara agresif. Ingin memeriksa apa yang server Anda lakukan?
Saya mengalami masalah ini. Python 2.7, permintaan 2.18.4, urllib3 1.22.
Menjalankan kode multi-thread (bukan multi-proses). Menghubungkan ke paling banyak 6 URL sekaligus, membuat dan menutup sesi baru secara manual untuk masing-masing URL.
Saya mengalami masalah yang sama pada Python 3.5
, requests==2.18.4
@mcobzarenco apakah Anda yakin (secara implisit) menutup koneksi yang mendasari respons? Sekadar mengembalikan respons tidak akan menutup koneksi. Saat membaca response.content, data sebenarnya dibaca dan setelah itu soket tidak akan tinggal di CLOSE_WAIT.
Komentar yang paling membantu
"Terlalu banyak file yang terbuka" adalah hasil dari bug yang disebabkan oleh soket yang tetap berada di CLOSE_WAIT.
Jadi ulimit tidak akan memperbaiki hanya membuat solusi.