原则

软件需要在不同的环境中部署,代码是保持不变的,但是不同的运行环境存在差异,所以需要使用配置适应不同的环境。比如:

  • 数据库,Redis,以及其他 后端服务 的配置;
  • 第三方服务的证书,如 oAuth、支付接口 等;
  • 每份部署特有的配置,如域名等。

配置的原则是:代码与配置要严格分离,不允许在代码中使用常量保存配置。

最常见的配置方式就是配置文件,按照配置文件的存储位置,可以分为内部配置和外部配置:

  • 内部配置:部署文件是发布产物的一部分,存储在发布目录中,甚至打包在一起,比如 jar 包里面的 properties 文件。这些配置文件在不同的环境间不存在差异,其实他们可以看做是部署产物的一部分,比如 Spring 用来定义类创建和注入关系的 xml 文件。从运维的角度来看,尽管他们是配置文件,实际上和写死代码没有什么区别。反过来说,如果某个配置项在不同环境中是有差异的,就不应该放到内部;
  • 外部配置:不在部署产物内,需要在部署环境上修改。需要注意不要把这样的文件提交到代码控制系统,总是有人不小心这样做。

配置漂移

构建好的程序被部署在服务器上后,为了解决故障、性能优化、适应新的需求,需要对服务器和应用的配置进行更改。如果直接登录服务器修改某个配置,随着时间的推移和管理的复杂化,就会引发配置漂移。

这种可以直接登录修改的服务器称为可变服务器。可变服务器会造成开发、测试、生产服务器不一致,生产环境中不同的节点也不一致,容易出现运行问题。

要防止配置漂移,服务器要禁止手动修改,只能通过自动化部署形式更改配置,这种服务器就叫不可变服务器。不可变服务器消除了不一致性,开发、测试环境中得到的程序包和最终到达服务器的程序包是完全相同的。这样就能防止配置漂移。

推荐方式

生产环境使用以下几配置种技术:

  • 配置文件:使用外部配置,按照 Linux 的目录规范在 /etc 目录,或者其他合适的位置;
  • 启动参数:在启动参数中注入配置数据,这是防止配置漂移的好办法;
  • 环境变量:与启动参数相似,也是推荐的方式;
  • 配置服务:使用某种集中配置平台,比如 etcd、Zookeeper、Spring Cloud Config. 这些平台使用不同的协议,在数据结构、存储一致性方面有不同的设计思想,可以选择一个合适的。配置服务可以支持动态修改,比如 Spring Cloud Config 提供了 refresh 端口,可以调动这个端口在不重启进程的情况下修改配置项。

Spring Boot 配置方式

示例程序演示了 Spring Boot 配置方式,打包运行:

mvn package
export message=bonjour
java -Dmessage=hello \
-jar spring-boot-config-sample-1.0.0-SNAPSHOT.jar \
--message=hi \
--spring.config.name=application,conf

message 配置出现在 4 个位置:

  • 系统环境变量 export message=bonjour
  • Java 属性 -Dmessage=hello
  • 命令行参数 --message=hi
  • 内部配置文件 application.properties

启动之后在 env 端口查看设置:

$ curl http://localhost:8080/actuator/env
{
"propertySources":
[
{
"name": "commandLineArgs",
"properties":
{
"message":
{
"value": "hi"
}
}
},
{
"name": "systemProperties",
"properties":
{
"message":
{
"value": "hello"
}
}
},
{
"name": "systemEnvironment",
"properties":
{
"message":
{
"value": "bonjour",
"origin": "System Environment Property \"message\""
}
}
},
{
"name": "applicationConfig: [classpath:/application.properties]",
"properties":
{
"message":
{
"value": "nihao",
"origin": "class path resource [application.properties]:9:9"
}
}
}
]
}

这里删掉了一些无关的内容,可以看到 message 设置是按照 commandLineArgssystemPropertiessystemEnvironmentapplicationConfig 的顺序加载的,以最先出现的为准。

spring.config.name 启动参数定义了配置文件的名称。Spring Boot 默认的配置文件是 application.properties,这里添加了一个 conf.properties

Spring Boot 按照特定的顺序加载配置项,位置和顺序如下:

  1. DevTool 定义的配置项
  2. @TestPropertySource 标签定义的配置项
  3. @SpringBootTest#properties 标签定义的配置项
  4. 启动参数
  5. SPRING_APPLICATION_JSON 环境变量
  6. ServletConfig 定义的 init 参数
  7. ServletContext 定义的 init 参数
  8. JNDI 属性
  9. Java 系统属性,使用 -Dkey=value 定义,System.getProperties() 可以查看到
  10. 操作系统环境变量
  11. RandomValuePropertySource 定义的随机值
  12. 带 profile 的外部配置文件
  13. 带 profile 的内部配置文件
  14. 不带 profile 的外部配置文件
  15. 不带 profile 的内部配置文件
  16. @Configuration 类型里面的 @PropertySource 标签定义的配置
  17. SpringApplication.setDefaultProperties 方法设置的默认值

内外部配置文件的加载位置和顺序如下:

  1. config 目录
  2. . 当前目录
  3. classpath:/config
  4. classpath:/

Docker

使用 Dockerfile 是在生产环境创建 Docker 镜像的唯一推荐方式,示例程序提供了 Dockerfile 样例。Dockerfile 将运行包和配置文件复制到镜像里:

RUN mkdir -p /opt/stack
COPY target/spring-boot-config-sample-1.0.0-SNAPSHOT.jar /opt/stack/
COPY ./conf.properties /opt/stack/

在环境变量和启动参数中注入配置项:

ENV message=bonjour
ENTRYPOINT ["java", \
"-jar", \
"spring-boot-config-sample-1.0.0-SNAPSHOT.jar", \
"--spring.config.name=application,conf"]

定义了健康检查规则:

HEALTHCHECK --interval=30s --timeout=10s \
CMD curl -f http://localhost:8080/actuator/health || exit 1

Dockerfile 里面还对镜像系统进行了设置,提高了打开文件句柄数。Docker 是实现不可变服务器的最佳方式。

RUN ulimit -n 65536

使用 docker build 命令制作镜像,第一次运行会下载一个 primetoninc/jdk 基础镜像,需要花一些时间:

docker build -t config-sample .

使用 docker run 命令运行程序:

docker run -it -p 8080:8080 config-sample

在实际环境上可以使用 Kubernetes、Mesos 这样的平台管理和运行 Docker 镜像,完全可以避免直接登录服务器操作。

本文代码示例:https://github.com/lane-cn/spring-boot-config-sample

程序配置的原则和实践以及 Spring Boot 支持方式的更多相关文章

  1. Spring Boot 支持多种外部配置方式

    Spring Boot 支持多种外部配置方式 http://blog.csdn.net/isea533/article/details/50281151 这些方式优先级如下: 命令行参数 来自java ...

  2. Spring Boot 支持 Https 有那么难吗?

    https 现在已经越来越普及了,特别是做一些小程序或者公众号开发的时候,https 基本上都是刚需了. 不过一个 https 证书还是挺费钱的,个人开发者可以在各个云服务提供商那里申请一个免费的证书 ...

  3. Spring Boot 支持 HTTPS 如此简单,So easy!

    这里讲的是 Spring Boot 内嵌式 Server 打 jar 包运行的方式,打 WAR 包部署的就不存在要 Spring Boot 支持 HTTPS 了,需要去外部对应的 Server 配置. ...

  4. Spring Boot 支持 HTTPS 如此简单,So easy!

    这里讲的是 Spring Boot 内嵌式 Server 打 jar 包运行的方式,打 WAR 包部署的就不存在要 Spring Boot 支持 HTTPS 了,需要去外部对应的 Server 配置. ...

  5. spring boot: 支持jsp,支持freemarker

    spring boot: 支持jsp,支持freemarker 支持jsp: 加入依赖 <!--jsp--> <dependency> <groupId>org.a ...

  6. 后端开发实践:Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  7. Spring REST实践之Spring Boot

    Spring Boot基本描述 可以利用http://start.spring.io网站的进行Spring Boot的初始化构建.这个初始化构建器允许你输入工程基本信息.挑选工程支持的功能,最后会生成 ...

  8. 55. spring boot 服务配置和部署【从零开始学Spring Boot】

    Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项 ...

  9. Spring Boot 实践 :Spring Boot + MyBatis

    Spring Boot 实践系列,Spring Boot + MyBatis . 目的 将 MyBatis 与 Spring Boot 应用程序一起使用来访问数据库. 本次使用的Library spr ...

随机推荐

  1. IDEA 控制台乱码问题

    一.修改IDEA的配置文件 找到IDEA安装目录下的 /bin/idea.exe.vmoptions(32位) 或 idea64.exe.vmoptions(64位),添加如下一行: -Dfile.e ...

  2. Docker外包团队 2019年3月更新 企业如何使用Docker

    很难将Docker所带来的影响统一的用一种特质来说.当使用Docker执行好时,它对组织,团队,开发者以及运维人员有多层次的好处.Docker使得架构设计简单化,因为所有的应用都将一致的从外部来透视主 ...

  3. MySQL 索引的增删查

    查看索引: > SHOW INDEX FROM table_name; > SHOW KEYS FROM table_name;   删除索引: > DROP INDEX index ...

  4. 【sql】ALTER更新数据库字段

    --数据库表字段更新sql脚本,以下是示例 --新增列字段 --alter table table_name add column `address` varchar() COLLATE utf8_b ...

  5. PAT 甲级 1035 Password (20 分)

    1035 Password (20 分) To prepare for PAT, the judge sometimes has to generate random passwords for th ...

  6. Kong配置参考

    kong配置的官网说明:https://docs.konghq.com/1.0.x/configuration/ 1. 配置加载 如果您通过其中一个官方软件包安装了Kong,Kong会附带默认配置文件 ...

  7. java核心-多线程-Java多线程编程涉及到包、类

    Java有关多线程编程设计的类主要涉及两个包java.lang和java.util.concurrent两个包 java.lang包,主要是线程基础类 <1>Thread <2> ...

  8. 为什么PPIO要设计支付代理节点?

    PPIO是我和姚欣发起的去中心化存储项目(https://pp.io),这是为开发者提供的存储和分发网络平台,使得比云存储更廉价,更高速,更隐私.   我在设计PPIO的时候,设计了一个商业角色——支 ...

  9. phpstorm 如何设置识别vue文件

    非常简单,步骤如下: 第一步: 设置->plugins->browser repositories 搜索vue.js,然后安装一下vue.js插件,重启ide. 第二步: Editor - ...

  10. Google SketchUp Cookbook: (Chapter 1) Making Multiple Copies

    软件环境 SketchUp Pro 2018 参考书籍 Google SketchUp Cookbook http://shop.oreilly.com/product/9780596155100.d ...