Skip to content

Commit 97d2ee7

Browse files
authored
Merge pull request #22 from andrewshan/main
feat:支持环境变量设置服务名和命名空间
2 parents 51f6af9 + b36717e commit 97d2ee7

File tree

5 files changed

+216
-39
lines changed

5 files changed

+216
-39
lines changed

Dockerfile

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@ RUN set -ex \
2525
&& rm -rf polaris-cpp
2626

2727
RUN set -ex \
28-
&& mkdir -p /server \
28+
&& mkdir -p /etc/nginx \
2929
&& cd /build/third_party \
3030
&& ngx_file_name=nginx-1.23.1 \
3131
&& curl http://nginx.org/download/"$ngx_file_name".tar.gz -o "$ngx_file_name".tar.gz \
3232
&& tar xf "$ngx_file_name".tar.gz \
3333
&& cp nginx/make "$ngx_file_name"/auto/ \
34+
&& cp nginx/nginx.conf "$ngx_file_name"/conf/ \
3435
&& chmod +x "$ngx_file_name"/configure \
3536
&& cd "$ngx_file_name" \
36-
&& ./configure --prefix=/server --add-module=../../source/nginx_polaris_limit_module --add-module=../polaris_client --with-stream --with-cpp=g++ \
37+
&& ./configure --prefix=/etc/nginx --add-module=../../source/nginx_polaris_limit_module --add-module=../polaris_client --with-stream --with-cpp=g++ \
3738
&& make \
38-
&& make install
39+
&& make install \
40+
&& ln -s /etc/nginx/sbin/nginx /usr/local/bin/nginx
3941

40-
41-
ENV PATH=/server/sbin:$PATH
42-
43-
CMD ["nginx", "-g", "daemon off;"]
42+
CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/conf/nginx.conf"]

build/build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ rm -rf "$ngx_file_name"
1616
curl http://nginx.org/download/"$ngx_file_name".tar.gz -o "$ngx_file_name".tar.gz
1717
tar xf "$ngx_file_name".tar.gz
1818
cp nginx/make "$ngx_file_name"/auto/
19+
cp nginx/nginx.conf "$ngx_file_name"/conf/
1920

2021
pushd polaris-cpp
2122
make

source/nginx_polaris_limit_module/ngx_http_polaris_limit_module.cpp

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
#include "ngx_http_polaris_limit_module.h"
1515

1616
typedef struct {
17-
ngx_str_t service_namespace; // 命名空间
18-
19-
ngx_str_t service_name; // 服务名
17+
ngx_int_t enable; // 是否启用限流
2018

2119
ngx_int_t status_code; // 返回码
2220

21+
std::string service_namespace; // 命名空间
22+
23+
std::string service_name; // 服务名
24+
2325
} ngx_http_polaris_limit_conf_t;
2426

2527
static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r);
@@ -82,20 +84,18 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
8284
std::map<std::string, std::string> labels;
8385
const std::set<std::string> *label_keys;
8486

85-
ngx_str_t service_namespace_str;
86-
ngx_str_t service_name_str;
8787
plcf = reinterpret_cast<ngx_http_polaris_limit_conf_t *>(
8888
ngx_http_get_module_loc_conf(r, ngx_http_polaris_limit_module));
89-
service_namespace_str = plcf->service_namespace;
90-
service_name_str =plcf->service_name;
9189

90+
if (plcf->enable == 0) {
91+
return NGX_DECLINED;
92+
}
9293
polaris::LimitApi* limit_api = Limit_API_SINGLETON.GetLimitApi();
9394
if (NULL == limit_api) {
94-
return NGX_OK;
95+
return NGX_DECLINED;
9596
}
96-
std::string service_namespace(reinterpret_cast<char *>(service_namespace_str.data), service_namespace_str.len);
97-
std::string service_name(reinterpret_cast<char *>(service_name_str.data), service_name_str.len);
98-
polaris::ServiceKey serviceKey = {service_namespace, service_name};
97+
98+
polaris::ServiceKey serviceKey = {plcf->service_namespace, plcf->service_name};
9999
std::string method = std::string(reinterpret_cast<char *>(r->uri.data), r->uri.len);
100100
ret = Limit_API_SINGLETON.GetLimitApi()->FetchRuleLabelKeys(serviceKey, label_keys);
101101

@@ -105,22 +105,22 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
105105
}
106106
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "[PolarisRateLimiting] FetchRuleLabelKeys return is: %d, labels %s", ret, labels_key_str.c_str());
107107
if (ret == polaris::kReturnTimeout) {
108-
return NGX_DECLINED; // 拉取labelkey超时,不限流
108+
return NGX_DECLINED; // 拉取labelkey超时,不限流
109109
} else if (ret != polaris::kReturnOk) {
110110
return plcf->status_code; // 返回为限流配置的状态码
111111
}
112112

113113
get_labels_from_request(r, label_keys, labels); // 从http 请求中获取labels
114114
std::string uri(reinterpret_cast<char *>(r->uri.data), r->uri.len);
115-
quota_request.SetServiceNamespace(service_namespace); // 设置限流规则对应服务的命名空间
116-
quota_request.SetServiceName(service_name); // 设置限流规则对应的服务名
115+
quota_request.SetServiceNamespace(plcf->service_namespace); // 设置限流规则对应服务的命名空间
116+
quota_request.SetServiceName(plcf->service_name); // 设置限流规则对应的服务名
117117
quota_request.SetMethod(uri);
118118
quota_request.SetLabels(labels); // 设置label用于匹配限流规则
119119

120120
std::string labels_values_str;
121121
join_map_str(r->connection->log, labels, labels_values_str);
122122
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
123-
"[PolarisRateLimiting] quota_request namespace %s, service %s, method %s, labels %s", service_namespace.c_str(), service_name.c_str(), uri.c_str(), labels_values_str.c_str());
123+
"[PolarisRateLimiting] quota_request namespace %s, service %s, method %s, labels %s", plcf->service_namespace.c_str(), plcf->service_name.c_str(), uri.c_str(), labels_values_str.c_str());
124124

125125
ret = Limit_API_SINGLETON.GetLimitApi()->GetQuota(quota_request, result);
126126

@@ -160,6 +160,10 @@ static void join_map_str(const ngx_log_t *log, const std::map<std::string, std::
160160
}
161161
}
162162

163+
bool string2bool(const std::string & v) {
164+
return !v.empty () && (strcasecmp (v.c_str (), "true") == 0 || atoi (v.c_str ()) != 0);
165+
}
166+
163167
/* 读取配置参数 polaris_limit */
164168
static char *ngx_http_polaris_limit_conf_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
165169
ngx_http_polaris_limit_conf_t *plcf;
@@ -168,34 +172,80 @@ static char *ngx_http_polaris_limit_conf_set(ngx_conf_t *cf, ngx_command_t *cmd,
168172
plcf = reinterpret_cast<ngx_http_polaris_limit_conf_t *>(conf);
169173
value = reinterpret_cast<ngx_str_t *>(cf->args->elts);
170174

175+
bool has_namespace = false;
176+
bool has_service = false;
177+
bool has_enable = false;
178+
171179
for (i = 1; i < cf->args->nelts; i++) {
172180
if (ngx_strncmp(value[i].data, KEY_NAMESPACE, KEY_NAMESPACE_SIZE) == 0) {
173181
size_t ns_size = value[i].len - KEY_NAMESPACE_SIZE;
174-
if (ns_size <= 0) {
175-
ngx_str_t namespace_str = {DEFAULT_NAMESPACE_SIZE, (u_char *)DEFAULT_NAMESPACE};
176-
plcf->service_namespace = namespace_str;
177-
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] nginx namespace not set, use 'default' as namespace");
178-
} else {
182+
if (ns_size > 0) {
179183
ngx_str_t namespace_str = {value[i].len - KEY_NAMESPACE_SIZE, &value[i].data[KEY_NAMESPACE_SIZE]};
180-
plcf->service_namespace = namespace_str;
181184
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %V as nginx namespace", &namespace_str);
185+
plcf->service_namespace = std::string(reinterpret_cast<char *>(namespace_str.data), namespace_str.len);
186+
has_namespace = true;
182187
}
183188
continue;
184189
}
185190

186191
if (ngx_strncmp(value[i].data, KEY_SERVICE_NAME, KEY_SERVICE_NAME_SIZE) == 0) {
187-
ngx_str_t svc_name_str = {value[i].len - KEY_SERVICE_NAME_SIZE, &value[i].data[KEY_SERVICE_NAME_SIZE]};
188-
plcf->service_name = svc_name_str;
189-
if (plcf->service_name.len <= 0) {
190-
plcf->service_name.data = NULL;
191-
plcf->service_name.len = 0;
192-
ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "[PolarisRateLimiting] service name not set");
193-
return static_cast<char *>(NGX_CONF_ERROR);
194-
} else {
195-
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %V as service", &svc_name_str);
192+
size_t svc_size = value[i].len - KEY_SERVICE_NAME_SIZE;
193+
if (svc_size > 0) {
194+
ngx_str_t svc_name_str = {value[i].len - KEY_SERVICE_NAME_SIZE, &value[i].data[KEY_SERVICE_NAME_SIZE]};
195+
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %V as nginx service name", &svc_name_str);
196+
plcf->service_name = std::string(reinterpret_cast<char *>(svc_name_str.data), svc_name_str.len);
197+
has_service = true;
198+
}
199+
continue;
200+
}
201+
202+
if (ngx_strncmp(value[i].data, KEY_ENABLE, KEY_ENABLE_SIZE) == 0) {
203+
size_t enable_size = value[i].len - KEY_ENABLE_SIZE;
204+
if (enable_size > 0) {
205+
ngx_str_t enable_str = {value[i].len - KEY_ENABLE_SIZE, &value[i].data[KEY_ENABLE_SIZE]};
206+
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %V as nginx ratelimit enable value", &enable_str);
207+
std::string enable_str_value = std::string(reinterpret_cast<char *>(enable_str.data), enable_str.len);
208+
if (string2bool(enable_str_value)) {
209+
plcf->enable = 1;
210+
} else {
211+
plcf->enable = 0;
212+
}
213+
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %V as nginx ratelimit enable", plcf->enable);
214+
has_enable = true;
196215
}
197216
continue;
198217
}
218+
219+
if (!has_namespace) {
220+
char *namespace_env_value = getenv(ENV_NAMESPACE.c_str());
221+
if (NULL != namespace_env_value) {
222+
plcf->service_namespace = std::string(namespace_env_value);
223+
} else {
224+
plcf->service_namespace = DEFAULT_NAMESPACE;
225+
}
226+
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %s as nginx namespace", plcf->service_namespace.c_str());
227+
}
228+
229+
if (!has_service) {
230+
char *service_env_value = getenv(ENV_SERVICE.c_str());
231+
if (NULL != service_env_value) {
232+
plcf->service_name = std::string(service_env_value);
233+
} else {
234+
plcf->service_name = DEFAULT_SERVICE;
235+
}
236+
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %s as nginx service name", plcf->service_name.c_str());
237+
}
238+
239+
if (!has_enable) {
240+
char *enable_env_value = getenv(ENV_RATELIMIT_ENABLE.c_str());
241+
if (NULL != enable_env_value) {
242+
std::string enable_str = std::string(enable_env_value);
243+
plcf->enable = string2bool(enable_str) ? 1 : 0;
244+
} else {
245+
plcf->enable = 0;
246+
}
247+
ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0, "[PolarisRateLimiting] use %V as nginx ratelimit enable", plcf->enable);
248+
}
199249
}
200250

201251
return static_cast<char *>(NGX_CONF_OK);

source/nginx_polaris_limit_module/ngx_http_polaris_limit_module.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,22 @@ extern "C" {
2525
#include <string>
2626
#include <unistd.h>
2727
#include <fstream>
28+
#include <cstring>
29+
#include <cstdlib>
2830

31+
static const char KEY_ENABLE[] = "enable";
32+
static const uint32_t KEY_ENABLE_SIZE = sizeof(KEY_ENABLE) - 1;
2933
static const char KEY_NAMESPACE[] = "namespace=";
3034
static const uint32_t KEY_NAMESPACE_SIZE = sizeof(KEY_NAMESPACE) - 1;
3135
static const char KEY_SERVICE_NAME[] = "service=";
3236
static const uint32_t KEY_SERVICE_NAME_SIZE = sizeof(KEY_SERVICE_NAME) - 1;
33-
static const char DEFAULT_NAMESPACE[] = "default";
34-
static const uint32_t DEFAULT_NAMESPACE_SIZE = sizeof(DEFAULT_NAMESPACE) - 1;
37+
38+
static const std::string ENV_NAMESPACE = "polaris.nginx.namespace";
39+
static const std::string ENV_SERVICE = "polaris.nginx.service";
40+
static const std::string ENV_RATELIMIT_ENABLE = "polaris.nginx.ratelimit.enable";
41+
42+
static const std::string DEFAULT_NAMESPACE = "default";
43+
static const std::string DEFAULT_SERVICE = "nginx-gateway";
3544

3645
static const std::string LABEL_KEY_METHOD = "$method";
3746
static const std::string LABEL_KEY_HEADER = "$header.";

third_party/nginx/nginx.conf

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
2+
#user nobody;
3+
worker_processes 1;
4+
5+
#error_log logs/error.log;
6+
#error_log logs/error.log notice;
7+
#error_log logs/error.log info;
8+
9+
#pid logs/nginx.pid;
10+
11+
12+
events {
13+
worker_connections 1024;
14+
}
15+
16+
17+
http {
18+
include mime.types;
19+
default_type application/octet-stream;
20+
21+
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
22+
# '$status $body_bytes_sent "$http_referer" '
23+
# '"$http_user_agent" "$http_x_forwarded_for"';
24+
25+
#access_log logs/access.log main;
26+
27+
sendfile on;
28+
#tcp_nopush on;
29+
30+
#keepalive_timeout 0;
31+
keepalive_timeout 65;
32+
33+
#gzip on;
34+
35+
server {
36+
listen 80;
37+
server_name localhost;
38+
39+
#charset koi8-r;
40+
41+
#access_log logs/host.access.log main;
42+
43+
location / {
44+
polaris_rate_limiting;
45+
root html;
46+
index index.html index.htm;
47+
}
48+
49+
#error_page 404 /404.html;
50+
51+
# redirect server error pages to the static page /50x.html
52+
#
53+
error_page 500 502 503 504 /50x.html;
54+
location = /50x.html {
55+
root html;
56+
}
57+
58+
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
59+
#
60+
#location ~ \.php$ {
61+
# proxy_pass http://127.0.0.1;
62+
#}
63+
64+
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
65+
#
66+
#location ~ \.php$ {
67+
# root html;
68+
# fastcgi_pass 127.0.0.1:9000;
69+
# fastcgi_index index.php;
70+
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
71+
# include fastcgi_params;
72+
#}
73+
74+
# deny access to .htaccess files, if Apache's document root
75+
# concurs with nginx's one
76+
#
77+
#location ~ /\.ht {
78+
# deny all;
79+
#}
80+
}
81+
82+
83+
# another virtual host using mix of IP-, name-, and port-based configuration
84+
#
85+
#server {
86+
# listen 8000;
87+
# listen somename:8080;
88+
# server_name somename alias another.alias;
89+
90+
# location / {
91+
# root html;
92+
# index index.html index.htm;
93+
# }
94+
#}
95+
96+
97+
# HTTPS server
98+
#
99+
#server {
100+
# listen 443 ssl;
101+
# server_name localhost;
102+
103+
# ssl_certificate cert.pem;
104+
# ssl_certificate_key cert.key;
105+
106+
# ssl_session_cache shared:SSL:1m;
107+
# ssl_session_timeout 5m;
108+
109+
# ssl_ciphers HIGH:!aNULL:!MD5;
110+
# ssl_prefer_server_ciphers on;
111+
112+
# location / {
113+
# root html;
114+
# index index.html index.htm;
115+
# }
116+
#}
117+
118+
}

0 commit comments

Comments
 (0)