1

我的功能被稱爲每小時15次(每4分鐘),並通過startQuery運行查詢。大約30分鐘後隨機發生「無效憑證」錯誤。它會越來越頻繁地發生,直到所有通話都失敗。隨機`ApiError:Invalid Credentials`從谷歌雲功能調用BigQuery

該查詢從數據集中的表中讀取數據,並通過選項destinationwriteDisposition=WRITE_TRUNCATE將結果保存到位於另一個數據集中的表中。 這兩個數據集位於歐盟。

重新部署該功能可暫時解決問題。

致電gcloud beta functions describe my-function表示它使用App Engine默認服務帳戶:[email protected]

下面是錯誤的詳細信息:

ApiError: Invalid Credentials 
at Object.parseHttpRespBody (/user_code/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:192:30) 
at Object.handleResp (/user_code/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:132:18) 
at /user_code/node_modules/@google-cloud/bigquery/node_modules/@google-cloud/common/src/util.js:465:12 
at Request.onResponse [as _callback] (/user_code/node_modules/@google-cloud/bigquery/node_modules/retry-request/index.js:160:7) 
at Request.self.callback (/user_code/node_modules/@google-cloud/bigquery/node_modules/request/request.js:188:22) 
at emitTwo (events.js:106:13) 
at Request.emit (events.js:191:7) 
at Request.<anonymous> (/user_code/node_modules/@google-cloud/bigquery/node_modules/request/request.js:1171:10) 
at emitOne (events.js:96:13) 
at Request.emit (events.js:188:7) 

編輯

代碼,剝離:

const bigquery = require('@google-cloud/bigquery')(); 

const destinationDataset = bigquery.dataset('destinationDataset'); 
const destinationTable = dataset.table('destinationTable'); 

exports.aggregate = function aggregate (event) { 
    const message = event.data; 
    const attributes = message.attributes; 

    let job; 
    let destinationTable; 
    return Promise.resolve() 
    .then(() => { 
     if (attributes.partition == null) { 
     throw new Error('Partition time not provided. Make sure you have a "partitionTime" attribute in your message'); 
     } 

     const query = 'SELECT ... FROM sourceTable WHERE _PARTITIONTIME = TIMESTAMP(@partitionTime)'; // The dataset is specified in the job options below 

     // Query options list: https://cloud.google.com/bigquery/docs/reference/v2/jobs/query 
     // and: https://googlecloudplatform.github.io/google-cloud-node/#/docs/bigquery/0.9.6/bigquery?method=startQuery 
     const options = { 
     destination: destinationTable, 
     writeDisposition: 'WRITE_TRUNCATE', 
     query: query, 
     defaultDataset: { datasetId: 'sourceDataset' }, 
     timeoutMs: 540000, // 9 minutes, same timeout as the Cloud Function 
     useLegacySql: false, 
     parameterMode: 'NAMED', 
     queryParameters: [{ 
      name: 'partitionTime', 
      parameterType: { type: 'STRING' }, 
      parameterValue: { value: attributes.partition } 
     }] 
     }; 

     return bigquery.startQuery(options); 
    }) 
    .then((results) => { 
     job = results[0]; 
     console.log(`BigQuery job ${job.id} started, generating data in ${destinationTable.dataset.id}.${destinationTable.id}.`); 
     return job.promise(); 
    }) 
    .then((results) => { 
     // Get the job's status 
     return job.getMetadata(); 
    }) 
    .then((metadata) => { 
     // Check the job's status for errors 
     const errors = metadata[0].status.errors; 
     if (errors && errors.length > 0) { 
     throw errors; 
     } 
    }) 
    // Only if a destination table is given 
    .then(() => { 
     console.log(`BigQuery job ${job.id} completed, data generated in ${destinationTable.dataset.id}.${destinationTable.id}.`); 
    }) 
    .catch((err) => { 
     console.log(`Job failed for ${inspect(attributes)}: ${inspect(err)}`); 
     return Promise.reject(err); 
    }); 
}; 

你會發現,我沒有給出選項,同時初始化對象的BigQuery :require('@google-cloud/bigquery')()

我應該創建角色的BigQuery招聘的服務帳戶,並use the RuntimeConfig API避免推憑據git的由來?

問題仍然存在,爲什麼我隨機得到這個錯誤。現在查看功能日誌,錯誤發生在午夜和凌晨4點之間的每次通話中,然後是三分之一的通話,直到上午5:36。自那時以來(4小時前)它並沒有發生過一次。

編輯2

這說明相對於成功的失敗調用的頻率。所有錯誤(綠色)都是「無效憑證」錯誤。在這7天內絕對沒有任何東西被觸動:沒有部署,沒有改變配置,沒有在BigQuery中擺弄。

frequency of credentials errors

+0

你能告訴我們你的代碼樣本嗎? –

+0

完成。添加了*編輯*部分。 – nfo

+0

遇到同樣的問題;我有一個從新的雲存儲上傳(每1分鐘發生一次)獲得通知的雲功能,並且該函數每隔1分鐘被調用一次,它只是調用bigquery將其加載到表中,該函數在兩週前部署運行沒有問題直到今天ApiError在幾分鐘內隨機發生,並非總是如此; 這必須是谷歌方面的操作問題 – user5672998

回答

0

我的解決方法是從GCE使用一個虛擬機並運行的NodeJS應用程序包的功能,如

const pubsub = require('@google-cloud/pubsub')(); 
const topic = pubsub.topic('...'); 
const sub = topic.subscribe('...', { ...options }); 
sub.on('message', msg => { 
    // the same cloud function does all bigquery data loading and querying stuff... 
    callthesamecloudfunction({ data: msg }); 
}); 

取決於哪一種在GCF的觸發的,包裝可不同;

好的一面是包裝很簡單,它已經在我們的生產環境中運行了幾個月了,沒有任何問題;

我的結論是GCloud在Beta中運行了很多服務,並非真正用於生產準備;我會遠離GCF,或者6個月後再訪問。

編輯:見https://issuetracker.google.com/issues/66695033 GCloud團隊聲稱有修復,但我沒有時間測試;我的包裝方式只需要一個雲虛擬機,而且非常便宜。