Como implantar um aplicativo Spring usando Postgresql no Heroku usando Spring Boot?
-
21-12-2019 - |
Pergunta
Estou avaliando o Spring 4 no Heroku e até agora estou muito impressionado com ambos.
No entanto, estou tendo problemas para executar meu aplicativo Spring Boot no Heroku.Tudo está funcionando bem, exceto Postgresql (acabei de receber Connection Refused
erros).
O problema certamente terá a ver com a forma como estou configurando o DataSource
mas até agora tenho seguido uma abordagem de tentativa e erro!Não tenho certeza de como devo configurar a fonte de dados do Heroku DATABASE_URL
e não consigo encontrar nenhum exemplo.
eu encontrei nuvem de primavera por acaso, pesquisando no Google, o que parece promissor, mas não explica nada sobre o DATABASE_URL
.Além disso, nem é mencionado no Spring.IO, então estou me perguntando se é uma opção para uso em produção?
Solução
Spring Cloud é uma boa opção.Não sei por que não está listado no spring.io - deveria estar, talvez ainda não tenha saído da incubação ou algo assim, mas usei-o com sucesso.Se você não gosta de usar isso, acho que provavelmente você pode simplesmente definir o spring.datasource.url
ao valor que o Heroku fornece em seu env var.
Outras dicas
Você pode usar Vars de configuração que pode ser configurado na aba de configurações do seu aplicativo no Heroku.Os Config Vars serão expostos como variáveis de ambiente para seu aplicativo.Como o Spring Boot pode mapear variáveis de ambiente para propriedades do aplicativo, você só precisa definir:
SPRING_DATASOURCE_URL
SPRING_DATASOURCE_USER
SPRING_DATASOURCE_PASSWORD
SPRING_DATASOURCE_DRIVER-CLASS-NAME
E eles serão mapeados para:
spring.datasource.url
spring.datasource.user
spring.datasource.password
spring.datasource.driver-class-name
Agora tudo que você precisa fazer é extrair os valores relevantes.A configuração completa do banco de dados pode ser inspecionada no painel de gerenciamento heroku postgres.Selecione o banco de dados ao qual deseja se conectar e você verá os valores para SPRING_DATASOURCE_USER
e SPRING_DATASOURCE_PASSWORD
agora mesmo.O SPRING_DATASOURCE_URL
tem que ser construído assim:
jdbc:postgresql://<Host>:<Port>/<Database>
Onde <Host>
, <Port>
e <Database>
deve ser substituído pelos valores correspondentes da página de conexão do banco de dados.Por último, mas não menos importante, o SPRING_DATASOURCE_DRIVER-CLASS-NAME
tem que ser definido para org.postgresql.Driver
.
Dessa forma, você pode usar a funcionalidade integrada do Spring Boot em vez de adicionar configuração específica do ambiente ao seu aplicativo.Observe, entretanto, que o Spring Boot possui um específico ordem de leitura da configuração externa.Então você tem que ter certeza de que não há
- Argumentos de linha de comando (passados através do Perfil)
- Atributos JNDI de java:comp/env (não sei de onde eles podem vir no Heroku).
- Propriedades do sistema Java (também podem ser passadas através do Procfile como
-D
argumentos)
já que elas substituiriam as variáveis de ambiente do sistema operacional.
Uma coisa que gostaria de acrescentar depois de lutar com isso por um tempo: apenas criar um objeto de configuração não é suficiente com o Heroku, mesmo com os conectores Spring Cloud.Você também deve declarar explicitamente o perfil da nuvem (-Dspring.profiles.active=cloud
) no perfil do seu aplicativo.
Além de DATABASE_URL
, que está sempre lá, o Heroku cria 3 variáveis de ambiente em tempo de execução.Eles são:
JDBC_DATABASE_URL
JDBC_DATABASE_USERNAME
JDBC_DATABASE_PASSWORD
Como você deve saber, o Spring Boot configurará automaticamente seu banco de dados se encontrar spring.datasource.*
propriedades em seu application.properties
arquivo.Aqui está um exemplo do meu application.properties
spring.datasource.url=${JDBC_DATABASE_URL}
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
spring.jpa.show-sql=false
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
Dependências do Hibernate/Postgres
No meu caso, estou usando o Hibernate (empacotado no spring-boot-starter-jpa
com PostgreSQL, então eu precisava das dependências certas no meu build.gradle
:
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile('org.postgresql:postgresql:9.4.1212')
}
Se bem me lembro, tive o mesmo problema e lendo a documentação do Heroku Postgres, descobri que precisava especificar duas propriedades de conexão extras para o DataSource.
Tive que configurar as seguintes propriedades:
- ssl=verdadeiro
- sslfactory=org.postgresql.ssl.NonValidatingFactory
Aqui está um exemplo de bean DataSource:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driverClassName}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
<property name="connectionProperties" value="ssl=true;sslfactory=org.postgresql.ssl.NonValidatingFactory"/>
</bean>
É claro que você precisa adicionar um PostgreSQL dependência de biblioteca.