todos.
Prérequis
- Elixir 1.15 ou version ultérieure et Erlang/OTP. Ce guide a été testé avec Elixir 1.20.4, Erlang/OTP 29, Phoenix 1.8.15,
ecto_sql3.14.0 et Postgrex 0.22.4. - Un compte ClickHouse Cloud
Créer un service ClickHouse Managed Postgres
Dans la console ClickHouse Cloud, cliquez sur New service et sélectionnez Postgres. L’instance est prête en quelques minutes. Pour une présentation pas à pas, consultez le guide de démarrage rapide.Obtenir vos informations de connexion
Ouvrez votre service et cliquez sur Connect dans la barre latérale gauche. La fenêtre modale affiche votre nom d’utilisateur, votre mot de passe, le serveur et le port, ainsi qu’un sélecteur Directly / via PgBouncer. Laissez Directly sélectionné et activez Use SSL. Copiez le mot de passe et le nom d’hôte du serveur, puis cliquez sur Download CA certificate. Le certificat de CA est propre à votre service. Vous pouvez également le télécharger plus tard depuis Settings → CA Certificate. Connexion directe ou PgBouncer ? Une application Phoenix est un processus de longue durée, et Ecto gère son propre pool de connexions (pool_size, dix par défaut). Dans ce guide, la connexion à Postgres se fait directement sur le port 5432. Si le nombre cumulé de connexions de vos instances de l’application approche de la limite de Postgres, consultez Utiliser PgBouncer.
Créer une application Phoenix
Installez le générateur de projets Phoenix, puis créez une application. Postgres est la base de données par défaut :Configurer la connexion à la base de données
Déplacez le certificat de CA que vous avez téléchargé dans le répertoirepriv de l’application, puis renommez-le en ca-certificate.pem. Le nom du fichier téléchargé correspond à celui de votre service, par exemple your-service-ca-certificate.pem :
priv sont également inclus dans les versions.
Dans config/dev.exs, remplacez les lignes username, password, hostname et database de la configuration Hello.Repo par url et ssl :
config/dev.exs
ssl est une liste de mots-clés, Postgrex active la vérification des certificats (verify: :verify_peer) ainsi que celle du nom d’hôte, et transmet le nom d’hôte de l’URL comme nom de serveur TLS. Il vous suffit de fournir le certificat de CA. ssl: true ne fonctionne pas, car cette option vérifie le certificat du serveur auprès du magasin de CA de votre système d’exploitation, qui ne contient pas la CA de votre service.
Définissez DATABASE_URL pour qu’elle pointe vers votre service, avec un nouveau nom de base de données. Ce guide utilise guide_phoenix :
mix ecto.create se connecte à la base de données postgres par défaut avec les mêmes paramètres TLS pour exécuter CREATE DATABASE.
Générer une ressource JSON et exécuter la migration
Générez un contexte, un schéma, une migration et un contrôleur JSON pour les todos :lib/hello_web/router.ex, décommentez le scope /api et ajoutez-y la ressource :
lib/hello_web/router.ex
schema_migrations et n’exécute que les nouvelles lors des exécutions suivantes.
Exécuter et vérifier
Vérifiez que la connexion est chiffrée. La requête interrogepg_stat_ssl pour la connexion courante :
3116 :
PATCH renvoie la tâche mise à jour :
http://localhost:3116/api/todos dans votre navigateur pour afficher la liste des tâches restantes :
guide_phoenix puis public, et cliquez sur la table todos. Le schéma public contient également schema_migrations :
Configurer l’environnement de production
En production, Phoenix lit les paramètres de la base de données dansconfig/runtime.exs. Dans la configuration Hello.Repo du bloc if config_env() == :prod do, remplacez la ligne # ssl: true, par le path du certificat de CA :
config/runtime.exs
Application.app_dir résout le path à l’intérieur de votre build ou de votre version, si bien que le paramètre fonctionne quel que soit le répertoire depuis lequel l’application démarre. Définissez DATABASE_URL dans votre environnement de déploiement, là encore sans query string.
Si votre application reposait initialement sur SQLite, config/runtime.exs lit plutôt DATABASE_PATH. Remplacez la variable database_path et l’appel config :hello, Hello.Repo associé par :
config/runtime.exs
--database sqlite3 exécutent également les migrations en attente au démarrage d’une version, via le processus enfant Ecto.Migrator déclaré dans lib/<your_app>/application.ex. Ce mécanisme fonctionne toujours avec Postgres.
Utiliser PgBouncer
Si les instances de votre application ouvrent ensemble trop de connexions directes, passez plutôt par le PgBouncer intégré. Sélectionnez via PgBouncer dans la fenêtre modale Connect, utilisez le port6432 dans DATABASE_URL et ajoutez prepare: :unnamed à la configuration du dépôt, à la fois dans config/dev.exs et dans config/runtime.exs :
config/dev.exs
-
Requêtes préparées : par défaut, Ecto exécute chaque requête sous forme de requête préparée nommée, et le PgBouncer intégré prend en charge les statements nommés. Postgrex libère les statements au moyen d’un message
Closeau niveau du protocole, jamais avec l’instruction SQLDEALLOCATE. Néanmoins, avec la valeur par défautprepare: :named, deux problèmes surviennent en passant par PgBouncer :- Une requête dont le texte SQL fait environ 4 Ko peut rester bloquée jusqu’à expiration du délai. L’appelant reçoit alors
DBConnection.ConnectionErrorau bout d’environ une minute. - Après une migration qui modifie le type d’une colonne, les requêtes qui lisent cette colonne continuent d’échouer avec
cached plan must not change result type, même après le redémarrage de l’application, car PgBouncer réutilise sa requête préparée sur le serveur.
prepare: :unnamed, Postgrex prépare de nouveau chaque requête à chaque exécution, ce qui élimine ces deux problèmes, au prix d’un aller-retour réseau supplémentaire par requête. - Une requête dont le texte SQL fait environ 4 Ko peut rester bloquée jusqu’à expiration du délai. L’appelant reçoit alors
-
Migrations :
mix ecto.migratefonctionne via PgBouncer avec le verrou de migration par défaut d’Ecto, qui verrouille la tableschema_migrationsau sein d’une transaction. Ne définissez pasmigration_lock: :pg_advisory_lockpour une connexion PgBouncer. Le verrou consultatif de niveau session risque d’être libéré sur une autre connexion Postgres : la libération échoue alors avecfailed to release advisory locket le verrou reste détenu, si bien que les exécutions suivantes, y compris celles sur le port5432, restent en attente. Pour exécuter les migrations via la connexion directe, définissez uneDATABASE_URLpointant vers le port5432pour la commandemix ecto.migrate. -
État de session : les statements
SET, comme unSET search_pathdans une fonction de rappelafter_connect, ne s’appliquent qu’à la connexion Postgres de la transaction en cours. Unsearch_pathdéfini dans l’optionparametersde Postgrex échoue avecunsupported startup parameter: search_path.LISTENetNOTIFY, utilisés parPostgrex.Notifications, nécessitent une connexion directe.
Dépannage
CLIENT ALERT: Fatal - Unknown CA:cacertfilene pointe pas vers le certificat de CA de votre service, ou vous avez définissl: true. Téléchargez de nouveau le certificat depuis Settings → CA Certificate. Chaque service dispose de sa propre CA.CLIENT ALERT: Fatal - Bad Certificateavechostname_check_failed: l’hôte indiqué dansDATABASE_URLne correspond pas au certificat du serveur, par exemple parce que vous avez utilisé une adresse IP. Utilisez le nom d’hôte affiché dans la fenêtre modale Connect.Invalid CA certificate file ... no such file or directory: le path indiqué danscacertfileest incorrect. Vérifiez que le fichierpriv/ca-certificate.pemexiste bien.
Étapes suivantes
- Connexion : chaînes de connexion, PgBouncer et TLS
- Paramètres : paramètres de Postgres et de PgBouncer, comme
max_connections - Répliques en lecture : redirigez les lectures vers une réplique à l’aide des dépôts de répliques d’Ecto
- Synchronisation avec ClickHouse : répliquez vos tables Phoenix vers ClickHouse à des fins d’analyse