回答編集履歴

2

脈絡が無いので取り消し、記述差し替え。

2019/10/27 00:29

投稿

dodox86
dodox86

スコア9183

test CHANGED
@@ -130,7 +130,7 @@
130
130
 
131
131
 
132
132
 
133
- 大量の同時リクエストがあったとしてもプロセス数の制限を設けることで堅牢性やメモリ占有率を担保しようとする(<たぶん)Unicornのような形態をとるWEBアプリでは、ワーカープロセスの終了まで長時間占有するような処理はご法度、と言うことですね。数に制限のあるスレッドプールなどにも言えそうです。なお、CPUコアの数が依然として関係ないのは前の回答と同様のはずです。なぜならば、Unicorn自体がプロセス数の制限を担っているからです。
133
+ 大量の同時リクエストがあったとしてもプロセス数の制限を設けることで堅牢性やメモリ占有率を担保しようとする(<たぶん)Unicornのような形態をとるWEBアプリでは、ワーカープロセスの終了まで長時間占有するような処理はご法度、と言うことですね。数に制限のあるスレッドプールなどにも言えそうです。なお、CPUコアの数が依然として関係ないのは前の回答と同様のはずです。~~なぜならば、Unicorn自体がプロセス数の制限を担っているからです。~~ご質問に提示されたコードと私のコードは、CPUコア数の多少に影響されるものではありません。
134
134
 
135
135
 
136
136
 

1

Unicornのワーカープロセスについて追記

2019/10/27 00:29

投稿

dodox86
dodox86

スコア9183

test CHANGED
@@ -11,3 +11,191 @@
11
11
 
12
12
 
13
13
  CPUがシングルコアではなく、マルチコア、メニイコアの場合は、良くWEBの記事ではコア1つに対して1スレッドなどと説明がありますが、そうとも限りません。割り当てられなければ1つのコアで複数のスレッドが時分割されて動きますし、反対に複数のコアでもスレッドが1つしか使われないようなケースもあります。
14
+
15
+
16
+
17
+ ---
18
+
19
+ **コメントを受けて追記しました:2019-10-27 09:02**
20
+
21
+
22
+
23
+ ※回答欄へのコメントより引用:
24
+
25
+ > (ここでのワーカーはunicornなどでのワーカーです)
26
+
27
+
28
+
29
+ 前提がそうであると、上記の私の回答は該当しませんね。この場合は質問者さんの疑問どおり、
30
+
31
+ 「ワーカー数3で起動していた場合、3人が同時にアクセスしてきて、sleep処理を実行していると4人目は誰かの待機処理及びfunc_Bが終わるまでfunc_Aも実行されない状態」になります。
32
+
33
+
34
+
35
+ 手間取りましたが、Ubuntu16上でRuby Sinatra + Unicorn + nginxを使って確認してみました。
36
+
37
+ unicornを起動した状態が、以下のようであるとします。ワーカープロセスは3881, 3883, 3886の3つです。
38
+
39
+ ```bash
40
+
41
+ $ unicorn -c unicorn.conf -D
42
+
43
+
44
+
45
+ $ ps -ax
46
+
47
+ ...
48
+
49
+ 3879 pts/19 Sl+ 0:00 unicorn master -c unicorn.conf
50
+
51
+ 3881 pts/19 Sl+ 0:00 unicorn worker[0] -c unicorn.conf
52
+
53
+ 3883 pts/19 Sl+ 0:00 unicorn worker[1] -c unicorn.conf
54
+
55
+ 3886 pts/19 Sl+ 0:00 unicorn worker[2] -c unicorn.conf
56
+
57
+ ```
58
+
59
+ この状況で Sinatraで造ったWEBアプリを動作させます。`http://<server>/test1`へのGETで、10秒`sleep`するだけするものです。処理の前後でタイムスタンプを保存し、レスポンス中にプロセスIDと共にデータとして載せます。
60
+
61
+ ```
62
+
63
+ $ cat config.ru
64
+
65
+
66
+
67
+ require 'rubygems'
68
+
69
+ require 'sinatra/base'
70
+
71
+
72
+
73
+ class HelloApp < Sinatra::Base
74
+
75
+ get '/test1' do
76
+
77
+ now1 = Time.now
78
+
79
+ sleep(10)
80
+
81
+ now2 = Time.now
82
+
83
+ ts = now1.strftime("%H:%M:%S")
84
+
85
+ te = now2.strftime("%H:%M:%S")
86
+
87
+ s = "PID=#{Process.pid}, s=#{ts}, e=#{te}"
88
+
89
+ return s
90
+
91
+ end
92
+
93
+ end
94
+
95
+ run HelloApp
96
+
97
+ ```
98
+
99
+ この状態で、クライアント側から`wget`コマンドで3つのリクエストを送ります。3つが受け付けられた後、更に1つのリクエストを送出します。すると、以下のような結果が得られました。
100
+
101
+
102
+
103
+ ```
104
+
105
+ # 1つ目のリクエストでのレスポンス内容
106
+
107
+ PID=3881, s=08:13:33, e=08:13:43
108
+
109
+
110
+
111
+ # 2つ目のリクエストでのレスポンス内容
112
+
113
+ PID=3886, s=08:13:34, e=08:13:44
114
+
115
+
116
+
117
+ # 3つ目のリクエストでのレスポンス内容
118
+
119
+ PID=3883, s=08:13:36, e=08:13:46
120
+
121
+
122
+
123
+ # 4つ目のリクエスト
124
+
125
+ PID=3881, s=08:13:43, e=08:13:53
126
+
127
+ ```
128
+
129
+ 4つ目のリクエストによるレスポンスが、接続はWEBサーバーであるnginxに受け付けられるものの、実際にUnicornのワーカープロセスの処理に制御に移るのは、1つ目のリクエストの処理が終わったPID=3881のプロセスによるものであることが分かります。
130
+
131
+
132
+
133
+ 大量の同時リクエストがあったとしてもプロセス数の制限を設けることで堅牢性やメモリ占有率を担保しようとする(<たぶん)Unicornのような形態をとるWEBアプリでは、ワーカープロセスの終了まで長時間占有するような処理はご法度、と言うことですね。数に制限のあるスレッドプールなどにも言えそうです。なお、CPUコアの数が依然として関係ないのは前の回答と同様のはずです。なぜならば、Unicorn自体がプロセス数の制限を担っているからです。
134
+
135
+
136
+
137
+ 技術的な疑問から出た今回のご質問だったと思いますが、1プロセスで長時間占有するようなWEBアプリの処理は考えたことも無かったので、私も勉強になりました。
138
+
139
+
140
+
141
+ 参考に、確認に使ったunicorn.confの内容とnginxの設定内容を記しておきます。
142
+
143
+
144
+
145
+ unicorn.confの内容:
146
+
147
+ ```
148
+
149
+ worker_processes 3
150
+
151
+ listen '/tmp/unicorn.sock'
152
+
153
+ stderr_path File.expand_path('unicorn.log', File.dirname(__FILE__))
154
+
155
+ stdout_path File.expand_path('unicorn.log', File.dirname(__FILE__))
156
+
157
+ preload_app true
158
+
159
+ ```
160
+
161
+ nginxのconfの内容:(/etc/nginx/sites-available/default)
162
+
163
+ ```
164
+
165
+ upstream unicornapps {
166
+
167
+ server unix:tmp/unicorn.sock;
168
+
169
+ }
170
+
171
+
172
+
173
+ server {
174
+
175
+ listen 80 default_server;
176
+
177
+ listen [::]:80 default_server;
178
+
179
+
180
+
181
+ root /var/www/html;
182
+
183
+
184
+
185
+ index index.html index.htm index.nginx-debian.html;
186
+
187
+
188
+
189
+ server_name _;
190
+
191
+
192
+
193
+ location / {
194
+
195
+ proxy_pass http://unicornapps;
196
+
197
+ }
198
+
199
+ }
200
+
201
+ ```