1. 기본 지식
1.1 Swoole
Swoole은 PHP 개발자가 Swoole을 사용하여 고성능 서버 서비스를 개발할 수 있는 제품입니다. Swoole의 서버 부분에는 많은 콘텐츠가 포함되어 있으며 많은 지식 포인트가 포함되어 있습니다. 이 문서에서는 해당 서버에 대한 간략한 개요만 제공하며, 후속 문서에서는 구체적인 구현 세부 사항을 자세히 소개합니다.
권장(무료): swoole
1.2 네트워크 프로그래밍
1 네트워크 통신은 하나(또는 여러) 머신에서 하나(또는 그 이상) 프로세스를 시작하고 하나(또는 여러) 포트를 모니터링하는 것을 의미합니다. 특정 프로토콜(표준 프로토콜인 http, dns일 수도 있고 자체 정의된 프로토콜일 수도 있음)에 따라 클라이언트와 정보를 교환합니다.
2. 현재 네트워크 프로그래밍의 대부분은 TCP, UDP 또는 상위 계층 프로토콜을 기반으로 합니다. Swoole의 서버 부분은 tcp 및 udp 프로토콜을 기반으로 합니다.
3. UDP를 사용한 프로그래밍은 비교적 간단합니다. 이 기사에서는 주로 TCP 프로토콜 기반의 네트워크 프로그래밍을 소개합니다. 4. TCP 네트워크 프로그래밍은 주로 4가지 유형의 이벤트를 포함합니다. 연결을 시작(연결)하고 서버가 연결을 수락(수락)
●메시지 도착: 서버는 클라이언트가 보낸 데이터를 수신합니다. 이 이벤트는 서버의 네트워크 프로그래밍에서 가장 중요한 이벤트입니다. 이러한 유형의 이벤트를 처리하려면 차단 또는 비차단을 사용할 수 있습니다. 또한 서버는 패킷화 및 애플리케이션 계층 버퍼와 같은 문제도 고려해야 합니다.
●메시지가 성공적으로 전송되었습니다.전송에 성공했다는 의미입니다. 계층이 커널의 소켓 전송 버퍼로 보낸 데이터를 성공적으로 전송한다고 해서 클라이언트가 데이터를 성공적으로 수락했다는 의미는 아닙니다. 트래픽이 적은 서비스의 경우 일반적으로 데이터가 한꺼번에 전송될 수 있으므로 이러한 이벤트에 신경 쓸 필요가 없습니다. 한번에 모든 데이터를 커널 버퍼로 보낼 수 없다면 메시지가 성공적으로 전송되었는지 주의해야 한다(블로킹 프로그래밍의 경우 시스템 호출(write, writev, send 등)이 반환된 후 전송이 성공하고, 논 블로킹 프로그래밍의 경우 실제 상황을 고려해야 합니다. 작성된 데이터가 예상과 일치하는지 여부)
●연결 끊김: 클라이언트 연결 끊김(읽기 반환 0) 및 서버 연결 끊김(읽기 반환 0)을 고려해야 합니다. close, shutdown)5. tcp가 연결을 설정합니다. 프로세스는 아래와 같습니다
● 그림에서 ACK와 SYN은 플래그 비트를 나타내며, seq와 ack는 TCP 패킷의 시퀀스 번호와 확인 시퀀스 번호입니다
6. TCP 연결 해제 과정은 아래와 같습니다. ● 위 그림은 클라이언트가 적극적으로 연결을 끊는 상황도 마찬가지입니다● 그림에서 FIN과 ACK는 다음과 같습니다. 플래그 비트, seq 및 ack는 TCP 패킷의 시퀀스 번호 및 확인 시퀀스 번호입니다1.3 프로세스 간 통신
1 프로세스 간 통신에는 명명되지 않은 파이프(파이프), 명명된 파이프(fifo), 신호가 포함됩니다. (신호), 세마포어(semaphore), 소켓(socket), 공유 메모리(shared memory) 및 기타 방법
2. Swoole은 여러 프로세스(Swoole 내부 프로세스를 의미함) 간의 통신을 위해 Unix 도메인 소켓(소켓의 일종)을 사용합니다.
1.4 Socketpair
1. Socketpair는 파이프와 유사하게 소켓 쌍을 만드는 데 사용됩니다. 차이점은 파이프가 양방향 통신을 두 번 만들어야 한다는 것입니다. 또한 소켓이므로 데이터 교환 방법을 정의할 수도 있습니다
2. 소켓 쌍 시스템 호출
sv[0], sv[1] 각각 파일 설명자
를 sv[0]에 저장합니다. sv[1]에 쓰고, sv[1]에서 읽을 수 있습니다.
sv[1]에 쓰고, sv에서 읽을 수 있습니다. [0]
프로세스가 소켓 쌍을 호출한 후 하위 프로세스를 포크하고 하위 프로세스는 기본적으로 sv를 상속받습니다. [0], sv[1] 이 두 파일 설명자는 상위 프로세스와 하위 프로세스 간의 통신을 실현할 수 있습니다. 예를 들어, 상위 프로세스는 sv[0]에 쓰고, 하위 프로세스는 sv[1]에서 읽고, 하위 프로세스는 sv[1]에 쓰고, 상위 프로세스는 sv[0]각 프로세스는 A 프로세스 그룹에 속합니다 그룹 리더의 프로세스 번호(PID)인 프로세스 그룹 번호
프로세스는 자신 또는 하위 프로세스에 대해서만 프로세스 그룹 번호를 설정할 수 있습니다
3.1.6 Swoole tcp 서버 예시
base mode 아래에서 Reactor_number 매개변수는 실제 효과가 없습니다
작업자 프로세스 수를 1로 설정하면 작업자 프로세스가 분기되지 않고 기본 프로세스가 직접 요청을 처리합니다. 모드는 디버깅에 적합합니다2. 시작 프로세스
php 코드 실행 $serv->start()에 도달하면 메인 프로세스가 서버 시작을 담당하는 int swServer_start(swServer *serv) 함수에 들어갑니다. swServer_start 함수에서 swReactorProcess_start가 호출됩니다. 프로세스와 작업자 프로세스는 각각 자체 이벤트 루프에 들어가 다양한 이벤트를 처리합니다
worker 프로세스는 도메인 소켓을 사용하여 기본 프로세스의 반응 스레드와 통신하며 작업자 프로세스 간 통신은 없습니다
if set 데몬 모드에서 필요한 매개 변수를 확인한 후 먼저 자신을 데몬 프로세스로 전환한 다음 관리자 프로세스를 포크한 다음 리액터 스레드를 생성합니다. 메인 프로세스는 먼저 관리자 프로세스를 분기하고, 관리자 프로세스는 작업자 프로세스와 task_worker 프로세스를 분기하는 역할을 담당합니다. 작업자 프로세스가 int swWorker_loop
위 그림에서는 task_worker 프로세스를 고려하지 않았습니다. 기본적으로 task_worker 프로세스 수는 0
3개입니다. 프로세스 모드)
3.1 리액터 스레드와 작업자 프로세스 간의 통신
1. Swoole 마스터 프로세스와 작업자 프로세스 간의 통신은 아래 그림과 같습니다
2 2개의 리액터 스레드가 있다고 가정합니다. 3개의 작업자 프로세스가 있고 리액터와 작업자 간의 통신은 아래 그림에 나와 있습니다.
3.리액터 스레드와 작업자 프로세스 간의 통신을 위한 데이터 패킷
3.2 요청 처리
1. 마스터 프로세스의 메인 스레드는 포트 수신을 담당합니다(listen code>) 연결을 수락하고(<code>accept
, fd 생성), 연결을 수락한 후 요청은 기본적으로 리액터 스레드에 할당되고 fd가 추가됩니다. epoll_ctl
을 통해 해당 리액터 스레드를 처음 조인할 때 쓰기 이벤트를 수신합니다. 새로 허용된 연결에 의해 생성된 소켓의 쓰기 버퍼는 비어 있으므로 쓰기 가능해야 하며 즉시 트리거됩니다. 그런 다음 리액터 스레드는 일부 초기화 작업을 수행합니다listen
), 接受连接(accept
, 产生一个fd), 接受连接后将请求分配给reactor线程, 默认通过fd % reactor_number进行分配, 之后通过epoll_ctl
将fd加入到对应reactor线程中, 刚加入时监听写事件, 因为新接受连接创建的套接字写缓冲区为空, 故而一定可写, 会被立刻触发, 进而reactor线程进行一些初始化操作
epoll_create
创建)的情况epoll_ctl
是线程安全的(对应一个epollfd), 一个线程正在执行, 其他线程会被阻塞(因为需要同时操作epoll底层的红黑树)epoll_wait
也是线程安全的, 但是一个事件可能会被多个线程同时接收到, 实际中不建议多个线程同时epoll_wait
一个epollfd。Swoole中也是不存在这种情况的, Swoole中每个reactor线程都有自己的epollfdepoll_wait
, 一个线程调用epoll_ctl
, 根据man手册, 如果epoll_ctl
新加入的fd已经准备好, 会使得执行epoll_wait
的线程变成非阻塞状态(可以通过man epoll_wait
epoll_create
를 통해 생성됨) 를 호출하는 여러 스레드가 있습니다. 동시에 epoll_ctl
은 스레드로부터 안전하며(하나의 epollfd에 해당) 하나의 스레드가 실행 중이고 다른 스레드는 차단됩니다(epoll의 기반이 되는 레드-블랙 트리가 동시에 작동해야 하기 때문입니다)
여러 스레드가 동시에 epoll_wait
를 호출하는 것도 스레드로부터 안전하지만 여러 스레드가 동시에 이벤트를 수신할 수 있습니다. 실제로는 여러 스레드가 되는 것을 권장하지 않습니다. >epoll_wait
epollfd를 동시에 실행합니다. Swoole에는 이러한 상황이 없습니다. Swoole의 각 리액터 스레드에는 자체 epollfd
맨 매뉴얼에 따르면 한 스레드는 epoll_wait
를 호출하고 다른 스레드는 epoll_ctl
를 호출합니다. 새로 추가된 epoll_ctl
의 fd가 준비되면 epoll_wait
를 실행하는 스레드는 비차단 상태가 됩니다(man epoll_wait
를 통해 관련 정보를 볼 수 있습니다). 내용)
6. 리액터 스레드는 작업자 프로세스에서 보낸 요청 처리 결과를 처리합니다. 연결 수신 상태를 변경해야 하는 경우(예: close
), 则需要先找到监听这个连接的reactor线程, 进而改变这个连接的监听状态(通过调用epoll_ctl
)
Gdb 디버깅 넷.
4.1 프로세스 모드 시작
4.2 기본 모드 시작
五. 요약 및 생각
1. 이 글에서는 주로 Swoole 서버의 두 가지 모드를 소개합니다. 그리고 처리 모드 두 모드의 네트워크 프로그래밍 모델을 자세히 설명하고 프로세스 모드의 프로세스 간 통신 방법, 요청 처리 흐름 등에 대해 중점적으로 설명합니다.
2. 메인 프로세스에서 스레드가 요청을 직접 처리하도록 하고(프로세스 간 통신의 오버헤드를 피할 수 있음) 관리자 프로세스를 생성한 다음 관리자 프로세스에서 작업자 프로세스를 생성하고 요청을 처리하는 프로세스는 다음과 같습니다.
3. 프로세스 모드에서는 기본 프로세스의 각 리액터 스레드가 동시에 여러 요청을 처리할 수 있으며 여러 요청이 동시에 처리됩니다. 2차원에서 봅니다
4. Swoole 사용 TCP 서버를 생성할 때 tcp는 바이트 스트림 프로토콜이므로 하청을 받아야 하며, Swoole은 클라이언트와 서버 간의 통신 프로토콜을 모르면 하청을 할 수 없습니다. 리액터를 통해 작업자 프로세스로 전달됩니다. 바이트 스트림만 가능하며 사용자가 처리해야 합니다. 물론 일반적으로 Swoole은 tcp 서버를 사용하여 Http, Https 및 기타 프로토콜을 이미 지원하므로 직접 프로토콜을 구축할 필요가 없습니다.
위 내용은 Swoole 서버에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!