يفشل عمال Rails Rails مع PgerRor: أغلق الخادم الاتصال بشكل غير متوقع
-
25-09-2019 - |
سؤال
لديّ موقع تشغيل تطبيق Rails وعمال Resque الذين يعملون في وضع الإنتاج ، على Ubuntu 9.10 ، Rails 2.3.4 ، Ruby-EE 2010.01 ، Postgresql 8.4.2
الأخطاء التي أثيرت باستمرار: Pgerror: أغلق الخادم الاتصال بشكل غير متوقع.
أفضل تخميني هو أن عملية Resque الرئيسية تنشئ اتصالًا بـ DB (مثل AuthLogic هل عند استخدام المستخدم. يحصل الأطفال على نوع من المكسور العالمي ActivereCord :: base.connection
يمكنني إعادة إنتاج سلوك مشابه جدًا مع هذا عينة من الرموز تقليد شوكة/معالجة في عامل resque. (AFAIK ، أوصى مستخدمو LIBPQ بإعادة إنشاء الاتصالات في عملية متشعب على أي حال ، وإلا فإنها ليست آمنة)
ولكن ، الشيء الغريب هو أنه عندما أستخدم PGBONCER أو PGPOOL-II بدلاً من اتصال PGSQL المباشر ، لا تظهر هذه الأخطاء.
لذا ، فإن السؤال هو أين وكيف يجب أن أحفر لمعرفة سبب كسره للاتصال العادي ويعمل مع تجمعات الاتصال؟ أو حلول معقول؟
المحلول
عندما خلقت نيستور, ، واجهت نفس النوع من المشكلة. كان الحل هو إعادة تأسيس الاتصال في عملية متشعب. انظر الرمز ذي الصلة في http://github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#l162
من وجهة نظري جداً نظرة محدودة على رمز resque ، أعتقد أنه ينبغي إجراء مكالمة إلى #STABLISH_CONNECTION هنا: https://github.com/resque/resque/blob/master/lib/resque/worker.rb#l123
نصائح أخرى
بعد القيام ببعض الأبحاث / التجربة والخطأ. لأي شخص يأتي عبر نفس القضية. لتوضيح ما ذكرته GC.
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }
يجب وضع الرمز أعلاه في: /lib/tasks/resque.rake
فمثلا:
require 'resque/tasks'
task "resque:setup" => :environment do
ENV['QUEUE'] = '*'
Resque.after_fork do |job|
ActiveRecord::Base.establish_connection
end
end
desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"
آمل أن يساعد هذا شخصًا ما ، بقدر ما كان عليه بالنسبة لي.
لا يمكنك تمرير مرجع LIBPQ عبر شوكة () (أو إلى مؤشر ترابط جديد) ، ما لم يكن التطبيق الخاص بك يعتني بعدم استخدامه بطرق متضاربة. (مثل ، طفرات حول كل محاولة لاستخدامها ، ويجب ألا تغلقها أبدًا). هذا هو نفسه بالنسبة لكل من الاتصالات المباشرة واستخدام pgBouncer. إذا نجحت في PGBOUNCER ، فقد كان ذلك محظوظًا في فقدان حالة السباق لسبب ما ، وسوف يكسر في النهاية.
إذا كان برنامجك يستخدم Forking ، فأنت يجب إنشاء الاتصال بعد، بعدما الشوكة.
تغيير تكوين Apache وأضف
PassengerSpawnMethod conservative
واجهت هذه المشكلة مع جميع فصول البريد الخاصة بي وكنت بحاجة للاتصال ActiveRecord::Base.verify_active_connections!
ضمن طرق البريد من أجل ضمان إجراء اتصال.