Upstream: proxy_limit_rate and friends.
The directives limit the upstream read rate. For example,
"proxy_limit_rate 42" limits proxy upstream read rate to
42 bytes per second.
Roman Arutyunyan
6 years ago
65 | 65 | return NGX_ABORT; |
66 | 66 | } |
67 | 67 | |
68 | if (rev->active && !rev->ready) { | |
69 | ngx_add_timer(rev, p->read_timeout); | |
70 | ||
71 | } else if (rev->timer_set) { | |
72 | ngx_del_timer(rev); | |
68 | if (!rev->delayed) { | |
69 | if (rev->active && !rev->ready) { | |
70 | ngx_add_timer(rev, p->read_timeout); | |
71 | ||
72 | } else if (rev->timer_set) { | |
73 | ngx_del_timer(rev); | |
74 | } | |
73 | 75 | } |
74 | 76 | } |
75 | 77 | |
98 | 100 | static ngx_int_t |
99 | 101 | ngx_event_pipe_read_upstream(ngx_event_pipe_t *p) |
100 | 102 | { |
103 | off_t limit; | |
101 | 104 | ssize_t n, size; |
102 | 105 | ngx_int_t rc; |
103 | 106 | ngx_buf_t *b; |
107 | ngx_msec_t delay; | |
104 | 108 | ngx_chain_t *chain, *cl, *ln; |
105 | 109 | |
106 | 110 | if (p->upstream_eof || p->upstream_error || p->upstream_done) { |
167 | 171 | break; |
168 | 172 | } |
169 | 173 | #endif |
174 | ||
175 | if (p->limit_rate) { | |
176 | if (p->upstream->read->delayed) { | |
177 | break; | |
178 | } | |
179 | ||
180 | limit = (off_t) p->limit_rate * (ngx_time() - p->start_sec + 1) | |
181 | - p->read_length; | |
182 | ||
183 | if (limit <= 0) { | |
184 | p->upstream->read->delayed = 1; | |
185 | delay = (ngx_msec_t) (- limit * 1000 / p->limit_rate + 1); | |
186 | ngx_add_timer(p->upstream->read, delay); | |
187 | break; | |
188 | } | |
189 | ||
190 | } else { | |
191 | limit = 0; | |
192 | } | |
170 | 193 | |
171 | 194 | if (p->free_raw_bufs) { |
172 | 195 | |
269 | 292 | break; |
270 | 293 | } |
271 | 294 | |
272 | n = p->upstream->recv_chain(p->upstream, chain, 0); | |
295 | n = p->upstream->recv_chain(p->upstream, chain, limit); | |
273 | 296 | |
274 | 297 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, |
275 | 298 | "pipe recv chain: %z", n); |
299 | 322 | break; |
300 | 323 | } |
301 | 324 | } |
325 | ||
326 | delay = p->limit_rate ? (ngx_msec_t) n * 1000 / p->limit_rate : 0; | |
302 | 327 | |
303 | 328 | p->read_length += n; |
304 | 329 | cl = chain; |
335 | 360 | |
336 | 361 | ln->next = p->free_raw_bufs; |
337 | 362 | p->free_raw_bufs = cl; |
363 | } | |
364 | ||
365 | if (delay > 0) { | |
366 | p->upstream->read->delayed = 1; | |
367 | ngx_add_timer(p->upstream->read, delay); | |
368 | break; | |
338 | 369 | } |
339 | 370 | } |
340 | 371 |
79 | 79 | size_t preread_size; |
80 | 80 | ngx_buf_t *buf_to_file; |
81 | 81 | |
82 | size_t limit_rate; | |
83 | time_t start_sec; | |
84 | ||
82 | 85 | ngx_temp_file_t *temp_file; |
83 | 86 | |
84 | 87 | /* STUB */ int num; |
332 | 332 | offsetof(ngx_http_fastcgi_loc_conf_t, upstream.force_ranges), |
333 | 333 | NULL }, |
334 | 334 | |
335 | { ngx_string("fastcgi_limit_rate"), | |
336 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
337 | ngx_conf_set_size_slot, | |
338 | NGX_HTTP_LOC_CONF_OFFSET, | |
339 | offsetof(ngx_http_fastcgi_loc_conf_t, upstream.limit_rate), | |
340 | NULL }, | |
341 | ||
335 | 342 | #if (NGX_HTTP_CACHE) |
336 | 343 | |
337 | 344 | { ngx_string("fastcgi_cache"), |
2349 | 2356 | |
2350 | 2357 | conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; |
2351 | 2358 | conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; |
2359 | conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE; | |
2352 | 2360 | |
2353 | 2361 | conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; |
2354 | 2362 | conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; |
2444 | 2452 | ngx_conf_merge_size_value(conf->upstream.buffer_size, |
2445 | 2453 | prev->upstream.buffer_size, |
2446 | 2454 | (size_t) ngx_pagesize); |
2455 | ||
2456 | ngx_conf_merge_size_value(conf->upstream.limit_rate, | |
2457 | prev->upstream.limit_rate, 0); | |
2447 | 2458 | |
2448 | 2459 | |
2449 | 2460 | ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, |
393 | 393 | ngx_conf_set_flag_slot, |
394 | 394 | NGX_HTTP_LOC_CONF_OFFSET, |
395 | 395 | offsetof(ngx_http_proxy_loc_conf_t, upstream.force_ranges), |
396 | NULL }, | |
397 | ||
398 | { ngx_string("proxy_limit_rate"), | |
399 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
400 | ngx_conf_set_size_slot, | |
401 | NGX_HTTP_LOC_CONF_OFFSET, | |
402 | offsetof(ngx_http_proxy_loc_conf_t, upstream.limit_rate), | |
396 | 403 | NULL }, |
397 | 404 | |
398 | 405 | #if (NGX_HTTP_CACHE) |
2489 | 2496 | |
2490 | 2497 | conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; |
2491 | 2498 | conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; |
2499 | conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE; | |
2492 | 2500 | |
2493 | 2501 | conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; |
2494 | 2502 | conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; |
2599 | 2607 | ngx_conf_merge_size_value(conf->upstream.buffer_size, |
2600 | 2608 | prev->upstream.buffer_size, |
2601 | 2609 | (size_t) ngx_pagesize); |
2610 | ||
2611 | ngx_conf_merge_size_value(conf->upstream.limit_rate, | |
2612 | prev->upstream.limit_rate, 0); | |
2602 | 2613 | |
2603 | 2614 | ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, |
2604 | 2615 | 8, ngx_pagesize); |
187 | 187 | ngx_conf_set_flag_slot, |
188 | 188 | NGX_HTTP_LOC_CONF_OFFSET, |
189 | 189 | offsetof(ngx_http_scgi_loc_conf_t, upstream.force_ranges), |
190 | NULL }, | |
191 | ||
192 | { ngx_string("scgi_limit_rate"), | |
193 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
194 | ngx_conf_set_size_slot, | |
195 | NGX_HTTP_LOC_CONF_OFFSET, | |
196 | offsetof(ngx_http_scgi_loc_conf_t, upstream.limit_rate), | |
190 | 197 | NULL }, |
191 | 198 | |
192 | 199 | #if (NGX_HTTP_CACHE) |
1108 | 1115 | |
1109 | 1116 | conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; |
1110 | 1117 | conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; |
1118 | conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE; | |
1111 | 1119 | |
1112 | 1120 | conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; |
1113 | 1121 | conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; |
1198 | 1206 | ngx_conf_merge_size_value(conf->upstream.buffer_size, |
1199 | 1207 | prev->upstream.buffer_size, |
1200 | 1208 | (size_t) ngx_pagesize); |
1209 | ||
1210 | ngx_conf_merge_size_value(conf->upstream.limit_rate, | |
1211 | prev->upstream.limit_rate, 0); | |
1201 | 1212 | |
1202 | 1213 | |
1203 | 1214 | ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, |
242 | 242 | ngx_conf_set_flag_slot, |
243 | 243 | NGX_HTTP_LOC_CONF_OFFSET, |
244 | 244 | offsetof(ngx_http_uwsgi_loc_conf_t, upstream.force_ranges), |
245 | NULL }, | |
246 | ||
247 | { ngx_string("uwsgi_limit_rate"), | |
248 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
249 | ngx_conf_set_size_slot, | |
250 | NGX_HTTP_LOC_CONF_OFFSET, | |
251 | offsetof(ngx_http_uwsgi_loc_conf_t, upstream.limit_rate), | |
245 | 252 | NULL }, |
246 | 253 | |
247 | 254 | #if (NGX_HTTP_CACHE) |
1288 | 1295 | |
1289 | 1296 | conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; |
1290 | 1297 | conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; |
1298 | conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE; | |
1291 | 1299 | |
1292 | 1300 | conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; |
1293 | 1301 | conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; |
1385 | 1393 | ngx_conf_merge_size_value(conf->upstream.buffer_size, |
1386 | 1394 | prev->upstream.buffer_size, |
1387 | 1395 | (size_t) ngx_pagesize); |
1396 | ||
1397 | ngx_conf_merge_size_value(conf->upstream.limit_rate, | |
1398 | prev->upstream.limit_rate, 0); | |
1388 | 1399 | |
1389 | 1400 | |
1390 | 1401 | ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, |
2578 | 2578 | p->downstream = c; |
2579 | 2579 | p->pool = r->pool; |
2580 | 2580 | p->log = c->log; |
2581 | p->limit_rate = u->conf->limit_rate; | |
2582 | p->start_sec = ngx_time(); | |
2581 | 2583 | |
2582 | 2584 | p->cacheable = u->cacheable || u->store; |
2583 | 2585 | |
3252 | 3254 | ngx_http_upstream_process_upstream(ngx_http_request_t *r, |
3253 | 3255 | ngx_http_upstream_t *u) |
3254 | 3256 | { |
3257 | ngx_event_t *rev; | |
3258 | ngx_event_pipe_t *p; | |
3255 | 3259 | ngx_connection_t *c; |
3256 | 3260 | |
3257 | 3261 | c = u->peer.connection; |
3262 | p = u->pipe; | |
3263 | rev = c->read; | |
3258 | 3264 | |
3259 | 3265 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
3260 | 3266 | "http upstream process upstream"); |
3261 | 3267 | |
3262 | 3268 | c->log->action = "reading upstream"; |
3263 | 3269 | |
3264 | if (c->read->timedout) { | |
3265 | u->pipe->upstream_error = 1; | |
3266 | ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); | |
3270 | if (rev->timedout) { | |
3271 | ||
3272 | if (rev->delayed) { | |
3273 | ||
3274 | rev->timedout = 0; | |
3275 | rev->delayed = 0; | |
3276 | ||
3277 | if (!rev->ready) { | |
3278 | ngx_add_timer(rev, p->read_timeout); | |
3279 | ||
3280 | if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
3281 | ngx_http_upstream_finalize_request(r, u, NGX_ERROR); | |
3282 | } | |
3283 | ||
3284 | return; | |
3285 | } | |
3286 | ||
3287 | if (ngx_event_pipe(p, 0) == NGX_ABORT) { | |
3288 | ngx_http_upstream_finalize_request(r, u, NGX_ERROR); | |
3289 | return; | |
3290 | } | |
3291 | ||
3292 | } else { | |
3293 | p->upstream_error = 1; | |
3294 | ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); | |
3295 | } | |
3267 | 3296 | |
3268 | 3297 | } else { |
3269 | if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { | |
3298 | ||
3299 | if (rev->delayed) { | |
3300 | ||
3301 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
3302 | "http upstream delayed"); | |
3303 | ||
3304 | if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
3305 | ngx_http_upstream_finalize_request(r, u, NGX_ERROR); | |
3306 | } | |
3307 | ||
3308 | return; | |
3309 | } | |
3310 | ||
3311 | if (ngx_event_pipe(p, 0) == NGX_ABORT) { | |
3270 | 3312 | ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
3271 | 3313 | return; |
3272 | 3314 | } |