خطأ 502 عند فتح بعض ملفات تعريف المستخدمين

يواجه الخادم مشاكل مع summary.json لبعض المستخدمين العشوائيين ويعيد رمز 502. ربما بدأ بعد التحديث الأخير، لكنني لست متأكدًا.

أنا لست على دراية بمكدس discourse ولدي صعوبة في البحث عن السجلات. تم التعديل لإخفاء اسم المستخدم وعنوان IP، قد يختلف الوقت ولكن في الغالب هو نفس طلب صفحة الملف الشخصي مكرر عدة مرات.

من التطبيق /var/log/nginx/error.log:

[error] 560#560: *416 upstream prematurely closed connection while reading response header from upstream, client: *.*.*.*, server: _, request: "GET /u/user/summary.json HTTP/2.0", upstream: "http://127.0.0.1:3000/u/user/summary.json", host: "forum.taucetistation.org", referrer: "https://forum.taucetistation.org/u/user"

/shared/log/rails/production_errors.log فارغ، و /shared/log/rails/production.log يحتوي فقط على

Started GET "/u/user/summary.json" for *.*.*.* at 2024-05-24 20:26:56 +0000
Processing by UsersController#summary as JSON
  Parameters: {"username"=>"user"}

بدون “Completed 200 OK” لطلبات مماثلة.

يبدو أنه لا توجد سجلات ذات صلة في unicorn (فقط أخطاء الاتصال بـ redis عند بدء التشغيل، ولكن يبدو أنها ناجحة في النهاية وليست ذات صلة).

ولكن هناك طلب واحد مشبوه مع وقت مدة طويل من /var/log/postgres/current:

2024-05-24 20:49:12.727 UTC [2919] discourse@discourse LOG:  duration: 95288.368 ms  execute <unnamed>: SELECT replies.user_id, COUNT(*) FROM "posts" INNER JOIN "topics" "topics_posts" ON "topics_posts". "deleted_at" IS NULL AND "topics_posts". "id" = "posts". "topic_id" JOIN posts replies ON posts.topic_id = replies.topic_id AND posts.reply_to_post_number = replies.post_number JOIN topics ON replies.topic_id = topics.id AND topics.archetype <> 'private_message' AND replies.post_type IN (1) WHERE "posts". "deleted_at" IS NULL AND (posts.post_type IN (1,4)) AND "topics". "deleted_at" IS NULL AND (topics.archetype <> 'private_message') AND "topics". "visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (4,8,20,46,55,60,62,67))) AND "posts". "user_id" = 5318 AND (replies.user_id <> posts.user_id) GROUP BY "replies". "user_id" ORDER BY COUNT(*) DESC LIMIT 6
2024-05-24 20:49:12.728 UTC [2919] discourse@discourse LOG:  could not send data to client: Broken pipe
2024-05-24 20:49:12.729 UTC [2919] discourse@discourse FATAL:  connection to client lost
إعجاب واحد (1)

يبدو أنها مشكلة لكل ملف تعريف مستخدم نشط. في بعض الأحيان يستغرق الأمر وقتًا طويلاً، وفي بعض الأحيان يكون سريعًا بسبب بعض ذاكرة التخزين المؤقت.

وفي بعض الأحيان يكون خارج الوقت ويتسبب في خطأ 502.

نحن نستخدم هذا الخادم من DO فقط للمنتدى.
Снимок экрана от 2024-05-25 00-12-28

ليس كثيرًا، ولكنه كان كافيًا لنا في الماضي.

أرى أن summary.json يستغرق ما بين 20 و 30 ثانية للتحميل.

أيضًا، هذه الأخطاء في وحدة التحكم:

وأحيانًا 502، بالفعل:

بالنظر إلى الوضع الآمن، لا يبدو أنه مرتبط بالمكونات الإضافية/مكونات السمات.

أرى أنك خلف Cloudflare. هل يمكنك محاولة تعطيل أي تحسينات؟

إعجاب واحد (1)

تم تعطيل وكيل CF.

لكن لا يبدو أنها مشكلة في الواجهة الأمامية، بل يبدو أنها طلب قاعدة بيانات ثقيل في الواجهة الخلفية.

إعجاب واحد (1)

قائمة الإضافات الخاصة بنا

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-patreon.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-staff-notes.git
          - git clone https://github.com/discourse/discourse-spoiler-alert.git
          - git clone https://github.com/discourse/discourse-bbcode.git
          - git clone https://github.com/discourse/discourse-signatures.git
          - git clone https://github.com/discourse/discourse-github
          - git clone https://github.com/discourse/discourse-whos-online.git
          - git clone https://github.com/discourse/discourse-chat-integration.git
          - git clone https://github.com/discourse/discourse-assign
          - git clone https://github.com/discourse/discourse-question-answer.git

لست خبيراً، لكن ديسكورس (Discourse) يميل إلى أن يتطلب المزيد من ذاكرة الوصول العشوائي (RAM) هذه الأيام، اعتماداً على إعداداتك (2 جيجابايت على الأقل). هل لديك مساحة تبديل (swap) مهيأة؟

هل ترى أي معلومات ذات صلة في المسار /logs؟

بالنسبة للإضافات (Plugins)، لا أرى أي إضافات خاطئة للوهلة الأولى. :thinking:

نأمل أن يتمكن شخص ما من تقديم رؤى أفضل هنا.

نعم، 4 جيجا بايت من التبديل. وفي /logs بعض التحذيرات مثل إشعارات الإهمال أو شيء عن geolite.

2024-05-24 20:49:12.727 UTC [2919] discourse@discourse LOG:  duration: 95288.368 ms  execute «unnamed»: SELECT replies.user_id, COUNT(*) FROM "posts" INNER JOIN "topics" "topics_posts" ON "topics_posts". "deleted_at" IS NULL AND "topics_posts". "id" = "posts". "topic_id" JOIN posts replies ON posts.topic_id = replies.topic_id AND posts.reply_to_post_number = replies.post_number JOIN topics ON replies.topic_id = topics.id AND topics.archetype <> 'private_message' AND replies.post_type IN (1) WHERE "posts". "deleted_at" IS NULL AND (posts.post_type IN (1,4)) AND "topics". "deleted_at" IS NULL AND (topics.archetype <> 'private_message') AND "topics". "visible" = TRUE AND (topics.category_id IS NULL OR topics.category_id IN (SELECT id FROM categories WHERE NOT read_restricted OR id IN (4,8,20,46,55,60,62,67))) AND "posts". "user_id" = 5318 AND (replies.user_id <> posts.user_id) GROUP BY "replies". "user_id" ORDER BY COUNT(*) DESC LIMIT 6

على حد فهمي، هذا طلب لـ “الأكثر رداً عليه”، وقد تم تغييره مؤخرًا في https://github.com/discourse/discourse/pull/26373، لذا ربما يؤثر هذا الإصلاح علينا.

لقد قمت بتشغيل EXPLAIN ANALYZE إذا كان ذلك قد يساعد:

 Limit  (cost=2552.39..2552.39 rows=1 width=12) (actual time=94412.810..94412.824 rows=6 loops=1)
   ->  Sort  (cost=2552.39..2552.39 rows=1 width=12) (actual time=94412.804..94412.808 rows=6 loops=1)
         Sort Key: (count(*)) DESC
         Sort Method: top-N heapsort  Memory: 25kB
         ->  GroupAggregate  (cost=2552.36..2552.38 rows=1 width=12) (actual time=94412.361..94412.743 rows=160 loops=1)
               Group Key: replies.user_id
               ->  Sort  (cost=2552.36..2552.36 rows=1 width=4) (actual time=94412.323..94412.405 rows=729 loops=1)
                     Sort Key: replies.user_id
                     Sort Method: quicksort  Memory: 59kB
                     ->  Nested Loop  (cost=12.24..2552.35 rows=1 width=4) (actual time=0.279..94409.497 rows=729 loops=1)
                           Join Filter: (topics_posts.id = topics.id)
                           ->  Nested Loop  (cost=1.13..2507.59 rows=4 width=16) (actual time=0.164..94354.548 rows=746 loops=1)
                                 Join Filter: ((replies.user_id <> posts.user_id) AND (posts.reply_to_post_number = replies.post_number))
                                 Rows Removed by Join Filter: 15395502
                                 ->  Nested Loop  (cost=0.71..1419.07 rows=131 width=16) (actual time=0.113..240.052 rows=1399 loops=1)
                                       ->  Index Scan using idx_posts_user_id_deleted_at on posts  (cost=0.42..561.22 rows=135 width=12) (actual time=0.077..59.712 rows=1408 loops=1)
                                             Index Cond: (user_id = 5318)
                                             Filter: (post_type = ANY ('{1,4}'::integer[]))
                                       ->  Index Only Scan using index_topics_on_id_and_deleted_at on topics topics_posts  (cost=0.29..6.35 rows=1 width=4) (actual time=0.123..0.123 rows=1 loops=1408)
                                             Index Cond: ((id = posts.topic_id) AND (deleted_at IS NULL))
                                             Heap Fetches: 1394
                                 ->  Index Scan using index_posts_on_topic_id_and_reply_to_post_number on posts replies  (cost=0.42..7.77 rows=36 width=12) (actual time=0.098..65.083 rows=11005 loops=1399)
                                       Index Cond: (topic_id = topics_posts.id)
                                       Filter: (post_type = 1)
                                       Rows Removed by Filter: 4
                           ->  Index Scan using topics_pkey on topics  (cost=11.11..11.18 rows=1 width=4) (actual time=0.065..0.065 rows=1 loops=746)
                                 Index Cond: (id = replies.topic_id)
                                 Filter: ((deleted_at IS NULL) AND visible AND ((archetype)::text <> 'private_message'::text) AND ((archetype)::text <> 'private_message'::text) AND ((category_id IS NULL) OR (hashed SubPlan 1)))
                                 Rows Removed by Filter: 0
                                 SubPlan 1
                                   ->  Seq Scan on categories  (cost=0.00..10.74 rows=31 width=4) (actual time=0.012..0.066 rows=37 loops=1)
                                         Filter: ((NOT read_restricted) OR (id = ANY ('{4,8,20,46,55,60,62,67}'::integer[])))
 Planning Time: 3.895 ms
 Execution Time: 94416.415 ms
(34 rows)

قد يكون من المفيد تشغيل
vmstat 5
على الخادم (في اتصال ssh) أثناء قيامك بذلك، لمعرفة ما قد يحدث مع الترحيل. (يمكن استخدام top ولكنه أقل فائدة بكثير هنا)

3 إعجابات

كم لديك من ذاكرة الوصول العشوائي؟ ما هو حجم قاعدة بياناتك؟ من المحتمل أنك تحتاج فقط إلى المزيد من ذاكرة الوصول العشوائي.

إعجابَين (2)

يبدو أن PostgreSQL يقوم ببعض التحسينات/التخزين المؤقت، لذا لا يستغرق الأمر وقتًا طويلاً في بعض الأحيان، لذلك أحتاج إلى البحث عن مستخدمين جدد لاختبار الطلبات.

  procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 0  0 287852  75220  17660 587788    6    8  4685   244  496    9  6  3 88  3  0  0
 0  0 287852  74048  17668 587836    0    0     0    18  209  465  1  2 96  0  0  0
 0  1 287852  82496  13452 582360    2   13 39937    38 4186 7339  8 16 14 62  0  0
 0  1 288620  77924   1020 601604    2  138 64178   166 5352 8263  9 22  0 68  0  0
 1  0 290156  80472    968 599840    1  313 37518    42 3612 5160 22 37  0 41  0  0
 1  0 289900  67588   3720 609896    4   29 13800    75 2062 2635 43 49  0  8  0  0
 1  0 291180  76816   2368 606924    0  245 30042    27 3414 5477 34 39  0 27  0  0
 2  0 292716  67184   1696 622528    4  318 44820    18 4152 6198 23 30  0 47  0  0
 1  0 293228  75100   3008 614144    0  132 10030     4 1803 1986 39 49  0 11  0  0
 1  0 293484  76020   2860 613444    1   34  3331    10 1197  767 44 54  0  2  0  0
 1  0 294508  66296   2868 623376    2  218  4994    24 1389 1206 40 54  0  6  0  0
 1  0 295020  75432   2892 614384    0  120  1304    58 1161  728 43 55  0  2  0  0
 1  0 295020  73084   2904 615984    0    0   314    11 1060  448 43 57  0  0  0  0
 1  0 295020  68864   3148 619388    6   33  8209    63  663 1190 10 13 74  3  0  0
  Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | ICU Locale | ICU Rules |   Access privileges    |  Size   | Tablespace | Description 
-----------+----------+----------+-----------------+-------------+-------------+------------+-----------+------------------------+---------+------------+-------------
 discourse | postgres | UTF8     | libc            | ru_RU.UTF-8 | ru_RU.UTF-8 |            |           | =Tc/postgres          +| 9493 MB | pg_default | 

2 جيجابايت من ذاكرة الوصول العشوائي + 4 جيجابايت من مساحة التبديل، نستخدم هذه القطرة (وحدة المعالجة المركزية القديمة) من DigitalOcean

أريد أن أجرب الاختبار بالتغييرات التي تم التراجع عنها من https://github.com/discourse/discourse/commit/db10dd53192cd9b82cf559a430e99bafca63f454، ولكن على الرغم من أنني قمت بتحرير app/models/user_summary.rb أثناء وجودي في حاوية discourse، ما زلت أرى أن صفحة الملف الشخصي تقوم بهذا الطلب بثلاثة JOINs.

هل أحتاج إلى مسح ذاكرة التخزين المؤقت في مكان ما؟ أو هل هناك طريقة أفضل للقيام بذلك.

تحديث: ساعدت إعادة تشغيل الحاوية، ويبدو أنها تعمل بشكل أفضل الآن بعد التراجع! يتم تحميل صفحات الملف الشخصي بشكل أسرع ولا توجد أخطاء 502.

3 إعجابات

أؤكد؛ هذا سريع للغاية الآن، ولا أرى أي أخطاء.

إعجابَين (2)

شكرًا على إخراج vmstat. بالنسبة لي، هذا يعني أن الذاكرة ليست مفرطة الالتزام - لينكس لا يقوم بالتبديل - ولكن قاعدة البيانات لم تتمكن من تخصيص ذاكرة وصول عشوائي كافية - فهي تقوم بالكثير من عمليات الإدخال/الإخراج على القرص.

لذلك أعتقد أن هذه ستكون حالة الحاجة إلى المزيد من ذاكرة الوصول العشوائي، وإضافة مساحة مبادلة لن تساعد كثيرًا.

إذًا لقد قمت أيضًا بالتراجع عن التغيير ووجدت أن الأداء عاد إلى طبيعته؟

إعجاب واحد (1)

ليس أنا، ألكسندر، في منشوره أعلاه. أردت تأكيد ذلك، حيث كنت أختبر سابقًا على منتداه. ونعم، مشكلة الأداء قد اختفت بعد التراجع عن هذا الالتزام.

إعجابَين (2)

ربما تكون مشكلة في وحدة المعالجة المركزية أيضاً. ولكن باستثناء عندما كان discourse يقوم ببعض مهام الصيانة، لم نواجه تقريباً أي مشاكل في الأداء من قبل. فقط الآن مع صفحة الملف الشخصي، لذلك كنت أفكر في آخر تحديث.

لكن يجب أن أقول أنه قبل محاولة التراجع، قمت أيضاً بتعديل app.yml:

  1. لسبب ما كان لدينا db_shared_buffers: \"128MB\"، أقل بأربع مرات من الموصى به، ربما شيء موروث من الوقت الذي كنت فيه أقوم بإعداد المنتدى لأول مرة. لقد علقت هذا، حتى يتمكن discourse من إعداده بنفسه بناءً على ذاكرة الوصول العشوائي للمضيف.
  2. لقد قمت أيضاً بإلغاء التعليق على db_work_mem: \"40MB\"

لكنني قمت بإعادة بناء سليمة واختبرت هذا أولاً، ولم يساعدنا. فقط بعد التراجع أصبح الوضع أفضل.

لقد اختبرت للتو مرة أخرى بدون تراجع فقط في حالة، ويمكنني رؤية 502 على الملفات الشخصية مرة أخرى.

إذا لزم الأمر، يمكنني إجراء المزيد من الاختبارات مع/بدون التصحيح.

إعجاب واحد (1)

اختبار شامل جيد!

ربما، ولكن بالنظر إلى الوقت المستغرق في الانتظار، أعتقد أن الأمر يتعلق في الغالب بالإدخال/الإخراج. بمجرد حل عنق زجاجة الإدخال/الإخراج، يمكن لـ vmstat إظهار ما إذا كانت وحدة المعالجة المركزية قد وصلت إلى أقصى حد لها.

إعجابَين (2)

لن يفعل. يمكنك تشغيل discourse-setup وسيقوم بذلك (يمكنك الضغط على control-c بعد الرسالة الأولى) أو إدخال الرقم الصحيح بنفسك.

غالبًا ما يكون من المفيد زيادة هذا، ولكن فقط إذا كان لديك ذاكرة وصول عشوائي كافية.

يبدو أن مشكلتك الأصلية قد تكون مشكلة في الاستعلام في المصدر، ولكنك بالتأكيد تريد تعيين db_work_mem. التعليق عليه ليس حلاً (على حد علمي الأخير)

إعجابَين (2)

الخلاصة هنا، أعتقد، هي أن طلب السحب المقبول، والذي كان يهدف إلى تسريع الأمور، قد أبطأها في الواقع، أو حتى كسرها، في المواقع ذات ذاكرة الوصول العشوائي (RAM) المحدودة؟

هل يمكننا التراجع عن طلب السحب هذا حتى يتم فهم ذلك؟

هل يمكننا تغيير فئة هذا الموضوع إلى خطأ؟

إعجاب واحد (1)

شكرًا لملاحظتك هذا، لقد تم تضليلي بواسطة التعليق حينها. أشعر أن ضبط هذا على 512 ميجابايت يدويًا قد ساعد قليلاً، لكن الأداء في صفحات الملف الشخصي لا يزال غير جيد بما فيه الكفاية ويستغرق أحيانًا نصف دقيقة للتحميل.

إعجاب واحد (1)