Network Request Timeout


Network Request Timeout

In this tutorial, we are going to discuss about network request timeout. In the earlier tutorials we had a quick overview on the virtual services, destination rules and gateway. And we did a couple of use cases to have a better understanding.

Still, we need to have a lot more detailed understanding on these entities along with time out, fault injection and retry. Using the Istio I will be in a position to inject artificial time delay as well as set the timer dynamically for any Services.

Also, I will be in a position to inject any fault into the web service so that I can test how the calling web service behaves when a fault occurs in the web services.

All this I will be demonstrating in the next few tutorials where I will be using the Jaeger UI and Kiali console significantly to try out various combinations like changing the time out duration, as well as changing the number of retries or injecting different type of fault into the micro services.

So Kiali web UI provides lot more facility in terms of updating the yaml file directly within the UI as well as I can provide the yaml file through the command prompt also.

Network Timeout Setup

Let us understand the concept of creating timeout and artificial delay within the microservices using virtual services. For this I am going to use the book info sample application.

You can refer book info sample application tutorial for deployment and refer here for how can we see this application in Kiali web UI.

So now coming back to the actual use case, what we’re going to discuss that is the request time out. By default, the Istio is having the request timeout as 15 seconds between the services. And within the services for testing purpose different delays have been injected into various services.

For that, I can get into the source code and get better understanding. Let me access the source code of product page, reviews and ratings.

Product Page Source Code

You can refer here source code of product page. Don’t worry about the technology or the syntax.

def getProductDetails(product_id, headers):
     try:
         url = details['name'] + "/" + details['endpoint'] + "/" + str(product_id)
         res = requests.get(url, headers=headers, timeout=3.0)
     except BaseException:
         res = None
     if res and res.status_code == 200:
         return 200, res.json()
     else:
         status = res.status_code if res is not None and res.status_code else 500
         return status, {'error': 'Sorry, product details are currently unavailable for this book.'}

So in the above code snippet, you can get the details. It’s going to add the timeout as 3 seconds (timeout=3.0).

Basically, this particular service will not wait beyond 3 seconds to send the response back. If the response is getting beyond the 3 seconds, then it is going to send their response saying that particular page is not available. So the product page, it’s going to have a time out of 3 seconds.

Review Page Source Code

Now, let me access the review page source code.

private JsonObject getRatings(String productId, HttpHeaders requestHeaders) {
     ClientBuilder cb = ClientBuilder.newBuilder();
     Integer timeout = star_color.equals("black") ? 10000 : 2500;
     cb.property("com.ibm.ws.jaxrs.client.connection.timeout", timeout);
     cb.property("com.ibm.ws.jaxrs.client.receive.timeout", timeout);
     Client client = cb.build();
     WebTarget ratingsTarget = client.target(ratings_service + "/" + productId);
     Invocation.Builder builder = ratingsTarget.request(MediaType.APPLICATION_JSON);
     for (String header: headers_to_propagate) {
         String value = requestHeaders.getHeaderString(header);
         if (value != null) {
             builder.header(header, value);
         }
     }
     try {
         Response r = builder.get();
         int statusCode = r.getStatusInfo().getStatusCode();
         if (statusCode == Response.Status.OK.getStatusCode()) {
             try (StringReader stringReader = new StringReader(r.readEntity(String.class)); 
             JsonReader jsonReader = Json.createReader(stringReader)) {
                 return jsonReader.readObject();
             }
         } else {
             System.out.println("Error: unable to contact " + ratings_service + " got status of " + statusCode);
             return null;
         }
     } catch (ProcessingException e) {
         System.err.println("Error: unable to contact " + ratings_service + " got exception " + e);
         return null;
     }
 }

Here I do have the timeout set as 10 seconds for the reviews having black color that is version 2 and 2.5 seconds for other subsets. So whenever it is trying to get the ratings, It’s going to set the timeout as 10 seconds for version 2 and 2.5 seconds for others.

The reason why this specific hard coding is done within the code to understand various scenarios and the concepts available as a part of Istio.

So finally, whenever this particular services are getting accessed, the product page it’s going to have a timeout of 3 seconds and the review page, when it is access the ratings, it’s going to have the timeout of 10 seconds for version 2 i.e., black color star and 2.5 seconds for the other version i.e., the other subset version 1 and version 3.

Now I’m going to create the virtual services so that all the request land with the destination that is version 2. I can create a yaml file or I can provide the yaml file as a part of the command itself.

root@cluster-node:~/istio-1.10.0# kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
    route:
    - destination:
        host: reviews
        subset: v2
EOF

virtualservice.networking.istio.io/reviews created

Here I am going to create a virtual service where I’m going to have the destination only as subset version 2 for reviews.

So if I access the page, always it will land up with version 2. So whatever the time I am accessing always I will land up with version 2. Let me go ahead and verify within the jaeger UI.

Jaeger Web UI

Please refer here to deploy the Jaeger in your Istio Kubernetes cluster. Once installed Jaeger in your Kubernetes cluster then you can use port-forward command to access Jaeger web UI.

root@cluster-node:~/istio-1.10.0# kubectl port-forward service/tracing 9000:80 -n istio-system

Now you can access the Jaeger web UI in localhost with port 9000.

Jaeger Web UI

So now I’m going to select the details within the default namespace and click on Find Traces to find the traces.

Jaeger Web UI 1

So these are all the traces that happened a few seconds ago. Here if I click on the first trace then you can see complete trace.

Jaeger Web UI 2

Here if I checked the time frame totally it took 13.02 milliseconds. Details page got the response within 0.98 milliseconds. Ratings page got the response in 0.42 milliseconds. Now everything is good.

Now I am going to artificially inject a fixed delay of 2 seconds for the ratings. Let me go ahead and create the virtual service.

root@cluster-node:~/istio-1.10.0# kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percent: 100
        fixedDelay: 2s
    route:
    - destination:
      host: ratings
      subset: v1
EOF
virtualservice.networking.istio.io/ratings created    

Here I’m creating a fault where it is going to inject a delay that is 100 percent. That means for all the request with delay of 2 seconds and the destination now it is getting into the version 1. Now verify the Jaeger UI.

Jaeger Web UI 3

Here it injected a delay of 2 seconds. So the reviews it injected a delay of 2 seconds.

Jaeger Web UI 4

Because here it got the response after 2 seconds. The reason because we injected a delay of 2 seconds.

So This is getting 2.02 seconds response time because the delay is getting injected within this particular service ratings and reviews will wait for that much amount of time. The reason, because the timeout within the reviews is that is 10 seconds for version 2 and 2.5 seconds for others.

Summary

So in a quick summary we had a detailed understanding on how the book info gateway will be mapped within the ingress gateway and how the traffic will be routed to the node port and to the book info gateway port.

And finally, to the actual service and the how the timeout has been hard coded within the services for test purpose and how artificially we can inject the delay to create the fault within the service.

Network Request Timeout
Scroll to top