1、spring boot內(nèi)置web
spring boot 其默認(rèn)是集成web容器的,啟動(dòng)方式由像普通java程序一樣,main函數(shù)入口啟動(dòng)。其內(nèi)置tomcat容器或jetty容器,具體由配置來(lái)決定(默認(rèn)tomcat)。當(dāng)然你也可以將項(xiàng)目打包成war包,放到獨(dú)立的web容器中(tomcat、weblogic等等),當(dāng)然在此之前你要對(duì)程序入口做簡(jiǎn)單調(diào)整。
對(duì)server的幾個(gè)常用的配置做個(gè)簡(jiǎn)單說(shuō)明:
1
2
3
4
5
6
7
8
9
10
|
# 項(xiàng)目contextpath,一般在正式發(fā)布版本中,我們不配置 server.context-path=/myspringboot # 錯(cuò)誤頁(yè),指定發(fā)生錯(cuò)誤時(shí),跳轉(zhuǎn)的url。請(qǐng)查看basicerrorcontroller源碼便知 server.error.path=/error # 服務(wù)端口 server.port= 9090 # session最大超時(shí)時(shí)間(分鐘),默認(rèn)為 30 server.session-timeout= 60 # 該服務(wù)綁定ip地址,啟動(dòng)服務(wù)器時(shí)如本機(jī)不是該ip地址則拋出異常啟動(dòng)失敗,只有特殊需求的情況下才配置 # server.address= 192.168 . 16.11 |
tomcat
tomcat為spring boot的默認(rèn)容器,下面是幾個(gè)常用配置:
pom.xml依賴(lài)配置:
1
2
3
4
5
|
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-tomcat</artifactid> <!--<scope>provided</scope>--> </dependency> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# tomcat最大線(xiàn)程數(shù),默認(rèn)為 200 server.tomcat.max-threads= 800 # tomcat的uri編碼 server.tomcat.uri-encoding=utf- 8 # 存放tomcat的日志、dump等文件的臨時(shí)文件夾,默認(rèn)為系統(tǒng)的tmp文件夾(如:c:\users\shanhy\appdata\local\temp) server.tomcat.basedir=h:/springboot-tomcat-tmp # 打開(kāi)tomcat的access日志,并可以設(shè)置日志格式的方法: #server.tomcat.access-log-enabled= true #server.tomcat.access-log-pattern= # accesslog目錄,默認(rèn)在basedir/logs #server.tomcat.accesslog.directory= # 日志文件目錄 logging.path=h:/springboot-tomcat-tmp # 日志文件名稱(chēng),默認(rèn)為spring.log logging.file=myapp.log |
jetty
如果你要選擇jetty,也非常簡(jiǎn)單,就是把pom中的tomcat依賴(lài)排除,并加入jetty容器的依賴(lài),如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> <exclusions> <exclusion> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-tomcat</artifactid> </exclusion> </exclusions> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-jetty</artifactid> </dependency> <dependencies> |
項(xiàng)目構(gòu)建我們使用maven或gradle,這將使項(xiàng)目依賴(lài)、jar包管理、以及打包部署變的非常方便。
2、maven構(gòu)建spring boot框架的可執(zhí)行jar包
在spring boot里,很吸引人的一個(gè)特性是可以直接把應(yīng)用打包成為一個(gè)jar/war,然后這個(gè)jar/war是可以直接啟動(dòng)的,不需要另外配置一個(gè)web server。單獨(dú)的jar包,然后通過(guò)java -jar <name>.jar命令運(yùn)行。
1.1 maven
springbootmaven插件為maven提供springboot支持,它允許你打包可執(zhí)行jar或war存檔,然后就地運(yùn)行應(yīng)用。為了使用
它,你需要使用maven 3.2(或更高版本)。
maven用戶(hù)可以繼承spring-boot-starter-parent項(xiàng)目來(lái)獲取合適的默認(rèn)設(shè)置。該父項(xiàng)目提供以下特性:
1、默認(rèn)編譯級(jí)別為java 1.6
2、源碼編碼為utf-8
3、一個(gè)依賴(lài)管理節(jié)點(diǎn),允許你省略普通依賴(lài)的 <version>標(biāo)簽,繼承自 spring-boot-dependenciespom。
4、合適的插件配置(exec插件,surefire,git commitid,shade)
5、針對(duì) application.properties和application.yml 的資源過(guò)濾
6、最后一點(diǎn):由于默認(rèn)配置文件接收spring風(fēng)格的占位符( ${...} ),maven filtering改用@..@ 占位符(你可以使用maven屬性 resource.delimiter來(lái)覆蓋它)。
1.2繼承starter parent
想配置你的項(xiàng)目繼承 spring-boot-starter-parent 只需要簡(jiǎn)單地設(shè)置parent為:
1
2
3
4
5
6
|
<!-- inherit defaults from spring boot --> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version> 1.3 . 0 .build-snapshot</version> </parent> |
注:你應(yīng)該只需要在該依賴(lài)上指定spring boot版本。如他的starters,你可以放心的省略版本號(hào)。
1.3使用沒(méi)有父pom的springboot
不是每個(gè)人都喜歡繼承spring-boot-starter-parentpom。你可能需要使用公司標(biāo)準(zhǔn)parent,或你可能傾向于顯式聲明所有
maven配置。
如果你不使用 spring-boot-starter-parent ,通過(guò)使用一個(gè)scope=import 的依賴(lài),你仍能獲取到依賴(lài)管理的好處:
1
2
3
4
5
6
7
8
9
10
11
12
|
<dependencymanagement> <dependencies> <dependency> <!-- import dependency management from spring boot --> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-dependencies</artifactid> <version> 1.3 . 0 .build-snapshot</version> <type>pom</type> <scope> import </scope> </dependency> </dependencies> </dependencymanagement> |
1.4改變java版本
spring-boot-starter-parent選擇相當(dāng)保守的java兼容策略。如果你遵循我們的建議,使用最新的java版本,你可以添加一
個(gè) java.version屬性:
1
2
3
|
<properties> <java.version> 1.8 </java.version> </properties> |
1.5 使用spring boot maven插件
springboot包含一個(gè)maven插件,它可以將項(xiàng)目打包成一個(gè)可執(zhí)行jar。如果想使用它,你可以將該插件添加到<plugins>節(jié)
點(diǎn)處:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version= "1.0" encoding= "utf-8" ?> <project xmlns= "http://maven.apache.org/pom/4.0.0" xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation= "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelversion> 4.0 . 0 </modelversion> <!-- ... --> <build> <plugins> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> <version> 1.3 . 0 .build-snapshot</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> |
注:如果使用spring-boot-tarter-parent pom,你只需要添加該插件而無(wú)需配置它,除非你想改變定義在partent中的設(shè)置。
該配置會(huì)在maven生命周期的 package階段重新打包一個(gè)jar或war。下面的示例顯示在target目錄下既有重新打包后的jar,
也有原始的jar:
1.6 linux下打包方法:
使用 mvn clean package 命令打包
如果還沒(méi)有安裝maven :
1
|
yum -y install apache-maven |
或者單獨(dú)下載安裝:
1
2
|
wget http: //apache.fayea.com/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz tar zxvf apache-maven- 3.3 . 9 -bin.tar.gz |
設(shè)置環(huán)境變量:
1
2
|
mvn_home=/usr/local/app/apache-maven- 3.3 . 9 export path=$path:$mvn_home/bin |
然后可以使用以下命令編譯:
1
|
mvn clean package |
可以追加參數(shù) -dmaven.test.skip=true 跳過(guò)測(cè)試。
1
2
|
$mvn package $ls target/*.ja |
target/myproject-1.0.0.jartarget/myproject-1.0.0.jar.original
1.6 使用eclipse下打包方法:
打開(kāi)maven插件的maven package,就可以打包了:
打包出來(lái)的文件:
如果不包含像上面那樣的<execution/>,你可以自己運(yùn)行該插件(但只有在package目標(biāo)也被使用的情況)。例如:
1
2
|
$ mvn package spring-boot:repackage $ ls target/*.jar |
target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original
如果使用一個(gè)里程碑或快照版本,你還需要添加正確的pluginrepository元素:
1
2
3
4
5
6
7
8
9
10
|
<pluginrepositories> <pluginrepository> <id>spring-snapshots</id> <url>http: //repo.spring.io/snapshot</url> </pluginrepository> <pluginrepository> <id>spring-milestones</id> <url>http: //repo.spring.io/milestone</url> </pluginrepository> </pluginrepositories> |
打包可執(zhí)行jar和war文件
一旦spring-boot-maven-plugin被包含到你的pom.xml中,它就會(huì)自動(dòng)嘗試使用spring-boot:repackage目標(biāo)重寫(xiě)存檔以使它們能夠執(zhí)行。為了構(gòu)建一個(gè)jar或war,你應(yīng)該使用常規(guī)的packaging元素配置你的項(xiàng)目:
1
2
3
4
5
6
7
|
<?xml version= "1.0" encoding= "utf-8" ?> <project xmlns= "http://maven.apache.org/pom/4.0.0" xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation= "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <!-- ... --> <packaging>jar</packaging> <!-- ... --> </project> |
生成的存檔在 package 階段會(huì)被springboot增強(qiáng)。你想啟動(dòng)的main類(lèi)即可以通過(guò)指定一個(gè)配置選項(xiàng),也可以通過(guò)為manifest添加一個(gè)main-class屬性這種常規(guī)的方式實(shí)現(xiàn)。如果你沒(méi)有指定一個(gè)main類(lèi),該插件會(huì)搜索帶有publicstaticvoidmain(string[]args)方法的類(lèi)。
為了構(gòu)建和運(yùn)行一個(gè)項(xiàng)目的artifact,你可以輸入以下命令:
1
2
|
$ mvn package $ java -jar target/spring-boot01- 1.0 -snapshot.jar |
這種方式,只要控制臺(tái)關(guān)閉,服務(wù)就不能訪(fǎng)問(wèn)了。下面我們使得 jar 包在后臺(tái)運(yùn)行:
java -jar spring-boot01-1.0-snapshot.jar > log.file 2>&1 &
為了構(gòu)建一個(gè)即是可執(zhí)行的,又能部署到一個(gè)外部容器的war文件,你需要標(biāo)記內(nèi)嵌容器依賴(lài)為"provided",例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version= "1.0" encoding= "utf-8" ?> <project xmlns= "http://maven.apache.org/pom/4.0.0" xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation= "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <!-- ... --> <packaging>war</packaging> <!-- ... --> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-tomcat</artifactid> <scope>provided</scope> </dependency> <!-- ... --> </dependencies> </project> |
4、打包為單個(gè)jar時(shí),spring boot的啟動(dòng)方式
maven打包之后,會(huì)生成兩個(gè)jar文件:
- demo-0.0.1-snapshot.jar
- demo-0.0.1-snapshot.jar.original
其中demo-0.0.1-snapshot.jar.original是默認(rèn)的maven-jar-plugin生成的包。
demo-0.0.1-snapshot.jar是spring boot maven插件生成的jar包,里面包含了應(yīng)用的依賴(lài),以及spring boot相關(guān)的類(lèi)。下面稱(chēng)之為fat jar。
先來(lái)查看spring boot打好的包的目錄結(jié)構(gòu)(不重要的省略掉):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
├── meta-inf │ ├── manifest.mf ├── application.properties ├── com │ └── example │ └── springbootdemoapplication. class ├── lib │ ├── aopalliance- 1.0 .jar │ ├── spring-beans- 4.2 . 3 .release.jar │ ├── ... └── org └── springframework └── boot └── loader ├── executablearchivelauncher. class ├── jarlauncher. class ├── javaagentdetector. class ├── launchedurlclassloader. class ├── launcher. class ├── mainmethodrunner. class ├── ... |
依次來(lái)看下這些內(nèi)容。
manifest.mf
1
2
3
4
5
6
7
8
|
manifest-version: 1.0 start- class : com.example.springbootdemoapplication implementation-vendor-id: com.example spring-boot-version: 1.3 . 0 .release created-by: apache maven 3.3 . 3 build-jdk: 1.8 .0_60 implementation-vendor: pivotal software, inc. main- class : org.springframework.boot.loader.jarlauncher |
可以看到有main-class是org.springframework.boot.loader.jarlauncher ,這個(gè)是jar啟動(dòng)的main函數(shù)。
還有一個(gè)start-class是com.example.springbootdemoapplication,這個(gè)是我們應(yīng)用自己的main函數(shù)
1
2
3
4
5
6
7
|
@springbootapplication public class springbootdemoapplication { public static void main(string[] args) { springapplication.run(springbootdemoapplication. class , args); } } |
com/example 目錄
這下面放的是應(yīng)用的.class文件。
lib目錄
這里存放的是應(yīng)用的maven依賴(lài)的jar包文件。
比如spring-beans,spring-mvc等jar。
org/springframework/boot/loader 目錄
這下面存放的是spring boot loader的.class文件。
啟動(dòng):
我們直接啟動(dòng):java -jar demo-0.0.1-snapshot.jar
5、maven添加本地jar包
我們有時(shí)候項(xiàng)目依賴(lài)外部的jar,我們使用eclipse開(kāi)發(fā)的時(shí)候我們直接通過(guò)build path添加jar就可以,但是使用mvn 打包的時(shí)候就會(huì)缺少這個(gè)包。
1. 使用system scope
我們直接引入rabbitmq-client.jar。這個(gè)方式比較靈活,到新的服務(wù)器上,無(wú)需做額外的操作。
1
2
3
4
5
6
7
|
<dependency> <groupid>rabbitmq.client</groupid> <artifactid>rabbitmq.client</artifactid> <version> 3.0 </version> <scope>system</scope> <systempath>${basedir}/src/main/web-inf/lib/rabbitmq-client.jar</systempath> </dependency> |
1、groupid和artifactid以及version都是可以隨便填寫(xiě)的 ,scope必須填寫(xiě)為system,而systempath我們現(xiàn)在我們jar包的目錄地址就可以了
2、${basedir}就是項(xiàng)目根目錄
2. 將jar包安裝到本地repository中
這個(gè)需要在新機(jī)器上執(zhí)行mvn install:install-file命令。
1
2
3
4
5
6
7
|
mvn install:install-file -dfile= jar文件所存放的地址 -dgroupid= jar文件所屬的group:包名 -dartifactid= jar的項(xiàng)目名 名稱(chēng),一般就是去掉后綴的文件名 -dversion=版本號(hào) -dpackaging=jar:此包的打包形式,就是jar -dgeneratepom= true |
例如執(zhí)行命令:
mvn install:install-file -dfile=d:\jar_lib\rabbitmq-client.jar -dgroupid=com.rabbitmq -dartifactid=client -dversion=3.5.0 -dpackaging=jar -dgeneratepom=true -dcreatechecksum=true
在項(xiàng)目中引用:
1
2
3
4
5
|
<dependency> <groupid>com.rabbitmq</groupid> <artifactid>client</artifactid> <version> 3.5 . 0 </version> </dependency> |
3、添加 in project repository
設(shè)置項(xiàng)目的庫(kù)目錄
1
2
3
4
5
6
7
8
9
|
<repository> <id>in-project</id> <name>in project repo</name> <url>file: //${project.basedir}/lib</url> </repository> |
添加依賴(lài):
1
2
3
4
5
6
7
8
9
|
<dependency> <groupid>com.rabbitmq</groupid> <artifactid>client</artifactid> <version> 3.5 . 0 </version> </dependency> |
jar包及路徑必須嚴(yán)格遵循格式:
/groupid/artifactid/version/artifactid-verion.jar
本例中: lib/com/rabbitmq/client/3.5.0/rabbitmq-client-3.5.0.jar
6、部署到j(luò)avaee容器
修改啟動(dòng)類(lèi),繼承 springbootservletinitializer 并重寫(xiě) configure 方法
1
2
3
4
5
6
7
8
9
10
|
public class springbootsampleapplication extends springbootservletinitializer{ private static final logger logger = loggerfactory.getlogger(springbootsampleapplication. class ); @override protected springapplicationbuilder configure(springapplicationbuilder builder) { return builder.sources( this .getclass()); } } |
修改pom文件中jar 為 war
1
2
|
<!-- <packaging>jar</packaging> --> <packaging>war</packaging> |
修改pom,排除tomcat插件
1
2
3
4
5
6
7
8
9
10
|
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> <exclusions> <exclusion> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-tomcat</artifactid> </exclusion> </exclusions> </dependency> |
打包部署到容器
7、熱部署
在我們開(kāi)發(fā)過(guò)程中,我們需要經(jīng)常修改,為了避免重復(fù)啟動(dòng)項(xiàng)目,我們可以啟用熱部署。
spring-loaded項(xiàng)目提供了強(qiáng)大的熱部署功能,添加/刪除/修改 方法/字段/接口/枚舉 等代碼的時(shí)候都可以熱部署,速度很快,很方便。
想在spring boot中使用該功能非常簡(jiǎn)單,就是在spring-boot-maven-plugin插件下面添加依賴(lài):
1
2
3
4
5
6
7
|
<dependencies> <dependency> <groupid>org.springframework</groupid> <artifactid>springloaded</artifactid> <version> 1.2 . 5 .release</version> </dependency> </dependencies> |
添加以后,通過(guò)mvn spring-boot:run啟動(dòng)就支持熱部署了。
注意:使用熱部署的時(shí)候,需要ide編譯類(lèi)后才能生效,你可以打開(kāi)自動(dòng)編譯功能,這樣在你保存修改的時(shí)候,類(lèi)就自動(dòng)重新加載了。
8、使用profile區(qū)分環(huán)境
application.properties區(qū)分環(huán)境
spring boot 可以在 “配置文件”、“java代碼類(lèi)”、“日志配置” 中來(lái)配置profile區(qū)分不同環(huán)境執(zhí)行不同的結(jié)果
1、配置文件
使用配置文件application.yml 和 application.properties 有所區(qū)別
以application.properties 為例,通過(guò)文件名來(lái)區(qū)分環(huán)境 application-{profile}.properties
1
2
3
4
5
6
7
8
9
10
11
|
application.properties app.name=myapp server.port= 8080 spring.profiles.active=dev application-dev.properties server.port= 8081 application-stg.properties server.port= 8082 |
在啟動(dòng)程序的時(shí)候通過(guò)添加 –spring.profiles.active={profile} 來(lái)指定具體使用的配置
例如我們執(zhí)行 java -jar demo.jar –spring.profiles.active=dev 那么上面3個(gè)文件中的內(nèi)容將被如何應(yīng)用?
spring boot 會(huì)先加載默認(rèn)的配置文件,然后使用具體指定的profile中的配置去覆蓋默認(rèn)配置。
app.name 只存在于默認(rèn)配置文件 application.properties 中,因?yàn)橹付ōh(huán)境中不存在同樣的配置,所以該值不會(huì)被覆蓋
server.port 默認(rèn)為8080,但是我們指定了環(huán)境后,將會(huì)被覆蓋。如果指定stg環(huán)境,server.port 則為 8082
spring.profiles.active 默認(rèn)指定dev環(huán)境,如果我們?cè)谶\(yùn)行時(shí)指定 –spring.profiles.active=stg 那么將應(yīng)用stg環(huán)境,最終 server.port 的值為8082
maven環(huán)境配置
項(xiàng)目工程統(tǒng)一使用maven的profile插件定義不同的項(xiàng)目構(gòu)建環(huán)境(dev, alpha, beta, prod),通過(guò)filter插件為不同環(huán)境下的配置項(xiàng)注入對(duì)應(yīng)的參數(shù)值來(lái)實(shí)現(xiàn)動(dòng)態(tài)配置目標(biāo)。
2定義profile
在pom.xml中配置四個(gè)profile,對(duì)應(yīng)項(xiàng)目所處的四個(gè)不同的環(huán)境-dev, alpha, beta, prod, profile的id屬性即為每個(gè)環(huán)境賦予一個(gè)唯一的標(biāo)示,元素的內(nèi)容則是以key-value的形式出現(xiàn)的鍵值對(duì),如我們定義了一個(gè)變量,其值在不同的環(huán)境下(不同id)被賦予了不同的值(dev, test, pre-prod, prod),要激活不同的環(huán)境打包,我們可以在命令行通過(guò)mvn package –p${profileid}來(lái)讓其運(yùn)行,為了開(kāi)發(fā)便利,默認(rèn)激活的是dev開(kāi)發(fā)環(huán)境,即開(kāi)發(fā)人員不需要通過(guò)命令行手動(dòng)輸入-p參數(shù)也能運(yùn)行dev環(huán)境的打包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<profile> <!-- 本地參數(shù) --> <id>dev</id> <properties> <server.port> 8081 </server.port> <server.address> 0.0 . 0.0 </server.address> <profileactive>dev</profileactive> </properties> <build> <filters> <filter> <groupid>${basedir}/src/main/resources/dev.properties</groupid> </filter> </profile> |
9、創(chuàng)建一個(gè)linux 應(yīng)用的sh腳本
下面幾個(gè)腳本僅供參考:
打包:clean.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 0 、check user time_stamp=`date +%y%m%d%h%m` who=`whoami` if [ "$who" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi code_home=/home/www/app projectname=qrealtime cd $code_home/$projectname git pull mvn clean package pid=`ps -ef |grep $projectname |grep -v "grep" |awk '{print $2}' ` if [ $pid != "" ]; then echo "app is running and pid=$pid" else echo "app is not running." fi |
start.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 0 、check user time_stamp=`date +%y%m%d%h%m` who=`whoami` if [ "$who" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi code_home=/home/www/app projectname=qrealtime cd $code_home/$projectname pid=`ps -ef |grep $projectname |grep -v "grep" |awk '{print $2}' ` if [ $pid ]; then echo "app is running and pid=$pid" else nohup java -jar $code_home/$projectname/target/$<span style= "font-family: 'microsoft yahei';" >projectname</span><span style= "font-family: 'microsoft yahei';" >- 0.0 . 1 -snapshot.jar > /dev/ null 2 >& 1 &</span> fi |
stop.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 0 、check user time_stamp=`date +%y%m%d%h%m` who=`whoami` if [ "$who" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi code_home=/home/www/app projectname=qrealtime cd $code_home/$projectname pid=`ps -ef |grep $projectname |grep -v "grep" |awk '{print $2}' ` if [ $pid ]; then echo "app is running and pid=$pid" kill - 9 $pid if [[ $? -eq 0 ]];then echo "sucess to stop $projectname " else echo "fail to stop $projectname " fi fi |
restart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 0 、check user time_stamp=`date +%y%m%d%h%m` who=`whoami` if [ "$who" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi code_home=/home/www/app projectname=qrealtime cd $code_home/$projectname pid=`ps -ef |grep $projectname |grep -v "grep" |awk '{print $2}' ` if [ $pid ]; then echo "app is running and pid=$pid" kill - 9 $pid fi nohup java -jar $code_home/$projectname/target/$projectname- 0.0 . 1 -snapshot.jar > /dev/ null 2 >& 1 & |
10、spring boot應(yīng)用的docker化
首先看spring boot應(yīng)用程序的docker化,由于spring boot內(nèi)嵌了tomcat、jetty等容器,因此我們對(duì)docker鏡像的要求就是需要java運(yùn)行環(huán)境。我的應(yīng)用代碼的的dockerfile文件如下:
1
2
3
4
5
6
7
8
9
10
|
#基礎(chǔ)鏡像:倉(cāng)庫(kù)是java,標(biāo)簽用8u66-jdk from java:8u66-jdk #當(dāng)前鏡像的維護(hù)者和聯(lián)系方式 maintainer duqi duqi @example .com #將打包好的spring程序拷貝到容器中的指定位置 add target/bookpub- 0.0 . 1 -snapshot.jar /opt/bookpub- 0.0 . 1 -snapshot.jar #容器對(duì)外暴露 8080 端口 expose 8080 #容器啟動(dòng)后需要執(zhí)行的命令 cmd java -djava.security.egd=file:/dev/./urandom -jar /opt/bookpub- 0.0 . 1 -snapshot.jar |
因?yàn)槟壳暗氖纠绦虮容^簡(jiǎn)單,這個(gè)dockerfile并沒(méi)有在將應(yīng)用程序的數(shù)據(jù)存放在宿主機(jī)上。如果你的應(yīng)用程序需要寫(xiě)文件系統(tǒng),例如日志,最好利用volume /tmp命令,這個(gè)命令的效果是:在宿主機(jī)的/var/lib/docker目錄下創(chuàng)建一個(gè)臨時(shí)文件并把它鏈接到容器中的/tmp目錄。
把這個(gè)dockerfile放在項(xiàng)目的根目錄下即可,后續(xù)通過(guò)docker-compose build統(tǒng)一構(gòu)建:基礎(chǔ)鏡像是只讀的,然后會(huì)在該基礎(chǔ)鏡像上增加新的可寫(xiě)層來(lái)供我們使用,因此java鏡像只需要下載一次。
docker-compose是用來(lái)做docker服務(wù)編排,參看《docker從入門(mén)到實(shí)踐》中的解釋?zhuān)?/p>
compose 項(xiàng)目目前在 github 上進(jìn)行維護(hù),目前最新版本是 1.2.0。compose 定位是“defining and running complex applications with docker”,前身是 fig,兼容 fig 的模板文件。
dockerfile 可以讓用戶(hù)管理一個(gè)單獨(dú)的應(yīng)用容器;而 compose 則允許用戶(hù)在一個(gè)模板(yaml 格式)中定義一組相關(guān)聯(lián)的應(yīng)用容器(被稱(chēng)為一個(gè) project,即項(xiàng)目),例如一個(gè) web 服務(wù)容器再加上后端的數(shù)據(jù)庫(kù)服務(wù)容器等。
單個(gè)docker用起來(lái)確實(shí)沒(méi)什么用,docker技術(shù)的關(guān)鍵在于持續(xù)交付,通過(guò)與jekins的結(jié)合,可以實(shí)現(xiàn)這樣的效果:開(kāi)發(fā)人員提交push,然后jekins就自動(dòng)構(gòu)建并測(cè)試剛提交的代碼,這就是我理解的持續(xù)交付。
11、守護(hù)進(jìn)程啟動(dòng)
使用java命令運(yùn)行應(yīng)用非常簡(jiǎn)單,但是通常我們都是通過(guò)ssh命令連接到服務(wù)器并運(yùn)行它,一旦ssh連接斷開(kāi),那么由它fork的java子進(jìn)程也就隨之銷(xiāo)毀了。所以我們必須借助工具將應(yīng)用作為服務(wù)運(yùn)行在服務(wù)器上:
systemd
systemd 是linux 下的一款系統(tǒng)和服務(wù)管理器。可以為spring boot應(yīng)用編寫(xiě)啟動(dòng)腳本:
1
2
3
4
5
6
7
8
9
|
[unit] description=spring boot application [service] execstart=/usr/bin/java -jar location_of_jar_file.jar --spring.config.location=location_of_config.properties --spring.profiles.active=profile user=${your expected user} [install] wantedby=multi-user.target |
supervisord
supervisord配置:
1
2
3
4
5
6
7
|
[program:app] command=/usr/bin/java -jar location_of_jar_file.jar --spring.config.location=location_of_config.properties --spring.profiles.active=profile user=${your expected user} autostart= true autorestart= true startsecs= 10 startretries= 3 |
12、生產(chǎn)環(huán)境運(yùn)維支持
與開(kāi)發(fā)和測(cè)試環(huán)境不同的是,當(dāng)應(yīng)用部署到生產(chǎn)環(huán)境時(shí),需要各種運(yùn)維相關(guān)的功能的支持,包括性能指標(biāo)、運(yùn)行信息和應(yīng)用管理等。所有這些功能都有很多技術(shù)和開(kāi)源庫(kù)可以實(shí)現(xiàn)。spring boot 對(duì)這些運(yùn)維相關(guān)的功能進(jìn)行了整合,形成了一個(gè)功能完備和可定制的功能集,稱(chēng)之為 actuator。只需要在 pom 文件中增加對(duì) “org.springframe.boot:spring-boot-starter-actuator” 的依賴(lài)就可以添加 actuator。actuator 在添加之后,會(huì)自動(dòng)暴露一些 http 服務(wù)來(lái)提供這些信息。這些 http 服務(wù)的說(shuō)明如表 2。
spring boot actuator 所提供的 http 服務(wù)
名稱(chēng) | 說(shuō)明 | 是否包含敏感信息 |
---|---|---|
autoconfig | 顯示 spring boot 自動(dòng)配置的信息。 | 是 |
beans | 顯示應(yīng)用中包含的 spring bean 的信息。 | 是 |
configprops | 顯示應(yīng)用中的配置參數(shù)的實(shí)際值。 | 是 |
dump | 生成一個(gè) thread dump。 | 是 |
env | 顯示從 configurableenvironment 得到的環(huán)境配置信息。 | 是 |
health | 顯示應(yīng)用的健康狀態(tài)信息。 | 否 |
info | 顯示應(yīng)用的基本信息。 | 否 |
metrics | 顯示應(yīng)用的性能指標(biāo)。 | 是 |
mappings |
顯示 spring mvc 應(yīng)用中通過(guò)“ @requestmapping”添加的路徑映射。 |
是 |
shutdown | 關(guān)閉應(yīng)用。 | 是 |
trace | 顯示應(yīng)用相關(guān)的跟蹤(trace)信息。 | 是 |
對(duì)于表中的每個(gè)服務(wù),通過(guò)訪(fǎng)問(wèn)名稱(chēng)對(duì)應(yīng)的 url 就可以獲取到相關(guān)的信息。如訪(fǎng)問(wèn)“/info”就可以獲取到 info 服務(wù)對(duì)應(yīng)的信息。服務(wù)是否包含敏感信息說(shuō)明了該服務(wù)暴露出來(lái)的信息是否包含一些比較敏感的信息,從而確定是否需要添加相應(yīng)的訪(fǎng)問(wèn)控制,而不是對(duì)所有人都公開(kāi)。所有的這些服務(wù)都是可以配置的,比如通過(guò)改變名稱(chēng)來(lái)改變相應(yīng)的 url。下面對(duì)幾個(gè)重要的服務(wù)進(jìn)行介紹。
health 服務(wù)
spring boot 默認(rèn)提供了對(duì)應(yīng)用本身、關(guān)系數(shù)據(jù)庫(kù)連接、mongodb、redis 和 rabbit mq 的健康狀態(tài)的檢測(cè)功能。當(dāng)應(yīng)用中添加了 datasource 類(lèi)型的 bean 時(shí),spring boot 會(huì)自動(dòng)在 health 服務(wù)中暴露數(shù)據(jù)庫(kù)連接的信息。應(yīng)用也可以提供自己的健康狀態(tài)信息,如代碼清單 7 所示。
health 服務(wù)
1
2
3
4
5
6
7
|
@component public class apphealthindicator implements healthindicator { @override public health health() { return health.up().build(); } } |
應(yīng)用只需要實(shí)現(xiàn) org.springframework.boot.actuate.health.healthindicator 接口,并返回一個(gè) org.springframework.boot.actuate.health.health 對(duì)象,就可以通過(guò) health 服務(wù)來(lái)獲取所暴露的信息。health 服務(wù)返回的
結(jié)果
{"status":"up","app":{"status":"up"},"db":{"status":"up","database":"hsql database engine","hello":1}}
info 服務(wù)
info 服務(wù)所暴露的信息是完全由應(yīng)用來(lái)確定的。應(yīng)用中任何以“info.”開(kāi)頭的配置參數(shù)會(huì)被自動(dòng)的由 info 服務(wù)來(lái)暴露。只需要往 application.properties 中添加以“info.”開(kāi)頭的參數(shù)即可,如:
1
2
|
info.app_name=my first spring boot application info.app_version= 1.0 . 0 |
當(dāng)訪(fǎng)問(wèn)“/info”時(shí),訪(fǎng)問(wèn)的 json 數(shù)據(jù):{"app_name":"my first spring boot application","app_version":"1.0.0"}
metrics 服務(wù)
當(dāng)訪(fǎng)問(wèn) metrics 服務(wù)時(shí),可以看到 spring boot 通過(guò) systempublicmetrics 默認(rèn)提供的一些系統(tǒng)的性能參數(shù)值,包括內(nèi)存、cpu、java 類(lèi)加載和線(xiàn)程等的基本信息。應(yīng)用可以記錄其他所需要的信息。spring boot 默認(rèn)提供了兩種類(lèi)型的性能指標(biāo)記錄方式:gauge 和 counter。gauge 用來(lái)記錄單個(gè)絕對(duì)數(shù)值,counter 用來(lái)記錄增量或減量值。比如在一個(gè) web 應(yīng)用中,可以用 counter 來(lái)記錄當(dāng)前在線(xiàn)的用戶(hù)數(shù)量。當(dāng)用戶(hù)登錄時(shí),把 counter 的值加 1;當(dāng)用戶(hù)退出時(shí),把 counter 的值減 1。
示例:
1
2
3
4
5
6
7
8
9
10
|
@restcontroller public class greetingscontroller { @autowired private counterservice counterservice; @requestmapping ( "/greet" ) public string greet() { counterservice.increment( "myapp.greet.count" ); return "hello!" ; } } |
上面代碼添加了對(duì) spring boot 提供的 counterservice 的依賴(lài)。當(dāng) greet 方法被調(diào)用時(shí),會(huì)把名稱(chēng)為“myapp.greet.count”的計(jì)數(shù)器的值加 1。也就是當(dāng)用戶(hù)每次訪(fǎng)問(wèn)“/greet”時(shí),該計(jì)算器就會(huì)被加 1。除了 counterservice 之外,還可以使用 gaugeservice 來(lái)記錄絕對(duì)值。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://blog.csdn.net/hguisu/article/details/51072683