swoole( 网络IO 十二)

 

Select count(*) from customers

 

数据量:2000000

 

Id,name,city,gender,birthdate,mobile,photo,monthsalary,yearbonus

主进程主要做什么

负责监听socket,还有没有新的连接

主线程:信号处理(accept)

Reactor线程组:处理tcp连接,处理网络io,收发数据

Worker

实际处理用户的请求

Task进程介绍

相对于woker来说是异步的工作进程,诞生的意义是处理一些耗时的任务,是从worker进程通过task()函数投递过来的,如果task里面一时间投递过多,也会阻塞的,需要等待

 

适用场景例如:

1)短信的批量发送(管理员给200万的用户发送短信/邮件)  

2)大数据的修改操作   

3)千万关注量的微博大V发送一条微博,其关注的粉丝就会接收到这个信息

 

必须要设置server的onTask和onFinish事件回调函数

 

1. worker进程当中,我们调用对应的task()方法发送数据通知到task worker进程

2. task worker进程会在onTask()回调中接收到这些数据,并进行处理。

3. 处理完成之后通过调用finsh()函数或者直接return返回消息给worker进程

4. worker进程在onFinsh()进程收到这些消息并进行处理

 

Task初体验代码实例

Task_ipc_mode

Task 与 worker之间的通信方式

  1. 定向投递
  2. 消息队列模式

 

消息队列模式使用的是操作系统(linux)提供的内存队列存储数据

 

生产  -> 任务信息(redis) <-  处理

 

task诞生的原因:

  1. 主程序挂了,重新启动的时候,没处理完的task要处理掉
  2. 投递一个大的数据时,超过8K,如果没有及时处理,会有很多临时缓存文件,因为意外情况,服务器会停止,我们更希望执行会完成

 

重点在于,重启之后是否再次执行这个任务

 

需要加上属性

$key = ftok(__FILE__,1)

Message_queue_key  => $key 只在2/3模式生效

为什么需要这个key?

相当于秘钥,由内核来区分是谁操作的。

Task存在的问题与注意的事项点

Task_worker_num 怎么设置合理的数量

单个task的处理耗时是1毫秒,那么一个进程1秒就可以处理10个左右的task.

如果每秒产生2000个task,则需要启用200个进程

 

Task任务如果投递过多,会不会影响worker?

注意:

Task进程本身自己是同步阻塞的

如果task进程处理能力低于投递能力,只能等着前面的任务处理完,可能会引起woker进程阻塞

(公司就这么大,突然公司来了一大批外来人,影响了原本正常的员工的走动)

 

解决办法:合理设置数量

 

其余问题:

Task_max_request

Task进程最大的任务数。一旦task进程在处理完超过此数值的任务后,将自动退出。为了防止php内存溢出。默认是5000的最大任务数,如果不希望进程自动退出可以设置为0

 

测试代码

Task任务的区分

由于worker进程之间是隔开的,如果我们期望任务是投递哪个task_worker处理,可以通过woker_id + task_id

 

获取worker_id $serv->worker_id

Task_id = $serv->task( $data , 0);

task任务切分

情景:

200w用户,根据客户的手机号去发送信息;

 

思路分析:

获取用户 - > 200w ->一个task任务处理,发送过程本质是一个循环操作;

(批量校验;新增;分库分表->mycat读取数据,根据库和表)

 

1.设置下php.ini的memory_limit = 2048m;

2.通过for循环,把任务进行分片切分,逐一投递给不同的task;

for($i=0;$i<4;$i++){

   $sql = ‘Select id,name,mobile from customers limit ($i*500000), (($i+1)*500000) ’;

   $data = $da->query( $sql );

   $task_id = $serv->task( $data , $i);

}

 

Select id,name,mobile from customers limit 0 , 500000;

 

Select id,name,mobile from customers where id >= 0 and id < 500000;

 

代码实例

发布了66 篇原创文章 · 获赞 2 · 访问量 4645

猜你喜欢

转载自blog.csdn.net/converoscar/article/details/104351006
今日推荐