我有一个基于Spring Boot的小型应用程序 ,该应用程序使用Postgres数据库作为数据存储。
我想记录将示例应用程序部署到Cloud Foundry的步骤 。 Spring Boot参考指南中描述了一些步骤 ,但是这些指南并未充分说明如何与基于云的环境中提供的数据存储集成。 Spring-cloud提供了连接在云上部署的基于Spring的应用程序以发现并连接到绑定服务的胶水,因此第一步是使用以下pom条目将Spring-cloud库引入项目中:
org.springframework.cloud
spring-cloud-spring-service-connector
1.0.0.RELEASE
org.springframework.cloud
spring-cloud-cloudfoundry-connector
1.0.0.RELEASE
一旦引入了这种依赖性,就很容易连接到绑定的服务,只需按照以下方式定义配置:
@Configuration
public class PostgresCloudConfig extends AbstractCloudConfig {
@Bean
public DataSource dataSource() {
return connectionFactory().dataSource();
}
}
Spring-Cloud理解该应用程序已部署在特定的云上(当前的Cloud Foundry和Heroku通过查找已部署的Cloud平台的某些特征),发现了绑定的服务,认识到存在一个绑定的服务,基于Postgres的数据源可以使用该绑定服务创建并返回数据源作为Spring bean。 现在,该应用程序可以干净地部署到基于Cloud Foundry的云中。 可以在使用bosh-lite部署的Cloud Foundry版本中试用该示例应用程序,这是在Cloud Foundry启动并使用bosh-lite运行后我机器中的步骤的样子:以下命令在以下位置创建用户提供的服务Cloud Foundry:
cf create-user-provided-service psgservice -p '{"uri":"postgres://postgres:[email protected]:5432/hotelsdb"}'
现在,推动应用程序,但是不要启动它。 一旦以上服务绑定到应用程序,我们就可以这样做:
cf push spring-boot-mvc-test -p target/spring-boot-mvc-test-1.0.0-SNAPSHOT.war --no-start
将服务绑定到应用程序并重新启动应用程序:
cf bind-service spring-boot-mvc-test psgservice
cf restart spring-boot-mvc-test
本质上就是这样,理想情况下,Spring Cloud应该接管并干净地解析来自绑定服务的凭证,该凭证在Cloud Foundry中转换为称为VCAP_SERVICES的环境变量,并从中创建数据源。 但是,这种方法存在一个问题–一旦使用spring-cloud方法创建了数据源bean,它就不再在本地环境中工作。 为此,可能的解决方法是使用Spring配置文件,假设在返回基于Spring-cloud的数据源的Cloud环境中有一个不同的“ cloud” Spring配置文件可用:
@Profile("cloud")
@Configuration
public class PostgresCloudConfig extends AbstractCloudConfig {
@Bean
public DataSource dataSource() {
return connectionFactory().dataSource();
}
}
并让Spring-boot自动配置在默认的本地环境中创建数据源,这样配置既可以在本地也可以在Cloud中工作。 该“云”配置文件来自何处,可以使用ApplicationContextInitializer创建它,并采用以下方式:
public class SampleWebApplicationInitializer implements ApplicationContextInitializer {
private static final Log logger = LogFactory.getLog(SampleWebApplicationInitializer.class);
@Override
public void initialize(AnnotationConfigEmbeddedWebApplicationContext applicationContext) {
Cloud cloud = getCloud();
ConfigurableEnvironment appEnvironment = applicationContext.getEnvironment();
if (cloud!=null) {
appEnvironment.addActiveProfile("cloud");
}
logger.info("Cloud profile active");
}
private Cloud getCloud() {
try {
CloudFactory cloudFactory = new CloudFactory();
return cloudFactory.getCloud();
} catch (CloudException ce) {
return null;
}
}
}
该初始化程序利用Spring-cloud的扫描功能来激活“云”配置文件。 我想尝试的最后一件事是在Spring-Cloud的眼中使我的本地设备表现得至少像Cloud,这可以通过添加一些环境变量来完成,Spring-Cloud使用这些环境变量来确定云的类型。应用程序已部署,以下是我在本地的启动脚本,该应用程序假装成好像已部署在Cloud Foundry中:
read -r -d '' VCAP_APPLICATION <<'ENDOFVAR'
{"application_version":"1","application_name":"spring-boot-mvc-test","application_uris":[""],"version":"1.0","name":"spring-boot-mvc-test","instance_id":"abcd","instance_index":0,"host":"0.0.0.0","port":61008}
ENDOFVAR
export VCAP_APPLICATION=$VCAP_APPLICATION
read -r -d '' VCAP_SERVICES <<'ENDOFVAR'
{"postgres":[{"name":"psgservice","label":"postgresql","tags":["postgresql"],"plan":"Standard","credentials":{"uri":"postgres://postgres:[email protected]:5432/hotelsdb"}}]}
ENDOFVAR
export VCAP_SERVICES=$VCAP_SERVICES
mvn spring-boot:run
- 可以在以下 github位置获得整个示例: https : //github.com/bijukunjummen/spring-boot-mvc-test
结论
Spring Boot和Spring-Cloud项目现在提供了一个出色的工具集,可以创建支持Spring的云就绪应用程序,希望这些说明对将Spring Boot与Spring-Cloud集成以及将它们用于无缝的本地和云部署有用。
翻译自: https://www.javacodegeeks.com/2014/08/deploying-a-spring-boot-application-to-cloud-foundry-with-spring-cloud.html