SpringBoot在貝聊的應用

做者:廖明(歡迎交流liaoming.lxm@gmail.com)java

隨着 Spring Boot 生態社區的日益強大,貝聊服務端團隊在開發部分新系統時,也逐步採用了 Spring Boot 框架,而且積累了必定的經驗,在此和你們作個分享。linux

Spring Boot 的優勢

項目採用 Spring Boot ,和直接使用 Spring MVC ,有什麼優勢了?這裏咱們分析了下,大概有如下幾點:git

  • 使用 Java Config 的配置方式替代 xml文件 配置,實現配置類複用。避免每次構建新的 Spring MVC 建項目,都得往舊的項目中拷貝 xml 配置文件。
  • 社區提供的豐富的 Starter pom 依賴包,極大方便了咱們整合第三方框架。
  • 提供嵌入式 Servlet 容器,支持 jar 和 war 部署,給運維和開發都帶來了極大的便利。
  • 自動管理依賴,勉去版本衝突煩惱。
  • 提供了基本的應用監控的功能。

總結來講,相比於直接使用 Spring MVC 構建項目,Spring Boot 使咱們在開發、配置、監控、部署的過程當中,都變得更加簡單。github

Spring Boot 在貝聊的應用狀況

在講Spring Boot 以前,有必要講下咱們貝聊服務端如今有用到的技術棧:web

  • 基礎框架 Spring MVC。
  • 服務治理方面,使用了 Dubbo。
  • 數據庫層面,使用了 Mybatis,Druid,並配置了多數據源。
  • 權限控制用到 Shiro。
  • 分佈式配置,使用了 Disconf。
  • 分佈式定時任務,使用 Elastic-Job。
  • 全鏈路監控方面使用了 Cat。
  • 部署方面,咱們用本身的發佈系統。

引入Spring Boot ,則必需要支持咱們現有的技術棧,而且要可以讓新同事可以很快熟悉。依託於Spring Boot 約定優於配置的理念,及官方和社區提供的各類豐富的 Starter pom 配置,在各同事的支持下,各方面的整合,都相對順利。在接下來的文字裏,我會和你們講解貝聊在使用 Spring Boot 的一些狀況。spring

在 Spring Boot 中使用 Dubbo

貝聊服務端使用了 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-Lite 整合

貝聊在很早的時候,就使用了 Elastic-Job 來進行分佈式做業管理,且一直沿用了較低版本,沒有作升級。以前已有的項目,Elastic-Job 的配置和做業都是放在一個 spring-job.xml 文件裏面。在整合 Elastic-Job 和 Spring Boot 的時候,發現社區有開源的 spring-boot-starer-elastic-job,不過採用了最新版的 Elastic-Job-Lite。 在此背景下,我準備了兩種方案:windows

  • 採用 @ImportResource({"classpath:spring-job.xml"}) 方式來兼容舊版本的 Elastic-Job 的任務,本身在寫 demo 時運行正常;
  • 升級 Elastic-Job 版本爲 Elastic-Job-Lite,並安裝最新版的 Elastic-Console ,參考社區的 Starter ,編寫使用註解方式配置定時任務,去 xml;

後面和同事討論下,採用了後面的方案,升級 Elastic-Job 版本爲 Elastic-Job-Lite,新項目使用 spring-boot-starter-elastic-job 來配置,而且使用註解來聲明做業。至此,又一個 xml 文件被移除。bash

和 Disconf 整合

Discof 是貝聊在早期引進的分佈式配置管理工具,使用起來也很簡單,雖然原做者已經中止維護,但仍是有熱心的網友提供了 disconf-spring-boot-starter ,基於此 Starter ,也極大簡化了咱們在新項目中的配置成本,新入職的同事在配置 Discof 的時候,也不須要再去拷貝舊項目 Diconf 的 xml 配置。

和 Mybatis、Druid 以及多數據源整合

這部分整合是相對容易的,Mybatis 和 Druid 官方,均有提供自動化配置的 Starter pom,拿來開箱即用。

須要特殊處理的是多數據源配置,以前系統用的公司統一的配置類,不過是 xml 配置。爲了爲複用代碼,咱們將其轉爲了 Java Config 的方式,並計劃在將來也抽成一個自動化配置的 Starter 包。一樣,咱們在整合 Shiro 的時候,也是採用了Java Config的形式,並整合了 JWT 做爲接口訪問令牌。

和 Cat 監控整合

APM 監控方面,咱們公司使用了 Cat,平臺組的同事搭建了 Cat,而且提供了對應的整合方式,其中一些配置 Bean 注入的時候,仍是使用 xml 的方式,後面筆者將其改成了 Java Config 的方式,總個整合過程以下:

  • 一、引入Cat 相關 jar 包;
  • 二、若是是 web 項目,要注入 CatServletFilter ,實現 MVC層Cat 配置;
  • 三、若是是項目中用到了 Dubbo ,添加 CatDubboFilter
  • 四、在 META-INF 中添加 app.properties,聲明項目名字;
  • 五、在 logback-spring.xml 中添加 CatLogbackAppender 配置;

上面的5個步驟中,前面3個步驟是能夠合併爲一個,2和3兩個步驟,能夠經過將xml配置變成Java Config 的方式,並生成一個 spring-boot-starter-cat-monitor 包,實現配置類的重用,簡化配置步驟。下面也介紹下步驟2和3實現自動化配置的原理:

  • 注入CatServletFilter,主要是利用 @ConditionalOnWebApplication 註解,若是當前環境是web環境,則該配置類會生效,核心代碼以下:
/**
 * 功能: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;
    }
}
複製代碼
  • 注入CatDubboFilter,主要是利用Dubbo的 @Activate 來無條件激活配置。由於咱們全部的項目,都整合了Dubbo,因此不須要根據環境來注入配置類。
/**
 * 功能:dubbo cat 監控,使用Activate註解, 無條件自動激活,不須要在yml 配置中聲明該filter 了
 */
@Activate(group = {Constants.PROVIDER, Constants.CONSUMER})
public class CatBootDubboConfigure extends Filter {
    //此處省略具體的埋點操做
}
複製代碼

使用 spring-boot-start-web-log 統一攔截請求和響應日誌

上面說了好些 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 應用

剛開始在咱們已有的發佈系統上部署 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個了,將來還會增長。

相關文章
相關標籤/搜索