varnish 4: serve graced object if beresp.status is an error? - varnish

is there a way to change what is delivered to the client between the backend response and the delivery?
i'm trying to figure out a way to continue to serve graced objects if the backend returns a 4xx or 5xx response (which don't get cached). the backend probe hits a static page, which will keep the backend healthy as long as the webserver on it is running, but dynamic pages will return errors if they run into problems.
currently, graced objects will continue to be served if the probe fails (e.g. i shut down the webserver completely on the backend). but if i just break the site itself, I see the first request returns the cached object and initiates a new fetch from the backend, and then the following requests pass through the non-cacheable error (404 in this case).
I can't seem to find a way for varnish to try to fetch from the backend, get an error response, and serve the graced object instead of the error, unless the backend is recognized as completely unhealthy.
am i missing a step?

You can do that adding some VCL to your configuration. Please, check my answer to a similar question: https://stackoverflow.com/a/32970571/1806102.
The idea is (1) abandon the request during vcl_backend_response; (2) restart the request during vcl_synth; (3) set a always-sick backend during vcl_recv; and (4) deliver grace content during vcl_hit if the backend is sick.

Related

Error 503 on Cloud Run for a simple messaging application

I have built a simple Python/Flask app for sending automatic messages in Slack and Telegram after receiving a post request in the form of:
response = requests.post(url='https://my-cool-endpoint.a.run.app/my-app/api/v1.0/',
json={'message': msg_body, 'urgency': urgency, 'app_name': app_name},
auth=(username, password))
, or even a similar curl request. It works well in localhost, as well as a containerized application. However, after deploying it to Cloud Run, the requests keep resulting in the following 503 Error:
POST 503 663 B 10.1 s python-requests/2.24.0 The request failed because either the HTTP response was malformed or connection to the instance had an error.
Does it have anything to do with a Flask timeout or something like that? I really don't understand what is happening, because the response doesn't take (and shouldn't) take more than a few seconds (usually less than 5s).
Thank you all.
--EDIT
Problem solved after thinking about AhmetB reply. I've found that I was setting the host as the public ip address of the SQL instance, and that is not the case when you post it to Cloud Run. For that to work out, you must replace host by unix_socket and then set its path.
Thanks you all! This question is closed.

Request module throwing 403 without trying

I have a really weird problem.
I have two node.js servers running express, say A and B. I use request to send request from one A to B. Sometimes, the request module just throws 403 at me Forbidden file type or location without even sending a request to B.
I have multiple servers running same code, only one of the servers have this issue. Everyone else properly sends the request and shows response.
I did a tcpdump, no entries for communication between A and B.
This was caused by HTTP_PROXY settings I had in my systemd configuration.

how to tell express.js to queue the requests in a certain order

I am sending requests to a route using express.js
my problem is that i am getting the requests according to the order in which they came to express.
imagine i have a create request which takes very long but i dont care to postpond it, and a get request (to the same route) that takes a very short while.
now imagine i send 3000 create requests (without waiting to responses) and then 1 get request. express is giving me the get request into the server's api only after sending in all the 3000 creations. i want to tell express "hey you, listen, if you got a request which has "get" in its body, place it in the head of the queue and not its tail". this way, express will give me the get request as the next request even that there were 2999 create request comming before it that weren't handled yet.
I tried to do a work queue in the server itself but it didn't solve the issue because the "get" job didn't reach my api at all until I handled many many create requests.
can i do that? if so, how?
Thanks for any help.

What does Varnish hit-for-pass mean?

Varnish Version 3 has some objects for different operations.
For example, pass is used when it has to retrieve data from backend, and it uses hit when it finds requesting content in cache.
But I cant understand usage of hit-for-pass. When does Varnish use it? I haven't found any useful material on the web which makes it clear.
A hit_for_pass object is made to optimize the fetch procedure against a backend server.
For ordinary cache misses, Varnish will queue all clients requesting the same cache object and send a single request to the backend. This is usually quickest, letting the backend work on a single request instead of swamping it with n requests at the same time.
Remember that some backends use a lot of time preparing an object; 10 seconds is not uncommon. If this is the front page HTML and you have 3000 req/s against it, sending just one backend request makes a lot of sense.
The issue arises when after Varnish has fetched the object it sees that it can't be cached. Reasons for this can be that the backend sends "Cache-Control: max-age=0", or (more often) a Set-Cookie header. In this case you have somewhere between 3,000 and 30,000 clients (3k req/s * 10sec) sitting idle in queue, and for each of these clients the same slow one-at-a-time backend request must complete to serve them. This will ruin your site response time.
So Varnish saves the decision that this request cannot be cached by creating a hit_for_pass object.
On the next request for the same URL, the cache lookup will return a hit_for_pass object. This signals that multiple fetches may be done at the same time. Your backend might not be too happy about it, but at least Varnish isn't queuing the clients for no reason.

In NodeJS, if I don't respond to a request, can anything negative happen to my server?

I have a nodeJS server running. There are some requests that the server will receive that don't need a response (just updating in the server). If the update fails, it isn't something that the client will need to worry about. In order to save bandwidth, I'd like to not respond to said requests. Can not responding to requests somehow affect my server's performance?
Assuming you are using http, You have to at least return an http response code. If you don't you are violating http -- the client is going to wait for a response, and will die trying (i.e. will timeout after a while).
According to the documentation for end, you must call end for every response. That is going to send a response code for you, if you don't specify one. So yes, need to respond.

Resources