如何在 Java 中使用 Google 我的商家信息 API 读取所有帐户的所有位置时解决错误代码 503 和 429

问题描述 投票:0回答:1

我将使用记录的

Google My Business Business Information API
检索所有帐户的所有位置 Google Business Profile APIs。 我尝试编写下面的代码的简化版本: 假设
mybusinessaccountLocations
变量是以下函数的返回类型,并负责身份验证和初始化 API。

我的业务业务信息 mybusinessaccountLocations = 初始化我的业务(主机);

我定义了一个名为 accountRecord 和 locationRecord 的类来管理数据库中的相关表。

ExecutorService ex = Executors.newFixedThreadPool(10);

    for (accountRecord rec : accountsList) {
        List<locationRecord> LocationsList = Collections.synchronizedList(new ArrayList<>());

        ex.execute(new Runnable() {
            @Override
            public void run() {
                String readMask = "storeCode,regularHours,name,languageCode,title,phoneNumbers,categories,storefrontAddress,websiteUri,regularHours,specialHours,serviceArea,labels,adWordsLocationExtensions,latlng,openInfo,metadata,profile,relationshipData,moreHours";

                List<Location> locations = Collections.synchronizedList(new ArrayList<>());
        
                String accountName = rec.getName();


                try {

                    MyBusinessBusinessInformation.Accounts.Locations.List locationsList = mybusinessaccountLocations
                            .accounts().locations().list(accountName).setReadMask(readMask);
                    ListLocationsResponse Response = locationsList.execute();
                    locations = Response.getLocations();
                    System.out.println("Response Size ="+ Response.size());
                    while (Response.getNextPageToken() != null && Response != null && !Response.isEmpty()) {
                        locationsList.setPageToken(Response.getNextPageToken());
                        Response = locationsList.execute();
                        if (Response != null && Response.getLocations() != null) {
                            locations.addAll(Response.getLocations());
                         
                        }  
                    }

                }  
                catch (Throwable t) {
                    throw new RuntimeException("\n\n Throwable occurred: " + t.getMessage(), t);
                }


            
                if (locations != null && !locations.isEmpty()) {
                  // processing the locations and saving in DB
                    .
                    .
                    .

                }

            }
        });


    }

    ex.shutdown();

    while (!ex.isTerminated()) {
    }

由于我使用的是

ExecutorService
,有时会超出google定义的time_limit(Quota),或者存在服务器端错误,例如

 {
  "code" : 503,
  "errors" : [ {
    "domain" : "global",
    "message" : "The service is currently unavailable.",
    "reason" : "backendError"
  } ],
  "message" : "The service is currently unavailable.",
  "status" : "UNAVAILABLE"
}

我需要代码等待几毫秒,直到不再出现此类错误,然后重试确切的请求,而不跳过任何分页或帐户。 我尝试使用

AtomicInteger

synchronized(i) {
                         
        if( i.getAndIncrement() >= 50 ) {

            Thread.sleep(20000);
            i.set(0);
            }
        }

但是,这不是一个非常有效的方法,我听说指数退避会更有效,但我不知道如何实现。我将不胜感激任何帮助。

java executorservice google-my-business-api exponential-backoff google-business-profile-api
1个回答
1
投票

已经存在 RateLimiter 实现 (https://guava.dev/releases/19.0/api/docs/index.html?com/google/common/util/concurrent/RateLimiter.html)。 至于重试/退避逻辑,如果您可以重用现有的实现,可能取决于您的框架(例如https://www.baeldung.com/spring-retry)。

© www.soinside.com 2019 - 2024. All rights reserved.