有好几个业务要访问ES集群。有些业务比较紧急,那么它们的请求应该优先处理,而有些业务对响应时间的要求不是那么在意,则可降低他们的并发量。针对于这种情况,可通过nginx的lua脚本来控制并发。
http { limit_conn_zone $binary_remote_addr zone=perip :10m; limit_conn_zone $server_name zone=perserver:10m; ... server { limit_conn perserver 100; limit_conn perip 10; ... } }
$binary_remote_addr:IP地址。这里配置的是IP,也可以使用如$server_name作为KEY来限制域名级别的最大连接数。 zone=perip:10m:设置zone为perip,perip是在server 中配置的,这里我们配置的是1.则意味着一个IP最多同时有10个连接。保存IP的缓存区的大小为10m。
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; ... server { ... location /search/ { limit_req zone=one burst=5; } }
$binary_remote_addr:IP地址。这里配置的是IP,也可以使用如$server_name作为KEY来限制域名级别的最大连接数。 zone=one:10m rate=1r/s:设置zone为one,one是在location /search/中配置的。rate=1r/s则表明平均一秒钟处理一个请求。 burst=5:令牌桶中保存的令牌最多有5个。
假设集群每秒钟最多处理100个请求,业务A访问量比较大,业务B的访问量比较少,那么我们就可以配置二者的并发对比为8:2,即业务A的并发每秒钟为80,业务B的并发为每秒钟20。举例代码如下:
http { local shared_data = ngx.shared.dict shared_data:set("draw", 0) content_by_lua_block { local request_uri = ngx.var.request_uri; if string.sub(request_uri,1,22) == "/activity/lottery/draw" then local val, err = ngx.shared.dict:incr("draw", 1); #进来一个请求就加1 if val > 100 then #限流100 ngx.log(ngx.ERR,"draw limit val is:"..val) ngx.exit(503) end ....业务处理 end } ... log_by_lua_block{ local request_uri = ngx.var.request_uri; if string.sub(request_uri,1,22) == "/activity/lottery/draw" then local val, err = ngx.shared.dict:incr("draw", -1); #出去一个请求就减1 if val < 0 then ngx.shared.dict:set("draw", 0); end end } }
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句