Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_upstream_hash_module.c @ 7152:3b635e8fd499
FastCGI: adjust buffer position when parsing incomplete records.
Previously, nginx failed to move buffer position when parsing an incomplete
record header, and due to this wasn't be able to continue parsing once
remaining bytes of the record header were received.
This can affect response header parsing, potentially generating spurious errors
like "upstream sent unexpected FastCGI request id high byte: 1 while reading
response header from upstream". While this is very unlikely, since usually
record headers are written in a single buffer, this still can happen in real
life, for example, if a record header will be split across two TCP packets
and the second packet will be delayed.
This does not affect non-buffered response body proxying, due to "buf->pos =
buf->last;" at the start of the ngx_http_fastcgi_non_buffered_filter()
function. Also this does not affect buffered response body proxying, as
each input buffer is only passed to the filter once.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 09 Nov 2017 15:35:20 +0300 |
parents | 3b4fa572d56d |
children | ed599ea6c1f1 |
rev | line source |
---|---|
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
1 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
2 /* |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
3 * Copyright (C) Roman Arutyunyan |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
4 * Copyright (C) Nginx, Inc. |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
5 */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
6 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
7 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
10 #include <ngx_http.h> |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
11 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
12 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
13 typedef struct { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
14 uint32_t hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
15 ngx_str_t *server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
16 } ngx_http_upstream_chash_point_t; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
17 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
18 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
19 typedef struct { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
20 ngx_uint_t number; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
21 ngx_http_upstream_chash_point_t point[1]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
22 } ngx_http_upstream_chash_points_t; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
23 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
24 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
25 typedef struct { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
26 ngx_http_complex_value_t key; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
27 ngx_http_upstream_chash_points_t *points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
28 } ngx_http_upstream_hash_srv_conf_t; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
29 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
30 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
31 typedef struct { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
32 /* the round robin data must be first */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
33 ngx_http_upstream_rr_peer_data_t rrp; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
34 ngx_http_upstream_hash_srv_conf_t *conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
35 ngx_str_t key; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
36 ngx_uint_t tries; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
37 ngx_uint_t rehash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
38 uint32_t hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
39 ngx_event_get_peer_pt get_rr_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
40 } ngx_http_upstream_hash_peer_data_t; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
41 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
42 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
43 static ngx_int_t ngx_http_upstream_init_hash(ngx_conf_t *cf, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
44 ngx_http_upstream_srv_conf_t *us); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
45 static ngx_int_t ngx_http_upstream_init_hash_peer(ngx_http_request_t *r, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
46 ngx_http_upstream_srv_conf_t *us); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
47 static ngx_int_t ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
48 void *data); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
49 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
50 static ngx_int_t ngx_http_upstream_init_chash(ngx_conf_t *cf, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
51 ngx_http_upstream_srv_conf_t *us); |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
52 static int ngx_libc_cdecl |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
53 ngx_http_upstream_chash_cmp_points(const void *one, const void *two); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
54 static ngx_uint_t ngx_http_upstream_find_chash_point( |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
55 ngx_http_upstream_chash_points_t *points, uint32_t hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
56 static ngx_int_t ngx_http_upstream_init_chash_peer(ngx_http_request_t *r, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
57 ngx_http_upstream_srv_conf_t *us); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
58 static ngx_int_t ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
59 void *data); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
60 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
61 static void *ngx_http_upstream_hash_create_conf(ngx_conf_t *cf); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
62 static char *ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
63 void *conf); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
64 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
65 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
66 static ngx_command_t ngx_http_upstream_hash_commands[] = { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
67 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
68 { ngx_string("hash"), |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
69 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
70 ngx_http_upstream_hash, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
71 NGX_HTTP_SRV_CONF_OFFSET, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
72 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
73 NULL }, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
74 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
75 ngx_null_command |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
76 }; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
77 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
78 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
79 static ngx_http_module_t ngx_http_upstream_hash_module_ctx = { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
80 NULL, /* preconfiguration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
81 NULL, /* postconfiguration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
82 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
83 NULL, /* create main configuration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
84 NULL, /* init main configuration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
85 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
86 ngx_http_upstream_hash_create_conf, /* create server configuration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
87 NULL, /* merge server configuration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
88 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
89 NULL, /* create location configuration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
90 NULL /* merge location configuration */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
91 }; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
92 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
93 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
94 ngx_module_t ngx_http_upstream_hash_module = { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
95 NGX_MODULE_V1, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
96 &ngx_http_upstream_hash_module_ctx, /* module context */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
97 ngx_http_upstream_hash_commands, /* module directives */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
98 NGX_HTTP_MODULE, /* module type */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
99 NULL, /* init master */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
100 NULL, /* init module */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
101 NULL, /* init process */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
102 NULL, /* init thread */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
103 NULL, /* exit thread */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
104 NULL, /* exit process */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
105 NULL, /* exit master */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
106 NGX_MODULE_V1_PADDING |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
107 }; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
108 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
109 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
110 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
111 ngx_http_upstream_init_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
112 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
113 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
114 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
115 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
116 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
117 us->peer.init = ngx_http_upstream_init_hash_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
118 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
119 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
120 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
121 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
122 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
123 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
124 ngx_http_upstream_init_hash_peer(ngx_http_request_t *r, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
125 ngx_http_upstream_srv_conf_t *us) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
126 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
127 ngx_http_upstream_hash_srv_conf_t *hcf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
128 ngx_http_upstream_hash_peer_data_t *hp; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
129 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
130 hp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_hash_peer_data_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
131 if (hp == NULL) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
132 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
133 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
134 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
135 r->upstream->peer.data = &hp->rrp; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
136 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
137 if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
138 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
139 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
140 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
141 r->upstream->peer.get = ngx_http_upstream_get_hash_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
142 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
143 hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
144 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
145 if (ngx_http_complex_value(r, &hcf->key, &hp->key) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
146 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
147 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
148 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
149 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
150 "upstream hash key:\"%V\"", &hp->key); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
151 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
152 hp->conf = hcf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
153 hp->tries = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
154 hp->rehash = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
155 hp->hash = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
156 hp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
157 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
158 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
159 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
160 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
161 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
162 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
163 ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
164 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
165 ngx_http_upstream_hash_peer_data_t *hp = data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
166 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
167 time_t now; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
168 u_char buf[NGX_INT_T_LEN]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
169 size_t size; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
170 uint32_t hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
171 ngx_int_t w; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
172 uintptr_t m; |
6121
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
173 ngx_uint_t n, p; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
174 ngx_http_upstream_rr_peer_t *peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
175 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
176 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
177 "get hash peer, try: %ui", pc->tries); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
178 |
6102 | 179 ngx_http_upstream_rr_peers_wlock(hp->rrp.peers); |
180 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
181 if (hp->tries > 20 || hp->rrp.peers->single) { |
6102 | 182 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
183 return hp->get_rr_peer(pc, &hp->rrp); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
184 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
185 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
186 now = ngx_time(); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
187 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
188 pc->cached = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
189 pc->connection = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
190 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
191 for ( ;; ) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
192 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
193 /* |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
194 * Hash expression is compatible with Cache::Memcached: |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
195 * ((crc32([REHASH] KEY) >> 16) & 0x7fff) + PREV_HASH |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
196 * with REHASH omitted at the first iteration. |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
197 */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
198 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
199 ngx_crc32_init(hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
200 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
201 if (hp->rehash > 0) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
202 size = ngx_sprintf(buf, "%ui", hp->rehash) - buf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
203 ngx_crc32_update(&hash, buf, size); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
204 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
205 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
206 ngx_crc32_update(&hash, hp->key.data, hp->key.len); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
207 ngx_crc32_final(hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
208 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
209 hash = (hash >> 16) & 0x7fff; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
210 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
211 hp->hash += hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
212 hp->rehash++; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
213 |
6121
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
214 w = hp->hash % hp->rrp.peers->total_weight; |
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
215 peer = hp->rrp.peers->peer; |
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
216 p = 0; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
217 |
6121
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
218 while (w >= peer->weight) { |
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
219 w -= peer->weight; |
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
220 peer = peer->next; |
b6047abf5f30
Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents:
6102
diff
changeset
|
221 p++; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
222 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
223 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
224 n = p / (8 * sizeof(uintptr_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
225 m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
226 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
227 if (hp->rrp.tried[n] & m) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
228 goto next; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
229 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
230 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
231 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
232 "get hash peer, value:%uD, peer:%ui", hp->hash, p); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
233 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
234 if (peer->down) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
235 goto next; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
236 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
237 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
238 if (peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
239 && peer->fails >= peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
240 && now - peer->checked <= peer->fail_timeout) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
241 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
242 goto next; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
243 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
244 |
6705 | 245 if (peer->max_conns && peer->conns >= peer->max_conns) { |
246 goto next; | |
247 } | |
248 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
249 break; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
250 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
251 next: |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
252 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
253 if (++hp->tries > 20) { |
6102 | 254 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
255 return hp->get_rr_peer(pc, &hp->rrp); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
256 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
257 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
258 |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
259 hp->rrp.current = peer; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
260 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
261 pc->sockaddr = peer->sockaddr; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
262 pc->socklen = peer->socklen; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
263 pc->name = &peer->name; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
264 |
6099
6ff0ebd6fbf4
Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents:
5991
diff
changeset
|
265 peer->conns++; |
6ff0ebd6fbf4
Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents:
5991
diff
changeset
|
266 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
267 if (now - peer->checked > peer->fail_timeout) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
268 peer->checked = now; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
269 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
270 |
6102 | 271 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
272 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
273 hp->rrp.tried[n] |= m; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
274 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
275 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
276 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
277 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
278 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
279 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
280 ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
281 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
282 u_char *host, *port, c; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
283 size_t host_len, port_len, size; |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
284 uint32_t hash, base_hash; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
285 ngx_str_t *server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
286 ngx_uint_t npoints, i, j; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
287 ngx_http_upstream_rr_peer_t *peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
288 ngx_http_upstream_rr_peers_t *peers; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
289 ngx_http_upstream_chash_points_t *points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
290 ngx_http_upstream_hash_srv_conf_t *hcf; |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
291 union { |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
292 uint32_t value; |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
293 u_char byte[4]; |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
294 } prev_hash; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
295 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
296 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
297 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
298 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
299 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
300 us->peer.init = ngx_http_upstream_init_chash_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
301 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
302 peers = us->peer.data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
303 npoints = peers->total_weight * 160; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
304 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
305 size = sizeof(ngx_http_upstream_chash_points_t) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
306 + sizeof(ngx_http_upstream_chash_point_t) * (npoints - 1); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
307 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
308 points = ngx_palloc(cf->pool, size); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
309 if (points == NULL) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
310 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
311 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
312 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
313 points->number = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
314 |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
315 for (peer = peers->peer; peer; peer = peer->next) { |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
316 server = &peer->server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
317 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
318 /* |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
319 * Hash expression is compatible with Cache::Memcached::Fast: |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
320 * crc32(HOST \0 PORT PREV_HASH). |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
321 */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
322 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
323 if (server->len >= 5 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
324 && ngx_strncasecmp(server->data, (u_char *) "unix:", 5) == 0) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
325 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
326 host = server->data + 5; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
327 host_len = server->len - 5; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
328 port = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
329 port_len = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
330 goto done; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
331 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
332 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
333 for (j = 0; j < server->len; j++) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
334 c = server->data[server->len - j - 1]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
335 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
336 if (c == ':') { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
337 host = server->data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
338 host_len = server->len - j - 1; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
339 port = server->data + server->len - j; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
340 port_len = j; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
341 goto done; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
342 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
343 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
344 if (c < '0' || c > '9') { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
345 break; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
346 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
347 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
348 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
349 host = server->data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
350 host_len = server->len; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
351 port = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
352 port_len = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
353 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
354 done: |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
355 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
356 ngx_crc32_init(base_hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
357 ngx_crc32_update(&base_hash, host, host_len); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
358 ngx_crc32_update(&base_hash, (u_char *) "", 1); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
359 ngx_crc32_update(&base_hash, port, port_len); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
360 |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
361 prev_hash.value = 0; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
362 npoints = peer->weight * 160; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
363 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
364 for (j = 0; j < npoints; j++) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
365 hash = base_hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
366 |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
367 ngx_crc32_update(&hash, prev_hash.byte, 4); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
368 ngx_crc32_final(hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
369 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
370 points->point[points->number].hash = hash; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
371 points->point[points->number].server = server; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
372 points->number++; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
373 |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
374 #if (NGX_HAVE_LITTLE_ENDIAN) |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
375 prev_hash.value = hash; |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
376 #else |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
377 prev_hash.byte[0] = (u_char) (hash & 0xff); |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
378 prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff); |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
379 prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff); |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
380 prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff); |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
381 #endif |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
382 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
383 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
384 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
385 ngx_qsort(points->point, |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
386 points->number, |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
387 sizeof(ngx_http_upstream_chash_point_t), |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
388 ngx_http_upstream_chash_cmp_points); |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
389 |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
390 for (i = 0, j = 1; j < points->number; j++) { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
391 if (points->point[i].hash != points->point[j].hash) { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
392 points->point[++i] = points->point[j]; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
393 } |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
394 } |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
395 |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
396 points->number = i + 1; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
397 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
398 hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
399 hcf->points = points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
400 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
401 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
402 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
403 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
404 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
405 static int ngx_libc_cdecl |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
406 ngx_http_upstream_chash_cmp_points(const void *one, const void *two) |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
407 { |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
408 ngx_http_upstream_chash_point_t *first = |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
409 (ngx_http_upstream_chash_point_t *) one; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
410 ngx_http_upstream_chash_point_t *second = |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
411 (ngx_http_upstream_chash_point_t *) two; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
412 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
413 if (first->hash < second->hash) { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
414 return -1; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
415 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
416 } else if (first->hash > second->hash) { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
417 return 1; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
418 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
419 } else { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
420 return 0; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
421 } |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
422 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
423 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
424 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
425 static ngx_uint_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
426 ngx_http_upstream_find_chash_point(ngx_http_upstream_chash_points_t *points, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
427 uint32_t hash) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
428 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
429 ngx_uint_t i, j, k; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
430 ngx_http_upstream_chash_point_t *point; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
431 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
432 /* find first point >= hash */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
433 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
434 point = &points->point[0]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
435 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
436 i = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
437 j = points->number; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
438 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
439 while (i < j) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
440 k = (i + j) / 2; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
441 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
442 if (hash > point[k].hash) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
443 i = k + 1; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
444 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
445 } else if (hash < point[k].hash) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
446 j = k; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
447 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
448 } else { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
449 return k; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
450 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
451 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
452 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
453 return i; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
454 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
455 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
456 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
457 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
458 ngx_http_upstream_init_chash_peer(ngx_http_request_t *r, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
459 ngx_http_upstream_srv_conf_t *us) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
460 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
461 uint32_t hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
462 ngx_http_upstream_hash_srv_conf_t *hcf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
463 ngx_http_upstream_hash_peer_data_t *hp; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
464 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
465 if (ngx_http_upstream_init_hash_peer(r, us) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
466 return NGX_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
467 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
468 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
469 r->upstream->peer.get = ngx_http_upstream_get_chash_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
470 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
471 hp = r->upstream->peer.data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
472 hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
473 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
474 hash = ngx_crc32_long(hp->key.data, hp->key.len); |
6102 | 475 |
476 ngx_http_upstream_rr_peers_rlock(hp->rrp.peers); | |
477 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
478 hp->hash = ngx_http_upstream_find_chash_point(hcf->points, hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
479 |
6102 | 480 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
481 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
482 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
483 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
484 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
485 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
486 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
487 ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
488 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
489 ngx_http_upstream_hash_peer_data_t *hp = data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
490 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
491 time_t now; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
492 intptr_t m; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
493 ngx_str_t *server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
494 ngx_int_t total; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
495 ngx_uint_t i, n, best_i; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
496 ngx_http_upstream_rr_peer_t *peer, *best; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
497 ngx_http_upstream_chash_point_t *point; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
498 ngx_http_upstream_chash_points_t *points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
499 ngx_http_upstream_hash_srv_conf_t *hcf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
500 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
501 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
502 "get consistent hash peer, try: %ui", pc->tries); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
503 |
6102 | 504 ngx_http_upstream_rr_peers_wlock(hp->rrp.peers); |
505 | |
7123
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
506 if (hp->tries > 20 || hp->rrp.peers->single) { |
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
507 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
508 return hp->get_rr_peer(pc, &hp->rrp); |
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
509 } |
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
510 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
511 pc->cached = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
512 pc->connection = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
513 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
514 now = ngx_time(); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
515 hcf = hp->conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
516 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
517 points = hcf->points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
518 point = &points->point[0]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
519 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
520 for ( ;; ) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
521 server = point[hp->hash % points->number].server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
522 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
523 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
524 "consistent hash peer:%uD, server:\"%V\"", |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
525 hp->hash, server); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
526 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
527 best = NULL; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
528 best_i = 0; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
529 total = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
530 |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
531 for (peer = hp->rrp.peers->peer, i = 0; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
532 peer; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
533 peer = peer->next, i++) |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
534 { |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
535 n = i / (8 * sizeof(uintptr_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
536 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
537 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
538 if (hp->rrp.tried[n] & m) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
539 continue; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
540 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
541 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
542 if (peer->down) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
543 continue; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
544 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
545 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
546 if (peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
547 && peer->fails >= peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
548 && now - peer->checked <= peer->fail_timeout) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
549 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
550 continue; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
551 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
552 |
6705 | 553 if (peer->max_conns && peer->conns >= peer->max_conns) { |
554 continue; | |
555 } | |
556 | |
7124
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
557 if (peer->server.len != server->len |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
558 || ngx_strncmp(peer->server.data, server->data, server->len) |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
559 != 0) |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
560 { |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
561 continue; |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
562 } |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
563 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
564 peer->current_weight += peer->effective_weight; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
565 total += peer->effective_weight; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
566 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
567 if (peer->effective_weight < peer->weight) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
568 peer->effective_weight++; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
569 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
570 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
571 if (best == NULL || peer->current_weight > best->current_weight) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
572 best = peer; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
573 best_i = i; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
574 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
575 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
576 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
577 if (best) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
578 best->current_weight -= total; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
579 goto found; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
580 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
581 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
582 hp->hash++; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
583 hp->tries++; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
584 |
7123
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
585 if (hp->tries > 20) { |
6102 | 586 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
7123
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
587 return hp->get_rr_peer(pc, &hp->rrp); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
588 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
589 } |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
590 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
591 found: |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
592 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
593 hp->rrp.current = best; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
594 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
595 pc->sockaddr = best->sockaddr; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
596 pc->socklen = best->socklen; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
597 pc->name = &best->name; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
598 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
599 best->conns++; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
600 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
601 if (now - best->checked > best->fail_timeout) { |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
602 best->checked = now; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
603 } |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
604 |
6102 | 605 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
606 | |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
607 n = best_i / (8 * sizeof(uintptr_t)); |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
608 m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t)); |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
609 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
610 hp->rrp.tried[n] |= m; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
611 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
612 return NGX_OK; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
613 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
614 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
615 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
616 static void * |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
617 ngx_http_upstream_hash_create_conf(ngx_conf_t *cf) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
618 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
619 ngx_http_upstream_hash_srv_conf_t *conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
620 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
621 conf = ngx_palloc(cf->pool, sizeof(ngx_http_upstream_hash_srv_conf_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
622 if (conf == NULL) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
623 return NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
624 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
625 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
626 conf->points = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
627 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
628 return conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
629 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
630 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
631 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
632 static char * |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
633 ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
634 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
635 ngx_http_upstream_hash_srv_conf_t *hcf = conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
636 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
637 ngx_str_t *value; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
638 ngx_http_upstream_srv_conf_t *uscf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
639 ngx_http_compile_complex_value_t ccv; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
640 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
641 value = cf->args->elts; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
642 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
643 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
644 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
645 ccv.cf = cf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
646 ccv.value = &value[1]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
647 ccv.complex_value = &hcf->key; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
648 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
649 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
650 return NGX_CONF_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
651 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
652 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
653 uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
654 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
655 if (uscf->peer.init_upstream) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
656 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
657 "load balancing method redefined"); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
658 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
659 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
660 uscf->flags = NGX_HTTP_UPSTREAM_CREATE |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
661 |NGX_HTTP_UPSTREAM_WEIGHT |
6705 | 662 |NGX_HTTP_UPSTREAM_MAX_CONNS |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
663 |NGX_HTTP_UPSTREAM_MAX_FAILS |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
664 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
665 |NGX_HTTP_UPSTREAM_DOWN; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
666 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
667 if (cf->args->nelts == 2) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
668 uscf->peer.init_upstream = ngx_http_upstream_init_hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
669 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
670 } else if (ngx_strcmp(value[2].data, "consistent") == 0) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
671 uscf->peer.init_upstream = ngx_http_upstream_init_chash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
672 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
673 } else { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
674 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
675 "invalid parameter \"%V\"", &value[2]); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
676 return NGX_CONF_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
677 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
678 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
679 return NGX_CONF_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
680 } |