ÔõÑùʵÏÖNginxµÄÏÞÖÆÇëÇóËÙÂÊÉèÖÃ
ÔõÑùʵÏÖNginxµÄÏÞÖÆÇëÇóËÙÂÊÉèÖÃ
NginxÊÇÒ»¿î¸ßÐÔÄܵÄWebЧÀÍÆ÷£¬¿ÉÒÔͨ¹ýÉèÖÃʵÏÖ¶ÔÇëÇóµÄÏÞÖƺͿØÖÆ¡£ÔÚÏÖʵӦÓÃÖУ¬ÎªÁ˱£»¤Ð§ÀÍÆ÷×ÊÔ´£¬ÍùÍùÐèÒª¶ÔÇëÇóËÙÂʾÙÐÐÏÞÖÆ¡£±¾ÎĽ«ÏÈÈÝÔõÑùÔÚNginxÖÐʵÏÖÇëÇóËÙÂʵÄÏÞÖÆ¡£
Ò»¡¢Ê¹ÓÃHttpLimitReqModuleÄ£¿é
NginxÌṩÁËHttpLimitReqModuleÄ£¿é£¬¿ÉÒÔͨ¹ý¸ÃÄ£¿éʵÏÖ¶ÔÇëÇóËÙÂʵÄÏÞÖÆ¡£ÔÚ×îÏÈÉèÖÃ֮ǰ£¬ÐèҪȷ±£ÒѾװÖÃÁËHttpLimitReqModuleÄ£¿é¡£
±à¼NginxÉèÖÃÎļþ
·¿ªNginxµÄÉèÖÃÎļþ£¬Ò»Ñùƽ³£Î»ÓÚ/etc/nginx/nginx.conf£¬ÕÒµ½http¶Î£¬Ìí¼ÓÈçÏÂÉèÖãº
http { ... limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { ... } }
µÇ¼ºó¸´ÖÆ
limit_req_zoneÓÃÓÚ½ç˵ÏÞÖÆÇøÓòµÄÃû³ÆºÍ¾Þϸ£¬$binary_remote_addrÌåÏÖʹÓÿͻ§¶ËµÄIPµØµã×÷ΪÏÞÖƵÄÒªº¦×Ö¡£zone=one:10mÌåÏÖʹÓÃÃûΪoneµÄÏÞÖÆÇøÓò£¬¾ÞϸΪ10MB¡£rate=1r/sÌåÏÖÿÃëÇëÇóËÙÂÊÏÞÖÆΪ1¸ö¡£
ÉèÖÃÇëÇóÏÞÖÆ
ÔÚÐèÒª¾ÙÐÐÇëÇóÏÞÖƵĵط½£¬Ìí¼Ólimit_reqÖ¸ÁîÀ´ÏÞÖÆÇëÇóËÙÂÊ¡£ÀýÈ磬½«ÇëÇóËÙÂÊÏÞÖÆΪ10¸öÇëÇó/Ã룬¿ÉÔÚserver¶ÎÖÐÌí¼ÓÈçÏÂÉèÖãº
location / { limit_req zone=one burst=5; ... }
µÇ¼ºó¸´ÖÆ µÇ¼ºó¸´ÖÆ
limit_reqÖ¸ÁîÓÃÓÚÓ¦ÓÃÇëÇóÏÞÖÆ£¬zone²ÎÊýÖ¸¶¨Ê¹ÓõÄÏÞÖÆÇøÓòÃû³Æ£¬burst²ÎÊýÖ¸¶¨Í¬Ê±´¦Öóͷ£µÄÇëÇóÊýÄ¿¡£ÉÏÊöÉèÖÃÌåÏÖÈôÊÇÇëÇóÊýÁè¼Ý10¸ö/Ã룬½«»á·µ»Ø503¹ýʧ¡£
ÖØмÓÔØNginxÉèÖÃ
Íê³ÉÉèÖÃÖ®ºó£¬ÐèÒªÖØмÓÔØNginxÉèÖÃʹÆäÉúЧ¡£¿ÉÒÔʹÓÃÒÔÏÂÏÂÁî¾ÙÐÐÉèÖüì²éºÍÖØмÓÔØ£º
$ nginx -t # ¼ì²éÉèÖÃÊÇ·ñ׼ȷ $ nginx -s reload # ÖØмÓÔØÉèÖÃ
µÇ¼ºó¸´ÖÆ
¶þ¡¢Ê¹ÓÃngx_http_limit_req_moduleÄ£¿é
³ýÁËHttpLimitReqModuleÄ£¿éÍ⣬»¹¿ÉÒÔʹÓÃngx_http_limit_req_moduleÄ£¿éÀ´ÊµÏÖ¶ÔÇëÇóËÙÂʵÄÏÞÖÆ¡£¸ÃÄ£¿éÌṩÁËÔ½·¢ÎÞаµÄÉèÖÃÑ¡Ïî¡£
±à¼NginxÉèÖÃÎļþ
·¿ªNginxµÄÉèÖÃÎļþ£¬ÕÒµ½http¶Î£¬Ìí¼ÓÈçÏÂÉèÖãº
http { ... limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { ... } }
µÇ¼ºó¸´ÖÆ
¸ÃÉèÖÃÓëHttpLimitReqModuleÄ£¿éÏàͬ£¬¶¼Êǽç˵ÁËÒ»¸öÃûΪoneµÄÏÞÖÆÇøÓò£¬¾ÞϸΪ10MB£¬ÇëÇóËÙÂÊÏÞÖÆΪ1¸ö/Ãë¡£
ÉèÖÃÇëÇóÏÞÖÆ
ÔÚÐèÒª¾ÙÐÐÇëÇóÏÞÖƵĵط½£¬Ìí¼Ólimit_reqÖ¸ÁîÀ´ÏÞÖÆÇëÇóËÙÂÊ¡£ÀýÈ磬½«ÇëÇóËÙÂÊÏÞÖÆΪ10¸öÇëÇó/Ã룬¿ÉÔÚserver¶ÎÖÐÌí¼ÓÈçÏÂÉèÖãº
location / { limit_req zone=one burst=5; ... }
µÇ¼ºó¸´ÖÆ µÇ¼ºó¸´ÖÆ
limit_reqÖ¸ÁîÓÃÓÚÓ¦ÓÃÇëÇóÏÞÖÆ£¬zone²ÎÊýÖ¸¶¨Ê¹ÓõÄÏÞÖÆÇøÓòÃû³Æ£¬burst²ÎÊýÖ¸¶¨Í¬Ê±´¦Öóͷ£µÄÇëÇóÊýÄ¿¡£
ÖØмÓÔØNginxÉèÖÃ
Íê³ÉÉèÖÃÖ®ºó£¬ÐèÒªÖØмÓÔØNginxÉèÖÃʹÆäÉúЧ£¬¿ÉÒÔʹÓÃÒÔÏÂÏÂÁî¾ÙÐÐÉèÖüì²éºÍÖØмÓÔØ¡£
$ nginx -t # ¼ì²éÉèÖÃÊÇ·ñ׼ȷ $ nginx -s reload # ÖØмÓÔØÉèÖÃ
µÇ¼ºó¸´ÖÆ
Èý¡¢Ê¹ÓÃlua¾ç±¾À©Õ¹ÇëÇóÏÞÖÆ
Nginx»¹Ö§³ÖʹÓÃlua½ÅÔÀ´À©Õ¹ÇëÇóÏÞÖƵĹ¦Ð§¡£Í¨¹ý±àд×Ô½ç˵µÄlua¾ç±¾£¬¿ÉÒÔʵÏÖÔ½·¢ÎÞаºÍÖØ´óµÄÇëÇóÏÞÖÆÕ½ÂÔ¡£
×°ÖÃluaÄ£¿é
Ê×ÏÈ£¬ÐèҪȷ±£ÒÑ×°ÖúÃNginxµÄluaÄ£¿é¡£
±àдlua¾ç±¾
ÔÚNginxµÄÉèÖÃÎļþÖУ¬Ìí¼ÓÈçÏÂÉèÖãº
http { ... lua_shared_dict limit_req_store 10m; server { ... location / { access_by_lua_block { local limit_req = require "resty.limit.req" local lim, err = limit_req.new("limit_req_store", 1, 1) if not lim then ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err) return ngx.exit(500) end local key = ngx.var.binary_remote_addr local delay, err = lim:incoming(key, true) if not delay then if err == "rejected" then return ngx.exit(503) end ngx.log(ngx.ERR, "failed to limit req: ", err) return ngx.exit(500) end if delay >= 0.001 then ngx.sleep(delay) end } ... } } }
µÇ¼ºó¸´ÖÆ
¸ÃÉèÖÃʹÓÃlua_shared_dictÖ¸Áî½ç˵һ¸öÃûΪlimit_req_storeµÄ¹²ÏíÄÚ´æÇøÓò£¬¾ÞϸΪ10MB¡£
ÖØмÓÔØNginxÉèÖÃ
Íê³ÉÉèÖÃÖ®ºó£¬ÖØмÓÔØNginxÉèÖÃʹÆäÉúЧ¡£
ËÄ¡¢×ܽá
±¾ÎÄÏÈÈÝÁËÈýÖÖʵÏÖNginxÇëÇóËÙÂÊÏÞÖƵķ½·¨£¬»®·ÖÊÇʹÓÃHttpLimitReqModuleÄ£¿é¡¢ngx_http_limit_req_moduleÄ£¿éºÍlua¾ç±¾¡£Í¨¹ýºÏÊʵÄÉèÖúÍÏÞÖÆÕ½ÂÔ£¬¿ÉÒÔÓÐÓñ£»¤Ð§ÀÍÆ÷×ÊÔ´£¬±ÜÃâ¶ñÒâÇëÇó¶ÔЧÀÍÆ÷Ôì³É¹ý´ó¸ºÔØ¡£ÔÚÏÖʵӦÓÃÖУ¬¿ÉÒÔƾ֤ÏêϸÐèÇóÑ¡ÔñºÏÊʵķ½·¨À´¾ÙÐÐÇëÇóËÙÂÊÏÞÖÆ¡£
ÒÔÉϾÍÊÇÔõÑùʵÏÖNginxµÄÏÞÖÆÇëÇóËÙÂÊÉèÖõÄÏêϸÄÚÈÝ£¬¸ü¶àÇë¹Ø×¢±¾ÍøÄÚÆäËüÏà¹ØÎÄÕ£¡