spring-boot

要了解Spring Boot,我们先来编写第一个Spring Boot应用程序,看看与前面我们编写的Spring应用程序有何异同。

我们新建一个springboot-hello的工程,创建标准的Maven目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
springboot-hello
├── pom.xml
├── src
│ └── main
│ ├── java
│ └── resources
│ ├── application.yml
│ ├── logback-spring.xml
│ ├── static
│ └── templates
└── target

其中,在src/main/resources目录下,注意到几个文件:

application.yml

这是Spring Boot默认的配置文件,它采用YAML格式而不是.properties格式,文件名必须是application.yml而不是其他名称。

YAML格式比key=value格式的.properties文件更易读。比较一下两者的写法:

使用.properties格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# application.properties

spring.application.name=${APP_NAME:unnamed}

spring.datasource.url=jdbc:hsqldb:file:testdb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.dirver-class-name=org.hsqldb.jdbc.JDBCDriver

spring.datasource.hikari.auto-commit=false
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.validation-timeout=3000
spring.datasource.hikari.max-lifetime=60000
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=1

使用YAML格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# application.yml

spring:
application:
name: ${APP_NAME:unnamed}
datasource:
url: jdbc:hsqldb:file:testdb
username: sa
password:
driver-class-name: org.hsqldb.jdbc.JDBCDriver
hikari:
auto-commit: false
connection-timeout: 3000
validation-timeout: 3000
max-lifetime: 60000
maximum-pool-size: 20
minimum-idle: 1

可见,YAML是一种层级格式,它和.properties很容易互相转换,它的优点是去掉了大量重复的前缀,并且更加易读。

使用环境变量

在配置文件中,我们经常使用如下的格式对某个key进行配置:

1
2
3
4
5
app:
db:
host: ${DB_HOST:localhost}
user: ${DB_USER:root}
password: ${DB_PASSWORD:password}

这种${DB_HOST:localhost}意思是,首先从环境变量查找DB_HOST,如果环境变量定义了,那么使用环境变量的值,否则,使用默认值localhost

这使得我们在开发和部署时更加方便,因为开发时无需设定任何环境变量,直接使用默认值即本地数据库,而实际线上运行的时候,只需要传入环境变量即可:

1
$ DB_HOST=10.0.1.123 DB_USER=prod DB_PASSWORD=xxxx java -jar xxx.jar

logback-spring.xml

这是Spring Boot的logback配置文件名称(也可以使用logback.xml),一个标准的写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>

<appender name="APP_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
<file>app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<maxIndex>1</maxIndex>
<fileNamePattern>app.log.%i</fileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>1MB</MaxFileSize>
</triggeringPolicy>
</appender>

<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="APP_LOG" />
</root>
</configuration>

关于云原生和微服务

云原生技术使组织能够在新式动态环境(如公有云、私有云和混合云)中构建和运行可缩放的应用程序。 容器、服务网格、微服务、不可变基础结构和声明性 API 便是此方法的范例。

云原生系统采用微服务,而微服务是一种用于构造新式应用程序的常用体系结构样式。

微服务

  • 各自都在较大的域上下文中实现特定业务功能。

  • 各自都自主开发,可以独立部署。

  • 各自都是独立的,封装其自己的数据存储技术、依赖项和编程平台。

  • 各自都在自己的进程中运行,并使用 HTTP/HTTPS、gRPC、WebSocket 或 AMQP 等标准通信协议与其他微服务进行通信。

  • 它们组合在一起形成应用程序。

为何使用微服务?

微服务提供敏捷性。

在本章的前面部分,我们将构建为整体结构的电子商务应用程序与采用微服务的应用程序进行比较。 在示例中,我们看到了一些明显的好处:

  • 每个微服务都有自治生命周期,可以独立发展并频繁部署。 不必等待每季度发布一次才能部署新功能或更新。 可以更新实时应用程序的小区域,降低中断整个系统的风险。 无需完全重新部署应用程序即可进行更新。

  • 每个微服务都可以独立缩放。 你可以仅横向扩展需要更多处理能力才能满足所需性能级别和服务级别协议的服务,而不是将整个应用程序作为单个单元进行缩放。 精细缩放可使你更好地控制系统,并且有助于降低总体成本,因为是缩放部分系统(而不是所有内容)。

开发微服务

可以在任何新式开发平台上创建微服务。

spring-boot 平台是一个很好的选择。 它免费且开放源代码,有许多可简化微服务开发的内置功能。 Java 是跨平台的。 可以在 Windows、macOS 和大多数 Linux 风格上生成和运行应用程序。