FAQ
High Memory Usage
Connections not Closing due to Client Non-standard Usage
If the client initiates a large number of connections without closing them, there will be a large waste of resources in extreme cases, which can cause high memory usage problems over time.
Solution
Configure idleTimeout
reasonably. Hertz Server will close the connection to ensure the stability of the server after the timeout. The default configuration is 3 minutes.
Vast Request/Response
- If the request and response are very large, the data will all enter the memory, causing great pressure on it, when stream and chunk are not used.
- The streaming under the netpoll network library is a fake streaming. Since netpoll uses the LT trigger mode, it will trigger netpoll to read data when data arrives. The
Reader
interface is not implemented in terms of interface design. To enable streaming, Hertz encapsulates netpoll as a Reader, but the data still enters memory uncontrollably, so in a case of very vast streaming requests, memory pressure can result.
Solution
For very vast requests cases, use a combination of streaming and go net.
Common Error Code Checking
If the framework reports the following error codes, you can check it for possible causes. If there is an error code other than the following, the error code is not caused by the framework and needs to be located by the user to see whether it is set by itself or by some middleware.
404
- Access to the wrong port, commonly access to the debug port.
- Solution: Distinguish between listening port for framework service and listening port for debug server, the default is 8888.
- No routes matched
- Check whether all expected routes are registered correctly based on the startup log.
- Check that the access method is correct.
417
The server returns false
after executing the custom ContinueHandler
(the server actively rejects the subsequent body of the 100 Continue).
500
- Throwing the panic in middleware or in
handlerFunc
.- Solution: Locate specific problems with panic stack information.
- In the fs case, the path carries
/../
, and unexpected files may be accessed. The error log in server app log:cannot serve path with '/../' at position %d due to security reasons: %q
.- Solution: Check for illegal requests.
Context Guide
Description
Hertz also provides a standard context.Content
and a request context as input arguments to the function in the HandleFunc
Design. The handler/middleware
function signature is:
type HandlerFunc func(c context.Context, ctx *RequestContext)
Metadata Storage
Both contexts have the ability to store values, which is a simple principle for choosing which one to use: the life cycle of the stored value and the selected context to match.
Specifics
The ctx
is primarily used to store request-level variables, which are recycled after the request ends. It is characterized by high query efficiency (the bottom is map
), unsafe coroutines and the context.Context
Interface is not implemented.
c
is passed as the context between middleware /handler
. With all the semantics of context.Content
and safe coroutine. All that requires the context.Content
interface as input arguments, just pass c
directly.
In addition, Hertz also provides the ctx.Copy()
interface to make it easier for businesses to obtain a copy of the safe coroutine if they are faced with cases where they must pass ctx
asynchronously.
Numeric Precision Problem
Description
- JavaScript’s numeric type will lose precision once the number exceeds the limit, which will lead to inconsistencies between the front and back end values.
var s = '{"x":6855337641038665531}';
var obj = JSON.parse(s);
alert(obj.x);
// Output 6855337641038666000
- In the JSON specification, integers and floating-point types are not distinguished for numeric types.When using
json.Unmarshal
for JSON deserialization, if no data type is specified,interface{}
is used as the receiving variable, andfloat64
is used as the accepted type of the number by default. When the precision of the number exceedsWhen the precision range that float can represent, it will cause the problem of loss of precision.
Solution
- Use the
string
tag of the json standard package.
package main
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
type User struct {
ID int `json:"id,string"`
}
func main() {
h := server.Default()
h.GET("/hello", func(ctx context.Context, c *app.RequestContext) {
var u User
u.ID = 6855337641038665531
c.JSON(consts.StatusOK, u)
})
h.Spin()
}
- Using
json.Number
package main
import (
"context"
"encoding/json"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
type User struct {
ID json.Number `json:"id"`
}
func main() {
h := server.Default()
h.GET("/hello", func(ctx context.Context, c *app.RequestContext) {
var u User
err := json.Unmarshal([]byte(`{"id":6855337641038665531}`), &u)
if err != nil {
panic(err)
}
c.JSON(consts.StatusOK, u)
})
h.Spin()
}