-
Notifications
You must be signed in to change notification settings - Fork 421
Expand file tree
/
Copy pathch29s03.html
More file actions
138 lines (118 loc) · 10.4 KB
/
ch29s03.html
File metadata and controls
138 lines (118 loc) · 10.4 KB
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>29.3. 容器中如何优雅关闭 Springboot</title><link rel="stylesheet" type="text/css" href="../docbook.css" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="home" href="../index.html" title="Netkiller Java 手札(版)" /><link rel="up" href="spring.boot.shutdown.html" title="第 29 章 如何优雅停止 Springboot 运行" /><link rel="prev" href="ch29s02.html" title="29.2. kill 命令演示" /><link rel="next" href="ch29s04.html" title="29.4. 写入PID文件" /></head><body><a xmlns="" href="//www.netkiller.cn/">Home</a> | <a xmlns="" href="//netkiller.github.io/">简体中文</a> | <a xmlns="" href="http://netkiller.sourceforge.net/">繁体中文</a> | <a xmlns="" href="/journal/index.html">杂文</a>
| <a xmlns="" href="https://github.com/netkiller">Github</a> | <a xmlns="" href="https://zhuanlan.zhihu.com/netkiller">知乎专栏</a> | <a xmlns="" href="https://www.facebook.com/bg7nyt">Facebook</a> | <a xmlns="" href="http://cn.linkedin.com/in/netkiller/">Linkedin</a> | <a xmlns="" href="https://www.youtube.com/user/bg7nyt/videos">Youtube</a> | <a xmlns="" href="//www.netkiller.cn/home/donations.html">打赏(Donations)</a> | <a xmlns="" href="//www.netkiller.cn/home/about.html">About</a><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">29.3. 容器中如何优雅关闭 Springboot</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch29s02.html">上一页</a> </td><th width="60%" align="center">第 29 章 如何优雅停止 Springboot 运行</th><td width="20%" align="right"> <a accesskey="n" href="ch29s04.html">下一页</a></td></tr></table><hr /></div><table xmlns=""><tr><td><iframe src="//ghbtns.com/github-btn.html?user=netkiller&repo=netkiller.github.io&type=watch&count=true&size=large" height="30" width="170" frameborder="0" scrolling="0" style="width:170px; height: 30px;" allowTransparency="true"></iframe></td><td><iframe src="//ghbtns.com/github-btn.html?user=netkiller&repo=netkiller.github.io&type=fork&count=true&size=large" height="30" width="170" frameborder="0" scrolling="0" style="width:170px; height: 30px;" allowTransparency="true"></iframe></td><td><iframe src="//ghbtns.com/github-btn.html?user=netkiller&type=follow&count=true&size=large" height="30" width="240" frameborder="0" scrolling="0" style="width:240px; height: 30px;" allowTransparency="true"></iframe></td><td></td><td><a href="https://zhuanlan.zhihu.com/netkiller"><img src="/images/logo/zhihu-card-default.svg" height="25" /></a></td><td valign="middle"><a href="https://zhuanlan.zhihu.com/netkiller">知乎专栏</a></td><td></td><td></td><td></td><td></td></tr></table><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="id2095"></a>29.3. 容器中如何优雅关闭 Springboot</h3></div></div></div>
<p>容器与进程模式并没有什么区别,我们给容器发送终止信号,容器会转发给 Springboot。</p>
<p>理论归理论,我们还是需要亲自实践,这样才能理解更深刻。</p>
<p>准备实验环境和素材,下面是 docker-compose.yaml 编排文件</p>
<pre class="screen">
version: '3.9'
services:
spring:
image: openjdk:latest
container_name: spring
restart: always
hostname: www.netkiller.cn
environment:
TZ: Asia/Shanghai
JAVA_OPTS: -Xms256m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
ports:
- 8099:8080
volumes:
- ./test-0.0.1-SNAPSHOT.jar:/app/test-0.0.1-SNAPSHOT.jar
entrypoint: java -jar /app/test-0.0.1-SNAPSHOT.jar
command:
--spring.profiles.active=dev
--server.port=8080
</pre>
<div class="itemizedlist"><p class="title"><strong>实验步骤</strong></p><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">运行容器:docker-compose up</li><li class="listitem">观察容器:docker-compose logs -f</li><li class="listitem">停止容器:</li></ul></div>
<p>运行容器</p>
<pre class="screen">
[root@localhost netkiller.cn]# docker-compose up -d
Starting spring ... done
</pre>
<p>观察容器日志</p>
<pre class="screen">
[root@localhost netkiller.cn]# docker-compose logs -f
spring | Starting...
spring |
spring | . ____ _ __ _ _
spring | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
spring | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
spring | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
spring | ' |____| .__|_| |_|_| |_\__, | / / / /
spring | =========|_|==============|___/=/_/_/_/
spring | :: Spring Boot :: (v2.5.3)
spring |
spring | 2021-07-29 11:29:34.556 INFO 1 --- [ main] cn.netkiller.Application : Starting Application v0.0.1-SNAPSHOT using Java 16.0.2 on www.netkiller.cn with PID 1 (/app/test-0.0.1-SNAPSHOT.jar started by root in /)
spring | 2021-07-29 11:29:34.559 INFO 1 --- [ main] cn.netkiller.Application : The following profiles are active: dev
spring | 2021-07-29 11:29:35.903 WARN 1 --- [ main] io.undertow.websockets.jsr : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
spring | 2021-07-29 11:29:35.921 INFO 1 --- [ main] io.undertow.servlet : Initializing Spring embedded WebApplicationContext
spring | 2021-07-29 11:29:35.921 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1274 ms
spring | 2021-07-29 11:29:36.411 INFO 1 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator'
spring | 2021-07-29 11:29:36.437 INFO 1 --- [ main] io.undertow : starting server: Undertow - 2.2.9.Final
spring | 2021-07-29 11:29:36.444 INFO 1 --- [ main] org.xnio : XNIO version 3.8.4.Final
spring | 2021-07-29 11:29:36.451 INFO 1 --- [ main] org.xnio.nio : XNIO NIO Implementation Version 3.8.4.Final
spring | 2021-07-29 11:29:36.511 INFO 1 --- [ main] org.jboss.threads : JBoss Threads version 3.1.0.Final
spring | 2021-07-29 11:29:36.547 INFO 1 --- [ main] o.s.b.w.e.undertow.UndertowWebServer : Undertow started on port(s) 8080 (http)
spring | 2021-07-29 11:29:36.560 INFO 1 --- [ main] cn.netkiller.Application : Started Application in 2.48 seconds (JVM running for 2.923)
</pre>
<p>停止容器</p>
<pre class="screen">
[root@localhost netkiller.cn]# docker ps | grep spring
8901384d1973 openjdk:latest "java -jar /app/test…" 3 minutes ago Up About a minute 0.0.0.0:8099->8080/tcp, :::8099->8080/tcp spring
[root@localhost netkiller.cn]# docker stop spring
spring
[root@localhost netkiller.cn]# docker ps | grep spring
</pre>
<p>在观察日志</p>
<pre class="screen">
spring | 2021-07-29 11:31:31.807 INFO 1 --- [ionShutdownHook] io.undertow : stopping server: Undertow - 2.2.9.Final
spring | ==============================
spring | Destroying Spring
spring | ==============================
spring exited with code 143
</pre>
<p>现在可以看到 Springboot 是正常退出的</p>
<p>下面我们再做一个实验 docker kill</p>
<pre class="screen">
[root@localhost netkiller.cn]# docker-compose start
Starting spring ... done
[root@localhost netkiller.cn]# docker-compose logs -f
[root@localhost netkiller.cn]# docker kill spring
spring
</pre>
<p>此时再观察日志,只输出了一行。</p>
<pre class="screen">
spring exited with code 137
</pre>
<p>结论,docker kill = kill -9</p>
<p>现在你应该明白什么时候该使用什么命令终止程序了吧,同时我们在写程序的时候,也应该将程序的运行状态反应出来,在我们停止程序运行的时候,可以去观察进程的状态,而不是半天没有反应,只能怀疑进程死了,必须执行B计划(kill -9)这会造成很多数据丢失的问题。</p>
</div><script xmlns="" type="text/javascript" id="clustrmaps" src="//cdn.clustrmaps.com/map_v2.js?u=r5HG&d=9mi5r_kkDC8uxG8HuY3p4-2qgeeVypAK9vMD-2P6BYM"></script><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch29s02.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="spring.boot.shutdown.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="ch29s04.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">29.2. kill 命令演示 </td><td width="20%" align="center"><a accesskey="h" href="../index.html">起始页</a></td><td width="40%" align="right" valign="top"> 29.4. 写入PID文件</td></tr></table></div><script xmlns="">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-11694057-1', 'auto');
ga('send', 'pageview');
</script><script xmlns="" async="async">
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?93967759a51cda79e49bf4e34d0b0f2c";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script><script xmlns="" async="async">
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script></body></html>