對(duì)于大多數(shù)流行云PaaS(平臺(tái)即服務(wù))提供商梯皿,Spring Boot的可執(zhí)行jars就是為它們準(zhǔn)備的。這些提供商往往要求你帶上自己的容器县恕;它們管理應(yīng)用的進(jìn)程(不特別針對(duì)Java應(yīng)用程序)东羹,所以它們需要一些中間層來將你的應(yīng)用適配到云概念中的一個(gè)運(yùn)行進(jìn)程。
兩個(gè)流行的云提供商忠烛,Heroku和Cloud Foundry属提,采取一個(gè)打包('buildpack')方法。為了啟動(dòng)你的應(yīng)用程序美尸,不管需要什么垒拢,buildpack都會(huì)將它們打包到你的部署代碼:它可能是一個(gè)JDK和一個(gè)java調(diào)用旬迹,也可能是一個(gè)內(nèi)嵌的webserver,或者是一個(gè)成熟的應(yīng)用服務(wù)器求类。buildpack是可插拔的,但你最好盡可能少的對(duì)它進(jìn)行自定義設(shè)置屹耐。這可以減少不受你控制的功能范圍尸疆,最小化部署和生產(chǎn)環(huán)境的發(fā)散。
理想情況下惶岭,你的應(yīng)用就像一個(gè)Spring Boot可執(zhí)行jar寿弱,所有運(yùn)行需要的東西都打包到它內(nèi)部。
Cloud Foundry
如果不指定其他打包方式按灶,Cloud Foundry會(huì)啟用它提供的默認(rèn)打包方式症革。Cloud Foundry的Java buildpack對(duì)Spring應(yīng)用有出色的支持,包括Spring Boot鸯旁。你可以部署獨(dú)立的可執(zhí)行jar應(yīng)用噪矛,也可以部署傳統(tǒng)的.war形式的應(yīng)用。
-
一旦你構(gòu)建了應(yīng)用(比如铺罢,使用 mvn clean package )并安裝了cf命令行工具艇挨,你可以使用下面的 cf push 命令(將路徑指向你編譯后的.jar)來部署應(yīng)用。在發(fā)布一個(gè)應(yīng)用前韭赘,確保你已登陸cf命令行客戶端缩滨。
$ cf push acloudyspringtime -p target/demo-0.0.1-SNAPSHOT.jar
查看 cf push 文檔獲取更多可選項(xiàng)。如果相同目錄下存在manifest.yml泉瞻,Cloud Foundry會(huì)使用它脉漏。
就此,cf開始上傳你的應(yīng)用:
Uploading acloudyspringtime... OK
Preparing to start acloudyspringtime... OK
-----> Downloaded app package (8.9M)
-----> Java Buildpack source: system
-----> Downloading Open JDK 1.7.0_51 from .../x86_64/openjdk-1.7.0_51.tar.gz (1.8s)
Expanding Open JDK to .java-buildpack/open_jdk (1.2s)
-----> Downloading Spring Auto Reconfiguration from 0.8.7 .../auto-reconfiguration-0.8.7.jar (0.1s)
-----> Uploading droplet (44M)
Checking status of app 'acloudyspringtime'...
0 of 1 instances running (1 starting)
...
0 of 1 instances running (1 down)
...
0 of 1 instances running (1 starting)
...
1 of 1 instances running (1 running)
App started
恭喜袖牙!應(yīng)用現(xiàn)在處于運(yùn)行狀態(tài)侧巨!
檢驗(yàn)部署應(yīng)用的狀態(tài)是很簡(jiǎn)單的:
$ cf apps
Getting applications in ...
OK
name requested state instances memory disk urls
...
acloudyspringtime started 1/1 512M 1G acloudyspringtime.cfapps.io
...
- 一旦Cloud Foundry意識(shí)到你的應(yīng)用已經(jīng)部署,你就可以點(diǎn)擊給定的應(yīng)用URI贼陶,此處是acloudyspringtime.cfapps.io/刃泡。
綁定服務(wù)
- 默認(rèn)情況下,運(yùn)行應(yīng)用的元數(shù)據(jù)和服務(wù)連接信息被暴露為應(yīng)用的環(huán)境變量(比如碉怔,$VCAP_SERVICES)烘贴。采用這種架構(gòu)的原因是因?yàn)镃loud Foundry多語言特性(任何語言和平臺(tái)都支持作為buildpack)。進(jìn)程級(jí)別的環(huán)境變量是語言無關(guān)(language agnostic)的撮胧。
- 環(huán)境變量并不總是有利于設(shè)計(jì)最簡(jiǎn)單的API桨踪,所以Spring Boot自動(dòng)提取它們,然后將這些數(shù)據(jù)導(dǎo)入能夠通過Spring Environment 抽象訪問的屬性里:
@Component
class MyBean implements EnvironmentAware {
private String instanceId;
@Override
public void setEnvironment(Environment environment) {
this.instanceId = environment.getProperty("vcap.application.instance_id");
}
// ...
}
- 所有的Cloud Foundry屬性都以vcap作為前綴芹啥。你可以使用vcap屬性獲取應(yīng)用信息(比如應(yīng)用的公共URL)和服務(wù)信息(比如數(shù)據(jù)庫(kù)證書)锻离。具體參考VcapApplicationListener Javadoc铺峭。
注:Spring Cloud Connectors項(xiàng)目很適合比如配置數(shù)據(jù)源的任務(wù)。Spring Boot提供自動(dòng)配置支持和一個(gè) spring-bootstarter-cloud-connectors starter POM汽纠。
Heroku
-
Heroku是另外一個(gè)流行的Paas平臺(tái)卫键。想要自定義Heroku的構(gòu)建過程,你可以提供一個(gè) Procfile 虱朵,它提供部署一個(gè)應(yīng)用所需的指令莉炉。Heroku為Java應(yīng)用分配一個(gè)端口,確保能夠路由到外部URI碴犬。
web: java -Dserver.port=$PORT -jar target/demo-0.0.1-SNAPSHOT.jar
Spring Boot將 -D 參數(shù)作為屬性絮宁,通過一個(gè)Spring的Environment實(shí)例訪問。 server.port 配置屬性適合于內(nèi)嵌的Tomcat服协,Jetty或Undertow實(shí)例啟用時(shí)使用绍昂。 $PORT 環(huán)境變量被分配給Heroku Paas使用。
-
Heroku默認(rèn)使用Java 1.6偿荷。只要你的Maven或Gradle構(gòu)建時(shí)使用相同的版本就沒問題(Maven用戶可以設(shè)置 java.version 屬性)窘游。如果你想使用JDK 1.7,在你的pom.xml和Procfile臨近處創(chuàng)建一個(gè)system.properties文件遭顶。在該文件中添加以下設(shè)置:
java.runtime.version=1.7
這就是你需要做的一切张峰。對(duì)于Heroku部署來說,經(jīng)常做的工作就是使用 git push 將代碼推送到生產(chǎn)環(huán)境棒旗。
$ git push heroku master
Initializing repository, done.
Counting objects: 95, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (78/78), done.
Writing objects: 100% (95/95), 8.66 MiB | 606.00 KiB/s, done.
Total 95 (delta 31), reused 0 (delta 0)
-----> Java app detected
-----> Installing OpenJDK 1.7... done
-----> Installing Maven 3.2.3... done
-----> Installing settings.xml... done
-----> executing /app/tmp/cache/.maven/bin/mvn -B
-Duser.home=/tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229
-Dmaven.repo.local=/app/tmp/cache/.m2/repository
-s /app/tmp/cache/.m2/settings.xml -DskipTests=true clean install
[INFO] Scanning for projects...
Downloading: http://repo.spring.io/...
Downloaded: http://repo.spring.io/... (818 B at 1.8 KB/sec)
....
Downloaded: http://s3pository.heroku.com/jvm/... (152 KB at 595.3 KB/sec)
[INFO] Installing /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/target/...
[INFO] Installing /tmp/build_0c35a5d2-a067-4abc-a232-14b1fb7a8229/pom.xml ...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 59.358s
[INFO] Finished at: Fri Mar 07 07:28:25 UTC 2014
[INFO] Final Memory: 20M/493M
[INFO] ------------------------------------------------------------------------
-----> Discovering process types
Procfile declares types -> web
-----> Compressing... done, 70.4MB
-----> Launching... done, v6
http://agile-sierra-1405.herokuapp.com/ deployed to Heroku
To git@heroku.com:agile-sierra-1405.git
* [new branch] master -> master
- 現(xiàn)在你的應(yīng)用已經(jīng)啟動(dòng)并運(yùn)行在Heroku喘批。
Openshift
-
Openshift是RedHat公共(和企業(yè))PaaS解決方案。和Heroku相似铣揉,它也是通過運(yùn)行被git提交觸發(fā)的腳本來工作的饶深,所以你可以使用任何你喜歡的方式編寫Spring Boot應(yīng)用啟動(dòng)腳本,只要Java運(yùn)行時(shí)環(huán)境可用(這是在Openshift上可以要求的一個(gè)標(biāo)準(zhǔn)特性)逛拱。為了實(shí)現(xiàn)這樣的效果敌厘,你可以使用DIY Cartridge,并在 .openshift/action_scripts 下hooks你的倉(cāng)庫(kù):
基本模式如下:
1.確保Java和構(gòu)建工具已被遠(yuǎn)程安裝朽合,比如使用一個(gè) pre_build hook(默認(rèn)會(huì)安裝Java和Maven俱两,不會(huì)安裝Gradle)。
2.使用一個(gè) build hook去構(gòu)建你的jar(使用Maven或Gradle)曹步,比如#!/bin/bash cd $OPENSHIFT_REPO_DIR mvn package -s .openshift/settings.xml -DskipTests=true
3.添加一個(gè)調(diào)用 java -jar … 的 start hook
#!/bin/bash
cd $OPENSHIFT_REPO_DIR
nohup java -jar target/*.jar --server.port=${OPENSHIFT_DIY_PORT} -- server.address=${OPENSHIFT_DIY_IP} &
4.使用一個(gè) stop hook
#!/bin/bash
source $OPENSHIFT_CARTRIDGE_SDK_BASH
PID=$(ps -ef | grep java.*\.jar | grep -v grep | awk '{ print $2 }')
if [ -z "$PID" ]
then
client_result "Application is already stopped"
else
kill $PID
fi
5.將內(nèi)嵌的服務(wù)綁定到平臺(tái)提供的在application.properties定義的環(huán)境變量宪彩,比如
spring.datasource.url: jdbc:mysql://${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/${OPENSHIFT_APP_NAME}
spring.datasource.username: ${OPENSHIFT_MYSQL_DB_USERNAME}
spring.datasource.password: ${OPENSHIFT_MYSQL_DB_PASSWORD}
- 在Openshift的網(wǎng)站上有一篇running Gradle in Openshift博客,如果想使用gradle構(gòu)建運(yùn)行的應(yīng)用可以參考它讲婚。由于一個(gè)Gradle bug尿孔,你不能使用高于1.6版本的Gradle。
Google App Engine
- Google App Engine跟Servlet 2.5 API是有聯(lián)系的,所以在不修改的情況下你是不能部署一個(gè)Spring應(yīng)用的活合。具體查看本指南的Servlet 2.5章節(jié) Container.md)雏婶。