Recently, I found that although some students know HTTP error codes, they are not clear about the specific causes. Therefore, I plan to simulate common error codes to help you understand them.
Environment set up
First of all, we set up an environment for simulation. The company structure is generally divided into load balancing layer and service layer. Nginx is used for load balancing and Go is used for service.
Go
This time use Go code, all code at: github.com/shidawuhen/…
The service listening port is 8082
Return visit: http://127.0.0.1:8082/ping to see
Nginx
The installation
Brew install Nginx for Mac
The Nginx installation directory is /usr/local/etc/ Nginx
Start the
Command line execution: nginx. If no error message is displayed, the execution succeeds.
access
http://localhost:8080/
configuration
Modify the Nginx config file to delegate the request to the Go service.
location / { # request url filtering, regular matching, ~ is case sensitive, ~* is case insensitive.
proxy_pass http://127.0.0.1:8082; Request redirected to mysvr defined server list
proxy_set_header Host $host;
proxy_set_header Connection ""; # set Connection to long Connection (default: no)
proxy_connect_timeout 30; Connection timeout with upstream server
proxy_read_timeout 60s; # how long does nginx wait to get a response to a request
proxy_send_timeout 12s; Upstream timeout to send requests to upstream server
proxy_http_version 1.1;
}
Copy the code
Nginx loads a new configuration: Nginx -s reload
Request ping and see that the request is forwarded to the Go service.
200-OK
Let’s take a look at the normal case.
request
http://localhost:8080/httpcode/code200
code
The corresponding Go code is:
func Code200(c *gin.Context) {
c.String(http.StatusOK, "ok")}Copy the code
return
500-Internal Server Error
instructions
500 (server internal error) : The server encountered an error and could not complete the request.
Internal service error: The server encountered an unexpected condition that prevented it from completing the processing of the request. It’s usually a syntax error or the service Panic.
request
http://localhost:8080/httpcode/code500
code
func Code500(c *gin.Context) {
panic("1")
c.String(http.StatusOK, "ok")}Copy the code
return
why
The main reason is that Gin uses the default Recover middleware, and the state is set to 500 after panic
func Default(a) *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
func defaultHandleRecovery(c *Context, err interface{}) {
c.AbortWithStatus(http.StatusInternalServerError)
}
Copy the code
504-Gateway Time-out
instructions
504 (gateway timeout) : The server acts as a gateway or proxy, but does not receive the request from the upstream server in time.
Gateway timeout: The server, when working as a gateway or proxy, does not receive a timely response (data) from the upstream server for the access required to complete the request. In other words, nginx, as a gateway, must obtain data from the upstream server in order to complete the request, but the upstream server did not provide the data within the specified time, so nginx cannot access the data. The upstream server response timed out.
After receiving the request, the gateway invokes other servers, which are upstream servers, to complete the work.
request
http://localhost:8080/httpcode/code504
code
func Code504(c *gin.Context) {
time.Sleep(time.Second * 100)
c.String(http.StatusOK, "ok")}Copy the code
return
why
Nginx sets the timeout period to 60 seconds, but the Go service can only respond after 100 seconds. Therefore, after 60 seconds, Nginx will directly return 504 if it receives no response.
502-Bad Gateway
instructions
502 (error gateway) : The server acting as a gateway or proxy received an invalid response from the upstream server.
Gateway error: The server, working as a gateway or proxy, receives an invalid response from the upstream server it entered while trying to process the request.
The so-called illegal, invalid, refers to the expected response.
request
http://localhost:8080/httpcode/code502
code
The Go service went down. Procedure
In this case, Nginx simply returns 502.
Go Actively closes the connection
Plan 1: new service
This operation requires the server to Close conn immediately after receiving the request:
package main
import (
"fmt"
"net"
)
func main(a) {
ln, err := net.Listen("tcp"."127.0.0.1:8082")
iferr ! =nil {
return
}
go func(a) {
for {
c, err := ln.Accept()
fmt.Println("Accept")
iferr ! =nil {
break
}
c.Close()
}
}()
select{}}Copy the code
Solution 2: Adjust WriteTimeout
Instead of using run in the main function, use your own server and set WriteTimeout to 1s.
//r.Run(":8082")
server := http.Server{
Addr: ": 8082",
WriteTimeout: time.Second * 1,
ReadTimeout: time.Second * 10,
IdleTimeout: time.Second * 10,
Handler: r,
}
server.ListenAndServe()
Copy the code
And let the function sleep for 2s.
func Code502(c *gin.Context) {
/ / 2
time.Sleep(time.Second * 2)
c.String(http.StatusOK, "ok")}Copy the code
return
503-Service Unavailable
instructions
503 (Service unavailable) : The server is currently unavailable (due to overloading or downtime for maintenance). Usually, this is a temporary state.
Generally speaking, 503 errors are mostly caused by traffic overload or resource overload caused by a large number of concurrent visits.
To simulate this situation, many system parameters need to be modified, which is risky, so we will not do the simulation this time. If you have other simulations, let me know.
499-CLIENT CLOSED REQUEST
instructions
499 (Client close Request) : a nonstandard status code introduced by Nginx for a scenario where the client closes the HTTP connection while Nginx is processing the request.
When the HTTP request reaches Nginx and is still being processed, the browser timeout expires and closes the connection. However, this status code is barely visible when requested by the browser, because the browser’s default timeout is long. See more at the service call, between business architecture often hierarchical design, broken down into different subsystems or service, such systems can often way through HTTP requests, and can set the timeout of each request, when the request in the upstream of the call to request time no return service, will take the initiative to close the connection, 499 is recorded in the upstream service log.
request
Using curl to set a 3-second timeout:
The curl – I – m 3 http://127.0.0.1:8080/httpcode/code499
code
func Code499(c *gin.Context) {
time.Sleep(time.Second * 100)
c.String(http.StatusOK, "ok")}Copy the code
return
Nginx -v: access. Log
127.0.0.1 - - [28/Nov/ 201:23:13:09 +0800] "GET /httpcode/code499 HTTP/1.1" -" "curl/7.64.1"Copy the code
conclusion
Although the simulation of various situations, but more detailed reasons in Nginx source code and Go source code, if you are interested in in-depth understanding.
In addition, in the simulation process, the examples used are only some of the reasons leading to the emergence of the corresponding status code, there are some other reasons, you can look for.
In the process of simulation, I also found a lot of new knowledge points, or very interesting.
data
-
Common HTTP error codes
-
HTTP 5** series status code details
-
HTTP status code 499/500/502/504
-
Golang HTTP server 502 problem analysis
-
Gin to set the Timeout
-
The HTTP status CODE CODE 500 | 502 | 504 analysis
-
Install nginx on MAC
-
Golang HTTP server 502 problem analysis
-
Record an online 502 sweep
-
Golang Optimization Path – HTTP long connections
-
Client Disconnection _Go Enables the client and server to capture packets and analyze the TCP three-way handshake and disconnection
-
Analysis of the case that the server terminates the connection
-
Gin IdleTimeout Local authentication
-
Nginx 503 error summary
-
How to simulate large load in low terminal environment
The last
If you like my article, you can follow my public account (Programmer Malatang)
My personal blog is shidawuhen.github. IO /
Review of previous articles:
-
Design patterns
-
recruitment
-
thinking
-
storage
-
The algorithm series
-
Reading notes
-
Small tools
-
architecture
-
network
-
The Go