Laravel Octane 和 Swoole 协程的使用分析

之前在工作中使用 Laravel Octane 的 concurrently 处理并发时,发现在队列和定时任务中不会触发并发效果。经过分析,作了如下猜测:队列和定时任务都属于一个独立的进程,与 Octane 服务无关,而 Octane concurrently 恰恰需要在 Octane 环境下才能运行。

后来通过代码进行环境检测和查看 php 的进程,证明猜想成立。

info('check env', ['served by octane' => isset($_SERVER['LARAVEL_OCTANE']) && ((int)$_SERVER['LARAVEL_OCTANE'] === 1),'on swoole server' => (extension_loaded('swoole') || extension_loaded('openswoole')) && app()->bound(Server::class)
]);

为了能够在任意代码中实现并发,我们研究参考了 Hyperf 框架关于协程的代码,然后抽取了如下两个类:

<?phpnamespace App\Services;use App\Exceptions\ParallelExecutionException;
use Laravel\Octane\Facades\Octane;
use Throwable;
use Swoole\Coroutine as Co;class Parallel
{protected array $callbacks = [];protected array $results = [];/*** @var Throwable[]*/protected array $throwables = [];public function add(callable $callable, $key = null): void{if (is_null($key)) {$this->callbacks[] = $callable;} else {$this->callbacks[$key] = $callable;}}public function wait(bool $throw = true): array{if (isset($_SERVER['LARAVEL_OCTANE']) && ((int)$_SERVER['LARAVEL_OCTANE'] === 1)) {return Octane::concurrently($this->callbacks, 300000);}app('log')->useLoggingLoopDetection(false);Co\run(function () {foreach ($this->callbacks as $key => $callback) {Co::create(function () use ($callback, $key) {try {$this->results[$key] = $callback();} catch (Throwable $throwable) {$this->throwables[$key] = $throwable;unset($this->results[$key]);}});}});if ($throw && ($throwableCount = count($this->throwables)) > 0) {$message = 'Detecting ' . $throwableCount . ' throwable occurred during parallel execution:' . PHP_EOL . $this->formatThrowAbles($this->throwables);$executionException = new ParallelExecutionException($message);$executionException->setResults($this->results);$executionException->setThrowAbles($this->throwables);unset($this->results, $this->throwables);throw $executionException;}app('log')->useLoggingLoopDetection(true);return $this->results;}private function formatThrowAbles(array $throwables): string{$output = '';foreach ($throwables as $key => $value) {$output .= sprintf('(%s) %s: %s' . PHP_EOL . '%s' . PHP_EOL, $key, get_class($value), $value->getMessage(), $value->getTraceAsString());}return $output;}
}
<?phpnamespace App\Exceptions;use RuntimeException;class ParallelExecutionException extends RuntimeException
{protected array $results = [];protected array $throwables = [];public function getResults(): array{return $this->results;}public function setResults(array $results): void{$this->results = $results;}public function getThrowAbles(): array{return $this->throwables;}public function setThrowAbles(array $throwables): array{return $this->throwables = $throwables;}
}

其中,第一个类的作用是检测系统是否运行在 Octane 环境下,是则调用Octane concurrently,否则就执行 Swoole 协程代码,使用起来也比较简单:

$parallel = new Parallel();
$parallel->add(fn() => $this->analysisStructure(), 'structure');
$parallel->add(fn() => $this->analysisHabit(), 'habit');
['structure' => $structure,'habit' => $habit,
] = $parallel->wait();

之所以没有完全使用 Swoole 协程,是因为相比之下,Octane 代码更加优雅,我们在期待着某天更新后,Octane concurrently 也能直接在队列中运行使用。

第二个类的作用比较简单,就是对协程中异常的一个定义。

另外在分析过程中,我们也发现了一个比较有意思的事情:
在这里插入图片描述

如图所示,当我在路由中运行检测代码时,Octane 和 Swoole Server 都为 true;在控制器中运行检测代码时,又只有 Octane 为true;为什么会有这样的区分?我个人猜测是 Octane 在将框架代码读进内存时,特意跳过了控制器中的代码,以避免数据更新不及时等问题。

有知道具体原因的小伙伴,欢迎留言探讨。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#高级:DataGridView的详解

一、每条数据增加一个按钮&#xff0c;点击输出对应实体 请先确保正确添加实体的名称和文本&#xff1a; private void button6_Click(object sender, EventArgs e) {//SQL查询到数据&#xff0c;存于list中List<InforMessage> list bll.QueryInforMessage();//含有字段…

数据页和缓存页(BufferPool)

1. 数据页&#xff08;dataPage&#xff09; 什么是数据页&#xff1f; 数据页是 MySQL 存储引擎在磁盘和内存之间传输数据的基本单位&#xff0c;默认大小为16KB。 数据页的结构&#xff1a; 表头&#xff1a;储存与页相关的元信息&#xff0c;比如&#xff0c;页号&#…

buuctf_reverse_新年快乐+内涵的软件

新年快乐 题目&#xff1a;新年快乐.exe 这玩意有壳&#xff01;我去down了upx脱壳 开始放exeinfope的图片没截&#xff0c;我记得下载完upx后exeinfoPE显示还不一样。留了一张脱壳的实验图片&#xff1a; 然后放IDA 我是笔记本键盘&#xff0c;shiftFnF12转字符串 诶呦&…

flutter 安装流程

flutter文档 0.安装flutter https://flutter.cn/docs/get-started/install/windows/desktop?tabdownload 1.jdk 安装地址 Java Archive | Oracle 2. android studio 下载地址 https://developer.android.com/studio 3.Visual Studio下载地址 下载 Visual Studio Tools …

C++之map

1、map介绍 map是C STL的一个关联容器&#xff0c;它提供一对一的数据处理能力。其中&#xff0c;各个键值对的键和值可以是任意数据类型&#xff0c;包括 C 基本数据类型&#xff08;int、double 等&#xff09;、使用结构体或类自定义的类型。 第一个可以称为关键字(key)&…

docker构建hyperf环境

一&#xff0c;构建hyperf 镜像 官网git https://github.com/hyperf/hyperf-docker 使用dockerfile构建镜像 根据需要这里我使用8.1 swoole版本的镜像 在/home/hyperfdocker 目录中新建一个Dockerfile文件&#xff0c;将这个git上的Dockerfile内容复制粘贴进去 docker build…

HBase总结

基本介绍 特点(高可靠、高性能、面向列、可伸缩) 非关系型数据库大数据实时处理 表规模达数十亿行及数百万列读、写访问可实时分布式存储系统 HDFS(Hadoop Distributed File System)文件存储ZooKeeper作为协同服务列存储 优点:有利于单列数据查询缺点:整行读取时效率较慢,…

毫末智行开年融资,揭幕了自动驾驶最后的赛点

毫末智行日前官宣拿到的超亿元B1轮融资&#xff0c;在行业引起了不小的关注。 一方面是信心问题&#xff0c;自动驾驶从早期拼技术到去年拼量产落地&#xff0c;创业公司们的声量此消彼长&#xff0c;有人领先也有人掉队&#xff0c;但市场的态度都以谨慎为主&#xff0c;甚至…

Android ANR 日志分析定位

ANR 是 Android 应用程序中的 "Application Not Responding" 的缩写&#xff0c;中文意思是 "应用程序无响应"。这是当应用程序在 Android 系统上运行时&#xff0c;由于某种原因不能及时响应用户输入事件或执行一个操作&#xff0c;导致界面无法更新&…

Kubernetes(k8s第二部分)

资源清单相当于剧本 什么是资源&#xff1a; k8s中所有的内容都抽象为资源&#xff0c;资源实例化后&#xff0c;叫做对象。 1.K8S中的资源 集群资源分类 名称空间级别&#xff1a; kubeadm k8s kube-system kubectl get pod -n default 工作负载型资源&#xff0c;&a…

指针篇章-(1)

指针&#xff08;1&#xff09;学习流程 —————————————————————————————————————————————————————————————————————————————————————————————————————————————…

Linux:使用nslookup和dig查询DNS记录信息

nslookup nslookup&#xff08;Name Server Lookup&#xff09;用于从 DNS 服务器查询域名、IP 或其他 DNS 记录信息 示例 查询域名信息 $ nslookup baidu.comServer: 114.114.114.114 Address: 114.114.114.114#53Non-authoritative answer: Name: baidu.com Add…

springcloud项目,无法在Sentinel Dashboard查看到服务的访问监控信息【解决方法】

1.问题场景 因为warehouse子项目的前端未开发&#xff0c;所以只能通过postman测试接口访问&#xff1b; 2.解决方法 package org.sharetek.common.security.config;import cn.dev33.satoken.SaManager; import cn.dev33.satoken.filter.SaServletFilter; import cn.dev33.sat…

【Django】执行查询—检索对象(二)

主键 (pk) 查询快捷方式 pk查询等同于通过模型的 primary key 进行过滤&#xff0c;直接上例子&#xff0c;下面三个语句是等效的。 >>> Blog.objects.get(id__exact14) # Explicit form >>> Blog.objects.get(id14) # __exact is implied >>> …

构筑未来商业智能——数据中台的战略视角_光点科技

随着数字化时代的加速到来&#xff0c;企业对于数据的依赖程度日益增强。数据中台&#xff0c;作为连接数据与商业决策的关键枢纽&#xff0c;已成为企业打造持久竞争优势的战略选择。本文将从战略的高度&#xff0c;解析数据中台如何帮助企业捕捉数据红利&#xff0c;推进业务…

NXP实战笔记(十一):32K3xx基于RTD-SDK在S32DS上配置LPSPI(同步、异步、DMA、主机、从机、中断、轮询)

目录 1、概述 2、RTD-SDK配置 2.1、配置目标 2.2、主、从机引脚配置 2.3、时钟配置 2.4、LPSPI配置 2.5、中断配置 2.6、DMA配置(使用DMA才会配置) 2、dma Logic Instance 2.7、RM配置(使用DMA的情况下必须配置此选项) 3、代码实现 1、概述 S32K3_低功耗LPSPI轮询…

第七十六周周报

学习目标&#xff1a; 论文 实验 学习时间&#xff1a; 2024.2.24-2024.3.1 学习产出&#xff1a; 论文 仔细看了论文"All are Worth Words: A ViT Backbone for Diffusion Models"&#xff0c;”DiffiT: Diffusion Vision Transformers for Image Generation…

备战蓝桥杯Day19 - 堆排序基础知识

一、每日一题 - 填充 详细题解 s input() # 输入字符串 n len(s) # 定义字符的长度 judge ["00", "11", "0?", "1?", "?0", "?1", "??"] # 把所有的情况一一列举出来 count 0 # 设置计数…

性能优化篇(四) GPU Instancing

使用GPU Instancing可以在一个Draw Call中同时渲染多个相同或类似的物体&#xff0c;从而减少CPU和GPU的开销。 官方文档&#xff1a;https://docs.unity3d.com/Manual/GPUInstancing.html 启用GPU Instancing&#xff0c;我们可以选中一个材质&#xff0c;然后在Inspector窗口…

PostgreSQL教程(二十一):服务器管理(三)之服务器设置和操作

本章讨论如何设置和运行数据库服务器&#xff0c;以及它与操作系统的交互。 一、PostgreSQL用户账户 和对外部世界可访问的任何服务器守护进程一样&#xff0c;我们也建议在一个独立的用户账户下运行PostgreSQL。这个用户账户应该只拥有被该服务器管理的数据&#xff0c;并且…