3

コンピューターでこの投稿のMichaelによるbigqueryスニペットを試したときに、「401Unauthorized」の問題が発生しました。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);
        }
    }
}

結果:
url:GoogleのDremelとは何ですか?Mapreduceとはどう違うのですか?ビュー:27736
url:ローカルのApp Engine開発サーバーからBigQueryにアクセスできませんビュー: 4732
url :BigQueryでTABLE_QUERY()関数を使用するにはどうすればよいですか?ビュー:9674
url​​:非パーティションテーブルからパーティションテーブルへの移行ビュー:3549
url:BigQueryテーブルの削除を取り消すにはどうすればよいですか。ビュー:3332
url:Google App Engine:データストアでBig Queryを使用していますか?ビュー:6928
url : Google BigQueryでのランダムサンプリングビュー:11635
url:アプリエンジンと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のサーバーは、これらのリクエストを確実に拒否します。

NTPを介して同期するというMichaelの提案に同意します。

OAuthサービスを少し寛大にすることも検討できますが、セキュリティと使いやすさのバランスを取るのは常に困難です。

于 2012-05-12T22:44:16.830 に答える