在过去的几天里,我们的系统遇到了一个奇怪的问题。我们有一个ruby应用程序,其中有一个sidkiq worker(一个计划作业)。这个worker频繁地访问google cloud bucket。
此工作进程能够从存储桶执行getObject
操作,从同一存储桶中的一个位置复制到另一个位置,以及删除对象。但是,对于某些文件(随机时间的随机文件),我们在代码中遇到Unauthorized 401
错误。
这是纯粹的随机,没有顺序或模式。
由于大多数操作都按此工作线程的预期工作,因此其中一些操作失败,并出现以下错误。“Google::Apis::AuthorizationError Unauthorized“.
错误_回溯:
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/http_command.rb:222:in `check_status',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/api_command.rb:121:in `check_status',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/download.rb:109:in `execute_once',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/http_command.rb:113:in `block (2 levels) in execute',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/retriable-3.1.2/lib/retriable.rb:61:in `block in retriable',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `times',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `retriable',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/http_command.rb:110:in `block in execute',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/retriable-3.1.2/lib/retriable.rb:61:in `block in retriable',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `times',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/retriable-3.1.2/lib/retriable.rb:56:in `retriable',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/http_command.rb:102:in `execute',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/lib/google/apis/core/base_service.rb:366:in `execute_or_queue_command',
/home/app/webapp/vendor/bundle/ruby/3.0.0/gems/google-api-client-0.49.0/generated/google/apis/storage_v1/service.rb:1914:in `get_object'
我们在我们的应用程序中使用gem google-api-client-0.49.0
,并且我们用于进行REST API调用的服务帐户具有管理员级别的权限。我们不怀疑这是访问级别问题,因为应用程序能够对大多数文件执行获取/复制/删除操作。
任何帮助都将非常感谢,以确定什么可能是这个问题的根本原因。
1条答案
按热度按时间rqdpfwrv1#
Sidekiq在线程上运行,这意味着应用程序的身份验证上下文由所有线程共享。最有可能发生的情况是:
1.刷新令牌用于获取access token,以用于实际请求
1.访问令牌在有效期内成功使用一段时间
1.访问令牌最终会过期,使用它发出的下一个请求将返回401 Unauthorized
1.访问令牌被终止,这使得它在所有线程和将来的worker调用中都不可用
1.访问令牌被杀死后的下一个请求看到没有访问令牌,并使用刷新令牌为其请求获取新的访问令牌
1.重复步骤3到6
根据您拥有的并发量,当令牌过期时可能会出现争用情况,其中多个线程尝试使用令牌可能会导致多个401错误。
您可以根据自己的逻辑配置Google API客户端的错误重试。
或者,您可以在Sidekiq中配置错误重试,以便根据您的逻辑重新处理作业。