-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
UpstreamManager.h
222 lines (198 loc) · 8.3 KB
/
UpstreamManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
Copyright (c) 2019 Sogou, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Authors: Wu Jiaxu ([email protected])
*/
#ifndef _UPSTREAM_MANAGER_H_
#define _UPSTREAM_MANAGER_H_
#include <string>
#include <vector>
#include "WFServiceGovernance.h"
#include "UpstreamPolicies.h"
#include "WFGlobal.h"
/**
* @file UpstreamManager.h
* @brief Local Reverse Proxy & Load Balance & Service Discovery
* @details
* - This is very similar with Nginx-Upstream.
* - Do not cost any other network resource, We just simulate in local to choose one target properly.
* - This is working only for the current process.
*/
/**
* @brief Upstream Management Class
* @details
* - We support three modes:
* 1. Weighted-Random
* 2. Consistent-Hash
* 3. Manual-Select
* - Additional, we support Main-backup & Group for server and working well in any mode.
*
* @code{.cc}
upstream_create_weighted_random("abc.sogou", true); //UPSTREAM_WEIGHTED_RANDOM
upstream_add_server("abc.sogou", "192.168.2.100:8081"); //weight=1, max_fails=200
upstream_add_server("abc.sogou", "192.168.2.100:9090"); //weight=1, max_fails=200
AddressParams params = ADDRESS_PARAMS_DEFAULT;
params.weight = 2;
params.max_fails = 6;
upstream_add_server("abc.sogou", "www.sogou.com", ¶ms); //weight=2, max_fails=6
//send request with url like http://abc.sogou/somepath/somerequest
upstream_create_consistent_hash("def.sogou",
[](const char *path,
const char *query,
const char *fragment) -> int {
return somehash(...));
}); //UPSTREAM_CONSISTENT_HASH
upstream_create_manual("xyz.sogou",
[](const char *path,
const char *query,
const char *fragment) -> int {
return select_xxx(...));
},
true,
[](const char *path,
const char *query,
const char *fragment) -> int {
return rehash(...));
},); //UPSTREAM_MANUAL
* @endcode
*/
class UpstreamManager
{
public:
/**
* @brief MODE 0: round-robin select
* @param[in] name upstream name
* @param[in] try_another when first choice is failed, try another one or not
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @note
* when first choose server is already down:
* - if try_another==false, request will be failed
* - if try_another==true, upstream will choose the next
*/
static int upstream_create_round_robin(const std::string& name,
bool try_another);
/**
* @brief MODE 1: consistent-hashing select
* @param[in] name upstream name
* @param[in] consitent_hash consistent-hash functional
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @note consitent_hash need to return value in 0~(2^31-1) Balance/Monotonicity/Spread/Smoothness
* @note if consitent_hash==nullptr, upstream will use std::hash with request uri
*/
static int upstream_create_consistent_hash(const std::string& name,
upstream_route_t consitent_hash);
/**
* @brief MODE 2: weighted-random select
* @param[in] name upstream name
* @param[in] try_another when first choice is failed, try another one or not
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @note
* when first choose server is already down:
* - if try_another==false, request will be failed
* - if try_another==true, upstream will choose from alive-servers by weight-random strategy
*/
static int upstream_create_weighted_random(const std::string& name,
bool try_another);
/**
* @brief MODE 3: manual select
* @param[in] name upstream name
* @param[in] select manual select functional, just tell us main-index.
* @param[in] try_another when first choice is failed, try another one or not
* @param[in] consitent_hash consistent-hash functional
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @note
* when first choose server is already down:
* - if try_another==false, request will be failed, consistent_hash value will be ignored
* - if try_another==true, upstream will work with consistent hash mode,if consitent_hash==NULL, upstream will use std::hash with request uri
* @warning select functional cannot be nullptr!
*/
static int upstream_create_manual(const std::string& name,
upstream_route_t select,
bool try_another,
upstream_route_t consitent_hash);
/**
* @brief MODE 4: VNSWRR select
* @param[in] name upstream name
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @note
*/
static int upstream_create_vnswrr(const std::string& name);
/**
* @brief Delete one upstream
* @param[in] name upstream name
* @return success/fail
* @retval 0 success
* @retval -1 fail, not found
*/
static int upstream_delete(const std::string& name);
public:
/**
* @brief Add server into one upstream, with default config
* @param[in] name upstream name
* @param[in] address ip OR host OR ip:port OR host:port OR /unix-domain-socket
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @warning Same address add twice, means two different server
*/
static int upstream_add_server(const std::string& name,
const std::string& address);
/**
* @brief Add server into one upstream, with custom config
* @param[in] name upstream name
* @param[in] address ip OR host OR ip:port OR host:port OR /unix-domain-socket
* @param[in] address_params custom config for this target server
* @return success/fail
* @retval 0 success
* @retval -1 fail, more info see errno
* @warning Same address with different params, means two different server
* @warning Same address with exactly same params, still means two different server
*/
static int upstream_add_server(const std::string& name,
const std::string& address,
const struct AddressParams *address_params);
/**
* @brief Remove server from one upstream
* @param[in] name upstream name
* @param[in] address same as address when add by upstream_add_server
* @return success/fail
* @retval >=0 success, the amount of being removed server
* @retval -1 fail, upstream name not found
* @warning If server servers has the same address in this upstream, we will remove them all
*/
static int upstream_remove_server(const std::string& name,
const std::string& address);
/**
* @brief get all main servers address list from one upstream
* @param[in] name upstream name
* @return all main servers' address list
* @warning If server servers has the same address in this upstream, then will appear in the vector multiply times
*/
static std::vector<std::string> upstream_main_address_list(const std::string& name);
public:
/// @breif for plugin
static int upstream_disable_server(const std::string& name, const std::string& address);
static int upstream_enable_server(const std::string& name, const std::string& address);
static int upstream_replace_server(const std::string& name,
const std::string& address,
const struct AddressParams *address_params);
};
#endif