概述
PHP 5.5
以后内建了OpCache
,OpCache
的加速原理是把编译后的bytecode
存储在内存里面, 避免重复编译 PHP 所造成的资源浪费.Ubuntu 14.04
默认自带 PHP 5.5.9
,已经集成了这个功能。但是默认是不启用的。
启用
修改 php.ini 文件
在文件最后面加入:
重启服务器
效果
加速效果极端明显,强烈建议启用这个功能。
PHP 5.5
以后内建了OpCache
,OpCache
的加速原理是把编译后的bytecode
存储在内存里面, 避免重复编译 PHP 所造成的资源浪费.Ubuntu 14.04
默认自带 PHP 5.5.9
,已经集成了这个功能。但是默认是不启用的。
修改 php.ini 文件
在文件最后面加入:
重启服务器
加速效果极端明显,强烈建议启用这个功能。
Ubuntu14.04升级到Ubuntu16.04出现错误,如下图所示:
如果机器上安装了postgresql
,则是由于postgresql
处于升级黑名单中,因此无法升级。
一般建议手工卸载postgresql
。
卸载完成后继续执行升级命令
具体参考这个BUG的链接:
postgresql packages in the removal blacklist making it hard to upgrade
1.安装开发工具包
2.下载Apache 2.4.20
的源代码
3.安装apr
依赖库
4.安装pcre
库
5.解压缩代码
6.配置并编译
Ubuntu 14.04
系统上WordPress 4.5
升级到PHP7
之后执行插件升级报错,
如下图所示:
这个是由于PHP
升级之后,有些函数的支持出现了变化,导致调用失败。
目前已知的修复方法是修改wp-admin/includes/class-wp-filesystem-ssh2.php
中的如下的几个函数:
修改为:
在使用Ubuntu 14.04(64位)源码编译安装PHP7并配置Apache2支持之后,无法直接通过命令安装libssh2-php
,因此需要手工编译安装。
1.安装编译libssh2-php
需要的依赖库
2.下载libssh2-php
的源代码
3.解压缩文件
4.切换到目录
5.使用phpize
配置插件编译环境
6.配置编译环境
7.编译并安装
执行之后,文件被安装到了/opt/php-7.0.5/lib/php/extensions/no-debug-zts-20151012
目录下面。
8.配置php.ini
加载插件
找到如下内容
在最下面增加
9.重启Apache2
加载动态模块
调用glclear接口,发现它耗时比较长,翻了翻stackoverflow。
Measuring the elapsed time of an OpenGL API call is mostly meaningless.
研究OpenGL接口的耗时是无意义的。
The key aspect to understand is that OpenGL is an API to pass work to a GPU.
The easiest mental model (which largely corresponds to reality) is that when you make OpenGL API calls, you queue up work that will later be submitted to the GPU. For example, if you make a glDraw*()
call, picture the call building a work item that gets queued up, and at some point later will be submitted to the GPU for execution.
In other words, the API is highly asynchronous. The work you request by making API calls is not completed by the time the call returns. In most cases, it's not even submitted to the GPU for execution yet. It is only queued up, and will be submitted at some point later, mostly outside your control.
A consequence of this general approach is that the time you measure to make a glClear()
call has pretty much nothing to do with how long it takes to clear the framebuffer.
Now that we established how the OpenGL API is asynchronous, the next concept to understand is that a certain level of synchronization is necessary.
Let's look at a workload where the overall throughput is limited by the GPU (either by GPU performance, or because the frame rate is capped by the display refresh). If we kept the whole system entirely asynchronous, and the CPU can produce GPU commands faster than the GPU can process them, we would be queuing up a gradually increasing amount of work. This is undesirable for a couple of reasons:
To avoid this, drivers use throttling mechanisms to prevent the CPU from getting too far ahead. The details of how exactly this is handled can be fairly complex. But as a simple model, it might be something like blocking the CPU when it gets more than 1-2 frames ahead of what the GPU has finished rendering. Ideally, you always want some work queued up so that the GPU never goes idle for graphics limited apps, but you want to keep the amount of queued up work as small as possible to minimize memory usage and latency.
With all this background information explained, your measurements should be much less surprising. By far the most likely scenario is that your glClear()
call triggers a synchronization, and the time you measure is the time it takes the GPU to catch up sufficiently, until it makes sense to submit more work.
Note that this does not mean that all the previously submitted work needs to complete. Let's look at a sequence that is somewhat hypothetical, but realistic enough to illustrate what can happen:
glClear()
call that forms the start of rendering frame n
.n - 3
is on the display, and the GPU is busy processing rendering commands for frame n - 2
.glClear()
call until the GPU finished the rendering commands for frame n - 2
.n - 2
is shown on the display, which means waiting for the next beam sync.n - 2
is on the display, the buffer that previously contained frame n - 3
is not used anymore. It is now ready to be used for frame n
, which means that the glClear()
command for frame n
can now be submitted.Note that while your glClear()
call did all kinds of waiting in this scenario, which you measure as part of the elapsed time spent in the API call, none of this time was used for actually clearing the framebuffer for your frame. You were probably just sitting on some kind of semaphore (or similar synchronization mechanism), waiting for the GPU to complete previously submitted work.
Considering that your measurement is not directly helpful after all, what can you learn from it? Unfortunately not a whole lot.
If you do observe that your frame rate does not meet your target, e.g. because you observe stuttering, or even better because you measure the framerate over a certain time period, the only thing you know for sure is that your rendering is too slow. Going into the details of performance analysis is a topic that is much too big for this format. Just to give you a rough overview of steps you could take:
OpenGL是GPU的API
API call是以eventloop的形式工作
但需要一定的同步工作,任务数量太多,延迟会变大,开发者又需要尽快响应用户,GPU需要跟CPU保持一定过得同步。简单的来说,如果CPU发出的绘制指令超出GPU太多(1-2帧),GPU会锁住CPU。
在这个背景下,就可以解释为什么glClear耗时了,因为它触发了一次同步。
已3个缓冲区为例,n-3在绘制,n-2在合成,The driver decides that you really should not be getting more than 2 frames ahead。glClear就会block住,直到GPU工作完。
GPU工作渲染完n-2,glClear就会提交n。
最终结论,绘制太慢导致的。
可以看看CPU消耗,看看是不是CPU被锁住了。
安装libxml2-dev
安装gcc
安装依赖的库
安装apache2-dev
,否则无法指定--with-apxs2=/usr/bin/apxs
来生成libphp7.so
切换到编译目录
配置开启php-fpm
支持,开启多线程支持--enable-maintainer-zts
,否则无法使用Apache2
的Event MPM
功能。
php.ini
PHP7
已经默认加载opcache.so
了,因此不需要声明zend_extension=opcache.so
.
Apache2
的PHP7
模块Apache2
的Event
模块ubuntu 14.04上源码编译安装php7
How to install PHP 7 as PHP-FPM & FastCGI for ISPConfig 3 on Debian 8 (Jessie)
服务器已经根据Ubuntu 12.04下安装配置Worker工作模式的Apache 支持PHP设置成了Worker
模式,但是当系统从Ubuntu 12.04
升级到Ubuntu 14.04
导致Apache2
从2.2
升级到2.4.10
版本后,而MPM
模块被还原为prefork
模式,导致大量的Apache2
进程被创建出来,时间稍微一长,系统出现大量的OOM
记录,直到系统最后宕机。
Ubuntu 14.04
下查看所有可用的MPM
模块,命令如下:
查看当前正在使用的MPM
模块,命令如下:
可以看到,目前正在使用的模块就是prefork
模块。
使用apachectl -V | grep -i mpm
可以更加清晰的打印出当前使用的模块
注意,在Ubuntu 14.04
下执行apache2 -l
命令与Ubuntu 12.04
下面的输出结果是不同的,Ubuntu 14.04
下如果使用prefork
模块输出的信息如下:
默认情况下Ubuntu 14.04
中的PHP
默认是没有线程安全支持,如果使用mpm_event
支持的话,会提示如下信息:
1.重新安装系统升级过程中可能会被移除的PHP-FPM
模块
2.关闭Apache2
内建的PHP
支持,开启Apache2的FastCGI
,PHP5-FPM
支持
3.修改PHP5-FPM
的配置文件
找到
修改为:
注意,上面修改了四处地方,listen
,listen.owner
,listen.group
,listen.mode
。
注意,如果提示如下错误:
则说明listen.owner
,listen.group
,listen.mode
这三行没有打开。
4.重启PHP5-FPM
服务
5.切换Apache2
到Event-MPM
模式
6.启用Apache2
的cache
,expire
,gzip
模块,加强服务器性能
7.卸载libapache2-mod-php5
,否则每次这个模块更新之后,都会导致apache2
被自动切换到mpm_prefork
模式
8.调整配置文件
Apache 2.4.10
的配置文件如果按照Apache 2.2
的配置文件的话,是没办法启用PHP-FPM
的,Apache 2.4.10
版本使用SetHandler
的方式支持PHP-FPM
是改动最少的一种方式了。
找到
调整为如下:
同理,调整HTTPS
的配置文件。
9.重启Apache2
服务
这段时间貌似服务器经常被人攻击,由于服务器已经支持HTTPS登陆,而全站SSL加密又不是那么迫切,遂考虑后台SSL加密,强制HTTPS。
设置方法如下:
修改wp-config.php
在
之前(貌似放在后面也可以),加
就能使得后台强制加密了;
而加入一行
就可以使登录页面强制加密了。
最近在分析网站性能的时候,发现服务器返回了"X-Powered-By
"字段,这个字段中携带了PHP的版本号,系统的版本号。如下图:
而出于安全考虑,这两个信息是不应该被返回给客户端的。
Ubuntu 14.04
下服务器禁止返回"X-Powered-By
"的设置如下:
对于使用Apache2
内置PHP的服务器,则需要修改Apache2
对应目录下的配置文件
对于使用PHP-FPM
调度的服务器,则需要同时修改PHP-FPM
,FastCGI
对应目录下的配置文件
找到
把其中的expose_php = On
调整为:expose_php = Off
,调整后的结果如下:
接下来,重启Apache2
重启PHP-FPM
,如果配置了的话。
再次请求服务器后,发现"X-Powered-By
"已经不会再返回了。