심혈 을 기울 여 총 결 된 15 개의 'swoole' 흔 한 문제 (2)

앞서 말씀 드 렸 던 8 개의 문 제 를 이어서 공유 하 겠 습 니 다. 이전 글 을 보지 못 한 사람 은 여 기 를 클릭 하 세 요 ~
9. Swoole 은 어떻게 서 비 스 를 정확하게 재 개 합 니까?
우리 가 PHP 코드 를 수정 한 후에 코드 가 유효 하도록 서 비 스 를 다시 시작 해 야 합 니 다. 바 쁜 백 엔 드 서버 가 수시로 요청 을 처리 하고 있 습 니 다. 만약 관리자 가 통과 한다 면.  kill  프로 세 스 방식 으로 서버 프로그램 을 종료 / 재 부팅 하면 마침 코드 가 절반 까지 실 행 될 수 있 으 며 전체 업무 논리의 완전 성 을 보장 할 수 없습니다.Swoole  유연성 종료 / 재 부팅 메커니즘 을 제공 합 니 다. 관리 자 는  Server  특정한 신 호 를 보 내 거나 호출 하 다.  reload  방법, 작업 프로 세 스 가 끝나 고 다시 끌 어 올 릴 수 있 습 니 다.
그러나 몇 가지 주의해 야 할 것 이 있다.
우선 새로 수 정 된 코드 는 반드시  OnWorkerStart  이벤트 에 다시 불 러 와 야 유효 합 니 다. 예 를 들 어 어떤 종류 가 있 습 니 다.  OnWorkerStart  그 전에 composer 의 autoload 를 통 해 불 러 오 면 안 됩 니 다.
그 다음  reload  이 두 매개 변수 maxwait_time 와 reloadasync, 이 두 개의 인 자 를 설정 하면 실 현 됩 니 다 .
이 기능 이 없 으 면 Worker 프로 세 스 가 재 부팅 신 호 를 받 거나 max 에 도달 합 니 다.request 시 즉시 서 비 스 를 중단 합 니 다.  Worker  프로 세 스 내 에 이벤트 감청 이 있 을 수 있 습 니 다. 이 비동기 작업 들 은 버 려 집 니 다.위 매개 변 수 를 설정 하면 새 매개 변 수 를 만 듭 니 다.  Worker, 낡은  Worker  모든 사건 을 완성 한 후 스스로 퇴장, 즉 reloadasync。
하면, 만약, 만약...  Worker  계속 물 러 나 지 않 고 밑 에 타이머 가 추가 되 었 습 니 다. 약속 시간 (max wait time 초) 내 에 오래된 것 입 니 다.  Worker  물 러 나 지 않 으 면 밑바닥 은 강제로 중 지 될 것 이다.
예시:
php
$serv = new Swoole\Server("0.0.0.0", 9501, SWOOLE_PROCESS);
$serv->set(array(
    'worker_num' => 1,
    'max_wait_time' => 60,
    'reload_async' => true,
));
$serv->on('receive', function (Swoole\Server $serv, $fd, $reactor_id, $data) {

    echo "[#" . $serv->worker_id . "]\tClient[$fd] receive data: $data
"; Swoole\Timer::tick(5000, function () { echo 'tick'; }); }); $serv->start();

 
예 를 들 어 위의 코드 가 reload 가 없 으 면async 그러면 onReceive 에서 만 든 타 이 머 를 잃 어 버 리 고 타이머 의 리 셋 함 수 를 처리 할 기회 가 없습니다.
프로 세 스 종료 이벤트
비동기 재 부팅 기능 을 지원 하기 위해 서 바 텀 에 하나 가 추가 되 었 습 니 다. onWorkerExit 사건  Worker  종료 직전 시 시전  onWorkerExit  이벤트, 이 이벤트 리 셋 함수 에서 응용 층 은 긴 연결 을 청소 하려 고 시도 할 수 있 습 니 다.  Socket 이벤트 순환 중 fd 가 없 거나 max 에 도달 할 때 까지wait_time 프로 세 스 종료.
$serv->on('WorkerExit', function (Swoole\Server $serv, $worker_id) {
    $redisState = $serv->redis->getState();
    if ($redisState == Swoole\Redis::STATE_READY or $redisState == Swoole\Redis::STATE_SUBSCRIBE)
    {
        $serv->redis->close();
    }
});

 
동시에 우 리 는 Swoole Plus 파일 변 화 를 감지 하 는 기능 이 추가 되 었 습 니 다. 수 동 reload 나 신 호 를 보 내지 않 아 도 파일 변경 이 자동 으로 워 커 를 다시 시작 할 수 있 습 니 다.
10. 왜 send 가 끝나 면 바로 닫 지 않 는 것 은 안전 하지 않 습 니까?
send 가 끝나 면 바로 close 는 안전 하지 않 습 니 다. 서버 쪽 이 든 클 라 이언 트 든.
send 작업 이 성공 한 것 은 데이터 가 운영 체제 socket 캐 시 에 성공 적 으로 기록 되 었 음 을 나타 내 는 것 일 뿐, 엔 드 에 정말 데 이 터 를 받 았 다 는 것 은 아 닙 니 다.과연 운영 체제 가 전송 에 성 공 했 는 지, 상대방 서버 가 받 았 는 지, 서버 측 프로그램 이 처 리 했 는 지 는 확실 하지 않다.
close 후의 논 리 는 아래 의 linger 설정 을 보십시오
이 논리 와 전화 소통 은 하나의 이치 이다. A 가 B 에 게 한 가지 일 을 알려 주 고 A 가 말 을 마치 면 전 화 를 끊 는 다.그럼 B 는 들 었 습 니까? A 는 모 릅 니 다.만약 에 A 가 일 을 말 하고 B 가 약속 한 후에 B 가 전 화 를 끊 으 면 안전 하 다.
linger 설정
한 개  socket  close 에서 버퍼 에 데이터 가 있 는 것 을 발견 하면 운영 체제 의 밑바닥 은  linger  설정 은 어떻게 처리 할 것 인 가 를 결정 합 니 다.
struct linger
{
     int l_onoff;
     int l_linger;
};
  • l_onoff = 0, close 시 즉시 돌아 갑 니 다. 바 텀 은 보 내지 않 은 데 이 터 를 보 낸 후에 자원 을 방출 합 니 다. 즉, 우아 하 게 종료 합 니 다.
  • l_onoff != 0,l_linger = 0, close 는 즉시 되 돌아 오지 만 완료 되 지 않 은 데 이 터 를 보 내지 않 고 RST 패 키 지 를 통 해 socket 설명 자 를 강제로 닫 습 니 다. 즉, 강제 종료 입 니 다.
  • l_onoff !=0,l_linger > 0, closes 시 바로 돌아 오지 않 습 니 다. 커 널 은 일정 시간 지연 되 며, 이 시간 은 llinger 의 값 으로 결정 합 니 다.시간 초과 가 도착 하기 전에 보 내지 않 은 데이터 (FIN 패키지 포함) 를 보 내 고 다른 쪽 의 확인 을 받 으 면 close 는 정확 한 것 으로 돌아 갑 니 다. socket 설명자 가 우아 하 게 종 료 됩 니 다.그렇지 않 으 면 close 는 오류 값 을 직접 되 돌려 주 고 데 이 터 를 보 내지 않 으 면 socket 설명자 가 강제 적 으로 종 료 됩 니 다.socket 설명자 가 비 막힘 형 으로 설정 되면 close 는 값 을 직접 되 돌려 줍 니 다.

  • 질문
    아래 와 같이 제시 합 니 다.
    NOTICE    swFactoryProcess_finish (ERRNO 1004): send 165 byte failed, because connection[fd=123] is closed
    NOTICE    swFactoryProcess_finish (ERROR 1005): connection[fd=123] does not exists

    서버 응답 시 클 라 이언 트 가 연결 을 끊 어서
    흔히 볼 수 있 는 것:
  • 브 라 우 저 는 미 친 듯 이 페이지 를 새로 고침 합 니 다 (불 러 오기 도 전에 지 워 졌 습 니 다)
  • ab 압력 측정 절반 취소
  • wrk 시간 기반 압력 측정 (시간 이 되면 완료 되 지 않 은 요청 이 취 소 됩 니 다)
  • 상기 몇 가지 상황 은 모두 정상 적 인 현상 에 속 하기 때문에 무시 할 수 있 기 때문에 이 잘못된 단 계 는 NOTICE 입 니 다.
    다른 상황 으로 인해 이유 없 이 대량의 연결 이 끊 겼 을 때 만 주의해 야 한다.
    12. Swoole 을 공부 하려 면 어떤 기초 지식 을 습득 해 야 합 니까?
    1. 다 중 프로 세 스 / 다 중 스 레 드
  • 알 아 보기  Linux  운영 체제 프로 세 스 와 스 레 드 의 개념
  • 알 아 보기  Linux  프로 세 스 / 스 레 드 전환 스케줄 의 기본 지식
  • 프로 세 스 간 통신 의 기본 지식, 예 를 들 어 파이프, UnixSocket, 메시지 대기 열, 공유 메모리
  • 2、SOCKET
  • 알 아 보기  SOCKET  기본 동작  accept/connectsend/recvcloselistenbind
  • 알 아 보기  SOCKET  의 수신 캐 시 구역, 전송 캐 시 구역, 차단 / 비 차단, 시간 초과 등 개념
  • 3. IO 재 활용
  • 알 아 보기  select / poll / epoll
  • 이해 기반  select / epoll  실 현 된 이벤트 순환, Reactor 모형
  • 읽 을 수 있 는 사건, 쓸 수 있 는 사건 이해
  • 4. TCP / IP 네트워크 프로 토 콜
  • 알 아 보기  TCP/IP  협의
  • 알 아 보기  TCPUDP  전송 프로 토 콜
  • 5. 디 버 깅 도구
    gdb 디 버 깅 사용  Linux  프로그램
  • strace 추적 프로 세 스 를 사용 하 는 시스템 호출
  • tcpdump 를 사용 하여 네트워크 통신 과정 추적
  • 기타  Linux  시스템 도구, 예 를 들 어 ps, lsof, top, vmstat, netstat, sar, ss 등
  • 13. Redis 또는 MySQL 연결 을 1 개 공유 할 수 있 습 니까?
    절대 안 돼.프로 세 스 마다 따로 만들어 야 합 니 다.  RedisMySQLPDO  연결, 다른 저장 소 클 라 이언 트 도 마찬가지다.1 개의 연결 을 함께 사용 하면 되 돌아 오 는 결 과 는 어느 프로 세 스 에 의 해 처리 되 는 지 보장 할 수 없 기 때 문 입 니 다. 연결 을 가 진 프로 세 스 이론 적 으로 이 연결 을 읽 고 쓸 수 있 기 때문에 데이터 가 잘못 되 었 습 니 다.
    따라서 여러 프로 세 스 사이 에 서 는 연결 을 공유 할 수 없습니다.
  • Swole \ Server 에서 onWorkerStart 에 연결 대상 을 만들어 야 합 니 다
  • Swole \ Process 에 서 는 Swole \ Process - > start 후 하위 프로 세 스 의 리 셋 함수 에 연결 대상 을 만들어 야 합 니 다
  • 이 문제 에 대한 정보 사용  pcntl_fork  프로그램 도 유효 합 니 다
  • 예시:
    $server = new Swoole\Server("0.0.0.0", 9502);
    
    //   onWorkerStart     redis/mysql  
    $server->on('workerstart', function($server, $id) {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $server->redis = $redis;
    });
    
    $server->on('receive', function (Swoole\Server $server, $fd, $from_id, $data) {    
        $value = $server->redis->get("key");
        $server->send($fd, "Swoole: ".$value);
    });
    
    $server->start();

    14 、 Call to undefined function Co \ \ Run ()
    이 문서 의 대부분의 예제 가 사용 되 었 다.  Co\run()  협 정 용 기 를 만 들 고 협 정 용기 가 무엇 인지 알 아 보 세 요.
    다음 오류 가 발생 하면:
    PHP Fatal error:  Uncaught Error: Call to undefined function Co\Run()
    
    PHP Fatal error:  Uncaught Error: Call to undefined function go()

    설명 하 다  Swoole  확장 버 전  v4.4.0  또는 수 동 으로 협 정 짧 은 이름 을 닫 고 세 가지 해결 방법 을 제공 합 니 다.
  • 버 전이 너무 낮 으 면 확장 버 전 을 업그레이드 하 십시오.  >= v4.4.0  사용 하 다  go  키워드 교체  Co\Run  협 정 만 들 기;
  • 협 정 짧 은 이름 을 닫 았 다 면 협 정 짧 은 이름 을 열 어 주 십시오.
  • Corotune 사용:: create 방법 으로 교체  Co\Run  혹시  go  협 정 만 들 기;

  • 15. 일시 적 으로 리 소스 를 사용 할 수 없 음 [11]
    클 라 이언 트 swooleclient  recv  타임 즈
    swoole_client::recv(): recv() failed. Error: Resource temporarily unavailable [11]

    이 오 류 는 서버 측 이 정 해진 시간 내 에 데 이 터 를 되 돌려 주지 않 아 수신 시간 이 초과 되 었 음 을 나타 낸다.
  • tcpdump 를 통 해 네트워크 통신 과정 을 확인 하고 서버 가 데 이 터 를 보 냈 는 지 확인 할 수 있 습 니 다
  • 서버 의  $serv->send  함수 가 true 로 돌 아 왔 는 지 확인 해 야 합 니 다
  • 외부 네트워크 통신 시 시간 이 많이 걸 리 면 s wooleclient 의 시간 초과
  • 더 많은 학습 내용 은 우리 가 구조 사가 되 는 수련 의 길 을 방문 할 수 있다.

    좋은 웹페이지 즐겨찾기