@@ -33,8 +33,7 @@ static void split_query(std::string& s, std::map<std::string, std::string>& v);
3333static void parse_query_token (const std::string& token, std::map<std::string, std::string>& v);
3434static void get_labels_from_request (ngx_http_request_t * r, const std::set<std::string>*& label_keys,
3535 std::map<std::string, std::string>& keyword_map);
36- static void join_set_str (const ngx_log_t *log, const std::set<std::string>*& label_keys, std::string& labels_str);
37- static void join_map_str (const ngx_log_t *log, const std::map<std::string, std::string>& labels, std::string& labels_str);
36+ static void join_map_str (const std::map<std::string, std::string>& labels, std::string& labels_str);
3837
3938static ngx_command_t ngx_http_polaris_limit_commands[] = {
4039 { ngx_string (" polaris_rate_limiting" ),
@@ -88,22 +87,28 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
8887 ngx_http_get_module_loc_conf (r, ngx_http_polaris_limit_module));
8988
9089 if (plcf->enable == 0 ) {
90+ ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 , " [PolarisRateLimiting] RateLimit not enabled" );
9191 return NGX_DECLINED;
9292 }
93- polaris::LimitApi* limit_api = Limit_API_SINGLETON.GetLimitApi ();
93+ polaris::LimitApi* limit_api = Limit_API_SINGLETON.GetLimitApi (r-> connection -> log );
9494 if (NULL == limit_api) {
95+ ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 , " [PolarisRateLimiting] RateLimit api not created" );
9596 return NGX_DECLINED;
9697 }
9798
9899 polaris::ServiceKey serviceKey = {plcf->service_namespace , plcf->service_name };
99100 std::string method = std::string (reinterpret_cast <char *>(r->uri .data ), r->uri .len );
100- ret = Limit_API_SINGLETON.GetLimitApi ()->FetchRuleLabelKeys (serviceKey, label_keys);
101+ ret = limit_api->FetchRuleLabelKeys (serviceKey, label_keys);
102+
103+ if (ret != 0 ) {
104+ ngx_log_error (NGX_LOG_ERR, r->connection ->log , 0 , " [PolarisRateLimiting] fail to fetchRuleLabelKeys return is: %d" , ret);
105+ return NGX_DECLINED;
106+ }
101107
102- std::string labels_key_str;
103108 if (label_keys != NULL ) {
104- join_set_str ( r->connection ->log , label_keys, labels_key_str );
109+ ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 , " [PolarisRateLimiting] FetchRuleLabelKeys labels count %d " , label_keys-> size () );
105110 }
106- ngx_log_debug (NGX_LOG_DEBUG_HTTP, r-> connection -> log , 0 , " [PolarisRateLimiting] FetchRuleLabelKeys return is: %d, labels %s " , ret, labels_key_str. c_str ());
111+
107112 if (ret == polaris::kReturnTimeout ) {
108113 return NGX_DECLINED; // 拉取labelkey超时,不限流
109114 } else if (ret != polaris::kReturnOk ) {
@@ -117,12 +122,13 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
117122 quota_request.SetMethod (uri);
118123 quota_request.SetLabels (labels); // 设置label用于匹配限流规则
119124
120- std::string labels_values_str;
121- join_map_str (r->connection ->log , labels, labels_values_str);
122- ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 ,
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 ());
124-
125- ret = Limit_API_SINGLETON.GetLimitApi ()->GetQuota (quota_request, result);
125+ if (r->connection ->log ->log_level >= NGX_LOG_DEBUG) {
126+ std::string labels_values_str;
127+ join_map_str (labels, labels_values_str);
128+ ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 ,
129+ " [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 ());
130+ }
131+ ret = limit_api->GetQuota (quota_request, result);
126132
127133 ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 , " [PolarisRateLimiting] GetQuota return is: %d" , ret);
128134 if (ret == polaris::kReturnTimeout ) {
@@ -138,25 +144,12 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
138144 return NGX_DECLINED;
139145}
140146
141- static void join_set_str (const ngx_log_t *log, const std::set<std::string>*& label_keys, std::string& labels_str) {
142- if (log->log_level < NGX_LOG_DEBUG) {
143- return ;
144- }
145- for (std::set<std::string>::iterator it = label_keys->begin (); it != label_keys->end (); it++) {
146- labels_str += *it;
147- labels_str += " " ;
148- }
149- }
150-
151- static void join_map_str (const ngx_log_t *log, const std::map<std::string, std::string>& labels, std::string& labels_str) {
152- if (log->log_level < NGX_LOG_DEBUG) {
153- return ;
154- }
147+ static void join_map_str (const std::map<std::string, std::string>& labels, std::string& labels_str) {
155148 for (std::map<std::string, std::string>::const_iterator it = labels.begin (); it != labels.end (); it++) {
156149 labels_str += it->first ;
157150 labels_str += " =" ;
158151 labels_str += it->second ;
159- labels_str += " " ;
152+ labels_str += " , " ;
160153 }
161154}
162155
@@ -215,37 +208,38 @@ static char *ngx_http_polaris_limit_conf_set(ngx_conf_t *cf, ngx_command_t *cmd,
215208 }
216209 continue ;
217210 }
211+
212+ }
218213
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- }
214+ if (!has_namespace) {
215+ char *namespace_env_value = getenv (ENV_NAMESPACE.c_str ());
216+ if (NULL != namespace_env_value) {
217+ plcf->service_namespace = std::string (namespace_env_value);
218+ } else {
219+ plcf->service_namespace = DEFAULT_NAMESPACE;
220+ }
221+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %s as nginx namespace" , plcf->service_namespace .c_str ());
222+ }
228223
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- }
224+ if (!has_service) {
225+ char *service_env_value = getenv (ENV_SERVICE.c_str ());
226+ if (NULL != service_env_value) {
227+ plcf->service_name = std::string (service_env_value);
228+ } else {
229+ plcf->service_name = DEFAULT_SERVICE;
230+ }
231+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %s as nginx service name" , plcf->service_name .c_str ());
232+ }
238233
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- }
234+ if (!has_enable) {
235+ char *enable_env_value = getenv (ENV_RATELIMIT_ENABLE.c_str ());
236+ if (NULL != enable_env_value) {
237+ std::string enable_str = std::string (enable_env_value);
238+ plcf->enable = string2bool (enable_str) ? 1 : 0 ;
239+ } else {
240+ plcf->enable = 0 ;
241+ }
242+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %d as nginx ratelimit enable" , plcf->enable );
249243 }
250244
251245 return static_cast <char *>(NGX_CONF_OK);
@@ -282,6 +276,8 @@ static void *ngx_http_polaris_limit_create_conf(ngx_conf_t *cf) {
282276 }
283277
284278 conf->status_code = 429 ; // 限流默认返回429
279+
280+ Limit_API_SINGLETON.LoadPolarisConfig ();
285281 return conf;
286282}
287283
@@ -418,18 +414,58 @@ const std::string defaultConfigContent = R"##(
418414 serverConnector:
419415 addresses:
420416 - ${polaris_address}
417+ rateLimiter:
418+ rateLimitCluster:
419+ namespace: Polaris
420+ service: polaris.limiter
421421)##" ;
422422
423- LimitApiWrapper::LimitApiWrapper () {
423+ void LimitApiWrapper::Init (ngx_log_t *logger) {
424+ ngx_log_error (NGX_LOG_NOTICE, logger, 0 , " [PolarisRateLimiting] start to init polaris limit api, polaris config %s" , m_polaris_config.c_str ());
425+ std::string err_msg (" " );
426+ m_limit = polaris::LimitApi::CreateFromString (m_polaris_config, err_msg);
427+ if (NULL == m_limit) {
428+ ngx_log_error (NGX_LOG_ERR, logger, 0 , " [PolarisRateLimiting] fail to create limit api, err: %s" , err_msg.c_str ());
429+ } else {
430+ ngx_log_error (NGX_LOG_NOTICE, logger, 0 , " [PolarisRateLimiting] success to init polaris limit api" );
431+ }
432+ m_created = true ;
433+ }
434+
435+ // / @brief 将文件内容读入字符串中
436+ std::string readFileIntoString (const std::string& path) {
437+ std::ifstream input_file (path);
438+ return std::string ((std::istreambuf_iterator<char >(input_file)), std::istreambuf_iterator<char >());
439+ }
440+
441+ // / @brief 支持环境变量展开
442+ static std::string expand_environment_variables ( const std::string &s ) {
443+ if ( s.find ( " ${" ) == std::string::npos ) return s;
444+
445+ std::string pre = s.substr ( 0 , s.find ( " ${" ) );
446+ std::string post = s.substr ( s.find ( " ${" ) + 2 );
447+
448+ if ( post .find ( ' }' ) == std::string::npos ) return s;
449+
450+ std::string variable = post .substr ( 0 , post .find ( ' }' ) );
451+ std::string value = " " ;
452+
453+ post = post .substr ( post .find ( ' }' ) + 1 );
454+
455+ const char *v = getenv ( variable.c_str () );
456+ if ( v != NULL ) value = std::string ( v );
457+
458+ return expand_environment_variables ( pre + value + post );
459+ }
460+
461+ void LimitApiWrapper::LoadPolarisConfig () {
424462 std::string conf_path = get_polaris_conf_path ();
425- std::string err_msg ;
463+ std::string content ( " " ) ;
426464 if (exist_file (conf_path)) {
427- m_limit = polaris::LimitApi::CreateFromFile (conf_path, err_msg);
428- } else {
429- std::cout << " [polaris-limiter] config file " << conf_path << " not exists, create with default config" << std::endl;
430- m_limit = polaris::LimitApi::CreateFromString (defaultConfigContent, err_msg);
465+ content = readFileIntoString (conf_path);
431466 }
432- if (NULL == m_limit ) {
433- std::cout << " [polaris-limiter] fail to create limit api, err: " << err_msg << std::endl ;
467+ if (content. size () == 0 ) {
468+ content = defaultConfigContent ;
434469 }
470+ m_polaris_config = expand_environment_variables (content);
435471}
0 commit comments