最佳做法

本指南介绍了一些最佳做法,您可以运用它们来优化 AdWords API 应用的效率和性能。

日常维护

为确保您的应用不间断运行,可采取以下做法:

  • 确保 AdWords API 中心中的开发者联系电子邮件是最新的,这是我们在与您联系时使用的别名。如果我们无法就 API 条款及条件的遵从事宜与您取得联系,您的 API 访问权限可能会在您事先不知情的情况下被撤消。因此请避免使用与个人帐号或无人监控的帐号相关联的个人电子邮件地址。

  • 如需获知产品更改、维护停机、弃用日期等问题,请订阅我们的

AdWords API 团队会定期监控论坛,因此这里非常适合发布有关 API 的问题。

  • 确保您的应用满足 AdWords API 条款及条件 (T&C) 和最低功能要求 (RMF)。如果需要,令牌审核和合规团队将通过您的联系电子邮件与您联系。如果您对 T&C 或 RMF 有任何问题或疑虑,回复审核团队审核您的开发者令牌申请时发送给您的电子邮件,即可与他们联系。

优化

批量操作

向 API 发出请求需要承担许多固定开销,例如往返网络延迟、序列化和反序列化处理以及对后端系统的调用。为了减少这些固定开销的影响并提高总体性能,API 中的大多数 mutate() 方法都可以接受批量操作。在每个请求中包含可批处理的多个操作,可以减少所发出请求的数量和相关的固定开销。请尽可能避免发出只含一个操作的请求。

下面我们举例说明如何向某个广告系列的多个广告组添加 5 万个关键字。与其发出 5 万个请求,每个请求只包含 1 个关键字,不如发出 100 个请求,每个请求包含 500 个关键字,甚至只发出 10 个请求,每个请求包含 5000 个关键字。请注意,一个请求中允许的操作数量是有限制的,因此您可能需要调整批次规模,以获得最佳性能。

发出少量规模较大的请求这种做法还有另一个好处,就是您的应用遭遇基于请求的速率限制的可能性有所降低。

对操作进行组合

针对同一广告组或广告系列的多项操作与同等数量针对多个不同广告组或广告系列的操作相比,前者的处理速度更快。将针对同一广告组或广告系列的多项操作组合在一起,可减少请求中作为操作对象的广告组或广告系列的总数,从而提高总体性能。

针对同一广告组或广告系列发出多项并发请求可能会产生 CONCURRENT_MODIFICATION 错误。将修改同一广告组或广告系列的多项操作组合至单个请求中,可降低此类冲突发生的几率。

比如在上文的示例中,我们需要向一个广告系列的多个广告组添加 5 万个关键字。在将操作分成批次之前,一种简单的方法是按关键字定位的广告组对关键字进行排序。这样做的好处是,同一广告组的所有关键字更有可能包含在同一请求中,还可以减少单个请求中作为操作对象的广告组总数。也可以采用更高级的方法,将相关操作组合到数量尽可能少的请求中,同时每个批次的规模仍然很大。

重用访问令牌

在不同的线程和进程中重用相同的 OAuth2 访问令牌,可以减少定期刷新令牌的开销,您的应用因过度刷新令牌而受到速率限制的可能性也会降低。详细了解如何优化 OAuth2 请求

发送稀疏对象

将对象发送到 API 时,字段必须经过反序列化处理和验证,然后存储在数据库中。如果只需要更新少数字段,将完整对象传入就会增加处理时间并降低性能。为避免上述问题,AdWords API 支持稀疏更新,允许只填充对象中想要更改或必需的字段。未填充或含 null 值的字段则保持不变,从而提高请求的性能。

例如,更新关键字级出价的应用就可以受益于使用稀疏更新的做法,因为只需填充 adGroupIDcriterionID出价字段。在一项使用 150 个关键字的测试中,通过使用稀疏更新而不传递完整填充的对象,可以将性能提高 20%。

使用压缩

AdWords API 支持对请求和响应中的 SOAP 消息进行 gzip 压缩。要在响应中启用 gzip 压缩,请在请求中包含以下两个 HTTP 标头:

  • User-Agent:包含字符串“gzip”。
  • Accept-Encoding:带有值 gzip

示例:

User-Agent: My App (gzip)
Accept-Encoding: gzip

如果您使用客户端库,请参阅其有关启用压缩的文档。

错误处理和管理

在开发过程中,您可能会遇到错误。本节介绍在应用中构建错误管理机制的注意事项和策略。

除本节之外,还可参阅问题排查指南了解有关错误管理的更多信息。

区分请求来源

一些应用主要进行交互操作,它们直接发出 API 调用来响应用户在界面中发起的操作;还有一些应用主要是脱机工作,它们将 API 调用作为定期后端进程的一部分发出。许多应用结合了这两者。在考虑错误管理时,可能需要区分这些不同类型的请求。

对于用户发起的请求,您的主要关注点应该是为用户提供良好的体验。就所发生的具体错误,在界面中尽可能多地为用户提供相关背景信息。在可能的情况下,为他们提供可以修正错误的简单步骤(参见下面的建议)。

对于后端发起的请求,请就应用可能遇到的各种错误类型,实现相应的处理程序(参见下面的建议)。请务必加入一个默认处理程序,用来处理罕见或以前未曾显现的错误。对于默认处理程序,推荐的方法是将失败的操作和错误添加到队列中,供操作员查看并确定适当的解决方案。

区分错误类型

以下是四大类错误,对每一类都应该采取不同的处理方式。虽然这些类别并未穷尽所有可能的错误,并且某些错误可划归于一个以上的类别,但仍可从这里着手来设计应用的错误处理机制。有关特定错误的更多详细信息,请参阅常见错误

  1. 身份验证和授权错误

    • 身份验证表示您的应用是否已获得用户授予的代表他们访问 AdWords 的权限。身份验证的管理是通过 OAuth2 流程生成的凭据实现的。

    • 授权指的是您的应用(已经过身份验证,可代表用户进行操作)是否已获允处理其尝试读取或写入的特定 AdWords 数据。

    身份验证错误可能是由您无法控制的因素导致的,其中最常见的一个原因是经过身份验证的用户撤消了他们向您的应用授予的代表他们执行操作的权限。例如,如果您的应用为多个独立客户分别管理不同的 AdWords 帐号,并在管理每个客户的帐号时分别以该客户的身份接受身份验证,则客户随时都可能撤消您应用的访问权限。这种情况下 API 可能会直接返回一个 AuthenticationError.OAUTH_TOKEN_REVOKED 错误,或者客户端库中的内置凭据对象可能会引发令牌被撤消异常,具体取决于您的访问权限被撤消的时间。无论在哪种情况下,如果您的应用为客户提供了界面,就可以要求他们重新启动 OAuth2 流程,以重建您的应用代表他们进行操作的权限。

    因您无法控制的因素而导致授权错误的另一个常见原因,是您的经理帐号层次结构发生了变化。处理单一经理帐号层次结构的应用,通常会以其顶级经理帐号的管理员用户身份接受身份验证,因为此用户有权访问层次结构中的所有子帐号。如果子帐号的用户解除与经理帐号的关联,您的应用将会在尝试访问该帐号时收到 AuthorizationError.USER_PERMISSION_DENIED 错误。使用 ManagedCustomerService 可以检查子帐号是否确实已从该层次结构中移除。

    如果您的应用以某个用户的身份接受身份验证,但该用户的访问权限发生了改变,这种情况下也可能发生授权错误。例如,您的应用以某个用户的身份接受身份验证,但对 AdWords 帐号具有管理员权限的另一用户将该用户的权限更改为只读,在这种情况下,所有转变请求将失败,并引发 AuthorizationError.USER_HAS_READONLY_PERMISSION 错误。

    对于这两个示例,您的应用既可以为用户提供说明,也可以将问题呈报给客户经理加以解决。

  2. 可重试错误

    有些错误可能是临时性问题所致,可在短时间暂停后重试请求加以解决。这些错误包括 CONCURRENT_MODIFICATIONUNEXPECTED_INTERNAL_API_ERRORRATE_EXCEEDED

    对于用户发起的请求,一种策略是立即在界面中指出错误,并为用户提供进行重试的选项。另一种策略是,您的应用先自动重试请求,只有在达到最大重试次数或用户总等待时间后才在界面中指出错误。

    对于后端发起的请求,您的应用应该自动重试请求,直到达到最大重试次数。

    重试请求时,请使用指数退避策略。例如,如果您在第一次重试前先暂停 5 秒,则可以在第二次重试后暂停 10 秒,在第三次后暂停 20 秒。指数退避有助于确保您不会过于频繁地调用 API。

    对于 RATE_EXCEEDED 错误,应用在重试之前暂停的时间应至少比错误中 retryAfterSeconds 字段值所规定的时间长。有关更多详细信息,请参阅速率限制指南。其他可重试错误可间隔更短的时间进行重试,但仍应遵循指数退避策略。

  3. 验证错误

    验证错误表示操作的输入不可接受。示例有 PolicyViolationErrorDateErrorDateRangeErrorStringLengthErrorUrlError 等,不一而足。

    验证错误最常发生的情况是,在用户发起的请求中包含无效的用户输入。在这些情况下,您应该根据收到的具体 API 错误向用户提供相应的错误消息。您还可以在进行 API 调用之前验证用户输入中是否有常见错误,从而提高您的应用的响应能力,同时提高对 API 的使用效率。

    对于后端发起的请求,您的应用可以将失败的操作添加到队列中,供操作员进行审核。

  4. 与同步相关的错误

    许多 AdWords 应用都会维护一个本地数据库,用于存储其 AdWords 对象。这种方法会遇到一个难题,就是本地数据库可能与 AdWords 中的实际对象不同步。例如,用户可能直接在 AdWords 中删除了广告组,但应用和本地数据库不知道有此更改,依然发出 API 调用,就像广告组仍存在一样。这些同步问题可以表现为各种错误,例如 INVALID_IDDUPLICATE_CAMPAIGN_NAMEDUPLICATE_ADGROUP_NAMEAD_NOT_UNDER_ADGROUPCANNOT_OPERATE_ON_REMOVED_ADGROUPAD 等等,不一而足。

    对于用户发起的请求,一种可能的策略是提醒用户可能会存在同步问题,并立即启动一个作业来获取 AdWords 对象的相关类和更新本地数据库,然后提示用户刷新界面。

    对于后端发起的请求,某些错误会提供充足的信息,供您的应用逐步自动更正您的本地数据库。例如,CANNOT_OPERATE_ON_REMOVED_ADGROUPAD 错误应该会促使您的应用在本地数据库中将相应广告标记为已移除。无法以这种方式处理的错误可能会导致您的应用启动更完整的同步作业,或者被添加到队列中供操作员审核。

处理部分失败

默认情况下,对 API 的请求具有原子性:如果在请求中的一个操作期间发生错误,所有操作都将中止。原子性是一个安全的默认设置,但在许多情况下是不可取的,原因在于操作可能是各自独立的,只有失败的操作需要加以审核。有两种策略可修正这种默认行为。

第一个策略是审核响应中的错误,将它们与引发错误的操作相关联,然后发出一个只包含未引发错误的操作的新请求。这些操作现在应该能成功。您还可以将引发错误的操作交由错误处理机制(见上文)处理,或将其排入队列供操作员审核。

第二个策略是在您的 API 请求中启用部分失败标志。启用此标志时,每个操作将被单独处理,一个操作中发生错误不会阻止其他操作的提交。特定操作中的错误仍会正常返回。我们所有的客户端库都支持此标志。

部分失败标志的主要好处是这种做法简单易行,还能减少 API 调用,因为系统会自动提交有效操作,不需要用户进行重试。对大多数应用来说,这都是合适的做法。

但是,在某些应用中,加强对错误处理方式的控制更为有用。例如,假设某应用不希望某个广告中出现的违规错误妨碍其他广告的提交,但却希望出现其他一些错误(例如那些指示发生了更严重问题的错误)时中止整个请求。要实现这个想法,该应用应该采用上面的第一个策略。

请注意,在这两种情况下,都可能有一些错误反映操作之间的依赖性,而两个操作本身可能都是有效的。示例包括 AdGroupAdError.ENTITY_REFERENCED_IN_MULTIPLE_OPSAdParamError.AD_PARAM_CANNOT_BE_SPECIFIED_MULTIPLE_TIMES

同步后端

如果应用用户有手动访问 AdWords 帐号的权限,他们可能会做出应用无法知晓的更改,导致应用的本地数据库不同步。如上所述,您可以在发生同步相关错误时再做出反应,也可主动加以防范。一种主动策略是对所有帐号每晚执行一次同步作业,获取帐号中的 AdWords 对象,并与本地数据库进行比较。要使获取过程可以高效完成,不妨考虑使用结构报告,而不是常规 API 服务。

记录错误

应将所有错误都记录到日志中以便进行调试和监控。至少应记录请求 ID、引发错误的操作和错误本身。要记录的其他信息包括客户 ID、API 服务、往返请求延迟、重试次数以及原始 SOAP 请求和响应。

客户端库提供内置的 SOAP 日志记录功能以及获取 requestId 标头的功能。

请务必监控 API 错误的趋势,以便可以检测和解决应用的问题。可以考虑构建自己的解决方案或从市售的众多商业工具中选择一个,以便使用您的日志来生成交互式信息中心,并自动发送提醒。

其他

使用测试帐号

测试帐号是不会实际投放广告的 AdWords 帐号。可以使用测试帐号来对 AdWords API 进行实验,并测试应用的连接性、广告系列管理逻辑或其他处理过程能否正常运作。您的开发者令牌不需要获得批准即可在测试帐号中使用,因此,即使应用尚未得到审核,您仍可以在请求开发者令牌后立即开始使用 AdWords API 进行开发。

批量定位提示

使用 TargetingIdeaService 生成定位提示时,TargetingIdeaSelector 可接受类型为 IDEASSTATSRequestTypeSTATS 请求可用于获取已知关键字的统计信息。要获取多个关键字的统计信息,请在 RelatedToQuerySearchParameter 中列出关键字,将它们合并到单个请求中。这种做法将为每个关键字返回一个 TargetingIdea,比为每个关键字单独发出请求更有效率。

发送以下问题的反馈:

此网页
AdWords API
AdWords API
需要帮助?请访问我们的支持页面