todos.
Pré-requisitos
- Elixir 1.15 ou superior e Erlang/OTP. Este guia foi testado com Elixir 1.20.4, Erlang/OTP 29, Phoenix 1.8.15,
ecto_sql3.14.0 e Postgrex 0.22.4. - Uma conta no ClickHouse Cloud
Crie um serviço ClickHouse Managed Postgres
No console do ClickHouse Cloud, clique em New service e selecione Postgres. A instância estará pronta em poucos minutos. Consulte o guia de início rápido para ver o passo a passo completo.Obtenha os detalhes de conexão
Abra o seu serviço e clique em Connect na barra lateral esquerda. O modal exibe seu nome de usuário, senha, servidor e porta, além de um seletor Directly / via PgBouncer. Mantenha Directly selecionado e ative Use SSL. Copie a senha e o hostname do servidor e, em seguida, clique em Download CA certificate. O certificado da CA é exclusivo do seu serviço. Você também pode baixá-lo depois em Settings → CA Certificate. Conexão direta ou PgBouncer? Uma aplicação Phoenix é um processo de longa duração, e o Ecto mantém seu próprio pool de conexões (pool_size, dez por padrão). Neste guia, a conexão com o Postgres é feita diretamente pela porta 5432. Se o total de conexões de várias instâncias da aplicação se aproximar do limite de conexões do Postgres, consulte Usando o PgBouncer.
Crie um app Phoenix
Instale o gerador de projetos Phoenix e crie um app. O Postgres é o banco de dados padrão:Configure a conexão com o banco de dados
Mova o certificado de CA que você baixou para o diretóriopriv da aplicação e renomeie-o para ca-certificate.pem. O arquivo baixado tem o nome do seu serviço, por exemplo, your-service-ca-certificate.pem:
priv também são incluídos nos lançamentos.
Em config/dev.exs, substitua as linhas username, password, hostname e database da configuração de Hello.Repo por url e ssl:
config/dev.exs
ssl é uma keyword list, o Postgrex ativa a verificação de certificados (verify: :verify_peer) e a verificação do hostname, além de enviar o hostname da URL como nome do servidor TLS. Basta fornecer o certificado da CA. ssl: true não funciona, porque valida o certificado do servidor com base no repositório de CAs do seu sistema operacional, que não contém a CA do seu serviço.
Defina DATABASE_URL apontando para o seu serviço, com um novo nome de banco de dados. Este guia usa guide_phoenix:
mix ecto.create se conecta ao banco de dados padrão postgres com as mesmas configurações de TLS para executar CREATE DATABASE.
Gere um recurso JSON e execute a migração
Gere um contexto, um schema, uma migração e um controller JSON para as tarefas (todos):lib/hello_web/router.ex, descomente o scope /api e adicione o recurso a ele:
lib/hello_web/router.ex
schema_migrations e, nas execuções seguintes, roda apenas as novas.
Executar e verificar
Verifique se a conexão está criptografada. A consulta lêpg_stat_ssl referente à conexão atual:
3116:
PATCH retorna o item de tarefa (todo) atualizado:
http://localhost:3116/api/todos no navegador para listar as tarefas restantes:
guide_phoenix e, em seguida, public e clique na tabela todos. O schema public também contém schema_migrations:
Configurar o ambiente de produção
Em produção, o Phoenix lê as configurações do banco de dados emconfig/runtime.exs. Na configuração Hello.Repo, dentro de if config_env() == :prod do, substitua a linha # ssl: true, pelo caminho do certificado da CA:
config/runtime.exs
Application.app_dir resolve o caminho dentro da sua compilação ou do seu lançamento, de modo que a configuração funciona independentemente do diretório em que a aplicação é iniciada. Defina DATABASE_URL no seu ambiente de implantação, novamente sem string de consulta.
Se a sua aplicação começou com SQLite, o config/runtime.exs lê DATABASE_PATH. Substitua a variável database_path e a respectiva chamada config :hello, Hello.Repo por:
config/runtime.exs
--database sqlite3 também executam as migrações pendentes quando um lançamento é iniciado, por meio do processo filho Ecto.Migrator em lib/<your_app>/application.ex. Isso continua funcionando com o Postgres.
Usando o PgBouncer
Se as instâncias da sua aplicação, somadas, abrirem conexões diretas demais, conecte-se pelo PgBouncer incluído no pacote. Selecione via PgBouncer no modal Connect, use a porta6432 em DATABASE_URL e adicione prepare: :unnamed à configuração do repo, tanto em config/dev.exs quanto em config/runtime.exs:
config/dev.exs
-
Prepared statements: por padrão, o Ecto executa toda consulta como um prepared statement nomeado, e o PgBouncer incluído oferece suporte a instruções nomeadas. O Postgrex libera as instruções com uma mensagem
Closeno nível do protocolo, nunca com o comando SQLDEALLOCATE. Ainda assim, com o padrãoprepare: :named, dois problemas surgem ao passar pelo PgBouncer:- Uma consulta cujo texto SQL tenha cerca de 4 KB pode travar até atingir o tempo limite. O chamador recebe
DBConnection.ConnectionErrorapós aproximadamente um minuto. - Depois que uma migração altera o tipo de uma coluna, as consultas que leem essa coluna continuam falhando com
cached plan must not change result type, mesmo após reiniciar a aplicação, porque o PgBouncer reutiliza o prepared statement no servidor.
prepare: :unnamed, o Postgrex prepara cada consulta novamente a cada execução, e os dois problemas desaparecem. Em contrapartida, cada consulta exige uma ida e volta de rede adicional. - Uma consulta cujo texto SQL tenha cerca de 4 KB pode travar até atingir o tempo limite. O chamador recebe
-
Migrações: o
mix ecto.migratefunciona pelo PgBouncer com o bloqueio de migração padrão do Ecto, que bloqueia a tabelaschema_migrationsdentro de uma transação. Não definamigration_lock: :pg_advisory_lockem uma conexão com o PgBouncer. O advisory lock no nível da sessão pode ser liberado em outra conexão Postgres, o que falha comfailed to release advisory locke deixa o bloqueio ativo, fazendo com que execuções posteriores, inclusive na porta5432, fiquem aguardando sua liberação. Para executar migrações pela conexão direta, defina umaDATABASE_URLcom a porta5432no comandomix ecto.migrate. -
Estado da sessão: instruções
SET, como umSET search_pathem um callbackafter_connect, se aplicam apenas à conexão Postgres da transação atual. Umsearch_pathna opçãoparametersdo Postgrex falha comunsupported startup parameter: search_path.LISTENeNOTIFY, usados peloPostgrex.Notifications, exigem uma conexão direta.
Solução de problemas
CLIENT ALERT: Fatal - Unknown CA:cacertfilenão aponta para o certificado da CA do seu serviço, ou você definiussl: true. Baixe o certificado novamente em Settings → CA Certificate. Cada serviço tem a própria CA.CLIENT ALERT: Fatal - Bad Certificatecomhostname_check_failed: o host emDATABASE_URLnão corresponde ao certificado do servidor, por exemplo, porque você usou um endereço IP. Use o hostname exibido no modal Connect.Invalid CA certificate file ... no such file or directory: o caminho decacertfileestá incorreto. Verifique se o arquivopriv/ca-certificate.pemexiste.
Próximos passos
- Conexão: strings de conexão, PgBouncer e TLS
- Configurações: parâmetros do Postgres e do PgBouncer, como
max_connections - Réplicas de leitura: direcione leituras para uma réplica com os repositórios de réplica do Ecto
- Sincronizar com o ClickHouse: replique suas tabelas do Phoenix no ClickHouse para fins de analytics