Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the source code analysis of nginx common status codes

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

Nginx common status code source code analysis is what, I believe that many inexperienced people do not know what to do, so this paper summarizes the causes of the problem and solutions, through this article I hope you can solve this problem.

Recently, there are more 502 alarms in the production environment, and some problems are quite interesting through troubleshooting. Through the analysis of the nginx source code, it may bring some inspiration to check the source of the nginx status code. This article is based on 1.6.2 (mainly aligned with the build environment).

First of all, the common error code is defined in ngx_http_request.h. Some of it is caused by client and some is cited by upstream. Under what circumstances will it cause the following problems? What aspects do we start with to find out the problem?

# define NGX_HTTP_CLIENT_CLOSED_REQUEST 499#define NGX_HTTP_INTERNAL_SERVER_ERROR 500#define NGX_HTTP_NOT_IMPLEMENTED 501#define NGX_HTTP_BAD_GATEWAY 502#define NGX_HTTP_SERVICE_UNAVAILABLE 503#define NGX_HTTP_GATEWAY_TIME_OUT 504#define NGX_HTTP_INSUFFICIENT_STORAGE 507

Access.log can type the status of req, so you need to check the status assignment logic.

Grep-r status= src | grep 502

The logic of the backend status code 5xx is basically in the ngx_http_upstream_next of ngx_http_upstream.c, here is the status code of

Switch (ft_type) {case NGX_HTTP_UPSTREAM_FT_TIMEOUT: status = NGX_HTTP_GATEWAY_TIME_OUT; break; case NGX_HTTP_UPSTREAM_FT_HTTP_500: status = NGX_HTTP_INTERNAL_SERVER_ERROR; break; case NGX_HTTP_UPSTREAM_FT_HTTP_403: status = NGX_HTTP_FORBIDDEN; break Case NGX_HTTP_UPSTREAM_FT_HTTP_404: status = NGX_HTTP_NOT_FOUND; break

Here there is a correspondence between ft_type and status. Here ft_error NGX_HTTP_UPSTREAM_FT_TIMEOUT has an one-to-one correspondence with 504,500,500 and so on. Other ft type uses 502. Here, you need to check the assignment of ft.

# define NGX_HTTP_UPSTREAM_FT_ERROR 0x00000002#define NGX_HTTP_UPSTREAM_FT_TIMEOUT 0x00000004#define NGX_HTTP_UPSTREAM_FT_INVALID_HEADER 0x00000008#define NGX_HTTP_UPSTREAM_FT_HTTP_500 0x00000010#define NGX_HTTP_UPSTREAM_FT_HTTP_502 0x00000020#define NGX_HTTP_UPSTREAM_FT_HTTP_503 0x00000040#define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080#define NGX_HTTP _ UPSTREAM_FT_HTTP_403 0x00000100#define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000200#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000#define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000#define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000

504, NGX_HTTP_GATEWAY_TIME_OUT has several values assigned in ngx_http_upstream.c

The first place is ngx_http_upstream_process_upgraded.

If (downstream- > write- > timedout) {c-> timedout = 1; ngx_connection_error (c, NGX_ETIMEDOUT, "client timedout"); ngx_http_upstream_finalize_request (r, u, NGX_HTTP_REQUEST_TIME_OUT); return;} if (upstream- > read- > timedout | | upstream- > write- > timedout) {ngx_connection_error (c, NGX_ETIMEDOUT, "upstream timedout") Ngx_http_upstream_finalize_request (r, u, NGX_HTTP_GATEWAY_TIME_OUT); return;}

The second place is ngx_http_upstream_process_non_buffered_upstream.

Ngx_connection_t * c; c = u-> peer.connection; ngx_log_debug0 (NGX_LOG_DEBUG_HTTP, c-> log, 0, "http upstream process non buffered upstream"); c-> log- > action = "reading upstream"; if (c-> read- > timedout) {ngx_connection_error (c, NGX_ETIMEDOUT, "upstream timedout") Ngx_http_upstream_finalize_request (r, u, NGX_HTTP_GATEWAY_TIME_OUT); return;} ngx_http_upstream_process_non_buffered_request (r, 0)

The third place is ngx_http_upstream_process_body_in_memory.

C = u-> peer.connection; rev = c-> read; ngx_log_debug0 (NGX_LOG_DEBUG_HTTP, c-> log, 0, "http upstream process body on memory"); if (rev- > timedout) {ngx_connection_error (c, NGX_ETIMEDOUT, "upstream timedout"); ngx_http_upstream_finalize_request (r, u, NGX_HTTP_GATEWAY_TIME_OUT); return;}

In all three places, the connection is taken from upstream, and then read or write timeout. It can be seen that the main reason for 504 is read and write downstream timeout.

503, NGX_HTTP_SERVICE_UNAVAILABLE, grep can be found, mainly in the limit current limiting module will appear

Grep NGX_HTTP_SERVICE_UNAVAILABLE-r srcsrc/http/modules/ngx_http_limit_req_module.c: NGX_HTTP_SERVICE_UNAVAILABLE); src/http/modules/ngx_http_limit_conn_module.c: NGX_HTTP_SERVICE_UNAVAILABLE)

The source code can be clearly seen that the status code is reset here through ngx_http_limit_req_merge_conf, while ngx_http_limit_req_merge_conf is called in ngx_http_limit_conn_handler. If the current limit is hit, 503 is returned.

Static ngx_int_tngx_http_limit_conn_handler (ngx_http_request_t * r) {... If (r-> main- > limit_conn_set) {return NGX_DECLINED;} lccf = ngx_http_get_module_loc_conf (r, ngx_http_limit_conn_module); limits = lccf- > limits.elts; for (I = 0; I

< lccf->

Limits.nelts; iTunes +) {/ / process every limit_conn policy} return NGX_DECLINED;}

502 is relatively complex, and there are many situations. Grep 502, NGX_HTTP_BAD_GATEWAY, etc.

1. You can see that when ngx_resolve_start is in the resolve phase, if resolve fails, it will NGX_HTTP_BAD_GATEWAY.

2. Upstream- > read/write will NGX_HTTP_BAD_GATEWAY when it encounters eof / 0 / error. The recv system call returns n. If it is greater than 0, it will read and write bytes. It will return 0 when fin is accepted, and-1 when other errors occur. A common mistake here is that when the downstream of the nginx dies, it will return to an upstream fin, and then 502 to the client.

3. In the upstream connection phase, the failure report downstream of the ngx_http_upstream_connect connection will pass the NGX_HTTP_UPSTREAM_FT_ERROR to ngx_http_upstream_next.

Rc = ngx_event_connect_peer (& u-> peer); ngx_log_debug1 (NGX_LOG_DEBUG_HTTP, r-> connection- > log, 0, "http upstream connect:% I", rc); if (rc = = NGX_ERROR) {ngx_http_upstream_finalize_request (r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return } u-> state- > peer = u-> peer.name; if (rc = = NGX_BUSY) {ngx_log_error (NGX_LOG_ERR, r-> connection- > log, 0, "no live upstreams"); ngx_http_upstream_next (r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); return } if (rc = = NGX_DECLINED) {ngx_http_upstream_next (r, u, NGX_HTTP_UPSTREAM_FT_ERROR); return;}

4 when the header is invalid, the NGX_HTTP_UPSTREAM_FT_INVALID_HEADER will be passed to ngx_http_upstream_next

If (u-> buffer.last = = u-> buffer.end) {ngx_log_error (NGX_LOG_ERR, c-> log, 0, "upstream sent too big header"); ngx_http_upstream_next (r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); return;}

499 is relatively simple. When NGX_HTTP_CLIENT_CLOSED_REQUEST accesses nginx in client, if close is active, nginx will record 499. This status code will not be returned to client, only local records.

After reading the above, have you mastered the method of nginx common status code source code analysis? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report