Repository navigation
Expand file tree
/
Copy pathSIGNALS-zh-CN
More file actions
85 lines (54 loc) · 4.74 KB
/
Copy pathSIGNALS-zh-CN
File metadata and controls
85 lines (54 loc) · 4.74 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
== 信号处理
一般情况下,信号只需要往 Master 进程发送就可以了。然而,Unicorn 在内部也用信号的方式把信号发往各个子进程。除了 TTIN/TTOU 之外,信号的处理方式和 {nginx}[http://nginx.net/] 相似,所以可以共用 Unicorn 和 Nginx 的管理脚本。
这是一个 init script 管理分布式 Unicorn 的例子:
http://unicorn.bogomips.org/examples/init.sh
=== Master 进程
* HUP - 重新载入配置文件,并且完整的重启所有子进程。
如果 "preload_app" 为 false (默认的),那么子进程将会在重启的时候载入所有的应用程序代码。
如果 "preload_app" 为 true,那么应用程序代码改变将不会被重新载入;USR2 + QUIT (看下面的内容) 就是用来解决这这样的场景。在重启的时候,+Gem.refresh+ 会被调用,所以你新装的 RubyGems 也会被载入。不建议你在 Unicorn 跑着的时候卸载你应用程序依赖的 RubyGems,不然重新开启的子进程将会由于卸载掉的 Gem 依赖而启动失败。
* INT/TERM - 快速关闭,立刻杀掉所有子进程。
* QUIT - 正常关闭,关闭前会等待子进程完成进行中请求。
* USR1 - Master 进程与子进程重新打开所有的 log 文件,详见 Unicorn::Util.reopen_logs 是如何处理 log 的。
* USR2 - 重新启动,将会启动一个新的 Master 进程,当启动完成并且验证通过或,会发送 QUIT 到原始进程上面。
* WINCH - 正常结束子进程,但保持 Master 进程活着。
此方法只适用于 Master 进程。
* TTIN - 增加一个子进程。
* TTOU - 减少一个子进程。
=== 子进程
提示: Unicorn 4.8 里面大多数场景 Master 进程是通过 pipe 往子进程发送信号,而不是用 kill。然而也是支持信号的方式。
一般不需要直接往子进程发送信号,如果 Master 进程在运行,任何一个退出的子进程将会自动重新开启。
* INT/TERM - 快速关闭,立刻退出。
除非 WINCH 已经发给 Master 了(或 Master 已经没了),不然 Master 将会自动重新开启一个新进程出来。
直接关闭在 Unicorn 4.8 里面任然是用 kill(2) 的方式,而不是用内部 pipe。
* QUIT - 正常退出,直达当前处理结束。
同样的,如果 Master 还在,会又新开一个新的子进程出来。
* USR1 - 让此子进程重新打开 log 文件。
详见 Unicorn::Util.reopen_logs 是如何处理 log。
Log 文件在进程处理完当前请求之前不会重新打开的,
所以同一个请求的多行的 log 最终会写到同一个文件里面。
如果你的字进程启用了 user/group-switching,不建议用 "killall -USR1 unicorn"
直接对子进程发送 USR1 的信号。 你会遇到文件权限的问题,子进程将会被迫重启。
如果是对 Master 进程发送 USR1 信号,它会在在下发信号给子进程之前,首先会确保日志文件有正确的权限。
=== 运行中的 Unicorn 进程热更新过程
你是可以在不丢失已经接上的客户端连接的情况下,用一个新的 Unicorn 实例来替代老的。
那么做是可以重新载入你的应用程序源代码、Unicorn 配置、Ruby 可执行文件、以及所有的类库。
但是下面这些无法改变(和系统限制有关):
1. Unciron 的执行脚本路径。如果你想更换成另外一个 Ruby 安装路径,你可以修改 `#!` 行(PS: Bash script 的第一行)来执行不同的 Ruby 版本。
Unicorn Reload 过程和 Nginx 类似:
1. 发送 USR2 信号到 master 进程
2. 检查你的进程管理器或 pid 文件,看是否新的 master 是否启动成。如果使用 pid 文件,那么老进程的 pid 文件将会增加 ".oldbin" 后缀。
同时将会有两组 master 进程在同时运行,它们的 workers 都能接受请求。进程树看起来会是这样:
unicorn master (old)
\_ unicorn worker[0]
\_ unicorn worker[1]
\_ unicorn worker[2]
\_ unicorn worker[3]
\_ unicorn master
\_ unicorn worker[0]
\_ unicorn worker[1]
\_ unicorn worker[2]
\_ unicorn worker[3]
3. 现在可以发送 WINCH 到 old master 进程,于是会切换为仅 new workers 能处理请求。如果你是以交互模式启动 Unicorn(非 daemon),你可以跳过此步。后面第 5 步会有点困难,不过你依然可以跳过,如果不是 daemon 模式。
4. 现在你检查功能,确保从 old workers 切到 new workers 后,所有事情都正确运行。
5. 如果一切看起来都是正常的,你可以发送 QUIT 信号到 old master 来结束 old master 的进程。
如果有不正常的情况,你可以发送 HUP 信号到 old master 来恢复到 old master,然后发送 QUIT 到 new master 来终止。以达到回滚目的。