>  기사  >  백엔드 개발  >  PHP + Swoole을 사용하여 비동기 작업 대기열을 구현하는 방법

PHP + Swoole을 사용하여 비동기 작업 대기열을 구현하는 방법

零到壹度
零到壹度원래의
2018-04-09 11:37:093473검색

이 글의 내용은 php + swoole을 사용하여 비동기 작업 대기열을 구현하는 방법을 공유하는 것입니다. 특정 참조 값이 있습니다. 필요한 친구는 이를 참조할 수 있습니다.

100개의 이메일을 보내고 싶다면 , for 루프를 100번 실행하자 사용자는 즉시 반발하여 웹사이트를 파괴했습니다!
하지만 현실적으로 우리가 가지고 있는 이메일은 아마 10,000개가 넘을 것입니다. 이 지연 문제를 어떻게 처리합니까?
답은 비동기식을 사용하는 것입니다. "이메일 보내기" 작업을 캡슐화하고 백그라운드에서 비동기적으로 10,000회 실행합니다. 이 경우 사용자가 웹페이지를 제출한 후 그가 기다리는 시간은 "이메일 작업 요청을 대기열에 푸시"하는 시간뿐입니다. 그리고 우리의 백그라운드 서비스는 사용자가 볼 수 없는 곳에서 실행됩니다.
"비동기 대기열"을 구현하는 경우 어떤 사람들은 MySQL 테이블이나 Redis를 사용하여 보낼 이메일을 저장한 다음 1분마다 정기적으로 보낼 이메일 목록을 읽고 처리합니다. 이것이 예약된 비동기 작업 대기열입니다. 그러나 현재 제출된 작업은 실행하는 데 1분이 소요되며, 이는 문자 메시지 보내기와 같이 실시간 요구 사항이 높은 일부 응용 프로그램 시나리오에서는 여전히 빠르지 않습니다. 사용자는 결과가 반환될 때까지 기다릴 필요가 없습니다.

다음에서는 PHP를 사용하여 Swoole을 확장하여 실시간 비동기 작업 대기열을 구현하여 문자 메시지를 보내는 솔루션에 대해 설명합니다.

Server

1단계: tcp 서버 생성

2단계: 서버의 관련 속성 설정

3단계: 서버의 관련 콜백 기능을 설정하여 처리 task

구체적인 코드는 다음과 같습니다. tcp_server.php

<?php
class Server{
  private $serv;
  public function __construct(){

    $this->serv = new swoole_server("0.0.0.0",9501);
    $this->serv->set(
      array(  
            &#39;worker_num&#39; => 1,                //一般设置为服务器CPU数的1-4倍  
            &#39;daemonize&#39; => 1,                 //以守护进程执行  
            &#39;max_request&#39; => 10000,  
            &#39;dispatch_mode&#39; => 2,  
            &#39;task_worker_num&#39; => 8,           //task进程的数量  
            "task_ipc_mode " => 3,            //使用消息队列通信,并设置为争抢模式  
            "log_file" => "log/taskqueueu.log",
        )
    );
    $this->serv->on(&#39;Receive&#39;,array($this,&#39;onReceive&#39;));
    $this->serv->on(&#39;Task&#39;,array($this,&#39;onTask&#39;));
    $this->serv->on(&#39;Finish&#39;,array($this,&#39;onFinish&#39;));   
    $this->serv->start();

  }
  public function onReceive(swoole_server $serv, $fd, $from_id, $data){
    $serv->task($data);
  }
  public function onTask($serv, $task_id, $from_id, $data){
    $data = json_decode($data,true);
    if(!empty($data)){
      return $this->sendsms($data[&#39;mobile&#39;],$data[&#39;message&#39;]);   
    }
  }
  public function onFinish($serv, $task_id, $data){
      echo "Task {$task_id} finish\n";
  }
  public function sendsms($mobile,$text)
	{
		$timestamp = date("Y-m-d H-i-s");
		$pid = "888888888";
		$send_sign = md5($pid.$timestamp."abcdefghijklmnopqrstuvwxyz");
		$post_data = array();  
		$post_data[&#39;partner_id&#39;] = $pid;  
		$post_data[&#39;timestamp&#39;] =$timestamp;  
		$post_data[&#39;mobile&#39;] = $mobile;  
		$post_data[&#39;message&#39;] = $text;  
		$post_data[&#39;sign&#39;] = $send_sign;  
		$url=&#39;http://182.92.149.100/sendsms&#39;;  
		$o="";  
		foreach ($post_data as $k=>$v)  
		{  
			$o.= "$k=".urlencode($v)."&";  
		}  
		$post_data=substr($o,0,-1);  
		$ch = curl_init();  
		curl_setopt($ch, CURLOPT_POST, 1);  
		curl_setopt($ch, CURLOPT_HEADER, 0);  
		curl_setopt($ch, CURLOPT_URL,$url);  

		//为了支持cookie  
		//curl_setopt($ch, CURLOPT_COOKIEJAR, &#39;cookie.txt&#39;);  
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);  
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$result = curl_exec($ch);  
		if(strpos($result,"success")!==false)
		{
			$outstr=1;
		}
		else
		{
			$outstr=502;
		}
		return $outstr;
	
	}
}
$server = new Server();
?>

Client

클라이언트는 백엔드 서비스를 시작한 후 먼저 tcp 클라이언트 서버를 생성한 후 tcp 백엔드 서버에 접속하여 데이터를 보냅니다. 백엔드 TCP 서버에 대한 구체적인 코드는 다음과 같습니다: client.php

<?php
class Client{
  public $client;
  public function __construct(){
    $this->client= new swoole_client(SWOOLE_SOCK_TCP);//默认同步tcp客户端,添加参数SWOOLE_SOCK_ASYNC为异步
  }
  public function connect(){
    if(!$this->client->connect(&#39;127.0.0.1&#39;,9501,1)){
      throw new Exception(sprintf(&#39;Swoole Error: %s&#39;, $this->client->errCode));
    }
  }
  public function send($data){
    if($this->client->isConnected()){
      $data = json_encode($data);
      //print $data;  
      if($this->client->send($data)){
         return 1;    
      }else{
        throw new Exception(sprintf(&#39;Swoole Error: %s&#39;, $this->client->errCode));
      }
    }else{
      throw new Exception(&#39;Swoole Server does not connected.&#39;);  
    }

  }
  public function close(){
    $this->client->close();
  }
}
$client= new Client();
$client->connect();
$data=array(
  &#39;mobile&#39;=>&#39;18511487955&#39;,
  &#39;message&#39;=>&#39;you mobile 18511487955&#39;
);
if($client->send($data)){
  echo &#39;succ&#39;;
}else{
  echo &#39;fail&#39;;
}
?>

관련 권장 사항:

비동기 작업 대기열을 위한 두 가지 처리 방법

PHP는 swoole을 사용하여 실시간 비동기를 구현합니다. 작업 대기열

spring boot - redis의 Keyspace 알림을 사용하여 예약된 작업 대기열 구현

위 내용은 PHP + Swoole을 사용하여 비동기 작업 대기열을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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