Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_upstream_hash_module.c @ 8509:5b0c229ba5fe quic
QUIC: fixed padding calculation.
Sometimes, QUIC packets need to be of certain (or minimal) size. This is
achieved by adding PADDING frames. It is possible, that adding padding will
affect header size, thus forcing us to recalculate padding size once more.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 05 Jul 2021 13:17:10 +0300 |
parents | d964b0aee8e7 |
children |
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 |
7300
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
179 ngx_http_upstream_rr_peers_rlock(hp->rrp.peers); |
6102 | 180 |
7513
d964b0aee8e7
Upstream hash: fall back to round-robin if hash key is empty.
Niklas Keller <me@kelunik.com>
parents:
7300
diff
changeset
|
181 if (hp->tries > 20 || hp->rrp.peers->single || hp->key.len == 0) { |
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 |
7300
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
231 ngx_http_upstream_rr_peer_lock(hp->rrp.peers, peer); |
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
232 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
233 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
234 "get hash peer, value:%uD, peer:%ui", hp->hash, p); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
235 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
236 if (peer->down) { |
7300
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
237 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
238 goto next; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
239 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
240 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
241 if (peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
242 && peer->fails >= peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
243 && now - peer->checked <= peer->fail_timeout) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
244 { |
7300
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
245 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
246 goto next; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
247 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
248 |
6705 | 249 if (peer->max_conns && peer->conns >= peer->max_conns) { |
7300
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
250 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer); |
6705 | 251 goto next; |
252 } | |
253 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
254 break; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
255 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
256 next: |
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 if (++hp->tries > 20) { |
6102 | 259 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
260 return hp->get_rr_peer(pc, &hp->rrp); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
261 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
262 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
263 |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
264 hp->rrp.current = peer; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
265 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
266 pc->sockaddr = peer->sockaddr; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
267 pc->socklen = peer->socklen; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
268 pc->name = &peer->name; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
269 |
6099
6ff0ebd6fbf4
Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents:
5991
diff
changeset
|
270 peer->conns++; |
6ff0ebd6fbf4
Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents:
5991
diff
changeset
|
271 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
272 if (now - peer->checked > peer->fail_timeout) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
273 peer->checked = now; |
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 |
7300
ed599ea6c1f1
Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents:
7124
diff
changeset
|
276 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer); |
6102 | 277 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
278 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
279 hp->rrp.tried[n] |= m; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
280 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
281 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
282 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
283 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
284 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
285 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
286 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
|
287 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
288 u_char *host, *port, c; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
289 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
|
290 uint32_t hash, base_hash; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
291 ngx_str_t *server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
292 ngx_uint_t npoints, i, j; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
293 ngx_http_upstream_rr_peer_t *peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
294 ngx_http_upstream_rr_peers_t *peers; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
295 ngx_http_upstream_chash_points_t *points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
296 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
|
297 union { |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
298 uint32_t value; |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
299 u_char byte[4]; |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
300 } prev_hash; |
5717
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 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
303 return NGX_ERROR; |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
306 us->peer.init = ngx_http_upstream_init_chash_peer; |
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 peers = us->peer.data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
309 npoints = peers->total_weight * 160; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
310 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
311 size = sizeof(ngx_http_upstream_chash_points_t) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
312 + sizeof(ngx_http_upstream_chash_point_t) * (npoints - 1); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
313 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
314 points = ngx_palloc(cf->pool, size); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
315 if (points == NULL) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
316 return NGX_ERROR; |
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 points->number = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
320 |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
321 for (peer = peers->peer; peer; peer = peer->next) { |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
322 server = &peer->server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
323 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
324 /* |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
325 * Hash expression is compatible with Cache::Memcached::Fast: |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
326 * crc32(HOST \0 PORT PREV_HASH). |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
327 */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
328 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
329 if (server->len >= 5 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
330 && ngx_strncasecmp(server->data, (u_char *) "unix:", 5) == 0) |
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 host = server->data + 5; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
333 host_len = server->len - 5; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
334 port = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
335 port_len = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
336 goto done; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
337 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
338 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
339 for (j = 0; j < server->len; j++) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
340 c = server->data[server->len - j - 1]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
341 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
342 if (c == ':') { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
343 host = server->data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
344 host_len = server->len - j - 1; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
345 port = server->data + server->len - j; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
346 port_len = j; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
347 goto done; |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
350 if (c < '0' || c > '9') { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
351 break; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
352 } |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
355 host = server->data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
356 host_len = server->len; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
357 port = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
358 port_len = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
359 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
360 done: |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
361 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
362 ngx_crc32_init(base_hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
363 ngx_crc32_update(&base_hash, host, host_len); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
364 ngx_crc32_update(&base_hash, (u_char *) "", 1); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
365 ngx_crc32_update(&base_hash, port, port_len); |
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 prev_hash.value = 0; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
368 npoints = peer->weight * 160; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
369 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
370 for (j = 0; j < npoints; j++) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
371 hash = base_hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
372 |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
373 ngx_crc32_update(&hash, prev_hash.byte, 4); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
374 ngx_crc32_final(hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
375 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
376 points->point[points->number].hash = hash; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
377 points->point[points->number].server = server; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
378 points->number++; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
379 |
6148
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
380 #if (NGX_HAVE_LITTLE_ENDIAN) |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
381 prev_hash.value = hash; |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
382 #else |
bf8b6534db3a
Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6121
diff
changeset
|
383 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
|
384 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
|
385 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
|
386 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
|
387 #endif |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
388 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
389 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
390 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
391 ngx_qsort(points->point, |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
392 points->number, |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
393 sizeof(ngx_http_upstream_chash_point_t), |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
394 ngx_http_upstream_chash_cmp_points); |
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 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
|
397 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
|
398 points->point[++i] = points->point[j]; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
399 } |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
400 } |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
401 |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
402 points->number = i + 1; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
403 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
404 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
|
405 hcf->points = points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
406 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
407 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
408 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
409 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
410 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
411 static int ngx_libc_cdecl |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
412 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
|
413 { |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
414 ngx_http_upstream_chash_point_t *first = |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
415 (ngx_http_upstream_chash_point_t *) one; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
416 ngx_http_upstream_chash_point_t *second = |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
417 (ngx_http_upstream_chash_point_t *) two; |
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 if (first->hash < second->hash) { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
420 return -1; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
421 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
422 } else if (first->hash > second->hash) { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
423 return 1; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
424 |
5991
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
425 } else { |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
426 return 0; |
435ee290c2e1
Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents:
5717
diff
changeset
|
427 } |
5717
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
430 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
431 static ngx_uint_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
432 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
|
433 uint32_t hash) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
434 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
435 ngx_uint_t i, j, k; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
436 ngx_http_upstream_chash_point_t *point; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
437 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
438 /* find first point >= hash */ |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
439 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
440 point = &points->point[0]; |
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 i = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
443 j = points->number; |
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 while (i < j) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
446 k = (i + j) / 2; |
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 if (hash > point[k].hash) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
449 i = k + 1; |
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 } else if (hash < point[k].hash) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
452 j = k; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
453 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
454 } else { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
455 return k; |
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 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
458 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
459 return i; |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
462 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
463 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
464 ngx_http_upstream_init_chash_peer(ngx_http_request_t *r, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
465 ngx_http_upstream_srv_conf_t *us) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
466 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
467 uint32_t hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
468 ngx_http_upstream_hash_srv_conf_t *hcf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
469 ngx_http_upstream_hash_peer_data_t *hp; |
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 if (ngx_http_upstream_init_hash_peer(r, us) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
472 return NGX_ERROR; |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
475 r->upstream->peer.get = ngx_http_upstream_get_chash_peer; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
476 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
477 hp = r->upstream->peer.data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
478 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
|
479 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
480 hash = ngx_crc32_long(hp->key.data, hp->key.len); |
6102 | 481 |
482 ngx_http_upstream_rr_peers_rlock(hp->rrp.peers); | |
483 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
484 hp->hash = ngx_http_upstream_find_chash_point(hcf->points, hash); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
485 |
6102 | 486 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
487 | |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
488 return NGX_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
489 } |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
492 static ngx_int_t |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
493 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
|
494 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
495 ngx_http_upstream_hash_peer_data_t *hp = data; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
496 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
497 time_t now; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
498 intptr_t m; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
499 ngx_str_t *server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
500 ngx_int_t total; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
501 ngx_uint_t i, n, best_i; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
502 ngx_http_upstream_rr_peer_t *peer, *best; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
503 ngx_http_upstream_chash_point_t *point; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
504 ngx_http_upstream_chash_points_t *points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
505 ngx_http_upstream_hash_srv_conf_t *hcf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
506 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
507 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
508 "get consistent hash peer, try: %ui", pc->tries); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
509 |
6102 | 510 ngx_http_upstream_rr_peers_wlock(hp->rrp.peers); |
511 | |
7513
d964b0aee8e7
Upstream hash: fall back to round-robin if hash key is empty.
Niklas Keller <me@kelunik.com>
parents:
7300
diff
changeset
|
512 if (hp->tries > 20 || hp->rrp.peers->single || hp->key.len == 0) { |
7123
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
513 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
|
514 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
|
515 } |
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
516 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
517 pc->cached = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
518 pc->connection = NULL; |
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 now = ngx_time(); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
521 hcf = hp->conf; |
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 points = hcf->points; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
524 point = &points->point[0]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
525 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
526 for ( ;; ) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
527 server = point[hp->hash % points->number].server; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
528 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
529 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
530 "consistent hash peer:%uD, server:\"%V\"", |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
531 hp->hash, server); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
532 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
533 best = NULL; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
534 best_i = 0; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
535 total = 0; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
536 |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
537 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
|
538 peer; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
539 peer = peer->next, i++) |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
540 { |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
541 n = i / (8 * sizeof(uintptr_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
542 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
543 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
544 if (hp->rrp.tried[n] & m) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
545 continue; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
546 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
547 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
548 if (peer->down) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
549 continue; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
550 } |
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 if (peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
553 && peer->fails >= peer->max_fails |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
554 && now - peer->checked <= peer->fail_timeout) |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
555 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
556 continue; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
557 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
558 |
6705 | 559 if (peer->max_conns && peer->conns >= peer->max_conns) { |
560 continue; | |
561 } | |
562 | |
7124
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
563 if (peer->server.len != server->len |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
564 || ngx_strncmp(peer->server.data, server->data, server->len) |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
565 != 0) |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
566 { |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
567 continue; |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
568 } |
3b4fa572d56d
Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7123
diff
changeset
|
569 |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
570 peer->current_weight += peer->effective_weight; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
571 total += peer->effective_weight; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
572 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
573 if (peer->effective_weight < peer->weight) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
574 peer->effective_weight++; |
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 == NULL || peer->current_weight > best->current_weight) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
578 best = peer; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
579 best_i = i; |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
583 if (best) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
584 best->current_weight -= total; |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
585 goto found; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
586 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
587 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
588 hp->hash++; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
589 hp->tries++; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
590 |
7123
6c52b24fcf8e
Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6705
diff
changeset
|
591 if (hp->tries > 20) { |
6102 | 592 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
|
593 return hp->get_rr_peer(pc, &hp->rrp); |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
594 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
595 } |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
596 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
597 found: |
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 hp->rrp.current = best; |
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 pc->sockaddr = best->sockaddr; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
602 pc->socklen = best->socklen; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
603 pc->name = &best->name; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
604 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
605 best->conns++; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
606 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
607 if (now - best->checked > best->fail_timeout) { |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
608 best->checked = now; |
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 |
6102 | 611 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); |
612 | |
6100
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
613 n = best_i / (8 * sizeof(uintptr_t)); |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
614 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
|
615 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
616 hp->rrp.tried[n] |= m; |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
617 |
c44459611d91
Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents:
6099
diff
changeset
|
618 return NGX_OK; |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
619 } |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
622 static void * |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
623 ngx_http_upstream_hash_create_conf(ngx_conf_t *cf) |
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 ngx_http_upstream_hash_srv_conf_t *conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
626 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
627 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
|
628 if (conf == NULL) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
629 return NULL; |
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 conf->points = NULL; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
633 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
634 return conf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
635 } |
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 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
638 static char * |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
639 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
|
640 { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
641 ngx_http_upstream_hash_srv_conf_t *hcf = conf; |
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_str_t *value; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
644 ngx_http_upstream_srv_conf_t *uscf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
645 ngx_http_compile_complex_value_t ccv; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
646 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
647 value = cf->args->elts; |
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 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
650 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
651 ccv.cf = cf; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
652 ccv.value = &value[1]; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
653 ccv.complex_value = &hcf->key; |
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 (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
656 return NGX_CONF_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
657 } |
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 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
|
660 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
661 if (uscf->peer.init_upstream) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
662 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
663 "load balancing method redefined"); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
664 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
665 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
666 uscf->flags = NGX_HTTP_UPSTREAM_CREATE |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
667 |NGX_HTTP_UPSTREAM_WEIGHT |
6705 | 668 |NGX_HTTP_UPSTREAM_MAX_CONNS |
5717
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
669 |NGX_HTTP_UPSTREAM_MAX_FAILS |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
670 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
671 |NGX_HTTP_UPSTREAM_DOWN; |
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 if (cf->args->nelts == 2) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
674 uscf->peer.init_upstream = ngx_http_upstream_init_hash; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
675 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
676 } else if (ngx_strcmp(value[2].data, "consistent") == 0) { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
677 uscf->peer.init_upstream = ngx_http_upstream_init_chash; |
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 } else { |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
680 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
681 "invalid parameter \"%V\"", &value[2]); |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
682 return NGX_CONF_ERROR; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
683 } |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
684 |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
685 return NGX_CONF_OK; |
efc84a5723b3
Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
686 } |