>  기사  >  백엔드 개발  >  PHP의 RPC 프레임워크는 Redis 기반의 흐름 제어 시스템을 구현합니다.

PHP의 RPC 프레임워크는 Redis 기반의 흐름 제어 시스템을 구현합니다.

小云云
小云云원래의
2018-03-15 14:03:363171검색


프로젝트 모듈에서 어느 정도 마이크로서비스 변환을 수행했습니다. 이전에는 모든 모듈이 하나의 프로젝트(대형 폴더)에 배치되었으며 온라인 배포에서도 마찬가지였습니다. 나중에 비즈니스 기능에 따라 하위 모듈로 분할한 다음 RPC 프레임워크를 통해 하위 모듈에 액세스했습니다. 각 하위 모듈에는 자체적인 독립적인 온라인 머신 클러스터, mysql, redis 및 기타 스토리지 리소스가 있습니다. 이러한 하위 모듈의 문제는 다른 모듈에 영향을 미치지 않으며 유지 관리 및 확장성이 더 좋습니다.

그러나 실제로는 각 서브 모듈의 서비스 능력이 다릅니다. 서브 모듈별로 분할한 후의 아키텍처 다이어그램에서 볼 수 있듯이 모듈 A에 도달하는 QPS는 100이고 A는 B에 의존하며 각 A 모듈은 도달한다고 가정합니다. B. 모듈의 요청 QPS도 100이지만, 모듈 B가 제공할 수 있는 최대 QPS 용량은 50입니다. 트래픽 제한이 없으면 모듈 B는 부하 초과로 인해 트래픽을 축적하게 되어 전체 시스템을 사용할 수 없게 됩니다. 동적 흐름 제어 시스템은 서브 모듈의 최적 서비스 기능을 찾는 것입니다. 모듈 A에서 모듈 B로의 트래픽을 50QPS로 제한하는 것입니다. 하나의 하위 서비스가 실패하는 경우.

저희 RPC 프레임워크는 주로 http 프로토콜 액세스를 지원하는 PHP 구현 프레임워크입니다. 프론트엔드 A 모듈, 그것이 의존하는 백엔드 B 모듈의 경우 B 모듈을 먼저 서비스 구성한 후 서비스 이름에 따라 참조하고 액세스해야 합니다. 일반적인 서비스 구성 형태는 다음과 같습니다. :

[MODULE-B]  ; 服务名字
protocol = "http"  ;交互协议
lb_alg = "random" ; 负载均衡算法
conn_timeout_ms = 1000 ; 连接超时,所有协议使用, 单位为ms 
read_timeout_ms = 3000 ; 读超时
write_timeout_ms = 3000 ; 写超时 
exe_timeout_ms = 3000 ; 执行超时
host.default[] = "127.0.0.1" ; ip或域名
host.default[] = "127.0.0.2" ; ip或域名
host.default[] = "127.0.0.3" ; ip或域名
port = 80 ; 端口
domain = 'api.abc.com' ; 域名配置,不作真正解析,作为header host字段传给后端

서비스에 접근하려면 모듈은 일반적으로 클러스터로 배포됩니다. 물론 내부 DNS 서비스가 있는 경우 도메인도 장착할 수 있습니다. 클러스터의 이름입니다.

RPC 프레임워크의 기본 기능에는 로드 밸런싱, 상태 확인, 다운그레이드 및 전류 제한 등이 포함됩니다. 트래픽 제어는 다운그레이드 및 전류 제한 기능을 위한 것입니다. 자세히 소개하기 전에 로드 밸런싱 및 상태에 대해 이야기하겠습니다. 검사가 구현되는 방식은 흐름 제어 구현의 기초입니다.

로드 밸런싱을 위해 무작위 및 폴링 알고리즘을 구현했습니다. 무작위 알고리즘은 모든 IP 중 하나를 무작위로 선택하여 구현할 수 있으며, 이는 비교적 구현하기 쉽습니다. 폴링 알고리즘은 독립형 폴링을 기반으로 합니다. 마지막으로 선택한 IP 일련 번호는 사용할 다음 IP 일련 번호를 쉽게 찾을 수 있도록 로컬 메모리에 기록됩니다.

접속된 머신이 실패할 수 있습니다. Redis에 실패한 요청 IP를 기록하고 기록된 실패 로그를 분석하여 머신 IP를 제거해야 하는지 여부를 결정합니다. 즉, 이 IP를 가진 머신은 중단된 것으로 간주되어 제공할 수 없습니다. 서비스, ​​헬스 체크의 기능입니다. 관련 서비스 구성 항목을 통해 헬스 체크의 구체적인 기능을 소개합니다:

ip_fail_sample_ratio = 1 ; 采样比例

失败IP记录采样比例,我们将失败的请求记录在redis中,为防止太多的redis请求,我们可以配一个失败采样比例

ip_fail_cnt_threshold  = 10;  IP失败次数
ip_fail_delay_time_s = 2 ;  时间区间
ip_fail_client_cnt = 3 ; 失败的客户端数

不可能一个IP失败一次就将其从健康IP列表中去掉,只有在有效的ip_fail_delay_time_s 时间范围内,请求失败了 ip_fail_cnt_threshold 次,并且失败的客户端达到ip_fail_client_cnt 个, 才认为其是不健康的IP。 

为什么要添加 ip_fail_client_cnt 这样一个配置,因为如果只是某一台机器访问后端某个服务IP失败,那不一定是服务IP的问题,也可能是访问客户端的问题,只有当大多数客户端都有失败记录时才认为是后端服务IP的问题

我们将失败日志记录在redis的list表中,并带上时间戳,就比较容易统计时间区间内的失败次数。

ip_retry_delay_time_s = 30 ; 检查失败IP是否恢复间隔时间

某个失败的IP有可能在一定时间内恢复,我们间隔 ip_retry_delay_time_s 长的时间去检查,如果请求成功,则从失败的IP列表中去除

ip_retry_fail_cnt = 10;  失败IP如果检查失败,记录的失败权重值

ip_log_ttl_s = 60000; 日志有效期时间

一般来说只有最近的失败日志才有意义,对于历史的日志我们将其自动删除。
ip_log_max_cnt = 10000; 记录的最大日志量

我们用redis记录失败日志,容量有限,我们要设定一个记录的最大日志数量,多余的日志自动删除。

코드 구현에서는 정상적인 서비스 IP 구성 외에도 실패한 IP도 유지합니다. 이런 방식으로 알고리즘을 통해 IP를 선택할 때 먼저 실패한 IP를 제거하고 실패한 IP를 파일에 기록하고 acu 메모리 캐시를 사용하여 액세스를 가속화해야 모든 작업이 기본적으로 메모리 액세스를 기반으로 합니다. 성능 문제는 없을 것입니다.

요청이 실패한 경우에만 Redis에 로그인을 기록합니다. 실패한 IP는 언제 알 수 있나요? 여기에는 Redis 목록의 모든 실패 로그를 쿼리하고 동시에 실패 횟수를 계산하는 작업이 포함됩니다. 복잡한 운영. 우리의 구현은 여러 PHP 프로세스가 잠금을 점유하는 방법입니다. 이를 점유하는 사람은 분석 작업을 수행하고 실패한 IP를 파일에 기록합니다. 하나의 프로세스만 분석 작업을 수행하므로 일반 요청에는 영향을 미치지 않습니다. 동시에 잠금은 실패할 때만 선점됩니다. 정상적인 상황에서는 기본적으로 Redis와의 상호 작용이 없으며 성능 손실도 없습니다.

우리의 상태 점검은 중앙 집중식 Redis 서비스에 의존합니다. 중단되면 어떻게 되나요? Redis 서비스 자체가 다운된 것으로 확인되면 rpc 프레임워크는 상태 확인 서비스를 자동으로 종료하고 더 이상 Redis와 상호 작용하지 않습니다. 이는 최소한 일반 RPC 기능에는 영향을 미치지 않습니다.

상태 확인 구현을 기반으로 흐름 제어를 구현할 수 있습니다. 즉, 대부분 또는 모든 IP가 실패하는 경우 과도한 트래픽으로 인해 백엔드 서비스가 응답할 수 없어 이때 요청이 실패한다고 추론할 수 있습니다. 우리는 특정 전략으로 트래픽을 제한해야 합니다. 일반적인 구현은 모든 트래픽을 직접 제거하는 것인데, 이는 다소 조잡합니다. 우리의 구현은 실패한 IP의 비율이 특정 값으로 떨어질 때까지 점차적으로 트래픽을 줄이는 것입니다. 점차적으로 트래픽을 늘려 가능성을 늘리고 줄이는 것은 순환 프로세스, 즉 동적 흐름 제어이며 결국 최적의 흐름 값을 찾을 것입니다. 관련 구성을 통해 흐름 제어 기능을 소개하겠습니다.

degrade_ip_fail_ratio = 1 ; 服务开始降级时失败IP比例

即失败的IP比例达到多少时开始降级,即开始减少流量

degrade_dec_step = 0.1 ; 每次限流增加多少

即每次减少多少比例的流量

degrade_stop_ip_ratio = 0.5; 

在失败的IP已降到多少比例时开始停止减少流量,并尝试增加流量
degrade_stop_ttl_s = 10;

停止等待多长时间开始尝试增加流量
degrade_step_ttl_s = 10

流量增加或减少需要等待的时间。
每一次流量增加或减少后,下一步如何做是根据当时失败的IP比例来决定的,而且会保持当前流量值一段时间,而不是立即做决定。

degrade_add_step = 0.1

每次增加流量增加的比例值

degrade_return = false ; 降级时返回值

降级时我们不会再去访问后端服务,而是直接给调用方返回一个配置的值。

흐름 제어 상태 다이어그램은 다음과 같습니다.
PHP의 RPC 프레임워크는 Redis 기반의 흐름 제어 시스템을 구현합니다.

특정 비율로 유량을 제어하는 ​​방법은 무엇입니까? 임의의 숫자를 얻고 그것이 특정 범위에 속하는지 판단하는 등 무작위 선택을 통해. 흐름을 최적의 값으로 제한함으로써 대부분의 요청은 사용자에게 최소한의 영향을 미치면서 정상적으로 작동할 수 있습니다. 동시에 흐름 제어는 모니터링 및 경고와 협력합니다. 관련 모듈에 시스템 전체에 병목 현상이 발생하면 다음 단계는 하드웨어 리소스를 늘리거나 프로그램 성능을 최적화하는 것입니다.

관련 권장 사항:

RPC 프레임워크의 자세한 예

PHP 원격 호출 및 RPC 프레임워크의 자세한 코드 설명(그림)

PHPRPC의 간단한 사용

위 내용은 PHP의 RPC 프레임워크는 Redis 기반의 흐름 제어 시스템을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.