目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

运行中的 SpringBoot

认识 Spring Boot 的各类 Actuator Endpoint

Actuator
 目的:监控并管理应用程序
 访问方式

1HTTP
2JMX

依赖

1<dependency>
2            <groupId>org.springframework.boot</groupId>
3            <artifactId>spring-boot-starter-actuator</artifactId>
4        </dependency>

一些常用的 Endpoint

一些常用的 Endpoint
一些常用的 Endpoint 2

如何访问 Actuator Endpoint

HTTP 访问

1/actuator/<Actuator ID>

端口与路径(配置 Actuator 发布的端口 和 应用程序分开,实现应用与管理的隔离,例如:应用发布在 8080 端口,Actuator 相关的所有 Endpoint 发布在 8090 端口,前段 nginx 请求转发给 8080 端口,外部请求不允许直接访问 8090 端口,起到了保护作用。)

1• management.server.address=
2• management.server.port=
3• management.endpoints.web.base-path=/actuator
4• management.endpoints.web.path-mapping.<id>=路径

开启 Endpoint

1• management.endpoint.<Actuator ID>.enabled=true
2• management.endpoints.enabled-by-default=false

暴露 Endpoint (按需发布 Endpoints)

1• management.endpoints.jmx.exposure.exclude=
2• management.endpoints.jmx.exposure.include=*
3• management.endpoints.web.exposure.exclude=
4• management.endpoints.web.exposure.include=info, health

手动定制自己的 Health Indicator

目的

  • 检查应用程序的运行状态

状态

1• DOWN - 503
2• OUT_OF_SERVICE - 503
3• UP - 200
4• UNKNOWN - 200

机制

  • 通过 HealthIndicatorRegistry 收集信息
  • HealthIndicator 实现具体检查逻辑

配置项

1• management.health.defaults.enabled=true|false
2• management.health.<id>.enabled=true
3• management.endpoint.health.show-details=never|when-authorized|always

Spring Boot 自带的 Health Indicator
Health Indicator

自定义 Health Indicator
步骤

1• 实现 HealthIndicator 接口  
2• 根据自定义检查逻辑返回对应 Health 状态: Health 中包含状态和详细描述信息

依赖

1<dependency>
2			<groupId>org.springframework.boot</groupId>
3			<artifactId>spring-boot-starter-actuator</artifactId>
4		</dependency>

application.properties

 1spring.jpa.hibernate.ddl-auto=none
 2spring.jpa.properties.hibernate.show_sql=true
 3spring.jpa.properties.hibernate.format_sql=true
 4
 5# 发布所有endpoints
 6management.endpoints.web.exposure.include=*
 7management.endpoint.health.show-details=always
 8
 9info.app.author=DigitalSonic
10info.app.encoding=@project.build.sourceEncoding@

CoffeeIndicator

 1package geektime.spring.springbucks.waiter.support;
 2
 3import geektime.spring.springbucks.waiter.service.CoffeeService;
 4import org.springframework.beans.factory.annotation.Autowired;
 5import org.springframework.boot.actuate.health.Health;
 6import org.springframework.boot.actuate.health.HealthIndicator;
 7import org.springframework.stereotype.Component;
 8
 9@Component
10public class CoffeeIndicator implements HealthIndicator {
11    @Autowired
12    private CoffeeService coffeeService;
13
14    @Override
15    public Health health() {
16        long count = coffeeService.getCoffeeCount();
17        Health health;
18        if (count > 0) {
19            health = Health.up()
20                    .withDetail("count", count)
21                    .withDetail("message", "We have enough coffee.")
22                    .build();
23        } else {
24            health = Health.down()
25                    .withDetail("count", 0)
26                    .withDetail("message", "We are out of coffee.")
27                    .build();
28        }
29        return health;
30    }
31}

测试

  1// http://localhost:8080/actuator
  2
  3{
  4  "_links": {
  5    "self": {
  6      "href": "http://localhost:8080/actuator",
  7      "templated": false
  8    },
  9    "auditevents": {
 10      "href": "http://localhost:8080/actuator/auditevents",
 11      "templated": false
 12    },
 13    "beans": {
 14      "href": "http://localhost:8080/actuator/beans",
 15      "templated": false
 16    },
 17    "caches-cache": {
 18      "href": "http://localhost:8080/actuator/caches/{cache}",
 19      "templated": true
 20    },
 21    "caches": {
 22      "href": "http://localhost:8080/actuator/caches",
 23      "templated": false
 24    },
 25    "health-component-instance": {
 26      "href": "http://localhost:8080/actuator/health/{component}/{instance}",
 27      "templated": true
 28    },
 29    "health": {
 30      "href": "http://localhost:8080/actuator/health",
 31      "templated": false
 32    },
 33    "health-component": {
 34      "href": "http://localhost:8080/actuator/health/{component}",
 35      "templated": true
 36    },
 37    "conditions": {
 38      "href": "http://localhost:8080/actuator/conditions",
 39      "templated": false
 40    },
 41    "configprops": {
 42      "href": "http://localhost:8080/actuator/configprops",
 43      "templated": false
 44    },
 45    "env": {
 46      "href": "http://localhost:8080/actuator/env",
 47      "templated": false
 48    },
 49    "env-toMatch": {
 50      "href": "http://localhost:8080/actuator/env/{toMatch}",
 51      "templated": true
 52    },
 53    "info": {
 54      "href": "http://localhost:8080/actuator/info",
 55      "templated": false
 56    },
 57    "loggers": {
 58      "href": "http://localhost:8080/actuator/loggers",
 59      "templated": false
 60    },
 61    "loggers-name": {
 62      "href": "http://localhost:8080/actuator/loggers/{name}",
 63      "templated": true
 64    },
 65    "heapdump": {
 66      "href": "http://localhost:8080/actuator/heapdump",
 67      "templated": false
 68    },
 69    "threaddump": {
 70      "href": "http://localhost:8080/actuator/threaddump",
 71      "templated": false
 72    },
 73    "prometheus": {
 74      "href": "http://localhost:8080/actuator/prometheus",
 75      "templated": false
 76    },
 77    "metrics-requiredMetricName": {
 78      "href": "http://localhost:8080/actuator/metrics/{requiredMetricName}",
 79      "templated": true
 80    },
 81    "metrics": {
 82      "href": "http://localhost:8080/actuator/metrics",
 83      "templated": false
 84    },
 85    "scheduledtasks": {
 86      "href": "http://localhost:8080/actuator/scheduledtasks",
 87      "templated": false
 88    },
 89    "httptrace": {
 90      "href": "http://localhost:8080/actuator/httptrace",
 91      "templated": false
 92    },
 93    "mappings": {
 94      "href": "http://localhost:8080/actuator/mappings",
 95      "templated": false
 96    }
 97  }
 98}
 99
100// http://localhost:8080/actuator/info
101{
102  "app": {
103    "author": "DigitalSonic",
104    "encoding": "UTF-8"
105  }
106}
107
108// http://localhost:8080/actuator/health
109{
110  "status": "UP",
111  "details": {
112    "coffeeIndicator": {
113      "status": "UP",
114      "details": {
115        "count": 5,
116        "message": "We have enough coffee."
117      }
118    },
119    "db": {
120      "status": "UP",
121      "details": {
122        "database": "H2",
123        "hello": 1
124      }
125    },
126    "diskSpace": {
127      "status": "UP",
128      "details": {
129        "total": 256059109376,
130        "free": 175957565440,
131        "threshold": 10485760
132      }
133    }
134  }
135}

通过 Micrometer 获取运行数据

 在应用运行过程中需要收集一些度量指标:操作系统、JVM、应用业务指标 等……
 SpringBoot2.X 中的 Micrometer 可以完成度量指标收集。Micrometer 为主流的监控系统提供了一些 instrumentation clients (探针客户端),允许向 JVM 中插入这些探针。同时它做了一层抽象,所以并不需要关心底层的这些探针的具体实现,可以把 Micrometer 看作是 度量界 的 SLF4J。

认识 Micrometer
特性

  • 多维度度量
1• 支持 Tag
  • 预置大量探针
1• 缓存、类加载器、GC、CPU 利用率、线程池……
  • 与 Spring 深度整合
1• webMVC
2• webFlux
3• restTemplate
4• webClient

支持多种监控系统

  • Dimensional (维度)
1AppOptics, Atlas, Azure Monitor, Cloudwatch, Datadog, Datadog StatsD, Dynatrace, Elastic, Humio, Inflflux, KairosDB,New Relic, Prometheus, SignalFx, Sysdig StatsD, Telegraf,StatsD, Wavefront
  • Hierarchical(分层)
1Graphite, Ganglia, JMX, Etsy StatsD

一些核心度量指标
核心接口

  • Meter

内置实现

  • Gauge, TimeGauge
  • Timer, LongTaskTimer, FunctionTimer
  • Counter, FunctionCounter
  • DistributionSummary

Micrometer in Spring Boot 2.x
⼀些 URL

1• /actuator/metrics
2• /actuator/prometheus

⼀些配置项

1• management.metrics.export.*
2• management.metrics.tags.*
3• management.metrics.enable.*
4• management.metrics.distribution.*
5• management.metrics.web.server.auto-time-requests

核心度量项

1JVM、CPU、⽂件句柄数、⽇志、启动时间

其他度量项

1• Spring MVC、Spring WebFlux
2• Tomcat、Jersey JAX-RS
3• RestTemplate、WebClient
4• 缓存、数据源、Hibernate
5• Kafka、RabbitMQ

自定义度量指标

1• 通过 MeterRegistry 注册 Meter
2• 提供 MeterBinder Bean 让 Spring Boot 自动绑定
3• 通过 MeterFilter 进行定制

CoffeeOrderService

 1package geektime.spring.springbucks.waiter.service;
 2
 3import geektime.spring.springbucks.waiter.model.Coffee;
 4import geektime.spring.springbucks.waiter.model.CoffeeOrder;
 5import geektime.spring.springbucks.waiter.model.OrderState;
 6import geektime.spring.springbucks.waiter.repository.CoffeeOrderRepository;
 7import io.micrometer.core.instrument.Counter;
 8import io.micrometer.core.instrument.MeterRegistry;
 9import io.micrometer.core.instrument.binder.MeterBinder;
10import lombok.extern.slf4j.Slf4j;
11import org.springframework.beans.factory.annotation.Autowired;
12import org.springframework.stereotype.Service;
13import org.springframework.transaction.annotation.Transactional;
14
15import java.util.ArrayList;
16import java.util.Arrays;
17
18@Service
19@Transactional
20@Slf4j
21public class CoffeeOrderService implements MeterBinder {
22    @Autowired
23    private CoffeeOrderRepository orderRepository;
24
25    //计数器(监控订单总量)
26    private Counter orderCounter = null;
27
28    public CoffeeOrder get(Long id) {
29        return orderRepository.getOne(id);
30    }
31
32    public CoffeeOrder createOrder(String customer, Coffee...coffee) {
33        CoffeeOrder order = CoffeeOrder.builder()
34                .customer(customer)
35                .items(new ArrayList<>(Arrays.asList(coffee)))
36                .state(OrderState.INIT)
37                .build();
38        CoffeeOrder saved = orderRepository.save(order);
39        log.info("New Order: {}", saved);
40        //每次创建订单 +1
41        orderCounter.increment();
42        return saved;
43    }
44
45    public boolean updateState(CoffeeOrder order, OrderState state) {
46        if (state.compareTo(order.getState()) <= 0) {
47            log.warn("Wrong State order: {}, {}", state, order.getState());
48            return false;
49        }
50        order.setState(state);
51        orderRepository.save(order);
52        log.info("Updated Order: {}", order);
53        return true;
54    }
55
56    @Override
57    public void bindTo(MeterRegistry meterRegistry) {
58        this.orderCounter = meterRegistry.counter("order.count");
59    }
60}

测试

  1// http://localhost:8080/actuator/metrics/order.count
  2{
  3  "name": "order.count",
  4  "description": null,
  5  "baseUnit": null,
  6  "measurements": [
  7    {
  8      "statistic": "COUNT",
  9      "value": 2.0
 10    }
 11  ],
 12  "availableTags": [
 13  ]
 14}
 15
 16//访问prometheus
 17http://localhost:8080/actuator/prometheus
 18order_count_total 2.0
 19
 20//Micrometer 对 spring 有很好的支持 
 21// http://localhost:8080/actuator/metrics
 22
 23{
 24  "names": [
 25    "jvm.threads.states",
 26    "http.server.requests",
 27    "jdbc.connections.active",
 28    "jvm.gc.memory.promoted",
 29    "jvm.memory.max",
 30    "jvm.memory.used",
 31    "jvm.gc.max.data.size",
 32    "jdbc.connections.max",
 33    "jdbc.connections.min",
 34    "jvm.memory.committed",
 35    "system.cpu.count",
 36    "logback.events",
 37    "tomcat.global.sent",
 38    "jvm.gc.pause",
 39    "jvm.buffer.memory.used",
 40    "tomcat.sessions.created",
 41    "jvm.threads.daemon",
 42    "system.cpu.usage",
 43    "jvm.gc.memory.allocated",
 44    "tomcat.global.request.max",
 45    "hikaricp.connections.idle",
 46    "hikaricp.connections.pending",
 47    "tomcat.global.request",
 48    "tomcat.sessions.expired",
 49    "hikaricp.connections",
 50    "jvm.threads.live",
 51    "jvm.threads.peak",
 52    "tomcat.global.received",
 53    "hikaricp.connections.active",
 54    "hikaricp.connections.creation",
 55    "process.uptime",
 56    "order.count",
 57    "tomcat.sessions.rejected",
 58    "process.cpu.usage",
 59    "tomcat.threads.config.max",
 60    "jvm.classes.loaded",
 61    "hikaricp.connections.max",
 62    "hikaricp.connections.min",
 63    "jvm.classes.unloaded",
 64    "tomcat.global.error",
 65    "tomcat.sessions.active.current",
 66    "tomcat.sessions.alive.max",
 67    "jvm.gc.live.data.size",
 68    "hikaricp.connections.usage",
 69    "tomcat.threads.current",
 70    "hikaricp.connections.timeout",
 71    "jvm.buffer.count",
 72    "jvm.buffer.total.capacity",
 73    "tomcat.sessions.active.max",
 74    "hikaricp.connections.acquire",
 75    "tomcat.threads.busy",
 76    "process.start.time"
 77  ]
 78}
 79
 80
 81//SpringMVC 请求统计 (SpringBoot 和 Micrometer 一起实现的)
 82//http://localhost:8080/actuator/metrics/http.server.requests
 83
 84{
 85  "name": "http.server.requests",
 86  "description": null,
 87  "baseUnit": "seconds",
 88  "measurements": [
 89    {
 90      "statistic": "COUNT",
 91      "value": 9.0
 92    },
 93    {
 94      "statistic": "TOTAL_TIME",
 95      "value": 0.707585
 96    },
 97    {
 98      "statistic": "MAX",
 99      "value": 0.0015951
100    }
101  ],
102  "availableTags": [
103    {
104      "tag": "exception",
105      "values": [
106        "None"
107      ]
108    },
109    {
110      "tag": "method",
111      "values": [
112        "GET"
113      ]
114    },
115    {
116      "tag": "uri",
117      "values": [
118        "/actuator/metrics/{requiredMetricName}",
119        "/actuator",
120        "/actuator/prometheus",
121        "/actuator/metrics"
122      ]
123    },
124    {
125      "tag": "outcome",
126      "values": [
127        "CLIENT_ERROR",
128        "SUCCESS"
129      ]
130    },
131    {
132      "tag": "status",
133      "values": [
134        "404",
135        "200"
136      ]
137    }
138  ]
139}

Spring Boot Admin

 目的:为 Spring Boot 应用程序提供⼀套管理界面

主要功能

  • 集中展示应用程序 Actuator 相关的内容
  • 变更通知

服务端
依赖

 1<?xml version="1.0" encoding="UTF-8"?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4	<modelVersion>4.0.0</modelVersion>
 5	<parent>
 6		<groupId>org.springframework.boot</groupId>
 7		<artifactId>spring-boot-starter-parent</artifactId>
 8		<version>2.1.3.RELEASE</version>
 9		<relativePath/> <!-- lookup parent from repository -->
10	</parent>
11	<groupId>geektime.spring.boot</groupId>
12	<artifactId>sba-server</artifactId>
13	<version>0.0.1-SNAPSHOT</version>
14	<name>sba-server</name>
15	<description>Demo project for Spring Boot</description>
16
17	<properties>
18		<java.version>1.8</java.version>
19		<spring-boot-admin.version>2.1.3</spring-boot-admin.version>
20	</properties>
21
22	<dependencies>
23		<dependency>
24			<groupId>org.springframework.boot</groupId>
25			<artifactId>spring-boot-starter-security</artifactId>
26		</dependency>
27		<dependency>
28			<groupId>org.springframework.boot</groupId>
29			<artifactId>spring-boot-starter-web</artifactId>
30		</dependency>
31		<dependency>
32			<groupId>de.codecentric</groupId>
33			<artifactId>spring-boot-admin-starter-server</artifactId>
34		</dependency>
35
36		<dependency>
37			<groupId>org.springframework.boot</groupId>
38			<artifactId>spring-boot-starter-test</artifactId>
39			<scope>test</scope>
40		</dependency>
41		<dependency>
42			<groupId>org.springframework.security</groupId>
43			<artifactId>spring-security-test</artifactId>
44			<scope>test</scope>
45		</dependency>
46	</dependencies>
47
48	<dependencyManagement>
49		<dependencies>
50			<dependency>
51				<groupId>de.codecentric</groupId>
52				<artifactId>spring-boot-admin-dependencies</artifactId>
53				<version>${spring-boot-admin.version}</version>
54				<type>pom</type>
55				<scope>import</scope>
56			</dependency>
57		</dependencies>
58	</dependencyManagement>
59
60	<build>
61		<plugins>
62			<plugin>
63				<groupId>org.springframework.boot</groupId>
64				<artifactId>spring-boot-maven-plugin</artifactId>
65			</plugin>
66		</plugins>
67	</build>
68</project>

application.properties

1spring.application.name=sba-server
2server.port=8080
3
4spring.security.user.name=geektime
5spring.security.user.password=sba-server-password

SbaServerApplication(启动类)

 1package geektime.spring.boot.sba;
 2
 3import de.codecentric.boot.admin.server.config.AdminServerProperties;
 4import de.codecentric.boot.admin.server.config.EnableAdminServer;
 5import org.springframework.beans.factory.annotation.Autowired;
 6import org.springframework.boot.SpringApplication;
 7import org.springframework.boot.autoconfigure.SpringBootApplication;
 8import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 9import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
10import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
11import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
12
13@SpringBootApplication
14@EnableAdminServer
15public class SbaServerApplication extends WebSecurityConfigurerAdapter {
16	@Autowired
17	private AdminServerProperties adminServerProperties;
18
19	public static void main(String[] args) {
20		SpringApplication.run(SbaServerApplication.class, args);
21	}
22
23	@Override
24	protected void configure(HttpSecurity http) throws Exception {
25		String adminContextPath = adminServerProperties.getContextPath();
26
27		SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
28		successHandler.setTargetUrlParameter("redirectTo");
29		successHandler.setDefaultTargetUrl(adminContextPath + "/");
30
31		http.authorizeRequests()
32				.antMatchers(adminContextPath + "/assets/**").permitAll()
33				.antMatchers(adminContextPath + "/login").permitAll()
34				.anyRequest().authenticated()
35				.and()
36				.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
37				.logout().logoutUrl(adminContextPath + "/logout").and()
38				.httpBasic().and()
39				.csrf()
40				.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
41				.ignoringAntMatchers(
42						adminContextPath + "/instances",
43						adminContextPath + "/actuator/**"
44				);
45	}
46}

测试

1http://localhost:8080/login
2
3geektime
4sba-server-password

客户端
依赖

 1<?xml version="1.0" encoding="UTF-8"?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4	<modelVersion>4.0.0</modelVersion>
 5	<parent>
 6		<groupId>org.springframework.boot</groupId>
 7		<artifactId>spring-boot-starter-parent</artifactId>
 8		<version>2.1.3.RELEASE</version>
 9		<relativePath/> <!-- lookup parent from repository -->
10	</parent>
11	<groupId>geektime.spring.boot</groupId>
12	<artifactId>sba-client</artifactId>
13	<version>0.0.1-SNAPSHOT</version>
14	<name>sba-client</name>
15	<description>Demo project for Spring Boot</description>
16
17	<properties>
18		<java.version>1.8</java.version>
19		<spring-boot-admin.version>2.1.3</spring-boot-admin.version>
20	</properties>
21
22	<dependencies>
23		<dependency>
24			<groupId>org.springframework.boot</groupId>
25			<artifactId>spring-boot-starter-actuator</artifactId>
26		</dependency>
27		<dependency>
28			<groupId>org.springframework.boot</groupId>
29			<artifactId>spring-boot-starter-security</artifactId>
30		</dependency>
31		<dependency>
32			<groupId>org.springframework.boot</groupId>
33			<artifactId>spring-boot-starter-web</artifactId>
34		</dependency>
35		<dependency>
36			<groupId>de.codecentric</groupId>
37			<artifactId>spring-boot-admin-starter-client</artifactId>
38		</dependency>
39
40		<dependency>
41			<groupId>org.springframework.boot</groupId>
42			<artifactId>spring-boot-starter-test</artifactId>
43			<scope>test</scope>
44		</dependency>
45		<dependency>
46			<groupId>org.springframework.security</groupId>
47			<artifactId>spring-security-test</artifactId>
48			<scope>test</scope>
49		</dependency>
50	</dependencies>
51
52	<dependencyManagement>
53		<dependencies>
54			<dependency>
55				<groupId>de.codecentric</groupId>
56				<artifactId>spring-boot-admin-dependencies</artifactId>
57				<version>${spring-boot-admin.version}</version>
58				<type>pom</type>
59				<scope>import</scope>
60			</dependency>
61		</dependencies>
62	</dependencyManagement>
63
64	<build>
65		<plugins>
66			<plugin>
67				<groupId>org.springframework.boot</groupId>
68				<artifactId>spring-boot-maven-plugin</artifactId>
69			</plugin>
70		</plugins>
71	</build>
72
73</project>

application.properties

 1spring.application.name=sba-client
 2server.port=8081
 3
 4management.endpoints.web.exposure.include=*
 5
 6info.demo.name=Spring Boot Admin Client Demo
 7
 8spring.security.user.name=geektime
 9spring.security.user.password=sba-client-password
10
11spring.boot.admin.client.url=http://localhost:8080
12spring.boot.admin.client.username=geektime
13spring.boot.admin.client.password=sba-server-password
14
15spring.boot.admin.client.instance.metadata.user.name=${spring.security.user.name}
16spring.boot.admin.client.instance.metadata.user.password=${spring.security.user.password}

如何定制 Web 容器的运行参数

内嵌 Web 容器

1• spring-boot-starter-tomcat
2• spring-boot-starter-jetty
3• spring-boot-starter-undertow
4• spring-boot-starter-reactor-netty

修改容器配置

 1# 端口
 2server.port
 3server.address
 4
 5# 压缩
 6server.compression.enabled
 7server.compression.min-response-size
 8server.compression.mime-types
 9
10# Tomcat 特定配置
11server.tomcat.max-connections=10000
12server.tomcat.max-http-post-size=2MB
13server.tomcat.max-swallow-size=2MB
14server.tomcat.max-threads=200
15server.tomcat.min-spare-threads=10
16
17# 修改容器配置
18server.error.path=/error
19server.error.include-exception=false
20server.error.include-stacktrace=never
21server.error.whitelabel.enabled=true
22
23# 其他
24server.use-forward-headers
25server.servlet.session.timeout

配置方式示例:
application.properties

1spring.jpa.hibernate.ddl-auto=none  
2spring.jpa.properties.hibernate.show_sql=true  
3spring.jpa.properties.hibernate.format_sql=true  
4  
5#server.compression.enabled=true  
6#server.compression.min-response-size=512B  
7  
8server.error.include-stacktrace=always  
9server.error.include-exception=true  

编程方式修改容器配置
WebServerFactoryCustomizer

1• TomcatServletWebServerFactory
2• JettyServletWebServerFactory
3• UndertowServletWebServerFactory

变成方式示例:
WaiterServiceApplication

 1package geektime.spring.springbucks.waiter;
 2
 3import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
 4import geektime.spring.springbucks.waiter.controller.PerformanceInteceptor;
 5import org.springframework.boot.SpringApplication;
 6import org.springframework.boot.autoconfigure.SpringBootApplication;
 7import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
 8import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
 9import org.springframework.boot.web.server.Compression;
10import org.springframework.boot.web.server.WebServerFactoryCustomizer;
11import org.springframework.cache.annotation.EnableCaching;
12import org.springframework.context.annotation.Bean;
13import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
14import org.springframework.util.unit.DataSize;
15import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
16import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
17
18import java.util.TimeZone;
19
20@SpringBootApplication
21@EnableJpaRepositories
22@EnableCaching
23public class WaiterServiceApplication implements WebMvcConfigurer,
24		WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
25
26	public static void main(String[] args) {
27		SpringApplication.run(WaiterServiceApplication.class, args);
28	}
29
30	/**
31	 * 编程方式配置 GZIP压缩
32	 * @param factory
33	 */
34	@Override
35	public void customize(TomcatServletWebServerFactory factory) {
36		Compression compression = new Compression();
37		compression.setEnabled(true);
38		compression.setMinResponseSize(DataSize.ofBytes(512));
39		factory.setCompression(compression);
40	}
41
42	@Override
43	public void addInterceptors(InterceptorRegistry registry) {
44		registry.addInterceptor(new PerformanceInteceptor())
45				.addPathPatterns("/coffee/**").addPathPatterns("/order/**");
46	}
47
48	@Bean
49	public Hibernate5Module hibernate5Module() {
50		return new Hibernate5Module();
51	}
52
53	@Bean
54	public Jackson2ObjectMapperBuilderCustomizer jacksonBuilderCustomizer() {
55		return builder ->
56				builder.indentOutput(true)
57						.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
58	}
59}

构建 Docker 镜像

Docker 镜像

  • 镜像是静态的只读模版
  • 镜像中包含构建 Docker 容器的指令
  • 镜像是分层的
  • 通过 Dockerfile 来创建镜像

Dockerfile
Dockerfile 指令

通过 Maven 构建 Docker 镜像
准备工作

  • 提供一个 Dockerfile
1FROM java:8
2EXPOSE 8080
3ARG JAR_FILE
4ADD target/${JAR_FILE} /waiter-service.jar
5ENTRYPOINT ["java", "-jar","/waiter-service.jar"]
  • 配置 dockerfile-maven-plugin 插件
    pom.xml
  1<?xml version="1.0" encoding="UTF-8"?>
  2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4	<modelVersion>4.0.0</modelVersion>
  5	<parent>
  6		<groupId>org.springframework.boot</groupId>
  7		<artifactId>spring-boot-starter-parent</artifactId>
  8		<version>2.1.3.RELEASE</version>
  9		<relativePath/> <!-- lookup parent from repository -->
 10	</parent>
 11	<groupId>geektime.spring.springbucks</groupId>
 12	<artifactId>waiter-service</artifactId>
 13	<version>0.0.1-SNAPSHOT</version>
 14	<name>waiter-service</name>
 15	<description>Demo project for Spring Boot</description>
 16
 17	<properties>
 18		<java.version>1.8</java.version>
 19		<docker.image.prefix>springbucks</docker.image.prefix>
 20	</properties>
 21
 22	<dependencies>
 23		<dependency>
 24			<groupId>org.springframework.boot</groupId>
 25			<artifactId>spring-boot-starter-cache</artifactId>
 26		</dependency>
 27		<dependency>
 28			<groupId>org.springframework.boot</groupId>
 29			<artifactId>spring-boot-starter-data-jpa</artifactId>
 30		</dependency>
 31		<dependency>
 32			<groupId>org.springframework.boot</groupId>
 33			<artifactId>spring-boot-starter-web</artifactId>
 34		</dependency>
 35		<dependency>
 36			<groupId>org.springframework.boot</groupId>
 37			<artifactId>spring-boot-starter-actuator</artifactId>
 38		</dependency>
 39
 40		<dependency>
 41			<groupId>org.joda</groupId>
 42			<artifactId>joda-money</artifactId>
 43			<version>1.0.1</version>
 44		</dependency>
 45		<dependency>
 46			<groupId>org.jadira.usertype</groupId>
 47			<artifactId>usertype.core</artifactId>
 48			<version>6.0.1.GA</version>
 49		</dependency>
 50		<!-- 增加Jackson的Hibernate类型支持 -->
 51		<dependency>
 52			<groupId>com.fasterxml.jackson.datatype</groupId>
 53			<artifactId>jackson-datatype-hibernate5</artifactId>
 54			<version>2.9.8</version>
 55		</dependency>
 56
 57		<dependency>
 58			<groupId>org.apache.commons</groupId>
 59			<artifactId>commons-lang3</artifactId>
 60		</dependency>
 61
 62		<dependency>
 63			<groupId>com.h2database</groupId>
 64			<artifactId>h2</artifactId>
 65			<scope>runtime</scope>
 66		</dependency>
 67		<dependency>
 68			<groupId>org.projectlombok</groupId>
 69			<artifactId>lombok</artifactId>
 70			<optional>true</optional>
 71		</dependency>
 72		<dependency>
 73			<groupId>org.springframework.boot</groupId>
 74			<artifactId>spring-boot-starter-test</artifactId>
 75			<scope>test</scope>
 76		</dependency>
 77	</dependencies>
 78
 79	<build>
 80		<plugins>
 81			<plugin>
 82				<groupId>org.springframework.boot</groupId>
 83				<artifactId>spring-boot-maven-plugin</artifactId>
 84			</plugin>
 85			<plugin>
 86				<groupId>com.spotify</groupId>
 87				<artifactId>dockerfile-maven-plugin</artifactId>
 88				<version>1.4.10</version>
 89				<executions>
 90					<execution>
 91						<id>default</id>
 92						<goals>
 93							<goal>build</goal>
 94							<goal>push</goal>
 95						</goals>
 96					</execution>
 97				</executions>
 98				<configuration>
 99					<repository>${docker.image.prefix}/${project.artifactId}</repository>
100					<tag>${project.version}</tag>
101					<buildArgs>
102						<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
103					</buildArgs>
104				</configuration>
105			</plugin>
106		</plugins>
107	</build>
108
109</project>

执行构建

1mvn package
23mvn dockerfile:build

检查结果

1docker images
2
3REPOSITORY                   TAG                 IMAGE ID            CREATED              SIZE
4springbucks/waiter-service   0.0.1-SNAPSHOT      61568abfa910        About a minute ago   683MB
5java                         8                   d23bdf5b1b1b        3 years ago          643MB

作者:Soulboy