【问题标题】:Google App Engine + Ruby on rails + Redis + actioncableGoogle App Engine + Ruby on rails + Redis + actioncable
【发布时间】:2019-01-08 21:10:14
【问题描述】:

我们应该如何在 Rails 中配置 action cable 以在 Google App Engine 中工作?

我有一个 Rails 应用程序,它使用动作电缆作为它的信使。 在我的本地主机上,动作电缆在开发和生产环境中运行良好,但 它在 Google App Engine 上不起作用

  • 我创建了一个计算机引擎实例并在其上安装了 Redis。

  • 防火墙允许所有流量流向 Redis 虚拟机。

  • Redis 已绑定 0.0.0.0

当我在 Google App Engine 上部署应用时出现错误:

Firefox 无法与位于 wss://mydomain.com/cable 的服务器建立连接。

这是我目前的配置:

config/environments/production.rb

config.action_cable.url = 'wss://[MYDOMAIN].com/cable'
config.action_cable.disable_request_forgery_protection = true
config.force_ssl = true
... 

config/cable.yml

production:
  adapter: redis
  url: redis://[IP_OF_REDIS_SERVER]:6379/

app.yaml

entrypoint: bundle exec rackup --port $PORT
env: flex
runtime: ruby
env_variables:
  REDIS_PROVIDER: REDIS_URL
  REDIS_URL: redis://[IP_OF_REDIS_SERVER]:6379/
  SECRET_KEY_BASE: [My_Secret_Key]

我在 App Engine 的 Google 文档中找不到任何有关可操作设置的信息。我希望这个问题可以帮助我和每个有同样问题的人。

【问题讨论】:

  • 你解决了吗?我在这里遇到同样的麻烦。每当我在生产模式下本地运行时,我都可以连接到 redis 实例。但是当我检查生产日志时,我可以看到错误“(Redis::TimeoutError)(Redis::CannotConnectError)”我认为这可能是与防火墙有关的错误,我在redis实例上有一个规则允许使用端口 6379,但我的应用实例上没有此规则。
  • 我最终转向了计算引擎,我在那里创建了 redis 服务器和生产服务器。如果您在计算机引擎上进行操作,事情会简单得多。在应用引擎中,您无权访问任何内容,也没有文档。我只花了 1 小时就创建了 redis 服务器,并用了 1 小时在计算机引擎上创建了生产服务器。

标签: ruby-on-rails google-app-engine redis actioncable


【解决方案1】:

您必须在 Redis 实例和 App Engine 实例之间设置创建 VPC。这记录在这里:

https://cloud.google.com/appengine/docs/standard/python/connecting-vpc

完成此操作后,您将拥有:

app.yaml

...
vpc_access_connector:
  name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME
...

其次,Google 管理的 Redis 服务器不允许您设置客户端 ID。我尝试强制它为 nil,但 ActionCable 订阅适配器会尝试为您设置一个:

https://github.com/rails/rails/blob/6-0-stable/actioncable/lib/action_cable/subscription_adapter/redis.rb#L18

为了让它正常工作,我不得不重写这个行为。

我将以下文件添加到我的 rails 应用程序中:

config/initializers/decorators/redis.rb

require 'action_cable/subscription_adapter/redis'

ActionCable::SubscriptionAdapter::Redis.class_eval do
  cattr_accessor :redis_connector, default: ->(config) do
    ::Redis.new(config.except(:id, :adapter, :channel_prefix))
  end
end

现在一切正常。我现在唯一担心的是客户端 ID 是必需的,因此我最终会遇到一些令人讨厌的错误。

如果您尝试一下,希望这对您有用!

【讨论】:

  • 谢谢。我希望您的回答可以帮助那些遇到同样问题但使用 App Engine 并且遇到很多问题并不会使部署更容易的人。我无法想象将 App Engine 投入生产。
  • 您在 any 平台上部署时遇到问题。 redis 问题实际上与 Google Cloud Managed Reids 相关,而不是 App Engine。我不确定他们为什么做出这样的选择,但这就是您解决问题的方式。而且我不认为 VPC 问题是 App Engine 工作方式的问题。他们有目的地对服务进行细分,作为部署者,您可以选择向 App Engine 公开该服务。
猜你喜欢
  • 2011-03-17
  • 2015-05-06
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多