3

当我从我的计算机上的这篇文章中尝试 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)
4

3 回答 3

4

在这个例子中我遇到了同样的问题。 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);
        }
    }
}

result:
url:什么是 Google 的 Dremel?它与 Mapreduce 有何不同?视图:27736
url:无法从本地 App Engine 开发服务器访问 BigQuery视图:4732
url:如何在 BigQuery 中使用 TABLE_QUERY() 函数?视图:9674
url​​:从非分区表迁移到分区表视图:3549
url:如何取消删除 BigQuery 表?意见:3332
网址:Google App Engine:在数据存储上使用 Big Query?浏览次数:6928
网址:Google BigQuery 中的随机抽样浏览次数:11635
网址:如何在应用程序引擎和 python 视图上使用 Bigquery 流式插入:4279
url:从 BigQuery 表视图中删除重复行:8552
url:如何提高 BigQuery 中 GeoIP 查询的性能?浏览量:3213

于 2018-10-04T07:42:33.357 回答
3

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

于 2012-05-12T06:12:59.787 回答
1

几毫秒不应该影响它。

失败的最大可能性是您的请求时间是否在未来——Google 的服务器肯定会拒绝这些请求。

我同意 Michael 关于通过 NTP 同步的建议。

我们还可以考虑让我们的 OAuth 服务稍微宽松一些——但平衡安全性和可用性总是很困难

于 2012-05-12T22:44:16.830 回答