Google Bigquery 401使用服务帐户未经授权的错误

时间:2012-05-12 03:12:32

标签: google-bigquery

当我在计算机上尝试来自this post的Michael的bigquery片段时,我遇到了“401 Unauthorized”问题。正如ryguyrg所建议的,我同步了我的计算机时间(点击“立即更新”)并且代码工作正常。但问题是,过了一段时间,也许几分钟,当我重新编写代码时,它再次失败,因为401错误。所以我几乎每次想要运行大量查询请求时都必须手动同步计算机时间。

我很确定我的电脑运行良好,时间与服务器的差异不应超过几毫秒。那究竟是什么导致了这个问题呢?我可以尝试在请求之前从代码中同步时间,还是有更好的方法?

以下是401错误消息供参考:

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:159)
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.execute(GoogleJsonResponseException.java:187)
    at com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:115)
    at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:112)
    at com.google.api.services.bigquery.Bigquery$Jobs$Insert.executeUnparsed(Bigquery.java:1418)
    at com.google.api.services.bigquery.Bigquery$Jobs$Insert.execute(Bigquery.java:1442)
    at BigQueryJavaServiceAccount.main(BigQueryJavaServiceAccount.java:83)

3 个答案:

答案 0 :(得分:3)

我首先要确保您使用ntpd同步时间,并将其设置为正确的时区:http://www.ntp.org/

答案 1 :(得分:1)

几毫秒不应该影响它。

失败的最大可能性是,如果你的请求的时间是将来 - 谷歌的服务器肯定会拒绝这些请求。

我同意迈克尔关于通过NTP进行同步的建议。

我们还可以考虑让我们的OAuth服务略微更宽松 - 但平衡安全性和可用性总是很难

答案 2 :(得分:1)

在此示例中,我遇到了同样的问题。 https://cloud.google.com/bigquery/docs/quickstarts/quickstart-client-libraries

我正尝试执行以下命令,但发生401错误

export GOOGLE_APPLICATION_CREDENTIALS=/Users/mattheu/credentialFileName.json

我使用下面的方法解决了凭据问题

String jsonPath = "/Users/mattheu/credentialFileName.json";
        GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath));
package com;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.bigquery.*;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;

public class App {
    public static void main(String[] args) throws InterruptedException, IOException {
        String jsonPath = "/Users/mattheu/credentialFileName.json";
        GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath));

        BigQuery bigquery = BigQueryOptions.newBuilder()
                .setCredentials(credentials)
                .build().getService();

        QueryJobConfiguration queryConfig =
                QueryJobConfiguration.newBuilder(
                        "SELECT "
                                + "CONCAT('https://stackoverflow.com/questions/', CAST(id as STRING)) as url, "
                                + "view_count "
                                + "FROM `bigquery-public-data.stackoverflow.posts_questions` "
                                + "WHERE tags like '%google-bigquery%' "
                                + "ORDER BY favorite_count DESC LIMIT 10")
                        // Use standard SQL syntax for queries.
                        // See: https://cloud.google.com/bigquery/sql-reference/
                        .setUseLegacySql(false)
                        .build();

        // Create a job ID so that we can safely retry.
        JobId jobId = JobId.of(UUID.randomUUID().toString());
        Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

        // Wait for the query to complete.
        queryJob = queryJob.waitFor();

        // Check for errors
        if (queryJob == null) {
            throw new RuntimeException("Job no longer exists");
        } else if (queryJob.getStatus().getError() != null) {
            // You can also look at queryJob.getStatus().getExecutionErrors() for all
            // errors, not just the latest one.
            throw new RuntimeException(queryJob.getStatus().getError().toString());
        }

        QueryResponse response = bigquery.getQueryResults(jobId);

        TableResult result = queryJob.getQueryResults();

        // Print all pages of the results.
        for (FieldValueList row : result.iterateAll()) {
            String url = row.get("url").getStringValue();
            long viewCount = row.get("view_count").getLongValue();
            System.out.printf("url: %s views: %d%n", url, viewCount);
        }
    }
}
  

结果:
  网址:What is Google's Dremel? How is it different from Mapreduce?观看次数:27736
  网址:Unable to access BigQuery from local App Engine development server浏览次数:4732
  网址:How do I use the TABLE_QUERY() function in BigQuery?观看次数:9674
  网址:Migrating from non-partitioned to Partitioned tables观看次数:3549
  网址:How can I undelete a BigQuery table?观看次数:3332
  网址:Google App Engine: Using Big Query on datastore?观看次数:6928
  网址:Random Sampling in Google BigQuery浏览次数:11635
  网址:How to use Bigquery streaming insertall on app engine & python观看次数:4279
  url:Delete duplicate rows from a BigQuery table浏览次数:8552
  网址:How to improve performance of GeoIP query in BigQuery?观看次数:3213