>  기사  >  10분 안에 전류 제한 및 일반적인 솔루션을 이해하세요!

10분 안에 전류 제한 및 일반적인 솔루션을 이해하세요!

Java后端技术全栈
Java后端技术全栈앞으로
2023-08-15 16:15:432008검색

최근 여러 네티즌들로부터 인터뷰 피드백을 받았는데 인터뷰 중에 모두 currentlimiting관련 질문을 받았습니다. 오늘 우리 프로젝트의 다양한 전류 제한 솔루션에 대해 이야기해 보겠습니다.

전류 제한의 기본 개념

일반적인 전류 제한 시나리오의 경우 정보의 두 가지 차원이 있습니다.

  • 시간 전류 제한은 특정 시간 범위 또는 특정 시점을 기반으로 합니다. , 분당, 초당 시간 창을 제한하는 등 우리가 흔히 "시간 창"이라고 부르는 것입니다
  • 자원은 최대 방문 횟수를 설정하거나 최대 횟수를 설정하는 등 사용 가능한 자원의 제한을 기반으로 합니다. of available Connection

위의 두 가지 차원을 결합한 전류 제한은 초당 최대 100개의 액세스 요청을 설정하는 등 특정 시간 창 내에서 리소스 액세스를 제한하는 것입니다. 그러나 실제 시나리오에서는 하나의 전류 제한 규칙을 설정할 뿐만 아니라 함께 작동하도록 여러 전류 제한 규칙도 설정합니다. 주요 전류 제한 규칙은 다음과 같습니다.

QPS 및 연결 수 제어

(연결) 데이터QPS) 전류 제한의 경우 IP 차원에서 전류 제한을 설정하거나 단일 서버를 기반으로 전류 제한을 설정할 수 있습니다.

10분 안에 전류 제한 및 일반적인 솔루션을 이해하세요!
Pictures

실제 환경에서는 일반적으로 동일한 IP의 액세스 빈도를 초당 10개 미만으로 설정, 연결 수를 5개 미만으로 설정하는 등 다차원의 전류 제한 규칙이 설정되며, 그런 다음 각 시스템의 최대 QPS를 1000으로 설정하면 최대 연결 수는 200으로 유지됩니다. 또한 서버 그룹이나 전체 컴퓨터실의 서버를 전체적으로 처리하고 더 높은 수준의 전류 제한 규칙을 설정할 수 있습니다. 이러한 모든 전류 제한 규칙은 트래픽 제어를 위해 함께 작동합니다.

전송 속도

리소스 다운로드 속도 등 "전송 속도"는 누구나 잘 알고 있습니다. 일부 웹 사이트에는 이 영역에 대해 더 자세한 전류 제한 논리가 있습니다. 예를 들어 일반 등록 사용자의 다운로드 속도는 100k/s이고 멤버십 구매 후 10M/s입니다. 그 뒤에는 사용자 그룹을 기반으로 한 전류 제한 논리가 있습니다. 또는 사용자 태그.

흑백 목록

흑백 목록은 대기업 응용 프로그램에서 트래픽을 제한하고 해제하는 매우 일반적인 수단이며, 흑색 및 흰색 목록은 동적으로 변경되는 경우가 많습니다. 예를 들어, 일정 기간 동안 너무 자주 방문한 IP가 시스템에 의해 로봇 사용자 또는 트래픽 공격으로 식별되면 해당 IP가 블랙리스트에 추가되어 시스템 리소스에 대한 액세스가 제한됩니다. 우리가 흔히 "IP 차단"이라고 부르는 것.

Zhihu에서 미인 사진을 크롤링하거나 중개 시스템에서 주식 시분할 정보를 크롤링하는 등 우리가 일반적으로 볼 수 있는 크롤러 프로그램은 블랙리스트에 추가되지 않도록 IP 변경 기능을 구현해야 합니다.

때때로 회사의 네트워크가 12306과 같은 대규모 공개 웹사이트에 액세스할 수 없는 경우도 있습니다. 이는 일부 회사의 아웃바운드 IP 주소가 동일한 주소이기 때문이기도 합니다. 따라서 방문 횟수가 너무 많으면 이 IP 주소가 사용됩니다. 시스템에 의해 식별된 후 블랙리스트에 추가됩니다. 가정용 광대역을 사용하는 학생은 대부분의 네트워크 운영자가 사용자를 다른 아웃바운드 IP 세그먼트에 할당하거나 때때로 사용자의 IP 주소를 동적으로 변경한다는 점을 알아야 합니다.

화이트리스트는 왕실에서 수여하는 금메달과도 같습니다. 다양한 전류 제한 규칙을 아무런 방해 없이 자유롭게 이동할 수 있습니다. 예를 들어, 일부 전자 상거래 회사는 대규모 판매자의 계정을 화이트리스트에 추가합니다. 왜냐하면 이러한 판매자는 종종 자체 운영 및 유지 관리 시스템을 보유하고 회사의 IT 시스템과 인터페이스하여 대량의 제품 출시, 보충을 수행해야 하기 때문입니다. , 등. 또한 공개 계정 프로그래밍 기술 서클 백엔드를 검색하고 "Java"라고 답하면 깜짝 선물 패키지를 얻을 수 있습니다.

분산 환경

분산은 단일 머신 전류 제한 시나리오와 다릅니다. 전체 분산 환경의 모든 서버를 전체적으로 고려합니다. 예를 들어, IP 전류 제한의 경우 하나의 IP를 초당 최대 10회 방문으로 제한합니다. 이 IP의 요청이 어떤 시스템에 속하든 관계없이 클러스터의 서비스 노드에 액세스하는 한에는 다음이 적용됩니다. 현재 제한은 규칙에 의해 제한됩니다.

클러스터에 있는 모든 시스템의 액세스 상태를 얻을 수 있도록 "중앙 집중식" 구성 요소에 전류 제한 정보를 저장하는 것이 좋습니다. 현재 두 가지 주류 전류 제한 솔루션이 있습니다.

  • Gateway Layer 전류 제한이 적용됩니다. 모든 트래픽의 진입에 대한 현재 제한 규칙
  • 미들웨어 전류 제한은 분산 환경(예: Redis 캐시)의 미들웨어에 현재 제한 정보를 저장하고 각 구성 요소는 여기에서 액세스할 수 있습니다. 현재의 트래픽 통계를 가져옵니다. 서비스 거부 또는 트래픽 허용 여부를 결정하는 순간
  • sentinel, 분산 전류 제한, 회로 차단기 성능 저하 및 기타 구성 요소를 위한 마이크로서비스를 위해 springcloud 생태계에서 맞춤 제작한 구성 요소

전류 제한 체계에 일반적으로 사용되는 알고리즘

토큰 버킷 알고리즘

토큰 버킷 토큰 버킷 알고리즘은 이름에서 알 수 있듯이 현재 가장 널리 사용되는 전류 제한 알고리즘입니다.

  • 토큰을 얻는 요청만 처리됩니다. 다른 요청은 대기열에 추가되거나 직접 삭제됩니다.
  • 버킷은 주로 이 버킷에서 토큰을 얻는 데 사용됩니다.
  • 토큰 생성

이 프로세스에는 토큰 생성기와 토큰 버킷이 포함됩니다. 앞서 토큰 버킷이 토큰을 위한 장소라고 언급했습니다. 이는 토큰 버킷이 보유할 수 있는 토큰 수가 고정된 값임을 의미합니다.

토큰 생성기의 경우 미리 결정된 속도에 따라 버킷에 토큰을 추가합니다. 예를 들어 초당 100개 요청 또는 분당 50개의 요청 속도로 토큰을 발행하도록 구성할 수 있습니다. 여기서 발행 속도는 균일하다는 점에 유의하세요. 즉, 이 50개의 토큰은 각 기간이 시작될 때 한꺼번에 발행되지 않지만 이 기간 내에 균일한 속도로 발행됩니다.

토큰 디스펜서는 수도꼭지입니다. 아래 물이 담긴 양동이가 가득 차면 물(토큰)이 자연스럽게 밖으로 흘러나옵니다. 토큰 발행 과정에서도 마찬가지입니다. 토큰 버킷의 용량은 제한되어 있습니다. 현재 정격 용량의 토큰이 채워져 있는 경우 새 토큰은 폐기됩니다.

  • 토큰 획득

각 액세스 요청이 도착한 후 후속 로직을 실행하려면 토큰을 획득해야 합니다. 토큰 수가 적고 액세스 요청이 많은 경우 일부 요청은 당연히 토큰을 얻을 수 없습니다. 이때 이러한 초과 토큰을 임시로 저장하기 위해 "버퍼 큐"를 설정할 수 있습니다.

버퍼 큐는 실제로 선택 사항이며, 토큰 버킷 알고리즘을 적용하는 모든 프로그램이 큐를 구현하는 것은 아닙니다. 캐시 대기열이 있는 경우 아직 토큰을 얻지 못한 요청은 새 토큰이 생성될 때까지 이 대기열에 대기한 다음 토큰과 일치하도록 대기열의 헤드에서 요청을 가져옵니다.

큐가 가득 차면 이러한 액세스 요청은 삭제됩니다. 실제 응용 프로그램에서는 대기열에 있는 요청의 생존 시간을 설정하거나 대기열을 PriorityQueue로 변환하고 선입선출 대신 특정 우선순위에 따라 정렬하는 등 일련의 특수 효과를 이 대기열에 추가할 수도 있습니다. .

Leaky Bucket Algorithm

Leaky Bucket은 또 다른 버킷입니다. 전류 제한 알고리즘은 버킷과 관련이 있습니다. 그렇다면 Leaky Bucket과 Token Bucket의 차이점은 무엇인가요?

리키 버킷 알고리즘의 전반부는 토큰과 유사합니다. 그러나 동작 대상이 다릅니다. 토큰 버킷은 토큰을 버킷에 넣는 반면, 리키 버킷은 액세스 요청 패킷을 버킷에 넣습니다. 마찬가지로 버킷이 가득 차면 수신 패킷이 삭제됩니다.

리키 버킷 알고리즘의 후반부는 항상 일정한 속도로 버킷에서 데이터 패킷이 흘러나오는 것이 특징입니다. 예를 들어, 100개의 데이터 패킷을 저장하기 위해 Leaky 버킷을 설정하고 유출 속도가 초당 1개라면 데이터 패킷이 버킷으로 유입되는 속도와 버킷에 있는 데이터 패킷 수에 관계없이 , 누출 버킷은 이러한 데이터 패킷이 항상 1초의 일정한 속도로 처리되도록 보장할 수 있습니다. 또한, 퍼블릭 계정 백엔드 아키텍트의 백엔드를 검색해 "클린 아키텍처"라고 답하시면 깜짝 선물 패키지를 받으실 수 있습니다.

  • 리키 버킷과 토큰 버킷의 차이

각각의 특성으로 보면 두 알고리즘 모두 "일정한" 비율과 "불확실한" 비율이 있습니다. 토큰 버킷은 일정한 속도로 토큰을 생성하지만, 액세스 요청이 토큰을 획득하는 속도는 "고정되지 않음"입니다. 어쨌든 토큰이 있는 만큼 발행되며, 토큰이 없어지면 기다리기만 하면 됩니다. Leaky 버킷은 요청을 "일정한" 속도로 처리하지만 이러한 요청이 버킷으로 유입되는 속도는 "가변"입니다.

이 두 가지 특성에서 누출 버킷의 자연스러운 특성에 따라 초당 1,000개의 요청이 도착하더라도 백그라운드 서비스 출력에 대한 액세스 속도는 항상 일정합니다. 토큰 버킷은 일정량의 토큰을 "사전 저장"할 수 있으므로 갑작스러운 트래픽을 처리할 때 모든 토큰을 짧은 시간 내에 소비할 수 있습니다. 버킷이지만 그에 따라 백엔드 시스템에 대한 압력도 증가합니다.

Sliding Window

예를 들어 1초마다 5명의 사용자가 방문하고 5초 내에 10명의 사용자가 방문한다면 0~5초의 시간대에 방문하는 횟수는 15회입니다. 인터페이스가 시간 창 내 액세스 상한을 20으로 설정한 경우 시간이 6초에 도달하면 이 시간 창의 총 개수는 10이 됩니다. 1초 그리드가 시간 창을 벗어났기 때문입니다. 6초 이내에 수신할 수 있는 방문수는 20-10=10입니다.

슬라이딩 창은 실제로 계산기 알고리즘입니다. 시간 창의 범위가 길면 전류 제한 효과가 더 부드러워집니다. 예를 들어, 현재 시간 창이 2초에 불과하고 모든 액세스 요청이 처음 1초에 집중되어 있는 경우 시간이 1초 뒤로 밀릴 때 현재 창의 개수가 크게 변경될 확률을 줄일 수 있습니다.

일반적으로 사용되는 전류 제한 솔루션

합법성 검증 전류 제한

인증 코드, IP 블랙리스트 등 이러한 수단은 악성 공격 및 크롤러 수집을 효과적으로 방지할 수 있습니다.

Guawa 전류 제한

전류 제한 분야에서 Guava는 멀티 스레딩 모듈에서 [RateLimiter为首的几个限流支持类,但是作用范围仅限于“当前”这台服务器,也就是说Guawa的限流是单机的限流,跨了机器或者jvm进程就无能为力了比如说,目前我有2台服务器[Server 1Server 2]을 제공합니다. 두 서버 모두 로그인 서비스를 배포했습니다. 예를 들어 두 시스템의 총 방문 수를 제어하려는 경우입니다. Guava를 사용하면 각 머신의 방문 횟수를 독립적으로

Guava는 분산 시스템을 위한 솔루션은 아니지만 간단하고 가벼운 클라이언트 측 전류 제한 구성 요소로서 전류 제한 알고리즘을 설명하는 데 매우 적합합니다.

게이트웨이 계층 전류 제한

서비스 게이트웨이는 전체 분산 시스템으로서 링크의 첫 번째 수준은 모든 사용자 요청을 처리하므로 게이트웨이 수준에서 트래픽을 제한하는 것이 좋은 시작점입니다.

  1. 사용자 트래픽은 게이트웨이 계층에서 서비스
  2. 로 전달됩니다.
  3. 백그라운드 서비스는 트래픽을 수락하고 캐시를 호출하여 데이터를 얻습니다.
  4. 캐시에 데이터가 없으면 데이터베이스에 액세스합니다.

트래픽은 위에서 아래로 계층별로 감소하며 가장 크고 밀도가 높습니다. 트래픽은 게이트웨이 계층 사용자 액세스 요청에서 수집되고 이어서 백그라운드 서비스가 수집됩니다.

백그라운드 서비스의 확인 로직을 통과한 후 일부 잘못된 요청은 플러시되고 나머지 요청은 캐시에 저장되므로 퍼널 하단에 있는 데이터베이스가 요청됩니다. 데이터베이스 수준의 요청 수가 가장 적습니다(다른 구성 요소에 비해 데이터베이스가 동시성 용량이 가장 나쁜 경우가 많습니다. Alibaba의 MySQL이 많은 수정을 거쳤더라도 단일 시스템 동시성은 비교할 수 없습니다. Redis 및 Kafka와 같은 구성 요소.)

현재 주류 게이트웨이 계층은 소프트웨어로 대표되는 Nginx이며 Spring Cloud의 Gateway 및 Zuul과 같은 게이트웨이 계층 구성 요소

Nginx 전류 제한

시스템 아키텍처에서는 Nginx의 프록시 라우팅 포워딩은 게이트웨이 계층 기능으로서 매우 중요합니다. Nginx 고유의 가볍고 우수한 설계로 인해 게이트웨이 수준을 고려할 때 Nginx는 대부분의 상황을 견딜 수 있는 가장 프런트엔드 게이트웨이로 사용될 수 있습니다. Nginx에서는 전류 제한과 관련하여 일반적으로 사용되는 정책 구성도 제공됩니다. 하나는 속도를 제어하는 ​​것이고, 다른 하나는 Nginx입니다. 다른 하나는 동시 연결 수를 제어하는 ​​것입니다.

속도 제어

단위 시간당 요청 수, 즉 속도 제한을 제한하려면

를 사용해야 합니다.

limit_req_zoneNginx의 현재 제한 통계는 밀리초 단위이므로 우리가 설정한 속도는 2r/s입니다. 즉, 단일 IP는 500밀리초 이내에 하나의 요청만 통과하도록 허용되고, 두 번째 요청은 501ms부터 통과하도록 허용됩니다.

  • 비율 제어의 최적화 버전
  • 위의 비율 제어는 매우 정확하지만 실제 환경에서는 너무 가혹한 방식이므로 IP 단위의 총 액세스 수를 제어해야 합니다. 위와 같이 총 시간이 아니라 밀리초 단위로 정확합니다. 버스트 키워드를 사용하여 이 설정을 켤 수 있습니다

burst=4는 모든 IP 허용을 의미합니다. 4개의 버스트 요청으로burst=4意思是每个IP最多允许4个突发请求

控制并发数

利用 limit_conn_zonelimit_conn 两个指令即可控制并发数

其中 limit_conn perip 10 表示限制单个 IP 同时最多能持有 10 个连接;limit_conn perserver 100

동시성 수 제어

limit_conn_zonelimit_conn 코드 > 두 개의 명령어로 동시성 수를 제어할 수 있습니다<p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>그 중<code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px; background-color : rgba(27, 31, 35, 0.05); 글꼴 계열: " operator mono consolas monaco menlo monospace break-all rgb> limit_conn perip 10은 단일 IP가 동시에 최대 10개의 연결을 유지하도록 제한하는 것을 의미합니다. limit_conn perserver 100은 서버가 동시에 총 100개의 동시 연결을 처리할 수 있음을 의미합니다.

참고: 이 연결은 요청 헤더가 백엔드에서 처리된 후에만 계산됩니다.

미들웨어 전류 제한

분산 환경의 경우 현재 제한된 데이터를 저장하는 중앙 노드와 같은 장소에 지나지 않습니다. 예를 들어 제어 인터페이스의 액세스 속도를 초당 100개 요청으로 설정하려면 현재 1초 내에 수신된 요청 수를 어딘가에 저장하고 클러스터 환경의 모든 노드가 액세스할 수 있도록 허용해야 합니다. 그렇다면 이 임시 데이터를 저장하기 위해 어떤 기술을 사용할 수 있습니까?

그래서 다들 Redis일 거라고 생각하셨을 겁니다. Redis의 만료 시간 기능을 사용하면 현재 제한의 시간 범위(예: 초당 10개 요청 또는 10초마다 10개 요청)를 쉽게 설정할 수 있습니다. 동시에 Redis에는 스크립트 프로그래밍이라는 특수한 기술이 있습니다. 이를 통해 현재 제한 논리를 서비스 계층에서 완전히 분리할 수 있습니다. 강력한 동시성 특성 및 높은 사용 가능한 클러스터 아키텍처는 대규모 클러스터(

reids + lua

)에 대한 현재 제한된 액세스도 잘 지원할 수 있습니다. 🎜🎜🎜전류 제한 구성 요소🎜🎜🎜위에 소개된 방법 외에도 현재 Sentinel과 같은 유사한 기능을 제공하는 일부 오픈 소스 구성 요소가 있으므로 이는 좋은 선택입니다. Sentinel은 Alibaba에서 제작한 오픈 소스 구성 요소이며 Spring Cloud Alibaba 구성 요소 라이브러리에 포함되어 있습니다. Sentinel은 전류 제한을 쉽게 관리하는 데 도움이 되는 풍부한 API 및 시각적 관리 콘솔 세트를 제공합니다.

건축적 차원에서 전류 제한 설계를 고려하세요

실제 프로젝트에서는 전류 제한 전략에 계층성을 부여하고 목표 달성을 위해 여러 가지 방법을 함께 사용하는 경우가 많습니다. 자원의 최대 활용. 이 과정에서 전류 제한 전략의 설계는 위에서 언급한 깔때기 모델을 참조할 수도 있습니다. 이 깔때기의 여러 부분에 대한 전류 제한 방식의 설계에는 주의를 기울여야 합니다. 현재 구성요소의 고가용성.

제가 참여한 실제 프로젝트를 예로 들면, 우리는 모바일 타오바오 전환을 통해 먼저 알리바바의 mtop 게이트웨이를 통과하게 됩니다. , 우리의 전류 제한은 상대적으로 느슨합니다. 요청이 게이트웨이를 통해 백엔드 제품 세부 정보 페이지 서비스에 도달한 후 일련의 미들웨어 + 전류 제한 구성 요소를 사용하여 서비스에 대한 보다 자세한 전류 제한 제어를 수행합니다

특정 전류 제한 구현 수단

1) Tomcat은 maxThreads를 사용하여 전류 제한을 구현합니다.

2) Nginx의 limit_req_zone 및 버스트 속도 제한을 구현합니다. limit_req_zone和 burst来实现速率限流。

3)Nginx的limit_conn_zonelimit_conn两个指令控制并发连接的总数。

4)时间窗口算法借助 Redis的有序集合可以实现。

5)漏桶算法可以使用Redis-Cell来实现。

6)令牌算法可以解决Google的guava包来实现。

需要注意的是借助Redis实现的限流方案可用于分布式系统,而guava实现的限流只能应用于单机环境。如果你觉得服务器端限流麻烦,可以在不改任何代码的情况下直接使用容器限流(Nginx或Tomcat),但前提是能满足项目中的业务需求。

Tomcat限流

Tomcat 8.5 版本的最大线程数在 conf/server.xml

3) Nginx의 limit_conn_zone및limit_conn두 명령은 총 동시 연결 수를 제어합니다. .

4) 시간 창 알고리즘은 Redis의 정렬된 컬렉션을 사용하여 구현할 수 있습니다. 🎜🎜5) Leaky Bucket 알고리즘은 Redis-Cell을 사용하여 구현할 수 있습니다. 🎜🎜6) 토큰 알고리즘은 Google의 guava 패키지를 해결하여 구현할 수 있습니다. 🎜
Redis로 구현된 현재 제한 체계는 다음과 같을 수 있다는 점에 유의해야 합니다. 분산 시스템을 사용하며 Guava에서 구현한 현재 제한은 독립 실행형 환경에만 적용될 수 있습니다. 서버 측 전류 제한이 번거롭다면 코드를 변경하지 않고 컨테이너 전류 제한(Nginx 또는 Tomcat)을 직접 사용할 수 있지만 프로젝트의 비즈니스 요구 사항을 충족할 수 있는 경우에만 가능합니다. 🎜

Tomcat 현재 제한 h4 >🎜Tomcat 8.5 버전의 최대 스레드 수는 conf / server.xml 구성에서 maxThreads는 Tomcat의 최대 스레드 수입니다. 요청 동시성이 이 값(maxThreads)보다 크면 요청이 실행 대기열에 추가되어 현재의 목적이 완료됩니다. 제한. 🎜🎜참고:🎜

maxThreads의 값은 적절하게 늘릴 수 있습니다. Tomcat의 기본값은 150(Tomcat 버전 8.5)이지만 이 값은 더 크지 않고 특정 서버 구성에 따라 다릅니다. 시작된 각 스레드는 1MB를 소비합니다. JVM 메모리 공간은 스레드 스택으로 사용되며, 스레드가 많을수록 GC 부담은 더 커진다.

마지막으로, 운영 체제에는 프로세스의 스레드 수에 대한 특정 제한이 있습니다. Windows의 각 프로세스의 스레드 수는 2000을 초과할 수 없으며, 각 프로세스의 스레드 수는 2000개를 초과할 수 없습니다. Linux에서는 1000을 초과할 수 없습니다.

위 내용은 10분 안에 전류 제한 및 일반적인 솔루션을 이해하세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 Java后端技术全栈에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제