Mercurial > hg > nginx
annotate src/http/modules/ngx_http_upstream_hash_module.c @ 9322:d6f75dd66761 default tip
Mp4: added and updated sanity checks for "end" handling.
When handling incorrect data in ngx_http_mp4_crop_stsc_data(),
trak->end_chunk_samples might end up being arbitrary large, leading
to reading before the buffer in ngx_http_mp4_update_stsz_atom(). Fix
is to check that trak->end_chunk_samples corresponds to a memory within
the stsz atom data. For consistency, trak->start_chunk_samples
is checked similarly.
Similarly, trak->end_chunk might end up being smaller than trak->start_chunk,
leading to reading memory after the buffer in ngx_http_mp4_update_stco_atom()
and ngx_http_mp4_update_co64_atom(). Corresponding checks are updated
to explicitly test (trak->end_chunk - trak->start_chunk) instead of just
checking trak->end_chunk and assuming it is larger than trak->start_chunk.
This is generally in line with existing checks of
(trak->end_sample - trak->start_sample) in ngx_http_mp4_update_stsz_atom(),
where trak->end_sample might also become smaller than trak->start_sample
when handling incorrect data in ngx_http_mp4_crop_stts_data().
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 25 Aug 2024 06:35:40 +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 } |