OpenResty 가 흐름 제한 을 실현 하 는 몇 가지 방식
api 게 이 트 웨 이 를 닫 을 때 간단 한 흐름 제한 을 한 적 이 있다. 예 를 들 어 정적 차단 과 동적 차단 등 이다.정적 차단 은 특정한 인터페이스 가 일정 시간 창 에 있 는 요청 수 를 제한 하 는 것 이다.사용 자 는 시스템 에서 그들의 인터페이스 에 초당 최대 호출 량 을 설정 할 수 있 습 니 다. 만약 에 이 제한 을 초과 하면 서비스 이 인 터 페 이 스 를 거부 합 니 다. 동적 차단 도 정적 차단 을 바탕 으로 개선 할 수 있 습 니 다. 우 리 는 현재 시스템 의 응답 시간 에 따라 제한 흐름 의 한도 값 을 동적 으로 조정 할 수 있 습 니 다. 만약 에 응답 이 빠 르 면 한도 값 을 크게 조정 하고 더 많은 요 구 를 할 수 있 습 니 다.반대로 흐름 제한 한도 값 을 자동 으로 낮 추고 소량의 요청 만 통과 시킨다.사실 이것 은 매우 간단 한 흐름 제한 방식 이다.하지만 이 장면 들 은 우리 가 개발 할 때 자주 만 나 기 때문에 여기 서 사용 합 니 다.
OpenResty 대략 흔히 볼 수 있 는 제한 방식 을 실현 하 다.(이곳 에 서 는 OpenResty1.13.6.1 버 전의 자체 테이프 lua-resty-limit-traffic 모듈 을 사용 하여 실현 하기에 더욱 편리 합 니 다)인터페이스 총 병발 수 제한
장면:
ip 동시 접속 수 제한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
ua_shared_dict my_limit_conn_store 100m; ... location /hello { access_by_lua_block { local limit_conn = require "resty.limit.conn" -- ip 1 -- burst 0, , 503, -- , burst ( ) -- ( ) , local lim, err = limit_conn.new("my_limit_conn_store", 1, 0, 0.5) if not lim then ngx.log(ngx.ERR, "failed to instantiate a resty.limit.conn object: ", err) return ngx.exit(500) end local key = ngx.var.binary_remote_addr -- commit true shared dict key , -- false 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 -- shared dict , ctx , -- , if lim:is_committed() then local ctx = ngx.ctx ctx.limit_conn = lim ctx.limit_conn_key = key ctx.limit_conn_delay = delay end local conn = err -- delay , -- , 100 , 200 , 500 , 200 -- 100 , 200 , 200 ,0-100 0.5 , -- 101-200 0.5*2=1 (0.5 ) if delay >= 0.001 then ngx.sleep(delay) end } log_by_lua_block { local ctx = ngx.ctx local lim = ctx.limit_conn if lim then local key = ctx.limit_conn_key -- , shared dict , -- , limit_conn.new , -- local conn, err = lim:leaving(key, 0.5) if not conn then ngx.log(ngx.ERR, "failed to record the connection leaving ", "request: ", err) return end end } proxy_pass http://10.100.157.198:6112; proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_send_timeout 600; 설명: 사실 이곳 은 설정 되 어 있 지 않 습 니 다.
burst 의 값 은 단순 한 제한 최대 병발 수 입 니 다. 설정 하면 burst 의 값 과 지연 처 리 를 했 습 니 다. 사실은 병발 수 에 누 통 알고리즘 을 사 용 했 지만 지연 처 리 를 하지 않 으 면 사용 하 는 토 큰 통 알고리즘 입 니 다. 아래 요청 수 에 누 통 토 큰 통 을 사용 하 는 부분 을 참고 하여 병발 수의 누 통 토 큰 통 은 이와 비슷 합 니 다.인터페이스 시간 창 요청 수 제한
필드: 제한
ip 분당 120 회 만 호출 가능 /hello 인터페이스 (시간 대 시작 시 120 개의 요청 을 한꺼번에 놓 칠 수 있 음)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
lua_shared_dict my_limit_count_store 100m; ... init_by_lua_block { require "resty.core" } .... location /hello { access_by_lua_block { local limit_count = require "resty.limit.count" -- rate: 10/min local lim, err = limit_count.new("my_limit_count_store", 120, 60) if not lim then ngx.log(ngx.ERR, "failed to instantiate a resty.limit.count object: ", err) return ngx.exit(500) end local key = ngx.var.binary_remote_addr local delay, err = lim:incoming(key, true) -- , ( 0, ) if not delay then if err == "rejected" then return ngx.exit(503) end ngx.log(ngx.ERR, "failed to limit count: ", err) return ngx.exit(500) end } proxy_pass http://10.100.157.198:6112; proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_send_timeout 600; } 부 드 러 운 제한 인터페이스 요청 수
필드: 제한
ip 분당 120 회 만 호출 가능 /hello 인터페이스 (매 끄 러 운 처리 요청, 즉 1 초 에 2 개의 요청 을 놓 치 는 것)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
lua_shared_dict my_limit_req_store 100m; .... location /hello { access_by_lua_block { local limit_req = require "resty.limit.req" -- rate=2/s, 0,( ) -- resty.limit.req , local lim, err = limit_req.new("my_limit_req_store", 2, 0) 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 } proxy_pass http://10.100.157.198:6112; proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_send_timeout 600; } 누 출 통 알고리즘 제한 흐름
필드: 제한
ip 분당 120 회 만 호출 가능 /hello 인터페이스 (부 드 러 운 처리 요청, 즉 1 초 에 2 개의 요청 을 놓 치 는 것), 부분 을 초과 하여 통 에 들 어가 기다 리 고 (통 용량 은 60), 통 이 가득 차 면 흐름 제한 을 한다.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
lua_shared_dict my_limit_req_store 100m; .... location /hello { access_by_lua_block { local limit_req = require "resty.limit.req" -- rate=2/s, 0,( ) -- resty.limit.req , local lim, err = limit_req.new("my_limit_req_store", 2, 60) 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 -- , delay , -- , , -- if delay >= 0.001 then ngx.sleep(delay) end } proxy_pass http://10.100.157.198:6112; proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_send_timeout 600; } 토 큰 통 알고리즘 흐름 제한
토 큰 통 은 사실 누 출 통 의 역 조작 을 볼 수 있 습 니 다. 우리 가 요청 속 도 를 초과 하여 통 에 들 어 가 는 요 구 를 어떻게 처리 하 는 지 볼 수 있 습 니 다. 만약 에 우리 가 이 부분 을 대기 행렬 에 넣 었 다 면 사실은 누 출 통 알고리즘 을 사 용 했 습 니 다. 그러나 우리 가 이 부분의 돌발 요 구 를 직접 처리 할 수 있다 면 사실은 토 큰 통 알고리즘 을 사용 한 것 입 니 다.
필드: 제한
ip 분당 120 회 만 호출 가능 /hello 인터페이스 (부 드 러 운 처리 요청, 즉 1 초 에 2 개의 요청 을 놓 치지 만 일정한 돌발 유량 (돌발 유량, 즉 통 의 용량 (통 의 용량 은 60) 을 허용 하고 통 의 용량 을 초과 하면 직접 거절 합 니 다.여 기 는 통 에서 요청 한 지연 처리 코드 를 백 엔 드 서비스 로 바로 보 내 면 됩 니 다. 이렇게 하면 토 큰 통 을 사용 합 니 다.
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
lua_shared_dict my_limit_req_store 100m; .... location /hello { access_by_lua_block { local limit_req = require "resty.limit.req" local lim, err = limit_req.new("my_limit_req_store", 2, 0) 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 -- , delay , -- , , -- if delay >= 0.001 then -- ngx.sleep(delay) end } proxy_pass http://10.100.157.198:6112; proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_send_timeout 600; } 설명: 사실
nginx 의 ngx_http_limit_req_module 이 모듈 의 delay 과 nodelay 는 여기 서 통 에 지연 처 리 를 요청 하 는 것 과 유사 한 두 가지 방안 이다. 즉, 각각 대응 하 는 누 출 통 과 토 큰 통 두 가지 알고리즘 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Openresty 및 Google BigQuery를 사용한 마이크로서비스 사용량 로깅Descartes Labs에서는 플랫폼 구축에 마이크로서비스 아키텍처를 사용해 왔습니다. Descartes Labs의 마이크로서비스 로깅, 특히 사용 로깅의 주요 요구 사항은 전체 위성 이미지 모음에 대한 API 액...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.