繁体   English   中英

Heroku应用程序在AWS RDS上的Postgres DB上使用控制器时出现问题

[英]Problems using controller on postgres DB on AWS RDS from Heroku app

我已经设置了一个postgres数据库,以将postgis用于我拥有的在Ruby on Rails上运行的Heroku应用程序。

我的步骤是:

  1. 创建运行pg 9.4.9的RDS数据库
  2. 在RDS参数组上启用rds.force_ssl。
  3. 将我的Heroku数据库备份并加载到新的postgres DB中。
  4. 下载Amazon RDS CA证书并将其放在config / amazon-rds-ca-cert.pem下。
  5. 将gem'activerecord-postgis-adapter'添加到我的gem文件中。
  6. 将database.yml文件更新为以下内容:

default: &default
    adapter: postgis
    encoding: unicode
    pool: 5

production:
    <<: *default
    encoding: utf8
    database: <%= ENV['RDS_DB_NAME'] %>
    username: <%= ENV['RDS_USERNAME'] %>
    password: <%= ENV['RDS_PASSWORD'] %>
    host: <%= ENV['RDS_HOSTNAME'] %>
    port: <%= ENV['RDS_PORT'] %>
    postgis_extension: postgis
    schema_search_path: public,postgis
  1. 将Heroku上的DATABASE_URL参数更新为postgres:// myuser:mypassword@mydbinstance.xxxxxxxxxxx.us-west-2.rds.amazonaws.com/mydbname?sslmode = verify-full&sslrootcert = config / amazon-rds-ca-cert.pem
  2. 这个非常有帮助的问题中的其他步骤: 在Heroku上启用Ruby PostGIS支持
  3. 推送更新的代码并访问我的应用程序。

当我尝试访问数据库以验证连接性时,它正常运行:

nc -zv mydbinstance.xxxxxxxx.us-west-2.rds.amazonaws.com 5432
Connection to mydbinstance.xxxxxxxxx.us-west-2.rds.amazonaws.com 5432 port [tcp/postgresql] succeeded!

当我在应用程序上导航时,我可以看到查询结果。 但是,当我尝试使用使用Postgis的模型时,某种程度上我的连接无法正常工作。 这是我的控制器的代码,该代码存储带有公交车站信息的经纬度对,并查找与参数中给定点接近的对数:

class TransitStopsController < ApplicationController
    def create
    end

    def show
        @transit_stop = TransitStop.find(params[:id])
        @transit_routes = @transit_stop.transit_routes
    end

    def get_nearby_stops
        radius_in_meters = params[:radius_in_meters].nil? ? 3219 : params[:radius_in_meters]
        @nearby_stops = TransitStop.close_to(params[:lat], params[:lng], radius_in_meters)
    end
end

我的模特:

class TransitStop < ActiveRecord::Base
  has_many :transit_stops_transit_routes, foreign_key: "onestop_id", class_name: "TransitStopsTransitRoute"
  has_many :transit_routes, through: :transit_stops_transit_routes, foreign_key: "route_onestop_id", class_name: "TransitRoute"
  validates_uniqueness_of :onestop_id

  #Get transit stops close to a given lat, lng pair. Default distance = 2 miles
  scope :close_to, -> (lat, lng, distance_in_meters = 3219) {
  where(%{
    ST_DWithin(
      ST_GeographyFromText(
          'SRID=4326;POINT(' || transit_stops.lng || ' ' || transit_stops.lat || ')'
        ),
        ST_GeographyFromText('SRID=4326;POINT(%f %f)'),
        %d
      )
    } % [lng, lat, distance_in_meters])
  }
end

和我的视图(get_nearby_stops.jbuilder):

json.nearby_stops @nearby_stops do |transit_stop|
  json.region_id transit_stop.region_id
  json.lat transit_stop.lat
  json.lng transit_stop.lng
  json.onestop_id transit_stop.onestop_id
  json.name transit_stop.name
  json.osm_way_id transit_stop.osm_way_id
  json.osm_way_id transit_stop.served_by_vehicle_types
  json.timezone transit_stop.timezone
  json.wheelchair_boarding transit_stop.wheelchair_boarding
  json.created_or_updated_in_changeset_id transit_stop.created_or_updated_in_changeset_id
  json.transit_routes transit_stop.transit_routes
end

Routes.rb在访问方法中添加了以下行:

get 'transit_stops/get_nearby_stops' => 'transit_stops#get_nearby_stops'

当我尝试通过以下方式访问此文件时: https : //myherokuapp.herokuapp.com/transit_stops/get_nearby_stops.json?lat=-122.49766&lng=37.71677

我得到的只是一条消息:

应用程序错误

应用程序中发生错误,无法提供您的页面。 如果您是应用程序所有者,请检查日志以获取详细信息。

当我查看heroku日志时,我看到的是超时错误:

app[web.1]: Processing by TransitStopsController#get_nearby_stops as JSON
app[web.1]:   Parameters: {"lat"=>"-122.49766", "lng"=>"37.71677"}
heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/transit_stops/get_nearby_stops.json?lat=-122.49766&lng=37.71677" host=myherokuapp.herokuapp.com request_id=1e081fdf-d0ce-4000-a6b4-4e75c176b8a2 fwd="10.0.0.1" dyno=web.1 connect=0ms service=30001ms status=503 bytes=0

AWS错误日志不显示任何内容。

对我来说奇怪的是,通过连接到Heroku的rails控制台,我可以执行相同的查询:

irb(main):001:0> TransitStop.close_to(-122.49766,37.71677,5000)
=> #<ActiveRecord::Relation [#<TransitStop region_id: 1, lat: #<BigDecimal:7fe69f6c95c0,'-0.122504106E3',18(18)>...
...
etc

所以在这一点上,我不明白是什么原因导致该控制器仅在通过视图而不是通过控制台访问时才失败? 如果我使用postgis方法,数据库网址应该不同吗?

任何帮助将不胜感激。

编辑:我已经测试了我的控制器的显示方法,它可以正常工作:

app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Started GET "/transit_stops/s-9q8ys6puje-655johnmuirave.json" for 159.16.243.2 at 2016-11-12 19:55:16 +0000
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Processing by TransitStopsController#show as JSON
app<a class="jive-link-external" href="http://web.1">http://web.1</a>:   Parameters: {"id"=>"s-9q8ys6puje-655johnmuirave"}
heroku<a href="https://forums.aws.amazon.com/">router</a>: at=info method=GET path="/transit_stops/s-9q8ys6puje-655johnmuirave.json" host=myapp.herokuapp.com request_id=15814367-5235-484b-bff9-7727a2349dd0 fwd="10.0.0.1" dyno=web.1 connect=0ms service=329ms status=200 bytes=1385
app<a class="jive-link-external" href="http://web.1">http://web.1</a>:   Rendered transit_stops/show.json.jbuilder (107.3ms)
app<a class="jive-link-external" href="http://web.1">http://web.1</a>: Completed 200 OK in 217ms (Views: 6.7ms | ActiveRecord: 207.4ms)<br class="jive-newline" />

对我来说,这可能意味着数据库中存在一些问题,无法执行我正在执行的查询? 查询本身应该很快,因为当我在控制台中对其进行测试时,几乎总是立即得到响应,但是也许需要更改有关数据库配置的信息?

只是让其他人看到,我的问题是查询之后,我的视图还产生了另外几个查询,因为该字段

transit_stop.transit_routes

与另一个表的关系。 因此,对于每个结果停止,数据库针对我得到的每个结果执行许多其他查询。 由于查询返回了数百个结果,因此最终视图执行了数百个附加查询,这给数据库带来了很多开销。

为了检测到这一点,我将log_statement = all更新为我的db参数组,以便可以看到所有活动都进入数据库。 我已经更新了查询,以通过将结果数减少到n个最接近的结果(最多10个)来提高效率,因为我对获得这么多结果并没有任何用处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM