Pertanyaan Aplikasi GAE mendapat kesalahan soket saat berkomunikasi dengan BigQuery


Aplikasi python GAE kami berkomunikasi dengan BigQuery menggunakan Klien Google Api untuk Python (saat ini kami menggunakan versi 1.3.1) dengan pembantu otentikasi khusus GAE. Sangat sering kita mendapatkan kesalahan soket saat berkomunikasi dengan BigQuery.

Lebih khusus lagi, kami membangun klien Google API python sebagai berikut

1. bq_scope = 'https://www.googleapis.com/auth/bigquery'
2. credentials = AppAssertionCredentials(scope=bq_scope)
3. http = credentials.authorize(httplib2.Http())
4. bq_service = build('bigquery', 'v2', http=http)

Kami kemudian berinteraksi dengan layanan BQ dan mendapatkan kesalahan berikut

File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/gae_override/httplib.py", baris 536, di getresponse       'Kesalahan terjadi saat menyambung ke server:% s'% e)   kesalahan: Terjadi kesalahan saat menyambung ke server: Tidak dapat mengambil URL: [api url ...]

Kesalahan yang muncul adalah tipe google.appengine.api.remote_socket._remote_socket_error.error, bukan pengecualian yang membungkus kesalahan.

Awalnya kami pikir itu mungkin terkait timeout, jadi kami juga mencoba menetapkan batas waktu mengubah baris 3 di cuplikan di atas menjadi

3. http = credentials.authorize(httplib2.Http(timeout=60))

Namun, menurut output log pustaka klien, panggilan API memerlukan waktu kurang dari 1 detik untuk mogok dan secara eksplisit menyetel batas waktu tidak mengubah perilaku sistem.

Perhatikan bahwa kesalahan terjadi di berbagai panggilan API, tidak hanya satu, dan biasanya ini terjadi pada operasi yang sangat ringan, misalnya kita sering melihat kesalahan saat melakukan polling BQ untuk status pekerjaan dan jarang pada pengambilan data. Ketika kami menjalankan kembali operasi, sistem bekerja.

Ada gagasan mengapa ini bisa terjadi dan - mungkin - praktik terbaik untuk menanganinya?


7
2018-05-06 10:32


asal


Jawaban:


Semua permintaan HTTP (s) akan dialihkan melalui layanan urlfetch.

Di bawahnya, Klien Google Api untuk Python menggunakan httplib2 untuk membuat permintaan HTTP (s) dan di bawah sampul perpustakaan ini menggunakan soket.

Karena kesalahan berasal dari soket Anda mungkin mencoba untuk mengatur batas waktu di sana.

import socket
timeout = 30
socket.setdefaulttimeout(timeout)

Jika kita melanjutkan tumpukan httplib2 akan menggunakan parameter timeout dari batas waktu level soket.

http://httplib2.readthedocs.io/en/latest/libhttplib2.html

Memindahkan lebih jauh tumpukan Anda dapat mengatur batas waktu dan coba lagi untuk BigQuery.

try:
    timeout = 30000
    num_retries = 5
    query_request = bigquery_service.jobs()
    query_data = {
        'query': (query_var),
        'timeoutMs': timeout,
    }

Dan akhirnya Anda dapat mengatur batas waktu untuk urlfetch.

from google.appengine.api import urlfetch
urlfetch.set_default_fetch_deadline(30)

Jika Anda yakin itu terkait dengan waktu habis, Anda mungkin ingin menguji setiap pustaka / level untuk memastikan batas waktu berlalu dengan benar. Anda juga dapat menggunakan pengatur waktu dasar untuk melihat hasilnya.

start_query = time.time()
query_response = query_request.query(
projectId='<project_name>',
body=query_data).execute(num_retries=num_retries)
end_query = time.time()
logging.info(end_query - start_query)

Ada puluhan pertanyaan tentang batas waktu dan batas waktu terlampaui untuk GAE dan BigQuery di situs ini jadi saya tidak akan terkejut jika Anda memukul sesuatu yang aneh.

Semoga berhasil!


0
2018-06-04 15:26