1. Background

A service cluster built with Spring Cloud components will often have a timeout condition on the first request, but will be fine on the second. The Spring Cloud version is dalston.sr4.

Start related services involved:

  • Gateway (zuul gateway)
  • Auth-service authentication Service
  • User-service (user Service)

The test endpoint interface is HTTP :/login/oauth/token. The Service invocation sequence is gateway-> auth-service -> user-service. The gateway receives the request from the client and forwards the request to the authentication service. The authentication service verifies the user identity by invoking the user service. The user service returns the result of identity verification to the authentication service. After the three services are started, the call link information is monitored by Zipkin, and the first and second calls can be seen as shown in the figure below:

not-eager-1st

second

The previous two link monitoring snapshots show that the first time takes more than 10 times as long as the second time. In some cases, it is likely that a timeout will occur on the first request. Check the official website. The main reason is that the Zuul gateway and the Ribbon between each calling service load balancing Client lazy loading. As a result, the first request invocation includes the creation time of the Ribbon Client. By starting the log information, you can find:

lazy-load

There are two parts to solve this problem. One is to call the Ribbon hungry load between services. The other is to call the user-service for auth-service. The second is hungry loading of zuul gateway.

2. Hunger loading in the ribbon

After investigation, it is found that the first invocation of User-service by Auth-service takes a long time. The Ribbon does not initiate the Service instance for client load balancing at Service startup, but creates the corresponding Service instance at invocation. Therefore, the first call to user-service takes not only the time to send the HTTP request, but also the time to create the Ribbon Client. If the creation time is slow and the request timeout is short, it may take a long time or even time out. You can see the following configuration instructions on the official website:

Each Ribbon named client has a corresponding child Application Context that Spring Cloud maintains, this application context is lazily loaded up on the first request to the named client. This lazy loading behavior can be changed to instead eagerly load up these child Application contexts at startup by specifying the names of the Ribbon clients.

Spring Cloud maintains a relative sub-application context for each Ribbon client. The application context loads lazily on the first request to the specified client. However, it can be modified through the following configuration:

ribbon:
  eager-load:
    enabled: true
    clients: client1, client2, client3Copy the code

After the previous configuration, the Ribbon client of the User service is loaded when the authentication service starts.

el

3. Hungry loading of zuul gateway

The previous section addresses hungry loading when the Ribbon client for Auth-Service calls user-Service starts. The gateway serves as the gateway for external requests. Zuul uses the Ribbon internally to call other services. By default, Spring Cloud lazy loads the Ribbon client at the first invocation. Zuul also needs to maintain a relative sub-application context, so it also needs to load hungry at startup.

Zuul internally uses Ribbon for calling the remote url’s and Ribbon clients are by default lazily loaded up by Spring Cloud on first call. This behavior can be changed for Zuul using the following configuration and will result in the child Ribbon related Application contexts being eagerly loaded up at application startup time.

The configuration is as follows:

zuul:
  ribbon:
    eager-load:
      enabled: trueCopy the code

At this point, the optimization is complete, restart the service again for the first request, and find that the situation is much better, you can try to improve it yourself.

4. To summarize

This article mainly introduces the optimization method of the Spring Cloud service’s first request timeout. First, the background of the problem is introduced, and the causes are investigated. The main cause is lazy loading of the Ribbon client. Then configure the Ribbon client called between zuul gateway and service to load the context information of the Ribbon client when it starts. Finally,, HTTP calls still perform much worse than RPC calls. 🙂

Subscribe for the latest news, follow our wechat account, and join my planet.

xq


reference

  1. spring-cloud Dalston.SR4
  2. Spring Cloud practical tip: The ageyload mode of the Ribbon