做者:廖明(欢迎交流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个了,将来还会增长。