做者:廖明(歡迎交流liaoming.lxm@gmail.com)java
隨着 Spring Boot 生態社區的日益強大,貝聊服務端團隊在開發部分新系統時,也逐步採用了 Spring Boot 框架,而且積累了必定的經驗,在此和你們作個分享。linux
項目採用 Spring Boot ,和直接使用 Spring MVC ,有什麼優勢了?這裏咱們分析了下,大概有如下幾點:git
總結來講,相比於直接使用 Spring MVC 構建項目,Spring Boot 使咱們在開發、配置、監控、部署的過程當中,都變得更加簡單。github
在講Spring Boot 以前,有必要講下咱們貝聊服務端如今有用到的技術棧:web
引入Spring Boot ,則必需要支持咱們現有的技術棧,而且要可以讓新同事可以很快熟悉。依託於Spring Boot 約定優於配置的理念,及官方和社區提供的各類豐富的 Starter pom 配置,在各同事的支持下,各方面的整合,都相對順利。在接下來的文字裏,我會和你們講解貝聊在使用 Spring Boot 的一些狀況。spring
貝聊服務端使用了 Dubbo 框架來實現服務治理,Dubbo 目前在Apache 孵化器進行孵化,官方也提供了 incubator-dubbo-spring-boot-project,不過官方的 0.1.0 版本在4月份才發佈,在此以前,咱們編寫了本身的 spring-boot-starter-dubbo,並知足已有需求。數據庫
新項目在使用了 spring-boot-starter-dubbo 後,咱們在暴露和引入 Dubbo 服務時,均使用了註解的形式,拋棄了本來的 xml 配置方式,開發的時候不用在關注是否在 dubbo.xml 中是否有引入服務,編碼時相對輕鬆了很多。apache
貝聊在很早的時候,就使用了 Elastic-Job 來進行分佈式做業管理,且一直沿用了較低版本,沒有作升級。以前已有的項目,Elastic-Job 的配置和做業都是放在一個 spring-job.xml 文件裏面。在整合 Elastic-Job 和 Spring Boot 的時候,發現社區有開源的 spring-boot-starer-elastic-job,不過採用了最新版的 Elastic-Job-Lite。 在此背景下,我準備了兩種方案:windows
後面和同事討論下,採用了後面的方案,升級 Elastic-Job 版本爲 Elastic-Job-Lite,新項目使用 spring-boot-starter-elastic-job 來配置,而且使用註解來聲明做業。至此,又一個 xml 文件被移除。bash
Discof 是貝聊在早期引進的分佈式配置管理工具,使用起來也很簡單,雖然原做者已經中止維護,但仍是有熱心的網友提供了 disconf-spring-boot-starter ,基於此 Starter ,也極大簡化了咱們在新項目中的配置成本,新入職的同事在配置 Discof 的時候,也不須要再去拷貝舊項目 Diconf 的 xml 配置。
這部分整合是相對容易的,Mybatis 和 Druid 官方,均有提供自動化配置的 Starter pom,拿來開箱即用。
須要特殊處理的是多數據源配置,以前系統用的公司統一的配置類,不過是 xml 配置。爲了爲複用代碼,咱們將其轉爲了 Java Config 的方式,並計劃在將來也抽成一個自動化配置的 Starter 包。一樣,咱們在整合 Shiro 的時候,也是採用了Java Config的形式,並整合了 JWT 做爲接口訪問令牌。
APM 監控方面,咱們公司使用了 Cat,平臺組的同事搭建了 Cat,而且提供了對應的整合方式,其中一些配置 Bean 注入的時候,仍是使用 xml 的方式,後面筆者將其改成了 Java Config 的方式,總個整合過程以下:
上面的5個步驟中,前面3個步驟是能夠合併爲一個,2和3兩個步驟,能夠經過將xml配置變成Java Config 的方式,並生成一個 spring-boot-starter-cat-monitor 包,實現配置類的重用,簡化配置步驟。下面也介紹下步驟2和3實現自動化配置的原理:
/**
* 功能:web 環境下,集成cat監控功能
*/
@Configuration
@ConditionalOnWebApplication
public class CatWebFilterConfigure {
@Bean
public FilterRegistrationBean catFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CatServletFilter());
registration.addUrlPatterns("/*");
registration.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.FORWARD);
registration.setName("cat-filter");
return registration;
}
}
複製代碼
/**
* 功能:dubbo cat 監控,使用Activate註解, 無條件自動激活,不須要在yml 配置中聲明該filter 了
*/
@Activate(group = {Constants.PROVIDER, Constants.CONSUMER})
public class CatBootDubboConfigure extends Filter {
//此處省略具體的埋點操做
}
複製代碼
上面說了好些 Starter ,都是用了社區已有的輪子,固然,咱們團部內部,也有封裝一些簡單的 Starter ,以實現代碼複用,簡化配置。
咱們在平常接口開發的調試階段,常常須要查看接口請求和響應日誌。使用 Spring 來攔截接口請求和響應日誌,有多種實現方式,能夠本身定義 Filter,Intercepter,或者使用 Aspectj,若是每個 Web 項目,都來寫一套實現,或者從別的項目中拷貝一份,這確定不是一個好的方式。基於此狀況,踐行 Spring Boot 約定優於配置的原則,咱們本身內部封裝了 spring-boot-start-web-log,並提供了一些常見的配置項。新的 Web 項目須要時,只須要引入依賴,並在 yml 配置文件中加入以下配置就好:
web.log:
## 攔截路徑
mapping-path: "/*"
## 排除路徑
exclude-mapping-path: "/files/*;/favicon.ico;/login;/captcha/* ## 打印header,多個按照';'分隔 print-header: "Authorization" ## 是否容許打印日誌,默認true,建議生成關閉 enable: true 複製代碼
日誌效果以下:
剛開始在咱們已有的發佈系統上部署 Spring Boot 應用時,遇到了一些問題。
在部署應用方面,咱們嘗試了 war 包部署和 jar 部署兩種方式。其中採用 war 包部署時,發現會和現有的 Resin 有衝突,須要移除 Resion 的部分 jar ,比較麻煩,因此咱們採用 jar 包部署的方式。
使用 jar 包部署,咱們也遇到了一些問題。咱們已有的 Dubbo 應用部署,就是採用了 jar 包部署。去除一些 JVM 參數是可配置的,最終都是使用到 java -cp jar包路徑 類名 的命令來運行應用。注意,這種方式,是須要指定jar路徑和類名的,和 java -jar spring-boot-app.jar 是不同的,所以,爲了不腳本改動,咱們得適配現有的發佈腳本。
Dubbo 打成可獨立運行的 jar 包,使用了 maven-shade-plugin 插件,指定的類名是 com.alibaba.dubbo.container.Main 。而在打包 Spring Boot 應用時,咱們採用了 spring-boot-maven-plugin 插件 。在選擇 java -cp 命令所須要參數類名時,咱們剛開始使用了Spring Boot默認的 Application 啓動類,畢竟咱們開發的時候,也是直接運行該類的 main 方法來啓動應用。然而實際運行的時候,發現應用根本起不來,提示找不到或沒法加載主類。後面通過一番資料查找與學習,才解決了該問題。
解決問題的關鍵,在於要了解 jar 運行的原理,也就是 MANIFEST.MF 文件。 解壓Spring Boot 打包後的jar文件,其中 MANIFEST.MF 文件以下:
Manifest-Version: 1.0
Implementation-Title: demo
Implementation-Version: 0.0.1-SNAPSHOT
Archiver-Version: Plexus Archiver
Built-By: Ming
Implementation-Vendor-Id: com.beiliao.app
Spring-Boot-Version: 1.5.4.RELEASE
Implementation-Vendor: Pivotal Software, Inc.
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.beiliao.app.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.3.1
Build-Jdk: 1.8.0_73
Implementation-URL: http://projects.spring.io/spring-boot/demo/
複製代碼
注意到這裏面 Main-Class: org.springframework.boot.loader.JarLauncher 纔是主方法,使用java -jar spring-boot-app.jar 能夠運行Spring Boot 應用,是由於 spring-boot-maven-plugin 插件在打包的時候已經生成該文件 ,java -jar 命令會讀取到該文件 。所以,使用 java -cp 命令啓動 Spring Boot 應用時,完整的命令應該是:
windows:
java -cp .;c:\\Project\\boot-demo\\target\\demo-0.0.1-SNAPSHOT.jar org.springframework.boot.loader.JarLauncher
linux:
java -cp .:/data/project/demo/* org.springframework.boot.loader.JarLauncher
複製代碼
以上就是Spring Boot 在貝聊的一些應用狀況。目前,貝聊已經有幾個新項目使用到 Spring Boot,並在組內反響不錯,用過的開發同事多說比以前直接用 Spring MVC 要方便很多。公司 Gitlab 倉庫的 Starter 依賴包也有6個了,將來還會增長。