首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
185 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
33
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-08-11
召唤神龙 – 安装 centos 8, php 8, mysql 8, laravel 8 的整套 php 运行环境
召唤神龙 – 安装 centos 8, php 8, mysql 8, laravel 8 的整套 php 运行环境系列文章:快如闪电的安装 php7.4 套件(centos 7)快如闪电的安装 php7.4 套件(centos 8)win 10 系统使用 docker 快速搭建 centos 8 的 php7.4 和 mysql 完整开发环召唤神龙 - 安装 centos 8, php 8, mysql 8, laravel 8 整套 php 运行环境本文编写时间:2020-11-27标题说明传说集齐龙珠可以召唤神龙。而使用 php 的常用开发框架 laravel 这一技术栈,大版本惊人的实现了统一,均为 8。centos 8, php 8, mysql 8, laravel 8。(假装不知道 ubuntu 也有很多人用。。)用 linux 的好处是开发环境和部署环境高度统一,而 win 10 和 docker 的普及使得所有的 php 程序员可以轻易在 windows 电脑和 mac 电脑进行 linux 环境下的开发,同时阿里巴巴开源镜像站的存在使得安装本文全部软件所需时间仅需 2 分钟左右,已经方便的没法形容了。也是写这个系列文章的初衷。以下列出这 4 类软件的大版本为 8 时的发行时间。软件 发行时间centos 8 2019-09-24php 8 2020-11-26mysql 8 2016-09-12laravel 8 2020-09-08本文各软件版本centos 8.2php 8.0.0mysql 8.0.21laravel 8.16.1 首先,安装阿里的 centos 仓库。(centos 8)curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.reporm -f /etc/yum.repos.d/CentOS-centosplus.reporm -f /etc/yum.repos.d/CentOS-PowerTools.reporm -f /etc/yum.repos.d/CentOS-Extras.reporm -f /etc/yum.repos.d/CentOS-AppStream.repodnf makecachednf repolist安装阿里的 epel 仓库。(centos 8)dnf install -y epel-releasesed -i 's|^#baseurl=https://download.fedoraproject.org/pub|baseurl=https://mirrors.aliyun.com|' /etc/yum.repos.d/epel*sed -i 's|^metalink|#metalink|' /etc/yum.repos.d/epel*dnf makecachednf repolist安装阿里的 remi 的仓库(centos 8)dnf install -y https://mirrors.aliyun.com/remi/enterprise/remi-release-8.rpmsed -i 's/https://rpms.remirepo.net/https://mirrors.aliyun.com/remi/g' /etc/yum.repos.d/remised -i 's/#baseurl/baseurl/g' /etc/yum.repos.d/remi*sed -i 's|^mirrorlist|#mirrorlist|' /etc/yum.repos.d/remi*dnf makecachednf repolist安装 php 8(centos 8)#dnf install -y yum-utilsdnf install -y php80 php80-php-devel php80-php-fpm php80-php-mbstring php80-php-memcached php80-php-redis php80-php-mysqlnd php80-php-pdo php80-php-bcmath php80-php-xml php80-php-gd php80-php-gmp php80-php-igbinary php80-php-imagick php80-php-pdo_mysql php80-php-posix php80-php-simplexml php80-php-opcache php80-php-xsl php80-php-xmlwriter php80-php-xmlreader php80-php-swoole php80-php-zip php80-php-yaml php80-php-uuid体验到快如闪电的速度了吧!提示 :php80-php-memcachephp80-php-mcryptphp80-php-phalconphp80-php-yarphp80-php-yaf这几个暂未发现,所以也没放在上面的命令里。安装阿里的 composer 镜像源(centos 8)#ln -s /usr/bin/php80 /usr/bin/phpcurl -o /usr/local/bin/composer https://mirrors.aliyun.com/composer/composer.pharchmod +x /usr/local/bin/composercomposer config -g repo.packagist composer https://mirrors.aliyun.com/composer/安装 nginx 并整合 php-fpm 服务(centos 8)下面这个 echo 是一句命令,得一起复制echo $'[nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=1enabled=1gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=true ' > /etc/yum.repos.d/nginx.repodnf makecachednf install -y nginxsystemctl enable nginxsystemctl enable php80-php-fpmsed -i 's/user\ =\ apache/user\ =\ nginx/g' /etc/opt/remi/php80/php-fpm.d/www.confsed -i 's/group\ =\ apache/group\ =\ nginx/g' /etc/opt/remi/php80/php-fpm.d/www.confsed -i 's/listen\ =\ /var/opt/remi/php80/run/php-fpm/www.sock/listen=9000/g' /etc/opt/remi/php80/php-fpm.d/www.confrm -f /etc/nginx/conf.d/default.confvi /etc/nginx/conf.d/default.conf/etc/nginx/conf.d/default.conf 文件内容如下server {listen 80; server_name localhost; charset utf-8 ; access_log /var/log/nginx/host.access.log main; root /www/blog/public; index index.php index.html index.htm; error_page 404 500 502 503 504 /50x.html; location = /50x.html { root /www/blog/public; } location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; }}安装 mysql 8(centos 8)实际也用了阿里的镜像,因为是从 AppStream 库下载的,速度极快。dnf install -y @mysqlsystemctl enable mysqldsystemctl start mysqldmysql -urootmysql -uroot,这个命令是登录 mysql 服务用的。进入后执行下面这个命令,创建一个空的数据库名叫 laravel,然后用 quit 退出。create database laravel default charset utf8mb4;安装 redis,git 以及其他常用库(centos 8)#dnf install -y git wget vim redis zip unzip p7zip rsync crontabs supervisor net-tools python3systemctl enable redissystemctl start redis安装 laravel 8(centos 8)#实际也用了阿里的镜像,因为 composer 镜像源已设置过。假设项目名称叫 blog,安装在 /www 目录下mkdir -p /wwwcd /wwwcomposer create-project --prefer-dist laravel/laravel blog "8.*"rm -f ./blog/routes/web.phpvi ./blog/routes/web.php<?phpuse Illuminate\Support\Facades\Route;Route::get('/', function () { ob_start(); phpinfo(INFO_GENERAL); $s = ob_get_contents(); ob_clean(); $system = preg_replace( '#^.+?Build.System.</td><td class="v">([^<]+?)\<.+$#s','$1',$s ); echo "operating system: ".$system."<br>\n"; echo "php: ".phpversion()."<br>\n"; echo "laravel: " . app()::VERSION."<br>\n"; $dbversion = \DB::select("select version() v"); echo "mysql: " . $dbversion[0]->v."<br>\n";});启动 php-fpm 和 nginx 并验证安装正确systemctl start nginxsystemctl start php80-php-fpmcurl localhost/就能看到类似下面的输出:operating system : Red Hat Enterprise Linux release 8.2 (Ootpa) php : 8.0.0laravel: 8.16.1mysql: 8.0.21CopyCopy总结(centos 8)感谢 php 开发组的努力,使得 php 在现代编程语言中保持了竞争力。感谢阿里的开源镜像库
2023年08月11日
15 阅读
0 评论
0 点赞
2023-08-11
深入了解PHP8 JIT(即时编译)功能
深入了解PHP8 JIT(即时编译)功能(Just-In-Time)即时编译器是PHP 8.0中最重要的新功能之一。JIT可以通过将PHP应用程序的全部或经常调用的部分作为CPU机器代码编译并存储并直接执行,从而绕过Zend VM及其过程开销,从而提高性能。JIT是传统解释器和AOT编译器的混合体。混合模型带来了这两种方法的利弊,而经过微调的应用程序可以胜过JIT的弊端。PHP的JIT实施是Dmitry Stogov付出的巨大努力,历时数年之久的讨论,实施和测试都是如此。PHP JIT:PHP 8.0的JIT基础概述和配置选项,请参阅PHP 8.0:JIT。这篇文章是关于基准,JIT如何工作以及理想的配置选项的。大多数PHP应用程序都接受HTTP请求,从数据库中检索和处理数据,并返回结果。IO通常是重要的性能瓶颈:从磁盘读取数据,写入和网络请求。PHP 8.0引入了JIT,以提高PHP应用程序的性能,但它也增加了调试的障碍,因为应用程序的某些部分可能作为CPU机器代码缓存,而标准PHP调试器无法使用。PHP 8.0的JIT pull-request在PHP代码库中增加了50,000多个新行,因此,除了从事JIT的开发人员之外,PHP核心开发人员本身可能并不精通。PHP虚拟机PHP代码一旦处理(标记,解析,构建AST和构建操作码),便在Zend虚拟机上运行。与Java和JavaScript相似,虚拟机对应用程序的硬件方面进行了抽象,从而可以“运行” PHP源代码而无需编译。Opcache扩展可以帮助将操作码存储在共享内存中,从而跳过重复的标记化/解析/操作码步骤。PHP已经包含了一些优化措施,例如在Opcode级别上消除了死代码,但是不可能在虚拟机级别之外执行优化,因为在这一点上,代码是由虚拟机解释的,而不是编译代码。移交给其他应用程序PHP已经具有一些集成,可以调用已编译的其他应用程序。GD扩展可能是最接近的。如果PHP要在矢量或位图级别处理图像,那将是非常慢的,这是因为PHP附加了虚拟机层。GD扩展调用已编译的二进制文件,可以利用高级CPU指令执行相同的操作。PHP 7.4引入了Foreign Functions Interface(也是Dmitry的工作),它提供了一个统一的接口来调用任意应用程序而无需开发PHP扩展。借助FFI,可以将C和Rust等传统编译语言与PHP集成在一起。编译PHP代码尽可能接近CPU的自然下一步就是跳过虚拟机,这就是JIT。即时编译是JavaScript早在多年前就被V8引擎成功采用的一项功能。其他语言也以一种方式或另一种方式实现JIT。最大的优点是仍然不需要预编译源代码,但是有了共享的已编译机器代码的缓存,该语言可以触发代码与已编译机器代码一起执行,稍后再编译或不使用JIT来执行。LLVMLLVM是一种流行的编译工具集,帮助开发编译器对于今天大多数AOT语言。LLVM的目标包括x86,x86-64和其他几种类型,包括图形处理器,Web汇编器,ARM等。PHP考虑使用LLVM,但由于编译器速度不理想,因此效果不佳。DynASMLuaJIT项目的DynASM对于PHP的JIT来说要快得多。与LLVM相比,它对目标CPU指令集的支持是有限的,但是它对x86和x86-64指令集提供了支持。服务器端编程语言(例如PHP)最常用的语言。PHP 8.0的JIT实现使用DynASM进行代码生成。PHP的JIT受DynASM对目标处理器体系结构的限制的约束。PHP JIT如何工作PHP JIT被实现为Opcache的一部分。这使JIT与PHP引擎分离。JIT的三个组件是使用虚拟机或直接使用存储在缓冲区中的机器代码来存储,检查和无缝调用代码。缓冲JIT缓冲区是存储已编译的CPU机器代码的位置。PHP提供了配置选项(opcache.jit_buffer_sizeINI设置)来控制应为JIT缓冲区分配多少内存。触发器Opcache中的触发器负责在遇到代码结构时调用已编译的机器代码。这些触发器可以是函数调用项,循环等。跟踪器JIT跟踪器功能在执行之前,之后或过程中检查代码,并确定哪些代码是“热门”代码,例如可以使用JIT编译哪些结构。当某个代码结构达到阈值时,跟踪器可以在运行代码时对其进行编译,这也是可配置的。Tracing JIT 和 Function JITPHP 8.0添加了两种JIT操作模式。这是可以进一步自定义的,但是最显着的JIT功能类型是function和tracing。Function JIT相比之下,Function JIT模式是一个相当简单的模式。它通过JIT编译整个函数,而无需跟踪常用的代码结构,例如函数内部的循环。它仍然支持对常用函数进行性能分析,并在执行应用程序请求之前,之后或期间触发JIT编译或编译后的机器代码的执行。Tracing JITTracing JIT(在PHP 8.0中默认选择)试图识别经常使用的代码部分,并选择性地编译这些结构,以在编译时间和内存使用之间取得最佳平衡。并非所有的编程语言都支持tracing JIT编译器,但是PHP支持从第一个发行版开始就支持tracing JIT,并且默认情况下也是选中的。有几个配置选项可以进一步调整如何确定热代码结构,例如函数调用的次数,循环结构的迭代次数等。分析和优化JIT可以在代码运行时对其进行检查,分析和优化。PHP JIT提供了对阈值和触发器的细粒度控制,其中涉及多少调用使其成为将JIT编译为机器代码的合适候选者,并且可以使用新编译的代码。如果在缓冲区中也存在后续的请求,则可以使用编译后的代码。PHP的JIT实现允许微调何时应该使用JIT(何时加载脚本,第一次运行后或在执行期间),什么(整个函数或单个代码结构)以及如何进行优化(使用 AVX指令,CPU寄存器等)。JIT友好代码当JIT可以尽可能多地分流到本机CPU寄存器和指令时,它将受益匪浅。PHP是一种弱类型的语言,这使得很难推断变量的类型,并且需要对变量的生命周期进行更多分析,因为变量的类型可能在同一代码结构的稍后位置发生变化。严格类型的代码以及具有标量类型的函数可以帮助JIT推断类型,并在可能的情况下利用CPU寄存器和专用指令。例如,一个纯函数(没有副作用),启用严格类型并带有参数和返回类型可能是理想的选择:declare(strict_types=1);function sum(float $a, float $b): float {return $a + $b;}当PHP无法推断类型时,它可能无法充分利用JIT优化。实际上,PHP 7的一些改进来自这些优化,它们可以消除无效代码并改善引用计数。这意味着更严格类型化的代码为PHP提供了更多机会来优化Opcache级别和JIT级别的代码。受IO约束的应用程序(例如,广泛使用数据库的应用程序,DNS查询,文件读/写操作,FTP,套接字等)可能不会看到明显的差异,因为IO操作本身通常是这种应用的瓶颈。基本的JIT配置默认情况下,JIT是启用的,但可通过限制缓冲区大小将其关闭。PHP JIT:PHP 8.0的JIT基础概述和配置选项,请参阅PHP 8.0:JIT。这篇文章是关于基准,JIT如何工作以及理想的配置选项的。最简单的设置是简单地为JIT设置缓冲区大小,然后JIT将使用合理的默认值。opcache.enable=1opcache.enable_cli=1opcache.jit_buffer_size=256M这将为JIT缓冲区分配256 MB,并在CLI应用程序上启用JIT。opcache.jit指令允许微调JIT功能。opcache.jit=tracingopcode.jit是有点复杂的配置值。它接受disable,on,off,trace,function,4 位值(4-digit)(不是位掩码),按顺序排列 4 个不同的标志。。disable:在启动时完全禁用JIT功能,并且在运行时无法启用。off:禁用,但是可以在运行时启用JIT。on:启用tracing模式。tracing:细化配置 的别名1254。function:细化配置 的别名1205。PHP JIT接受tracing或function作为表示配置组合的简单配置。除tracing和function别名外,该opcache.jit伪指令还接受4位数字的配置值。它可以进一步配置JIT行为。4位配置值的格式为CRTO,其中每个位置允许单个标记指定的字母数字值。JIT标记所述opcache.jit指令接受一个4位值以控制JIT行为,以CRTO的形式,并接受C,R,T,和O位置的以下值。C:CPU特定的优化标志0:禁用特定于CPU的优化。1:如果CPU支持,则启用AVX。R:寄存器分配0:不执行寄存器分配。1:执行块本地( block-local)寄存器分配。2:执行全局寄存器分配。T:触发器0:在脚本加载时编译所有函数。1:首次执行时编译所有函数。2:剖析第一个请求,然后编译最热的函数。3:即时分析并编译热函数。4:当前未使用。5:使用tracing JIT。动态分析并编译跟踪以查找热代码段。O:优化级别0:没有JIT。1:最小JIT(调用标准VM处理程序)。2:内联VM处理程序。3:使用类型推断。4:使用调用图。5:优化整个脚本。4触发器(T=4)下的选项未进入JIT实现的最终版本。它是使用@jitDocBlock注释属性声明的函数上的触发JIT 。现在未使用。function与tracingJIT配置都利用CPU指令集和CPU寄存器分配来充分利用 CPU 功能(C = 1,R = 2)。opcache.jit=functionfunction 是C = 1,R = 2,T = 0,O = 5的别名。与function配置的区别在于,它渴望尽快编译脚本,然后编译整个脚本。这是一种更加冒昧和大胆的方法,类似于使用PHP 7.4中的预加载功能将PHP文件预加载到Opcache。opcache.jit=tracingtracing 是C = 1,R = 2,T = 5,O = 4的别名。启用tracing后,JIT可以更精细,并选择函数中的代码段进行编译。理想的候选对象是循环结构和经常调用的函数。这是默认配置,可以在性能优势和编译开销之间提供更多的平衡。JIT tracing功能(T = 2、3或5)允许进一步调整将一个函数标记为hot并最终进行JIT编译需要多少次调用。指令 描述 默认值opcache.jit_hot_loop 经过几次迭代后,循环被认为很热。 64opcache.jit_hot_func 在几次调用之后,一个函数被认为是热的。 127opcache.jit_hot_return 在有多少返回后,返回被认为是热的。 8opcache.jit_hot_side_exit 在有多少退出一侧后,退出被认为是热的。 8默认值可能最适合几乎所有应用程序,降低默认值会降低阈值,从而导致要编译更多代码结构。理想的JIT配置更多的JIT编译代码并不一定意味着应用程序更快(如下面的Web应用程序基准所示)。由于花在JIT编译步骤上的时间,编译开销和较小的缓冲区会使应用程序变慢。opcache.jit值最好保持不变(默认值为 tracing),因为它已经在CPU使用率,内存和跟踪编译哪些代码结构方面保持了良好的平衡。对于大量IO绑定的应用程序,JIT将不会获得任何有意义的性能优势。实际上,当今的大多数Web应用程序都是IO大量的,JIT不会带来任何改变,更不用说是积极的了。对于缓冲区大小,请注意不要有太小的内存,这会浪费JIT编译的代码并导致频繁的重新编译。太大的内存也可能是一个过大的杀伤力。Opcode的当前Opcache共享内存的50-100%可能是opcache.jit_buffer_size的理想值。JIT基准以下所有测试均在8核16线程x86-64系统上完成。但是,测试从不使用需要64位寄存器的整数,以使测试与x86 CPU更相关。PHP脚本基准PHP源代码包含两个基准脚本,用于测试各种PHP功能。micro_bench.php和bench.php文件已在PHP 8.0分支上进行了测试(该分支自PHP 8.0.0发行以来包含一些错误修复)。第一次测试是在完全关闭Opcache的情况下进行的,第二个测试是在关闭JIT的情况下进行的,但启用了opcache。两种JIT模式均会带来实质性的性能提升,但tracing模式稍有领先。该基准几乎不能代表现实生活中的PHP应用程序。重复调用相同的函数,以及测试代码更简单,副作用更少的特性,使JIT受益匪浅。PHP斐波那契基准一个简单的斐波那契函数,用于计算斐波那契序列中的第42个数字。Fibonacci序列全都与重复的函数调用有关,并且也不会说出真实PHP应用程序的完整故事,除非它当然是Fibonacci计算器应用程序。斐波那契:PHP与其他语言其他编译语言(例如Go,Rust和C)和Node JS也具有相同的Fibonacci(42)测试,后者也具有JIT功能。PHP 8.0的JIT并未尝试其他AOT编译语言可以执行的所有可能的优化。但是,PHP 8.0的JIT带来了显着的性能提升,还有更多的改进余地。Web应用基准很难预测JIT的影响,因为JIT高度依赖强调工作负载。下面的大多数示例都是Web框架的hello-world示例,由于所涉及的各种插件和缓存系统,它们不一定代表实际使用情况。使用数据库连接的应用程序在数据库查询时可能会遇到最大的瓶颈。在测量每秒请求数的Web服务器测试中,TLS,HTTP和FPM开销可能远远超过JIT造成的性能差异。Laravel(8.4.4)和Symfony(演示版1.6.3,使用5.1.8版组件)及其骨架应用程序在与以前的基准测试相同的场景下,在相同的硬件上进行了测试。这两个应用程序均由内置的PHP Web服务器提供服务,并使用Apache Bench(ab)进行基准测试,并发率为5,并发请求为100。5次测试的平均值。这两个应用程序都没有收到明显的收益,在Laravel中,JIT的性能降低了约2%,这可能是由于编译开销并未超过工作量。对每个应用程序进行基准测试为了获得真正的性能收益,每个应用程序都需要处于基准之下,以衡量使用JIT是否可以带来显着的收益。CLI应用程序(尤其是CPU密集型应用程序)可能会获得实质性的性能提升。对于诸如Composer和PHPUnit之类的网络和文件密集型应用程序,由于它们无法从机器代码改进中受益匪浅,因此不太可能获得性能提升。增加更多的SSD / RAM容量和带宽以获得更好的结果。总结JIT是使PHP性能更快并利用强调硬件功能的重要一步。这是多年的努力,并且已经显示出在计算密集型工作负载方面的实质性改进。PHP的JIT仍有改进的余地,并且从现在开始可能只会变得更好。非常感谢Dmitry Stogov和Nikita Popov在JIT方面所做的出色工作。Nikita还友好而迅速地回顾了本文的第一部分,介绍了JIT是如何工作的。谢谢❤🙏🏼。via https://php.watch/articles/jit-in-depth
2023年08月11日
14 阅读
0 评论
0 点赞
2023-08-11
Nginx+php FastCGI到底是谁影响超时时间
Nginx+php FastCGI到底是谁影响超时时间需求:一个php程序要跑一段时间,但是时间不确定。问题:当该php程序运行超过一段时间被强制断开连接。PHP本身超时处理在 php.ini 中,有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时:0s就是说如果是使用 mod_php5.so 的模式运行 max_execution_time 是会生效的,但是如果是php-fpm模式中运行时不生效的。max_execution_time(php.ini中)计算的只是PHP脚本本身执行的时间,执行之外的时间都不会计算在内。哪些属于执行之外的时间呢?包含sleep、数据交互、socket交互等等。配置参数所在位置:php.ini:max_execution_timephp-fpm.conf:request_terminate_timeoutnginx.conf:fastcgi_connect_timeoutfastcgi_read_timeoutfastcgi_send_timeoutrequest_terminate_timeout = 0 即为不受时间控制,永不超时request_terminate_timeout引起的资源问题request_terminate_timeout的值如果设置为0或者过长的时间,可能会引起file_get_contents的资源问题。如果file_get_contents请求的远程资源如果反应过慢,file_get_contents就会一直卡在那里不会超时。我们知道php.ini 里面max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的request_terminate_timeout参数。request_terminate_timeout默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。修改该参数,设置一个 PHP 脚本最大执行时间是必要的,但是,治标不治本。例如改成 30s,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免”502 Bad Gateway”。解决办法是request_terminate_timeout设置为10s或者一个合理的值,或者给file_get_contents加一个超时参数如果常有请求超时,请打开php-fpm的慢日志,通过日志来确认评估超时时间。Ngnix中的fastcgi 请求时间控制fastcgi_connect_timeout语法:fastcgi_connect_timeout time默认值:fastcgi_connect_timeout 60使用字段:http, server, location指定同FastCGI服务器的连接超时时间,这个值不能超过75秒。fastcgi_read_timeout语法:fastcgi_read_timeout time默认值:fastcgi_read_timeout 60使用字段:http, server, location前端FastCGI服务器的响应超时时间,如果有一些直到它们运行完才有输出的长时间运行的FastCGI进程,或者在错误日志中出现前端服务器响应超时错误,可能需要调整这个值。fastcgi_send_timeout语法:fastcgi_send_timeout time默认值:fastcgi_send_timeout 60使用字段:http, server, location指令为上游服务器设置等待一个FastCGI进程的传送数据时间,如果有一些直到它们运行完才有输出的长时间运行的FastCGI进程,那么可以修改这个值,如果你在上有服务器的error log里面发现一些超时错误,那么可以恰当的增加这个值。指令指定请求服务器的超时时间,指完成了2次握手的连接,而不是完整的连接,如果在这期间客户端没有进行数据传递,那么服务器将关闭这个连接。在Nginx+FastCGI 配置测试中其中在request_terminate_timeout设置为永不超时的情况下,nginx中fastcgi_read_timeout 的设置时间将影响到最终的超时时间。测试中,如果是php-fpm中的超时将显示 502 Bad Gateway502 Bad Gateway502 Bad Gatewaynginx 如果是nginx中cgi配置超时 将显示 504 Gateway Time-out 504 Gateway Time-out 504 Gateway Time-out nginx
2023年08月11日
14 阅读
0 评论
0 点赞
2023-08-11
如何选择laravel的身份认证系统
如何选择laravel的身份认证系统最近经常有人问如何使用laravel的身份认证功能,因为laravel的身份认证方式比较多,laravel的作者最近专门写了一文章来解释说明,以下为译文:laravel认证生态系统概述Laravel提供了一些与身份验证相关的软件包。在继续之前,我们将回顾Laravel中的常规身份验证生态系统,并讨论每个软件包的预期目的。首先,请考虑身份验证的工作原理。使用网络浏览器时,用户将通过登录表单提供其用户名和密码。如果这些凭据正确,则应用程序将在用户的会话中存储有关经过身份验证的用户的信息。发布给浏览器的cookie包含会话ID,以便对应用程序的后续请求可以将用户与正确的会话相关联。接收到会话cookie后,应用程序将基于会话ID检索会话数据,注意身份验证信息已存储在会话中,并将用户视为“已身份验证”。当远程服务需要进行身份验证才能访问API时,通常不使用cookie,因为没有Web浏览器。而是,远程服务根据每个请求将API令牌发送到API。应用程序可以对照有效API令牌表验证传入令牌,并“认证”与该API令牌相关联的用户正在执行的请求。Laravel的内置浏览器身份验证服务Laravel包含内置的身份验证和会话服务,通常可以通过Auth和SessionFacades访问它们。这些功能为从Web浏览器发起的请求提供基于cookie的身份验证。它们提供了允许您验证用户凭据并验证用户身份的方法。另外,这些服务将自动在用户的会话中存储正确的数据并发出正确的会话cookie。本文档中包含有关如何使用这些服务的讨论。Jetstream / Fortify如本文档中所述,您可以手动与这些身份验证服务交互以构建应用程序自己的身份验证层。但是,为了帮助您更快地入门,我们发布了免费软件包,这些软件包为整个身份验证层提供了强大而现代的脚手架。这些软件包是Laravel Jetstream和Laravel Fortify。Laravel Fortify是Laravel的无头(headless)身份验证后端,它实现了本文档中的许多功能,包括基于cookie的身份验证以及其他功能,例如( two-factor)双因素身份验证和电子邮件验证。Laravel Jetstream是一个UI,它使用由Tailwind CSS,Laravel Livewire和/或Inertia.js提供支持的美观、现代的UI来使用Fortify的身份验证服务并将其公开。Laravel Jetstream除了提供基于浏览器的cookie身份验证之外,还包括与Laravel Sanctum的内置集成以提供API令牌身份验证。Laravel的API身份验证产品将在下面讨论。Laravel的API身份验证服务Laravel提供了两个可选的软件包来帮助您管理API令牌和认证使用API令牌发出的请求:Passport和Sanctum。请注意,这些库和基于Laravel的内置cookie的身份验证库不是互斥的。这些库主要关注API令牌身份验证,而内置身份验证服务则关注基于cookie的浏览器身份验证。许多应用程序将同时使用Laravel的基于内置cookie的身份验证服务和Laravel的API身份验证程序包之一。PassportPassport是OAuth2身份验证提供程序,提供各种OAuth2“授权类型”,使您可以颁发各种类型的令牌。通常,这是用于API身份验证的强大而复杂的程序包。但是,大多数应用程序都不需要OAuth2规范提供的复杂功能,这会使用户和开发人员感到困惑。另外,从历史上看,开发人员对于如何使用Passport等OAuth2身份验证提供程序对SPA应用程序或移动应用程序进行身份验证感到困惑。Sanctum为了应对OAuth2的复杂性和开发人员的困惑,我们着手构建一个更简单,更简化的身份验证程序包,该程序包既可以处理来自Web浏览器的第一方Web请求,也可以处理通过令牌的API请求。Laravel Sanctum的发布实现了这一目标,对于那些除了API之外还将提供第一方Web UI或将由单页面应用程序提供支持的应用程序,Laravel Sanctum的发布应被视为首选和推荐的身份验证程序包。与后端Laravel应用程序或提供移动客户端的应用程序分开存在。Laravel Sanctum是Web / API混合身份验证程序包,可以管理应用程序的整个身份验证过程。这是可能的,因为当基于Sanctum的应用程序收到请求时,Sanctum将首先确定该请求是否包括引用已验证会话的会话cookie。Sanctum通过调用我们前面讨论的Laravel的内置身份验证服务来实现此目的。如果未通过会话cookie对请求进行身份验证,Sanctum将检查请求中的API令牌。如果存在API令牌,Sanctum将使用该令牌对请求进行身份验证。要了解有关此过程的更多信息,请查阅Sanctum的“工作原理”文档。Laravel Sanctum是我们选择包含在Laravel Jetstream身份验脚手架中的API程序包,因为我们认为它最适合大多数Web应用程序身份验证需求。总结与选择总之,如果将使用浏览器访问您的应用程序,则您的应用程序将使用Laravel的内置身份验证服务。接下来,如果您的应用程序提供了API,则您将在Passport或Sanctum之间进行选择,以为您的应用程序提供API令牌认证。通常,应该尽可能使用Sanctum,因为它是API身份验证,SPA身份验证和移动身份验证的简单,完整的解决方案,包括对“范围(scopes)”或“功能(abilities)”的支持。当您的应用程序绝对地需要OAuth2规范提供的所有功能时,可以选择Passport。而且,如果您想快速入门,我们很高兴向您推荐Laravel Jetstream,这是启动新的Laravel应用程序的快速方法,该应用程序已经使用了我们首选的Laravel内置身份验证服务和Laravel Sanctum身份验证。用以下一张图示例如何选择:参考 http://laravel.p2hp.com/docs/8.x/authentication#ecosystem-overview
2023年08月11日
14 阅读
0 评论
0 点赞
2023-08-11
GO+PHP, 让全宇宙最好的两种语言合体的神器——RoadRunner
GO+PHP, 让全宇宙最好的两种语言合体的神器——RoadRunner数据说话从图中可以看出RoadRunner对比Nginx+FPM,运行效率是有数量级上的提升。一般PHP服务器传统CGI协议服务器客户端访问某个URL地址之后,通过 GET/POST/PUT等方式提交数据,并通过HTTP协议向Web服务器发出请求,服务器端将HTTP请求里描述的信息通过标准输入(stdin)和环境变量(environment variable)传递给新建的CGI进程。处理完成后,进程立即关闭。Nginx + PHP-FPM模式现在流行的PHP web程序一般都是运行在Nginx + PHP-FPM模式下的。PHP-FPM就是PHP对FastCGI的实现。master创建并监听多个worker进程,通过共享内存获取worker的状态,进而通过信号控制worker进程。每一个worker进程就类似一个CGI进程,收到CGI请求后会执行相应的PHP文件,并把请求内容作为PHP进程状态的一部分(_GET, _POST, _SERVER等等)。结束请求后,worker不会立刻结束,而是继续留在worker pool. 这就节省了频繁创建结束子进程的开支。RoadRunner为什么现在很多PHP的企业级框架都要求你加载至少十几个文件,构造多个类并解析一些配置,以便处理简单的用户请求或查询数据库。每个任务完成后,你不得不抛弃这些代码。收到下一个HTTP请求时,PHP-FPM会创建一个新的PHP子进程来处理这个请求,所有的文件都要重新加载一遍,即便文件可以有缓存,所有的代码也要重新运行。如果我们可以避免对每个请求都重启一次PHP子进程,我们就可以节约很多的资源。基本原理RoadRunner可以看作一个升级版的Nginx + PHP-FPM. 它直接把长时运行的PHP进程作为worker, 直接对PHP worker进行监控和维护,每次收到http请求时,就发给php worker来处理。这样,我们就不再需要对每个请求重启一遍PHP了。一些实现细节整个项目都是开源的,RoadRunner的代码在这里。RoaderRunner 通过 Socket/Pipe 上的二进制流完成和PHP子进程之间的通信。为此,他们创建了一个轻量的二进制协议,这个协议的包头长这样。不同的通信方式,创建worker时就会有所区别。RoadRunner实现了两套factory和relay:当使用pipe时,work是从pipe_factory.go创建的。PHP方面对应的Class是StreamRelay.php其中读取包头的部分代码是这样的$prefixBody = fread($this->in, 17);if ($prefixBody === false) {throw new Exceptions\PrefixException("unable to read prefix from the stream");}$result = unpack("Cflags/Psize/Jrevs", $prefixBody);if (!is_array($result)) {throw new Exceptions\PrefixException("invalid prefix");}if ($result['size'] != $result['revs']) {throw new Exceptions\PrefixException("invalid prefix (checksum)");当使用socket时,对应的PHP Class是SocketRelay.php, 代码是类似的。只不过PHP读取的部分从stdin/out变成了socket.RoadRunner实现了StaticPool和Worker来对所有的PHP worker进行管理。本质上就是一个进程池。当需要PHP对数据进行处理时,StaticPool的allocateWorker()方法会从进程池的free worker中分配一个进程,把数据发送给这个PHP进程。StaticPool不会在PHP进程返回数据后关闭进程,而是把这个进程放回进程池。如果某个PHP进程意外关闭,staticPool会主动丢弃并在需要的时候创建新的进程。举个栗子下面是一个实际应用RoadRunner的例子。我们创建了一个最多拥有4个PHP进程的StaticPool,Golang会把0到9的数字依次传给PHP处理,PHP把数字加1并返回。Golang部分://创建RoadRunner serversrv := roadrunner.NewServer(&roadrunner.ServerConfig{ Command: "php " + phpScriptName, Relay: "pipes", // 选择用pipe通信 Pool: &roadrunner.Config{ NumWorkers: 4, // worker的数量是4 AllocateTimeout: time.Second, DestroyTimeout: time.Second, }, })defer srv.Stop()err := srv.Start()if err != nil {panic(err)}for i := 0; i < 10; i++ {// 把i作为payload传给PHP进程 res, err = srv.Exec(&roadrunner.Payload{Body: i}) if err != nil { panic(err) } fmt.Print(res)}PHP部分<?phpuse Spiral\Goridge;use Spiral\RoadRunner;// 创建Worker实例,选择用pipe通信$rr = new RoadRunner\Worker(new Spiral\Goridge\StreamRelay(STDIN, STDOUT));// 长时运行,阻塞式接收go传来的数据while ($i = $this->rr->receive($context)) {try { $i = $i + 1; $rr->send($i, (string) $context); } catch (\Throwable $e) { $rr->error((string) $e); }}为什么要go + php?“有些人仍然坚持认为 PHP 是一种缓慢,笨重的语言,只能用来编写 WordPress 插件。他们甚至可能会说 PHP 有一个限制:一旦你的应用程序变得比较大,你就必须切换到更“成熟”的语言并取代之前的 PHP 代码。”基本上php脚本也都可以用go来写,那为什么不直接用100%的Go来开发项目呢?我会认为这种模式还是有一些存在的意义的:开发效率高。尤其是PHP对html渲染有很好的支持,这又正是Go的痛点。用工成本的考虑。让大牛用Go写出框架,每个模块再由php分别实现,也许是个好主意。(这也算PHP的优势吗-。-?)PHP作为弱类型的脚本语言,用来实现一些小模块,真的很爽~!参考文献https://blog.spiralscout.com/php-was-never-meant-to-die-830de87915ee
2023年08月11日
18 阅读
0 评论
0 点赞
1
...
49
50
51
...
112