草庐IT

PHP服务缓存优化(3)

冬日大草原的黄昏 2023-09-14 原文

1、zend虚拟机介绍

基础知识

编程语言的虚拟机是一种可以运行中间语言的程序。中间语言是抽象出的指令集,由原生语言编译而成,作为虚拟机执行阶段的输入。很多语言都实现了自己的虚拟机,比如Java、C#和Lua。PHP语言也有自己的虚拟机,称为Zend虚拟机。

PHP7完成基本的准备工作后,会启动Zend引擎,加载注册的扩展模块,然后读取对应的脚本文件,Zend引擎会对文件进行词法和语法分析,生成抽象语法树,接着抽象语法树被编译成Opcodes,如果开启了Opcache,编译的环节会被跳过从Opcache中直接读取Opcodes进行执行。

PHP7中词法语法分析,生成抽象语法树,然后编译成Opcodes及被执行均由Zend虚拟机完成。这里简要说明一下zend虚拟机的实现原理。

zend虚拟机

Zend虚拟机(称为Zend VM)是PHP语言的核心,承担了语法词法解析、抽象语法树编译以及指令的执行工作。

Zend虚拟机主要分为解释层、中间数据层和执行层,下面给出各层包含的内容,如下所示。

1.png

下面解释下各层的作用。

(1)解释层

这一层主要负责把PHP代码进行词法和语法分析,生成对应的抽象语法树;另一个工作就是把抽象语法树进行编译,生成符号表和指令集;

(2)中间数据层

这一层主要包含了虚拟机的核心部分,执行栈的维护,指令集和符号表的存储,而这三个是执行引擎调度执行的基础;

(3)执行层

这一层是执行指令集的引擎,这一层是最终的执行并生成结果,这一层里面实现了大量的底层函数。

2.PHP缓存操作码

缓存操作码(opcode)

Opcode,PHP编译后的中间文件,缓存给用户访问

当客户端请求一个PHP程序时,服务器的PHP引擎会解析该PHP程序,并将其编译为特定的操作码文件,该文件是执行PHP代码后的一种二进制文件表现形式。默认情况下,这个编译好的操作码文件由PHP引擎执行后丢弃;而操作码缓存的原理就是将编译后的操作码保存下来,并放入到共享内存里,以便再下一次调用该PHP页面时重用它,避免了相同代码的重复编译。节省了PHP引擎重复编译的时间,降低了服务器负载,同时减少了CPU和内存的开销.

缓存流程说明:

1 nginx 接受客户端的PHP程序访问请求

2 nginx根据扩展名等过滤规则将PHP程序请求传递给解析PHP的fcgi进程(php-fpm)

3 PHP fpm 进程调用PHP解析器读取站点磁盘上的PHP文件,并加载到内存中

4 PHP解析器将PHP程序编译成opcode文件,然后将opcode缓存起来

5 PHP fpm引擎执行opcode之后,返回数据给nginx,进而返回给客户端

6 nginx收到新的PHP请求时,PHP fpm引擎就会直接读取缓存中的opcode并执行,将结果返回。

3、 PHP加速器的种类

1 xcache

2 eaccelerator

3 zendopcache

选择方式:通过自己将平台打好进行压力测试,选择自己最合适的

建议:

1 首选xcache,原因是效率好,快,社区活跃支持更高的版本

2 次选eaccelerator,原因,安装配置简单,加速效果更高,文档资料多,但官方不活跃,仅适合于PHP版本5.4以下的程序

3 再选则zendopcache,原因是PHP官方颜值,发展潜力好,PHP5.5之前可以通过zendopcache软件以插件扩展的方式安装,从PHP5.5版本开始已经整合到PHP软件中,编译时只需要指定相关参数即可

4、环境安装(xcache)

下载xcache软件包

wget http://xcache.lighttpd.net/pub/Releases/1.3.0/xcache-1.3.0.tar.gz
##解压
tar zxvf xcache-1.3.0.tar.gz
cd xcache-1.3.0
/usr/local/php/bin/phpize
./configure --enable-xcache \
 --with-php-config=/usr/bin/php-config
# make && make install

安装完成后根据提示进入到/usr/lib64/php/modules目录

cd /usr/lib64/php/modules

2.png

可以看到xcache.so文件已经生成

进入到/etc/php.d/目录下配置xcache.ini 文件使扩展插件生效

cd /etc/php.d/

cp mysql.ini xcache.ini

vim xcache.ini

3.png

重启php-fpm

systemctl restart php-fpm

访问写好的index.php页面即可看到php已加载xcache插件

4.png

或者使用php -v也可以查看

5.png

5、配置Xcache插件加速

基本配置与加载

cd /etc/php.d/

cp mysql.ini xcache.ini

vim xcache.ini

; Enable mysqlnd extension module
extension=xcache.so

#登录管理界面的用户名和密码,留空则禁用管理界面
[xcache.admin]

xcache.admin.enable_auth = On
xcache.admin.user = "admin"

#MD5加密后的密码,echo -n pass | md5sum
xcache.admin.pass = "e10adc3949ba59abbe56e057f20f883e"

[xcache]

#决定 XCache 如何从系统分配共享内存
xcache.shm_scheme ="mmap"

#所用共享缓存的大小。如果为0,缓存将无法使用
xcache.size=60M

#指定将 cache 切分成多少块, 建议设置为 cpu 数 (cat /proc/cpuinfo |grep -c processor)
xcache.count =1

#只是作为 hash 槽个数的参考值
xcache.slots =8K

#Opcode文件的生存时间。如果将此值设置为0,则将无限期缓存 (int)
xcache.ttl=0

#回收器扫描过期的对象回收内存空间的间隔,0不扫描
xcache.gc_interval =0

#同上, 只是针对变量缓存设置
xcache.var_size=4M
xcache.var_count =1
xcache.var_slots =8K
xcache.var_ttl=0
xcache.var_maxttl=0
xcache.var_gc_interval =300

#启用或禁用测试功能
xcache.test =Off

#如果启用了 ReadonlyProtection, 将会略微降低性能, 但是会提高一定的安全系数,这个选项对于xcache.mmap_path = /dev/zero 无效.
xcache.readonly_protection = On

#用于只读保护的文件路径,这将限制两个 php 进程组共享同一个 /tmp/xcache 目录, 指定为 /dev/zero 时无效
xcache.mmap_path ="/tmp/xcache/"

#在遇到故障时,放置核心转储的目录。必须是PHP可写入的目录。保留为空代表禁用.
xcache.coredump_directory =""


在/etc/php.ini文件里根据编译安装后的提示添加如下字段

extension_dir = "/usr/lib64/php/modules/" extension_dir = xcache.so

详细介绍:

xcache.admin.user   (String) 管理认证用户名。默认设置"mOo"

xcache.admin.pass  (String)管理认证密码。默认设置为"<empty string>"。此值应该是MD5(你的密码)

xcache.admin.enable_auth (String)启用或禁用管理站点的身份验证。默认值"on"

xcache.test (String)启用或禁用测试功能

xcache.coredump_dir   (String)在遇到故障时,放置核心转储的目录。必须是PHP可写入的目录。保留为空带表禁用

xcache.cacher   (Boolean) 启用或禁用Opcode 缓存。默认开启

xcache.size    (int)所有共享缓存的大小。如果为0,缓存将无法使用

xcache.count  (int)缓存被分割的“块”数。默认值1

xcache.slots   哈希表提示。数字越大,哈希表内进行的搜索速度就越快。此值越高,所需内存也越多

xcache.ttl   (int)Opcode文件的生存时间。0=无限期缓存

xcache.gc_interval  (秒) 触发垃圾回收的时间间隔。默认0

xcache.var_size  (int)变量大小

xcache.var_count (int)变量个数

xcache.var_slots 可变数据槽设置

xcache.var_ttl (秒)可变数据的生存时间,默认设置0

xcache.var_maxttl (秒)处理变量时最大的生存时间

xcache.var_gc_interval (秒)垃圾回收的生存时间

xcache.readonly_protection (Boolean)启用ReadonlyProtection时可用。

xcache.mmap_path (String)用于只读保护的文件路径。这将限制两个PHP组共享同一个/tmp/cache目录

xcache.optimizer (Boolean)启用或禁用优化  默认禁用

xcache.coverager (Boolean)启用覆盖范围数据集合。

xcache.coveragerdump_directory (String)放置数据集合信息的目录位置。默认使用目录/tmp/pcovis

生成Xcache缓存文件

touch /tmp/xcache

chmod 777 /tmp/xcache

可将tmpfs挂载/tmp/xcache目录下,增加缓存的读写速度。

mount -t tmpfs -o size=64m tmpfs /tmp/xcache

复制相关网页到nginx的主目录下

cd xcache-3.2.0/

cp -a htdocs/ /usr/share/nginx/html

授予相关权限

chown -R nginx.nginx /usr/share/nginx/html

重启php-fpm后访问测试

http://192.168.112.201/htdocs/index.php

6.png

输入刚才配置的账号密码

7.png

这样就进入到xcache的web界面,可以对缓存信息进行管理

6、ab压力简单测试效果

未配置xcache之前的压测结果

[root@vm04 ~]# ab -n 3000 -c 100 192.168.112.201/index.php

This is ApacheBench, Version 2.3 <$Revision: 1430300 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.112.201 (be patient)

Completed 300 requests

Completed 600 requests

Completed 900 requests

Completed 1200 requests

Completed 1500 requests

Completed 1800 requests

Completed 2100 requests

Completed 2400 requests

Completed 2700 requests

Completed 3000 requests

Finished 3000 requests

Server Software: nginx/1.14.2

Server Hostname: 192.168.112.201

Server Port: 80

Document Path: /index.php

Document Length: 73351 bytes

Concurrency Level: 100

Time taken for tests: 26.551 seconds

Complete requests: 3000

Failed requests: 320

(Connect: 0, Receive: 0, Length: 320, Exceptions: 0)

Write errors: 0

Total transferred: 220496635 bytes

HTML transferred: 220052635 bytes

Requests per second: 112.99 [#/sec] (mean)

Time per request: 885.035 [ms] (mean)

Time per request: 8.850 [ms] (mean, across all concurrent requests)

Transfer rate: 8109.99 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 1 3.1 0 23

Processing: 9 847 1006.0 713 17514

Waiting: 6 787 902.5 682 17508

Total: 9 848 1006.0 714 17514

Percentage of the requests served within a certain time (ms)

50% 714

66% 883

75% 1089

80% 1242

90% 1716

95% 2279

98% 3042

99% 3855

100% 17514 (longest request)

2、配置xcache之后的压测结果

[root@vm04 ~]# ab -n 3000 -c 100 192.168.112.201/index.php

This is ApacheBench, Version 2.3 <$Revision: 1430300 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.112.201 (be patient)

Completed 300 requests

Completed 600 requests

Completed 900 requests

Completed 1200 requests

Completed 1500 requests

Completed 1800 requests

Completed 2100 requests

Completed 2400 requests

Completed 2700 requests

Completed 3000 requests

Finished 3000 requests

Server Software: nginx/1.14.2

Server Hostname: 192.168.112.201

Server Port: 80

Document Path: /index.php

Document Length: 34506 bytes

Concurrency Level: 100

Time taken for tests: 6.001 seconds

Complete requests: 3000

Failed requests: 296

(Connect: 0, Receive: 0, Length: 296, Exceptions: 0)

Write errors: 0

Total transferred: 103961667 bytes

HTML transferred: 103517667 bytes

Requests per second: 499.88 [#/sec] (mean)

Time per request: 200.047 [ms] (mean)

Time per request: 2.000 [ms] (mean, across all concurrent requests)

Transfer rate: 16916.87 [Kbytes/sec] received

Connection Times (ms)

min mean[+/-sd] median max

Connect: 0 2 3.6 0 26

Processing: 33 195 115.8 171 1304

Waiting: 2 192 110.0 170 1304

Total: 42 197 116.1 172 1305

Percentage of the requests served within a certain time (ms)

50% 172

66% 182

75% 187

80% 191

90% 227

95% 373

98% 633

99% 778

100% 1305 (longest request)

可以看到未安装xcache时并发数为113,安装xcache之后并发数为499,缓存效果提升了4倍左右。

有关PHP服务缓存优化(3)的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  4. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  5. ruby - 如何在 Ubuntu 中清除 Ruby Phusion Passenger 的缓存? - 2

    我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:

  6. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  7. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  8. ruby-on-rails - Ruby on Rails 计数器缓存错误 - 2

    尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot

  9. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  10. ruby - Rails 开发服务器、PDFKit 和多线程 - 2

    我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:

随机推荐