Spring boot(4)-應用打包部署

 

摘自: http://blog.csdn.net/hguisu/article/details/51072683html

 

一、Spring Boot內置web

 

 

   spring Boot 其默認是集成web容器的,啓動方式由像普通Java程序同樣,main函數入口啓動。其內置Tomcat容器或Jetty容器,具體由配置來決定(默認Tomcat)。固然你也能夠將項目打包成war包,放到獨立的web容器中(Tomcat、weblogic等等),固然在此以前你要對程序入口作簡單調整。java

對server的幾個經常使用的配置作個簡單說明:mysql

 

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. # 項目contextPath,通常在正式發佈版本中,咱們不配置  
  2. server.context-path=/myspringboot  
  3. # 錯誤頁,指定發生錯誤時,跳轉的URL。請查看BasicErrorController源碼便知  
  4. server.error.path=/error  
  5. # 服務端口  
  6. server.port=9090  
  7. # session最大超時時間(分鐘),默認爲30  
  8. server.session-timeout=60  
  9. # 該服務綁定IP地址,啓動服務器時如本機不是該IP地址則拋出異常啓動失敗,只有特殊需求的狀況下才配置  
  10. # server.address=192.168.16.11  

 

Tomcat 
Tomcat爲Spring Boot的默認容器,下面是幾個經常使用配置:linux

pom.xml依賴配置:git

     <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<scope>provided</scope>-->
</dependency>web

 

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. # tomcat最大線程數,默認爲200  
  2. server.tomcat.max-threads=800  
  3. # tomcat的URI編碼  
  4. server.tomcat.uri-encoding=UTF-8  
  5. # 存放Tomcat的日誌、Dump等文件的臨時文件夾,默認爲系統的tmp文件夾(如:C:\Users\Shanhy\AppData\Local\Temp)  
  6. server.tomcat.basedir=H:/springboot-tomcat-tmp  
  7. # 打開Tomcat的Access日誌,並能夠設置日誌格式的方法:  
  8. #server.tomcat.access-log-enabled=true  
  9. #server.tomcat.access-log-pattern=  
  10. # accesslog目錄,默認在basedir/logs  
  11. #server.tomcat.accesslog.directory=  
  12. # 日誌文件目錄  
  13. logging.path=H:/springboot-tomcat-tmp  
  14. # 日誌文件名稱,默認爲spring.log  
  15. logging.file=myapp.log  

Jetty 
若是你要選擇Jetty,也很是簡單,就是把pom中的tomcat依賴排除,並加入Jetty容器的依賴,以下:redis

 

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <dependencies>  
  2.   <dependency>  
  3.     <groupId>org.springframework.boot</groupId>  
  4.     <artifactId>spring-boot-starter-web</artifactId>  
  5.     <exclusions>  
  6.       <exclusion>  
  7.         <groupId>org.springframework.boot</groupId>  
  8.         <artifactId>spring-boot-starter-tomcat</artifactId>  
  9.       </exclusion>  
  10.     </exclusions>  
  11.   </dependency>  
  12.   <dependency>  
  13.     <groupId>org.springframework.boot</groupId>  
  14.     <artifactId>spring-boot-starter-jetty</artifactId>  
  15.   </dependency>  
  16. <dependencies>   

 

項目構建咱們使用Maven或Gradle,這將使項目依賴、jar包管理、以及打包部署變的很是方便。spring

 

二、Maven構建Spring Boot框架的可執行Jar包

 

      在spring boot裏,很吸引人的一個特性是能夠直接把應用打包成爲一個jar/war,而後這個jar/war是能夠直接啓動的,不須要另外配置一個Web Server。單獨的JAR包,而後經過Java -jar <name>.jar命令運行。sql

 

1.1 Mavenmongodb

 

     SpringBootMaven插件爲Maven提供SpringBoot支持,它容許你打包可執行jar或war存檔,而後就地運行應用。爲了使用
它,你須要使用Maven 3.2(或更高版本)。

 

      Maven用戶能夠繼承spring-boot-starter-parent項目來獲取合適的默認設置。該父項目提供如下特性:
一、默認編譯級別爲Java 1.6
二、源碼編碼爲UTF-8
三、一個依賴管理節點,容許你省略普通依賴的 <version>標籤,繼承自 spring-boot-dependenciesPOM。
      合適的資源過濾
四、合適的插件配置(exec插件,surefire,Git commitID,shade)
五、針對 application.properties和application.yml 的資源過濾
六、最後一點:因爲默認配置文件接收Spring風格的佔位符( ${...} ),Maven  filtering改用@..@ 佔位符(你可使用Maven屬性 resource.delimiter來覆蓋它)。

1.2繼承starter parent
 
想配置你的項目繼承  spring-boot-starter-parent 只須要簡單地設置parent爲:
[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <!-- Inherit defaults    from    Spring  Boot    -->  
  2. <parent>  
  3. <groupId>org.springframework.boot</groupId>  
  4. <artifactId>spring-boot-starter-parent</artifactId>  
  5. <version>1.3.0.BUILD-SNAPSHOT</version>  
  6. </parent>  

注:你應該只須要在該依賴上指定Spring Boot版本。如他的starters,你能夠放心的省略版本號。
 
 
1.3使用沒有父POM的SpringBoot
      不是每一個人都喜歡繼承spring-boot-starter-parentPOM。你可能須要使用公司標準parent,或你可能傾向於顯式聲明全部
Maven配置。
若是你不使用 spring-boot-starter-parent ,經過使用一個scope=import 的依賴,你仍能獲取到依賴管理的好處:
[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <dependencyManagement>  
  2. <dependencies>  
  3. <dependency>  
  4. <!-- Import  dependency  management  from    Spring  Boot    -->  
  5. <groupId>org.springframework.boot</groupId>  
  6. <artifactId>spring-boot-dependencies</artifactId>  
  7. <version>1.3.0.BUILD-SNAPSHOT</version>  
  8. <type>pom</type>  
  9. <scope>import</scope>  
  10. </dependency>  
  11. </dependencies>  
  12. </dependencyManagement>  


1.4改變Java版本

 

spring-boot-starter-parent選擇至關保守的Java兼容策略。若是你遵循咱們的建議,使用最新的Java版本,你能夠添加一
個 java.version屬性:
<properties>
<java.version>1.8</java.version>
</properties>

1.5 使用Spring Boot Maven插件

SpringBoot包含一個Maven插件,它能夠將項目打包成一個可執行jar。若是想使用它,你能夠將該插件添加到<plugins>節
點處:

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <?xml    version="1.0"   encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4. <modelVersion>4.0.0</modelVersion>  
  5. <!-- ... -->  
  6. <build>  
  7. <plugins>  
  8. <plugin>  
  9. <groupId>org.springframework.boot</groupId>  
  10. <artifactId>spring-boot-maven-plugin</artifactId>  
  11. <version>1.3.0.BUILD-SNAPSHOT</version>  
  12. <executions>  
  13. <execution>  
  14. <goals>  
  15. <goal>repackage</goal>  
  16. </goals>  
  17. </execution>  
  18. </executions>  
  19. </plugin>  
  20. </plugins>  
  21. </build>  
  22. </project>  



注:若是使用Spring-Boot-tarter-parent pom,你只須要添加該插件而無需配置它,除非你想改變定義在partent中的設置。

 

 

該配置會在Maven生命週期的 package階段從新打包一個jar或war。下面的示例顯示在target目錄下既有從新打包後的jar,
也有原始的jar:

 

1.6 Linux下打包方法: 

 

 

使用 mvn clean package 命令打包
若是尚未安裝maven :

yum -y install apache-maven

 

或者單獨下載安裝:
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 
設置環境變量:
MVN_HOME=/usr/local/app/apache-maven-3.3.9
export PATH=$PATH:$MVN_HOME/bin


而後可使用如下命令編譯:
mvn clean package

能夠追加參數 -Dmaven.test.skip=true 跳過測試。 

 

 

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. $mvn    package  
  2. $ls target/*.ja  

target/myproject-1.0.0.jartarget/myproject-1.0.0.jar.original

 

1.6 使用Eclipse下打包方法: 

打開maven插件的maven package,就能夠打包了:

 

打包出來的文件:

若是不包含像上面那樣的<execution/>,你能夠本身運行該插件(但只有在package目標也被使用的狀況)。例如:

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. $   mvn package spring-boot:repackage  
  2. $   ls  target/*.jar  


target/myproject-1.0.0.jar target/myproject-1.0.0.jar.original
若是使用一個里程碑或快照版本,你還須要添加正確的pluginRepository元素:

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <pluginRepositories>  
  2. <pluginRepository>  
  3. <id>spring-snapshots</id>  
  4. <url>http://repo.spring.io/snapshot</url>  
  5. </pluginRepository>  
  6. <pluginRepository>  
  7. <id>spring-milestones</id>  
  8. <url>http://repo.spring.io/milestone</url>  
  9. </pluginRepository>  
  10. </pluginRepositories>  



 

打包可執行jar和war文件

一旦spring-boot-maven-plugin被包含到你的pom.xml中,它就會自動嘗試使用spring-boot:repackage目標重寫存檔以使它們可以執行。爲了構建一個jar或war,你應該使用常規的packaging元素配置你的項目:

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <?xml    version="1.0"   encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4. <!-- ... -->  
  5. <packaging>jar</packaging>  
  6. <!-- ... -->  
  7. </project>  

 

 


生成的存檔在 package 階段會被SpringBoot加強。你想啓動的main類便可以經過指定一個配置選項,也能夠經過爲manifest添加一個Main-Class屬性這種常規的方式實現。若是你沒有指定一個main類,該插件會搜索帶有publicstaticvoidmain(String[]args)方法的類。


爲了構建和運行一個項目的artifact,你能夠輸入如下命令:

 

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. $   mvn package  
  2. $   java    -jar    target/spring-boot01-1.0-SNAPSHOT.jar  

這種方式,只要控制檯關閉,服務就不能訪問了。下面咱們使得 jar 包在後臺運行:

java -jar spring-boot01-1.0-SNAPSHOT.jar > log.file 2>&1 &

 

爲了構建一個便是可執行的,又能部署到一個外部容器的war文件,你須要標記內嵌容器依賴爲"provided",例如:

 

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <?xml    version="1.0"   encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4. <!-- ... -->  
  5. <packaging>war</packaging>  
  6. <!-- ... -->  
  7. <dependencies>  
  8. <dependency>  
  9. <groupId>org.springframework.boot</groupId>  
  10. <artifactId>spring-boot-starter-web</artifactId>  
  11. </dependency>  
  12. <dependency>  
  13. <groupId>org.springframework.boot</groupId>  
  14. <artifactId>spring-boot-starter-tomcat</artifactId>  
  15. <scope>provided</scope>  
  16. </dependency>  
  17. <!-- ... -->  
  18. </dependencies>  
  19. </project>  



 

 

四、打包爲單個jar時,spring boot的啓動方式

 

maven打包以後,會生成兩個jar文件:

demo-0.0.1-SNAPSHOT.jar demo-0.0.1-SNAPSHOT.jar.original

其中demo-0.0.1-SNAPSHOT.jar.original是默認的maven-jar-plugin生成的包。

demo-0.0.1-SNAPSHOT.jar是spring boot maven插件生成的jar包,裏面包含了應用的依賴,以及spring boot相關的類。下面稱之爲fat jar。

先來查看spring boot打好的包的目錄結構(不重要的省略掉):

 

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. ├── META-INF  
  2. │   ├── MANIFEST.MF  
  3. ├── application.properties  
  4. ├── com  
  5. │   └── example  
  6. │       └── SpringBootDemoApplication.class  
  7. ├── lib  
  8. │   ├── aopalliance-1.0.jar  
  9. │   ├── spring-beans-4.2.3.RELEASE.jar  
  10. │   ├── ...  
  11. └── org  
  12.     └── springframework  
  13.         └── boot  
  14.             └── loader  
  15.                 ├── ExecutableArchiveLauncher.class  
  16.                 ├── JarLauncher.class  
  17.                 ├── JavaAgentDetector.class  
  18.                 ├── LaunchedURLClassLoader.class  
  19.                 ├── Launcher.class  
  20.                 ├── MainMethodRunner.class  
  21.                 ├── ...                  

 

依次來看下這些內容。

MANIFEST.MF

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. Manifest-Version: 1.0  
  2. Start-Class: com.example.SpringBootDemoApplication  
  3. Implementation-Vendor-Id: com.example  
  4. Spring-Boot-Version: 1.3.0.RELEASE  
  5. Created-By: Apache Maven 3.3.3  
  6. Build-Jdk: 1.8.0_60  
  7. Implementation-Vendor: Pivotal Software, Inc.  
  8. Main-Class: org.springframework.boot.loader.JarLauncher  


能夠看到有Main-Class是org.springframework.boot.loader.JarLauncher ,這個是jar啓動的Main函數。

還有一個Start-Class是com.example.SpringBootDemoApplication,這個是咱們應用本身的Main函數

[plain]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. @SpringBootApplication  
  2. public class SpringBootDemoApplication {  
  3.   
  4.     public static void main(String[] args) {  
  5.         SpringApplication.run(SpringBootDemoApplication.class, args);  
  6.     }  
  7. }  

com/example 目錄

這下面放的是應用的.class文件。

lib目錄

這裏存放的是應用的Maven依賴的jar包文件。 
好比spring-beans,spring-mvc等jar。

org/springframework/boot/loader 目錄

這下面存放的是Spring boot loader的.class文件。

啓動:

咱們直接啓動:java -jar demo-0.0.1-SNAPSHOT.jar 

 

 

五、Maven添加本地Jar包

咱們有時候項目依賴外部的jar,咱們使用Eclipse開發的時候咱們直接經過build path添加jar就能夠,可是使用mvn 打包的時候就會缺乏這個包。

 

1. 使用system scope

咱們直接引入rabbitmq-client.jar。這個方式比較靈活,到新的服務器上,無需作額外的操做。

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <dependency>  
  2.         <groupId>rabbitmq.client</groupId>   
  3.         <artifactId>rabbitmq.client</artifactId>   
  4.         <version>3.0</version>   
  5.         <scope>system</scope>   
  6.         <systemPath>${basedir}/src/main/WEB-INF/lib/rabbitmq-client.jar</systemPath>   
  7.     </dependency>  

一、groupId和artifactId以及version都是能夠隨便填寫的 ,scope必須填寫爲system,而systemPath咱們如今咱們jar包的目錄地址就能夠了

 

二、${basedir}就是項目根目錄

 

 

2. 將jar包安裝到本地repository中

這個須要在新機器上執行mvn install:install-file命令。

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. mvn install:install-file  
  2. -Dfile= jar文件所存放的地址     
  3. -DgroupId= jar文件所屬的group:包名   
  4. -DartifactId=  jar的項目名 名稱,通常就是去掉後綴的文件名     
  5. -Dversion=版本號  
  6. -Dpackaging=jar:此包的打包形式,就是jar  
  7. -DgeneratePom=true  

例如執行命令:
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

 

在項目中引用:

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <dependency>  
  2.     <groupId>com.rabbitmq</groupId>  
  3.     <artifactId>client</artifactId>  
  4.     <version>3.5.0</version>  
  5. </dependency>  

 

 

三、添加 in project repository

設置項目的庫目錄

<repository>
    <id>in-project</id>
    <name>In Project Repo</name>
    <url>file://${project.basedir}/lib</url>
</repository>

添加依賴:

<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>client</artifactId>
    <version>3.5.0</version>
</dependency>

jar包及路徑必須嚴格遵循格式:

/groupId/artifactId/version/artifactId-verion.jar
本例中: lib/com/rabbitmq/client/3.5.0/rabbitmq-client-3.5.0.jar

 

六、部署到javaEE容器

 

 

修改啓動類,繼承 SpringBootServletInitializer 並重寫 configure 方法
[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. public class SpringBootSampleApplication extends SpringBootServletInitializer{  
  2.   
  3.     private static final Logger logger = LoggerFactory.getLogger(SpringBootSampleApplication.class);  
  4.   
  5.     @Override  
  6.     protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {  
  7.         return builder.sources(this.getClass());  
  8.     }  
  9.   
  10. }  
修改pom文件中jar 爲 war
[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <!-- <packaging>jar</packaging> -->  
  2. <packaging>war</packaging>  
修改pom,排除tomcat插件
[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. <dependency>  
  2.            <groupId>org.springframework.boot</groupId>  
  3.            <artifactId>spring-boot-starter-web</artifactId>  
  4.            <exclusions>  
  5.                <exclusion>  
  6.                    <groupId>org.springframework.boot</groupId>  
  7.                    <artifactId>spring-boot-starter-tomcat</artifactId>  
  8.                </exclusion>  
  9.            </exclusions>  
  10.        </dependency>  
打包部署到容器 
 

 

 

七、熱部署

 

 

在咱們開發過程當中,咱們須要常常修改,爲了不重複啓動項目,咱們能夠啓用熱部署。
Spring-Loaded項目提供了強大的熱部署功能,添加/刪除/修改 方法/字段/接口/枚舉 等代碼的時候均可以熱部署,速度很快,很方便。
想在Spring Boot中使用該功能很是簡單,就是在spring-boot-maven-plugin插件下面添加依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>springloaded</artifactId>
        <version>1.2.5.RELEASE</version>
    </dependency>
</dependencies>
添加之後,經過mvn spring-boot:run啓動就支持熱部署了。

注意:使用熱部署的時候,須要IDE編譯類後才能生效,你能夠打開自動編譯功能,這樣在你保存修改的時候,類就自動從新加載了。

 

 

八、使用Profile區分環境

 

application.properties區分環境

spring boot 能夠在 「配置文件」、「Java代碼類」、「日誌配置」 中來配置profile區分不一樣環境執行不一樣的結果

一、配置文件 
使用配置文件application.yml 和 application.properties 有所區別 
以application.properties 爲例,經過文件名來區分環境 application-{profile}.properties 

application.properties

app.name=MyApp
server.port=8080
spring.profiles.active=dev

application-dev.properties

server.port=8081

application-stg.properties

server.port=8082

在啓動程序的時候經過添加 –spring.profiles.active={profile} 來指定具體使用的配置 
例如咱們執行 java -jar demo.jar –spring.profiles.active=dev 那麼上面3個文件中的內容將被如何應用? 
Spring Boot 會先加載默認的配置文件,而後使用具體指定的profile中的配置去覆蓋默認配置。

app.name 只存在於默認配置文件 application.properties 中,由於指定環境中不存在一樣的配置,因此該值不會被覆蓋 
server.port 默認爲8080,可是咱們指定了環境後,將會被覆蓋。若是指定stg環境,server.port 則爲 8082 
spring.profiles.active 默認指定dev環境,若是咱們在運行時指定 –spring.profiles.active=stg 那麼將應用stg環境,最終 server.port 的值爲8082

Maven環境配置
   項目工程統一使用maven的profile插件定義不一樣的項目構建環境(dev, alpha, beta, prod),經過filter插件爲不一樣環境下的配置項注入對應的參數值來實現動態配置目標。
2.3.1定義profile
在POM.xml中配置四個profile,對應項目所處的四個不一樣的環境-dev, alpha, beta, prod, profile的id屬性即爲每一個環境賦予一個惟一的標示,元素的內容則是以key-value的形式出現的鍵值對,如咱們定義了一個變量,其值在不一樣的環境下(不一樣id)被賦予了不一樣的值(dev, test, pre-prod, prod),要激活不一樣的環境打包,咱們能夠在命令行經過mvn package –P${profileId}來讓其運行,爲了開發便利,默認激活的是dev開發環境,即開發人員不須要經過命令行手動輸入-p參數也能運行dev環境的打包。
 <profile>
            <!-- 本地參數 -->
            <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>

九、建立一個Linux 應用的sh腳本

下面幾個腳本僅供參考:

打包:clean.sh

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. #0、check user  
  2. TIME_STAMP=`date +%Y%m%d%H%M`  
  3. WHO=`whoami`  
  4. if [ "$WHO" != 'www' ]; then  
  5.         echo 'current user is not www'  
  6.         echo 'exit'  
  7.         exit  
  8. fi  
  9. CODE_HOME=/home/www/app  
  10. PROJECTNAME=qrealtime  
  11. cd $CODE_HOME/$PROJECTNAME  
  12. git pull  
  13. mvn clean package  
  14. pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}' `   
  15. if [ $pid != "" ]; then  
  16.         echo "App  is  running  and pid=$pid"  
  17. else  
  18.         echo "App is not  running."  
  19. fi  

 

 

start.sh

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. #0、check user  
  2. TIME_STAMP=`date +%Y%m%d%H%M`  
  3. WHO=`whoami`  
  4. if [ "$WHO" != 'www' ]; then  
  5.      echo 'current user is not www'  
  6.      echo 'exit'  
  7.      exit  
  8. fi  
  9. CODE_HOME=/home/www/app  
  10. PROJECTNAME=qrealtime  
  11. cd $CODE_HOME/$PROJECTNAME  
  12. pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}'`   
  13. if [ $pid ]; then  
  14.     echo "App  is  running  and pid=$pid"  
  15. else  
  16.    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>  
  17. fi  



 

stop.sh

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. #0、check user  
  2. TIME_STAMP=`date +%Y%m%d%H%M`  
  3. WHO=`whoami`  
  4. if [ "$WHO" != 'www' ]; then  
  5.         echo 'current user is not www'  
  6.         echo 'exit'  
  7.         exit  
  8. fi  
  9. CODE_HOME=/home/www/app  
  10. PROJECTNAME=qrealtime  
  11. cd $CODE_HOME/$PROJECTNAME  
  12. pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}' `   
  13. if [ $pid ]; then  
  14.     echo "App  is  running  and pid=$pid"  
  15.     kill -9 $pid  
  16.     if [[ $? -eq 0 ]];then   
  17.        echo "sucess to stop $PROJECTNAME "   
  18.     else   
  19.        echo "fail to stop $PROJECTNAME "  
  20.      fi  
  21. fi  

restart

 

 

[html]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. #0、check user  
  2. TIME_STAMP=`date +%Y%m%d%H%M`  
  3. WHO=`whoami`  
  4. if [ "$WHO" != 'www' ]; then  
  5.         echo 'current user is not www'  
  6.         echo 'exit'  
  7.         exit  
  8. fi  
  9. CODE_HOME=/home/www/app  
  10. PROJECTNAME=qrealtime  
  11. cd $CODE_HOME/$PROJECTNAME  
  12. pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}' `   
  13. if [ $pid ]; then  
  14.     echo "App  is  running  and pid=$pid"  
  15.     kill -9 $pid  
  16. fi  
  17. nohup java -jar $CODE_HOME/$PROJECTNAME/target/$PROJECTNAME-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &  



 

 

 

十、Spring Boot應用的docker化

 

首先看Spring Boot應用程序的Docker化,因爲Spring Boot內嵌了tomcat、Jetty等容器,所以咱們對docker鏡像的要求就是須要java運行環境。個人應用代碼的的Dockerfile文件以下:

#基礎鏡像:倉庫是java,標籤用8u66-jdk FROM java:8u66-jdk #當前鏡像的維護者和聯繫方式 MAINTAINER duqi duqi@example.com #將打包好的spring程序拷貝到容器中的指定位置 ADD target/bookpub-0.0.1-SNAPSHOT.jar /opt/bookpub-0.0.1-SNAPSHOT.jar #容器對外暴露8080端口 EXPOSE 8080 #容器啓動後須要執行的命令 CMD java -Djava.security.egd=file:/dev/./urandom -jar /opt/bookpub-0.0.1-SNAPSHOT.jar

由於目前的示例程序比較簡單,這個dockerfile並無在將應用程序的數據存放在宿主機上。若是你的應用程序須要寫文件系統,例如日誌,最好利用VOLUME /tmp命令,這個命令的效果是:在宿主機的/var/lib/docker目錄下建立一個臨時文件並把它連接到容器中的/tmp目錄。

把這個Dockerfile放在項目的根目錄下便可,後續經過docker-compose build統一構建:基礎鏡像是隻讀的,而後會在該基礎鏡像上增長新的可寫層來供咱們使用,所以java鏡像只須要下載一次。

docker-compose是用來作docker服務編排,參看《Docker從入門到實踐》中的解釋:

Compose 項目目前在 Github 上進行維護,目前最新版本是 1.2.0。Compose 定位是「defining and running complex applications with Docker」,前身是 Fig,兼容 Fig 的模板文件。

Dockerfile 可讓用戶管理一個單獨的應用容器;而 Compose 則容許用戶在一個模板(YAML 格式)中定義一組相關聯的應用容器(被稱爲一個 project,即項目),例如一個 Web 服務容器再加上後端的數據庫服務容器等。

單個docker用起來確實沒什麼用,docker技術的關鍵在於持續交付,經過與jekins的結合,能夠實現這樣的效果:開發人員提交push,而後jekins就自動構建並測試剛提交的代碼,這就是我理解的持續交付。

 

十一、守護進程啓動

 

使用java命令運行應用很是簡單,可是一般咱們都是經過ssh命令鏈接到服務器並運行它,一旦ssh鏈接斷開,那麼由它fork的java子進程也就隨之銷燬了。因此咱們必須藉助工具將應用做爲服務運行在服務器上:

Systemd

systemd 是Linux 下的一款系統和服務管理器。能夠爲Spring Boot應用編寫啓動腳本:

 

[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. [Unit]  
  2. Description=Spring Boot Application  
  3.   
  4. [Service]  
  5. ExecStart=/usr/bin/java -jar location_of_jar_file.jar --spring.config.location=location_of_config.properties --spring.profiles.active=profile  
  6. User=${your expected user}  
  7.   
  8. [Install]  
  9. WantedBy=multi-user.target  

 

 

Supervisord

Supervisord配置:

 

[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到個人代碼片
  1. [program:app]  
  2. command=/usr/bin/java -jar location_of_jar_file.jar --spring.config.location=location_of_config.properties --spring.profiles.active=profile  
  3. user=${your expected user}  
  4. autostart=true  
  5. autorestart=true  
  6. startsecs=10  
  7. startretries=3  

 

 

 

十二、生產環境運維支持

 

 

    與開發和測試環境不一樣的是,當應用部署到生產環境時,須要各類運維相關的功能的支持,包括性能指標、運行信息和應用管理等。全部這些功能都有不少技術和開源庫能夠實現。Spring Boot 對這些運維相關的功能進行了整合,造成了一個功能完備和可定製的功能集,稱之爲 Actuator。只須要在 POM 文件中增長對 「org.springframe.boot:spring-boot-starter-actuator」 的依賴就能夠添加 Actuator。Actuator 在添加以後,會自動暴露一些 HTTP 服務來提供這些信息。這些 HTTP 服務的說明如表 2

 Spring Boot Actuator 所提供的 HTTP 服務
名稱 說明 是否包含敏感信息
autoconfig 顯示 Spring Boot 自動配置的信息。
beans 顯示應用中包含的 Spring bean 的信息。
configprops 顯示應用中的配置參數的實際值。
dump 生成一個 thread dump。
env 顯示從 ConfigurableEnvironment 獲得的環境配置信息。
health 顯示應用的健康狀態信息。
info 顯示應用的基本信息。
metrics 顯示應用的性能指標。
mappings 顯示 Spring MVC 應用中經過「
@RequestMapping」添加的路徑映射。
shutdown 關閉應用。
trace 顯示應用相關的跟蹤(trace)信息。

對於表中的每一個服務,經過訪問名稱對應的 URL 就能夠獲取到相關的信息。如訪問「/info」就能夠獲取到 info 服務對應的信息。服務是否包含敏感信息說明了該服務暴露出來的信息是否包含一些比較敏感的信息,從而肯定是否須要添加相應的訪問控制,而不是對全部人都公開。全部的這些服務都是能夠配置的,好比經過改變名稱來改變相應的 URL。下面對幾個重要的服務進行介紹。

health 服務

Spring Boot 默認提供了對應用自己、關係數據庫鏈接、MongoDBRedis 和 Rabbit MQ 的健康狀態的檢測功能。當應用中添加了 DataSource 類型的 bean 時,Spring Boot 會自動在 health 服務中暴露數據庫鏈接的信息。應用也能夠提供本身的健康狀態信息,如代碼清單 7 所示。

health 服務
@Component
public class AppHealthIndicator implements HealthIndicator {
 @Override
 public Health health() {
 return Health.up().build();
 }
}

應用只須要實現 org.springframework.boot.actuate.health.HealthIndicator 接口,並返回一個 org.springframework.boot.actuate.health.Health 對象,就能夠經過 health 服務來獲取所暴露的信息。health 服務返回的結果

{"status":"UP","app":{"status":"UP"},"db":{"status":"UP","database":"HSQL Database Engine","hello":1}}

info 服務

info 服務所暴露的信息是徹底由應用來肯定的。應用中任何以「info.」開頭的配置參數會被自動的由 info 服務來暴露。只須要往 application.properties 中添加以「info.」開頭的參數便可,如:

info.app_name=My First Spring Boot Application
info.app_version=1.0.0

當訪問「/info」時,訪問的 JSON 數據:

{"app_name":"My First Spring Boot Application","app_version":"1.0.0"}

metrics 服務

當訪問 metrics 服務時,能夠看到 Spring Boot 經過 SystemPublicMetrics 默認提供的一些系統的性能參數值,包括內存、CPU、Java 類加載和線程等的基本信息。應用能夠記錄其餘所須要的信息。Spring Boot 默認提供了兩種類型的性能指標記錄方式:gauge 和 counter。gauge 用來記錄單個絕對數值,counter 用來記錄增量或減量值。好比在一個 Web 應用中,能夠用 counter 來記錄當前在線的用戶數量。當用戶登陸時,把 counter 的值加 1;當用戶退出時,把 counter 的值減 1。

示例:

@RestController
public class GreetingsController {
 @Autowired
 private CounterService counterService;
 @RequestMapping("/greet")
 public String greet() {
 counterService.increment("myapp.greet.count");
 return "Hello!";
 }
}

上面代碼添加了對 Spring Boot 提供的 CounterService 的依賴。當 greet 方法被調用時,會把名稱爲「myapp.greet.count」的計數器的值加 1。也就是當用戶每次訪問「/greet」時,該計算器就會被加 1。除了 CounterService 以外,還可使用 GaugeService 來記錄絕對值。

相關文章
相關標籤/搜索