todos بتنسيق JSON.
المتطلبات الأساسية
- Elixir 1.15 أو إصدار أحدث، بالإضافة إلى Erlang/OTP. اختُبر هذا الدليل باستخدام Elixir 1.20.4 وErlang/OTP 29 وPhoenix 1.8.15 و
ecto_sql3.14.0 وPostgrex 0.22.4. - حساب على ClickHouse Cloud
إنشاء خدمة ClickHouse Managed Postgres
في وحدة تحكم ClickHouse Cloud، انقر على New service واختر Postgres. سيكون المثيل جاهزًا خلال بضع دقائق. للاطلاع على شرح تفصيلي للخطوات، راجع دليل البدء السريع.الحصول على بيانات الاتصال
افتح خدمتك وانقر على Connect في الشريط الجانبي الأيسر. تعرض النافذة المنبثقة اسم المستخدم وكلمة المرور والخادم والمنفذ، وتتضمن مفتاح تبديل بين Directly وvia PgBouncer. أبقِ الخيار Directly محددًا وفعّل Use SSL. انسخ كلمة المرور واسم مضيف الخادم، ثم انقر على Download CA certificate. شهادة CA خاصة بخدمتك وحدها. ويمكنك أيضًا تنزيلها لاحقًا من Settings → CA Certificate. اتصال مباشر أم عبر PgBouncer؟ تطبيق Phoenix عملية تعمل لفترات طويلة، ويدير Ecto مجمّع الاتصالات الخاص به (pool_size، وقيمته الافتراضية عشرة). يتصل هذا الدليل مباشرةً بـ Postgres عبر المنفذ 5432. وإذا كان عدد كبير من مثيلات التطبيق يقترب مجتمعًا من الحد الأقصى لاتصالات Postgres، فراجع استخدام PgBouncer.
إنشاء تطبيق Phoenix
ثبّت مُولِّد مشاريع Phoenix، ثم أنشئ تطبيقًا. تُستخدم Postgres بوصفها قاعدة البيانات الافتراضية:تهيئة اتصال قاعدة البيانات
انقل شهادة CA التي نزّلتها إلى دليلpriv الخاص بالتطبيق، وغيّر اسمها إلى ca-certificate.pem. يحمل الملف الذي نزّلته اسم خدمتك، مثل your-service-ca-certificate.pem:
priv في الإصدارات.
في config/dev.exs، استبدل أسطر username وpassword وhostname وdatabase في تهيئة Hello.Repo بالسطرين url وssl:
config/dev.exs
ssl قائمة كلمات مفتاحية (keyword list)، يُفعّل Postgrex التحقق من الشهادة (verify: :verify_peer) والتحقق من اسم المضيف، ويُرسل اسم المضيف الوارد في URL بوصفه اسم خادم TLS. لذا يكفي أن تمرّر شهادة CA فقط. أما ssl: true فلا يعمل، لأنه يتحقق من شهادة الخادم بالاستناد إلى مخزن شهادات CA في نظام التشغيل لديك، وهذا المخزن لا يتضمن شهادة CA الخاصة بخدمتك.
اضبط DATABASE_URL ليشير إلى خدمتك، مستخدمًا اسم قاعدة بيانات جديدًا. يستخدم هذا الدليل الاسم guide_phoenix:
mix ecto.create بقاعدة البيانات الافتراضية postgres باستخدام إعدادات TLS ذاتها لتنفيذ CREATE DATABASE.
إنشاء مورد JSON وتشغيل الترحيل
أنشئ سياقًا ومخططًا وترحيلًا ووحدة تحكم JSON للمهام (todos):lib/hello_web/router.ex، ألغِ تعليق نطاق /api وأضِف المورد إليه:
lib/hello_web/router.ex
schema_migrations، فلا يشغّل في الاستدعاءات اللاحقة إلا عمليات الترحيل الجديدة.
التشغيل والتحقق
تحقّق من أن الاتصال مشفّر. يقرأ الاستعلامpg_stat_ssl الخاص بالاتصال الحالي:
3116:
PATCH المهمة بعد تحديثها:
http://localhost:3116/api/todos في المتصفح لعرض المهام المتبقية:
guide_phoenix ثم public، وانقر على الجدول todos. ويتضمن المخطط public أيضًا الجدول schema_migrations:
تهيئة بيئة الإنتاج
في بيئة الإنتاج، يقرأ Phoenix إعدادات قاعدة البيانات من الملفconfig/runtime.exs. وفي تهيئة Hello.Repo ضمن الكتلة if config_env() == :prod do، استبدل السطر # ssl: true, بمسار شهادة CA:
config/runtime.exs
Application.app_dir المسار داخل الإصدار أو النسخة المنشورة من تطبيقك، ولذلك يعمل هذا الإعداد أيًّا كان الدليل الذي يبدأ منه التطبيق. عيّن DATABASE_URL في بيئة النشر لديك، ودون استعلام هنا أيضًا.
إذا كان تطبيقك قد بدأ باستخدام SQLite، فإن config/runtime.exs يقرأ DATABASE_PATH بدلًا من ذلك. استبدل المتغير database_path واستدعاء config :hello, Hello.Repo المرتبط به بما يلي:
config/runtime.exs
--database sqlite3 أيضًا عمليات الترحيل المعلّقة عند بدء تشغيل الإصدار، وذلك عبر العملية الفرعية Ecto.Migrator في lib/<your_app>/application.ex. ويستمر هذا السلوك كما هو عند استخدام Postgres.
استخدام PgBouncer
إذا كانت مثيلات تطبيقك تفتح مجتمعةً عددًا مفرطًا من الاتصالات المباشرة، فاتصل بدلًا من ذلك عبر PgBouncer المضمَّن. اختر via PgBouncer في نافذة Connect، واستخدم المنفذ6432 في DATABASE_URL، ثم أضف prepare: :unnamed إلى تهيئة المستودع في كلٍّ من config/dev.exs وconfig/runtime.exs:
config/dev.exs
-
العبارات المُحضَّرة: افتراضيًا، يُنفّذ Ecto كل استعلام بوصفه عبارة مُحضَّرة مسمّاة، ويدعم PgBouncer المرفق العبارات المسمّاة. ويحرّر Postgrex العبارات برسالة
Closeعلى مستوى البروتوكول، ولا يستخدم عبارة SQLDEALLOCATEإطلاقًا. ومع ذلك، تظهر مشكلتان عبر PgBouncer عند استخدام الإعداد الافتراضيprepare: :named:- قد يتوقف استعلام يبلغ طول نص SQL الخاص به نحو 4 KB عن الاستجابة إلى أن تنتهي مهلته، فيتلقى المستدعي الخطأ
DBConnection.ConnectionErrorبعد دقيقة تقريبًا. - بعد أن يغيّر ترحيلٌ نوعَ أحد الأعمدة، تظل الاستعلامات التي تقرأ هذا العمود تفشل مع الخطأ
cached plan must not change result type، حتى بعد إعادة تشغيل التطبيق، لأن PgBouncer يعيد استخدام عبارته المُحضَّرة على الخادم.
prepare: :unnamed، فيُحضّر Postgrex كل استعلام من جديد في كل مرة يُنفَّذ فيها، فتزول المشكلتان كلتاهما، مقابل رحلة ذهاب وإياب إضافية واحدة عبر الشبكة لكل استعلام. - قد يتوقف استعلام يبلغ طول نص SQL الخاص به نحو 4 KB عن الاستجابة إلى أن تنتهي مهلته، فيتلقى المستدعي الخطأ
-
الترحيلات: يعمل
mix ecto.migrateعبر PgBouncer باستخدام قفل الترحيل الافتراضي في Ecto، الذي يقفل الجدولschema_migrationsداخل معاملة. لا تضبطmigration_lock: :pg_advisory_lockلاتصال PgBouncer؛ إذ قد يُحرَّر القفل الاستشاري على مستوى الجلسة عبر اتصال Postgres مختلف، فيفشل ذلك مع الخطأfailed to release advisory lockويبقى القفل محتجزًا، فتظل عمليات التشغيل اللاحقة تنتظره، بما فيها تلك التي تجري على المنفذ5432. ولتشغيل الترحيلات عبر الاتصال المباشر، اضبط للأمرmix ecto.migrateقيمةDATABASE_URLتستخدم المنفذ5432. -
حالة الجلسة: لا تسري عبارات
SET، مثلSET search_pathفي دالة رد النداءafter_connect، إلا على اتصال Postgres الخاص بالمعاملة الحالية. ويؤدي تحديدsearch_pathفي الخيارparametersالخاص بـ Postgrex إلى الفشل مع الخطأunsupported startup parameter: search_path. أماLISTENوNOTIFY، اللذان يستخدمهماPostgrex.Notifications، فيتطلبان اتصالًا مباشرًا.
استكشاف الأخطاء وإصلاحها
CLIENT ALERT: Fatal - Unknown CA: لا يشيرcacertfileإلى شهادة CA الخاصة بخدمتك، أو أنك ضبطتssl: true. نزّل الشهادة مجددًا من Settings → CA Certificate، علمًا بأن لكل خدمة شهادة CA خاصة بها.CLIENT ALERT: Fatal - Bad Certificateمعhostname_check_failed: المضيف المحدد فيDATABASE_URLلا يطابق شهادة الخادم، كأن تكون قد استخدمت عنوان IP مثلًا. استخدم اسم المضيف الظاهر في النافذة المنبثقة Connect.Invalid CA certificate file ... no such file or directory: مسارcacertfileغير صحيح. تحقّق من وجود الملفpriv/ca-certificate.pem.
الخطوات التالية
- الاتصال: سلاسل الاتصال وPgBouncer وTLS
- الإعدادات: معلمات Postgres وPgBouncer، مثل
max_connections - النسخ المتماثلة للقراءة: وجّه عمليات القراءة إلى نسخة متماثلة باستخدام مستودعات النسخ المتماثلة في Ecto
- المزامنة مع ClickHouse: انسخ جداول Phoenix إلى ClickHouse لإجراء التحليلات