7

AWS EC2 インスタンスで実行されているアプリ サーバーで Ruby 1.9.3 を使用しています。別の EC2 インスタンスで Postgres DB を実行していますが、両方のインスタンスが同じセキュリティ グループに属しています。m Ruby コードが DB に接続すると、Sequel ORM gem ( http://sequel.rubyforge.org/ ) が使用されます。

これで、Postgres 9.1.4 DB がアプリ サーバー インスタンスからの接続を適切に受け入れられるように構成できました。

ただし、アプリ サーバーのログで、Postgres DB インスタンスへの接続に問題が発生し、次のようなエラー メッセージが表示されることに気付きました。

PG::Error: could not receive data from server: Connection timed out

また

PG::Error: connection not open

そこで、Postgres DB インスタンスに移動して /var/log/postgresql/postgresql-9.1-main.log を調べたところ、次のようなメッセージがたくさん表示されます。

2012-11-07 08:15:17 UTC LOG:  could not receive data from client: Connection timed out
2012-11-07 08:15:17 UTC LOG:  unexpected EOF on client connection

スタック オーバーフローを含む Web を検索し、PostgreSQL で SSL が有効になっていないことを確認しました (postgresql.conf ファイル内に "ssl=off" があります)。

この時点で、Postgres 構成の問題が正確に何であるかは正確にはわかりません。正当な理由がなければ、運用サーバーの最大接続数または最大タイムアウト値を台無しにすることはありません。

ほとんどの場合、アプリ サーバーは DB に接続できますが、この問題は断続的にしか発生しません。

Ruby 側では、これは Postgres 呼び出しを行ったときの「接続が開いていません」のエラー トレースです。

PG::Error: connection not open
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:145:in `async_exec'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:145:in `block in execute_query'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/database/logging.rb:33:in `log_yield'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:145:in `execute_query'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:132:in `block in execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:111:in `check_disconnect_errors'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:132:in `execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:372:in `_execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:234:in `block (2 levels) in execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:379:in `check_database_errors'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:234:in `block in execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/database/connecting.rb:229:in `block in synchronize'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/connection_pool/threaded.rb:105:in `hold'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/database/connecting.rb:229:in `synchronize'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:234:in `execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/dataset/actions.rb:744:in `execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:483:in `fetch_rows'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/model/base.rb:785:in `primary_key_lookup'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/model/base.rb:124:in `[]'

同様に、これは「サーバーからデータを受信できませんでした」のトレースです。

    PG::Error: could not receive data from server: Connection timed out
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:124:in `block'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:124:in `ensure in check_disconnect_errors'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:124:in `check_disconnect_errors'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:132:in `execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:372:in `_execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:234:in `block (2 levels) in execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:379:in `check_database_errors'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:234:in `block in execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/database/connecting.rb:229:in `block in synchronize'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/connection_pool/threaded.rb:105:in `hold'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/database/connecting.rb:229:in `synchronize'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:234:in `execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/dataset/actions.rb:744:in `execute'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/adapters/postgres.rb:483:in `fetch_rows'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/model/base.rb:785:in `primary_key_lookup'
/var/lib/gems/1.9.1/gems/sequel-3.38.0/lib/sequel/model/base.rb:124:in `[]'

アプリ サーバーと Postgres DB の両方を同じインスタンスで実行している場合、少なくともまだ接続の問題は発生していません。たぶん、Postgres は非ローカル DB 接続に対して寛大ではありませんか?

私が見逃したかもしれないことを教えてください、ありがとうございます!

4

1 に答える 1

2

これについての通常の説明は、接続の問題です。

または、接続性がない場合は、プロトコル同期の問題である可能性があります。両端がソケットからの読み取りを試みている可能性があり、どちらも書き込みを試みていないようです。したがって、クライアントはサーバーが応答を送信することを期待しているのに対し、サーバーはクライアントがデータを送信することを期待している可能性があります。

これは、実際にはtcpdumpして分析することができないため、断続的で時折発生する場合、デバッグが非常に困難になります。

サーバー側にログを追加します- log_statement = 'all'、そしてlog_line_prefixクライアントIP、バックエンドの開始時刻、バックエンドのpidを表示します。そうすれば、これらの障害を障害の前に発生したセッションアクティビティに一致させて、特定のクライアント、特定のジョブ、または実際にはランダムであるかどうかを判断することができます。

このSequelORMgemlibpqは最下層で使用されていますか、それとも独自のPostgreSQLプロトコル実装ですか?後者の場合、それが原因であることが判明する可能性があります。

更新:pggem(libpqベース)、postgresgem、またはおそらくpostgres-pr(それが何であれ)を使用できるようです。pgインストールされている場合は優先されます。

すでにpggemを使用しているように見えるので、問題が発生した場所(特定のクエリ、特定のクライアントなど)を追跡し、問題を再現する方法を見つけるために、診断作業を行う必要があります。ログをより簡単にロードして分析できるように、 PostgreSQLcsvlogが役立つ場合があります。

于 2012-11-08T02:43:39.757 に答える