1VMOD_SAINTMODE(3) VMOD_SAINTMODE(3)
2
3
4
6 vmod_saintmode - Saint mode backend director
7
9 import saintmode [as name] [from "path"]
10
11 VOID blacklist(DURATION expires)
12
13 STRING status()
14
15 new xsaintmode = saintmode.saintmode(BACKEND backend, INT threshold)
16
17 BACKEND xsaintmode.backend()
18
19 INT xsaintmode.blacklist_count()
20
21 BOOL xsaintmode.is_healthy()
22
24 This VMOD provides saintmode functionality for Varnish Cache 4.1 and
25 newer. The code is in part based on Poul-Henning Kamp's saintmode
26 implementation in Varnish 3.0.
27
28 Saintmode lets you deal with a backend that is failing in random ways
29 for specific requests. It maintains a blacklist per backend, marking
30 the backend as sick for specific objects. When the number of objects
31 marked as sick for a backend reaches a set threshold, the backend is
32 considered sick for all requests. Each blacklisted object carries a
33 TTL, which denotes the time it will stay blacklisted.
34
35 Saintmode in Varnish 4.1 is implemented as a director VMOD. We instan‐
36 tiate a saintmode object and give it a backend as an argument. The
37 resulting object can then be used in place of the backend, with the
38 effect that it also has added saintmode capabilities.
39
40 Any director will then be able to use the saintmode backends, and as
41 backends marked sick are skipped by the director, this provides a way
42 to have fine grained health status on the backends, and making sure
43 that retries get a different backend than the one which failed.
44
45 Example:
46
47 vcl 4.0;
48
49 import saintmode;
50 import directors;
51
52 backend tile1 { .host = "192.0.2.11"; .port = "80"; }
53 backend tile2 { .host = "192.0.2.12"; .port = "80"; }
54
55 sub vcl_init {
56 # Instantiate sm1, sm2 for backends tile1, tile2
57 # with 10 blacklisted objects as the threshold for marking the
58 # whole backend sick.
59 new sm1 = saintmode.saintmode(tile1, 10);
60 new sm2 = saintmode.saintmode(tile2, 10);
61
62 # Add both to a director. Use sm0, sm1 in place of tile1, tile2.
63 # Other director types can be used in place of random.
64 new imagedirector = directors.random();
65 imagedirector.add_backend(sm1.backend(), 1);
66 imagedirector.add_backend(sm2.backend(), 1);
67 }
68
69 sub vcl_backend_fetch {
70 # Get a backend from the director.
71 # When returning a backend, the director will only return backends
72 # saintmode says are healthy.
73 set bereq.backend = imagedirector.backend();
74 }
75
76 sub vcl_backend_response {
77 if (beresp.status >= 500) {
78 # This marks the backend as sick for this specific
79 # object for the next 20s.
80 saintmode.blacklist(20s);
81 # Retry the request. This will result in a different backend
82 # being used.
83 return (retry);
84 }
85 }
86
87 VOID blacklist(DURATION expires)
88 Marks the backend as sick for a specific object. Used in vcl_back‐
89 end_response. Corresponds to the use of beresp.saintmode in Varnish
90 3.0. Only available in vcl_backend_response.
91
92 Example:
93
94 sub vcl_backend_response {
95 if (beresp.http.broken-app) {
96 saintmode.blacklist(20s);
97 return (retry);
98 }
99 }
100
101 STRING status()
102 Returns a JSON formatted status string suitable for use in vcl_synth.
103
104 sub vcl_recv {
105 if (req.url ~ "/saintmode-status") {
106 return (synth(700, "OK"));
107 }
108 }
109
110 sub vcl_synth {
111 if (resp.status == 700) {
112 synthetic(saintmode.status());
113 return (deliver);
114 }
115 }
116
117 Example JSON output:
118
119 {
120 "saintmode" : [
121 { "name": "sm1", "backend": "foo", "count": "3", "threshold": "10" },
122 { "name": "sm2", "backend": "bar", "count": "2", "threshold": "5" }
123 ]
124 }
125
126 new xsaintmode = saintmode.saintmode(BACKEND backend, INT threshold)
127 new xsaintmode = saintmode.saintmode(
128 BACKEND backend,
129 INT threshold
130 )
131
132 Constructs a saintmode director object. The threshold argument sets the
133 saintmode threshold, which is the maximum number of items that can be
134 blacklisted before the whole backend is regarded as sick. Corresponds
135 with the saintmode_threshold parameter of Varnish 3.0.
136
137 Example:
138
139 sub vcl_init {
140 new sm = saintmode.saintmode(b, 10);
141 }
142
143 BACKEND xsaintmode.backend()
144 Used for assigning the backend from the saintmode object.
145
146 Example:
147
148 sub vcl_backend_fetch {
149 set bereq.backend = sm.backend();
150 }
151
152 INT xsaintmode.blacklist_count()
153 Returns the number of objects currently blacklisted for a saintmode
154 director object.
155
156 Example:
157
158 sub vcl_deliver {
159 set resp.http.troublecount = sm.blacklist_count();
160 }
161
162 BOOL xsaintmode.is_healthy()
163 Checks if the object is currently blacklisted for a saintmode director
164 object. If there are no valid objects available (called from vcl_hit
165 or vcl_recv), the function will fall back to the backend's health func‐
166 tion.
167
168
169
170
171 VMOD_SAINTMODE(3)