Ускорение PHP | настройка Zend OPcache

2 комментария
php-logo

Для уменьшения потребления памяти PHP и ускорения его работы рекомендуется использовать различные акселераторы. Особенно это актуально для бюджетных VPS с небольшим количеством оперативной памяти на которых крутятся сайты на прожорливых CMS типа WordPress.

Zend OPcache — расширение для PHP, основное назначение которого — увеличение производительности интерпретатора при обработке сценариев путем кэширования их байт-кода.

В данной статье расскажу как установить Zend OPcache на Ubuntu Server 18.04.

Если вы используете PHP 5.5 и выше, то в нем по-умолчанию идет Zend OPcache и ничего дополнительно ставить не нужно.

Проверим ZendOpCache на Ubuntu Server

php -v

Вывод должен быть примерно такой:

PHP 7.3.9-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Sep  2 2019 12:54:24) ( NTS )
 Copyright (c) 1997-2018 The PHP Group
 Zend Engine v3.3.9, Copyright (c) 1998-2018 Zend Technologies
     with Zend OPcache v7.3.9-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

Настройка Zend OPcache

В сети много статей в которых описывается оптимальная настройка Zend OPcache. Почитав их, я решил объединить их в своей статье и найти золотую середину. На моем сервере установлен php 8.0 + nginx. И так, открываем файл конфигурации php. :

sudo nano /etc/php/8.0/fpm/php.ini 

Находим следующие строки и выставляем значения как у меня (хотя можете поэкспериментировать)

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.fast_shutdown=1
  • opcache.enable — включаем наш Zend OPcache.
  • opcache.enable_cli — включает OPcache в CLI-версии PHP.
  • opcache.memory_consumption — задает использование памяти для расширения (если ОЗУ позволяет, то можно увеличить значение).
  • opcache.interned_strings_buffer — задает объем памяти для хранения интернированных строк, в мегабайтах.
  • opcache.max_accelerated_files – максимальное количество скриптов в памяти (тут тоже можно увеличить, если памяти хватает).
  • opcache.revalidate_freq — это валидация кэша в секундах, в интернете все рекомендуют значение 60, я же использую 2, но иногда рекомендуют ставить 0 (ноль), то есть постоянно проверять на изменения. К примеру в Joomla OPcache кэширует все файлы и будет отдавать кэш после сохранения файлов еще то время, которое в этой строке. То есть вы сохранили файл, но все равно в течении указанного времени будете видеть старую копию из кеша. Поэтому не жалуйтесь, что файлы не сохраняются, подождите выставленное вами время.
  • opcache.fast_shutdown — определяет включено или выключено быстрое завершение последовательности ускоренного, кода, дает возможность использовать Zend Engine Memory Management

Перезапуск php

Чтобы изменения вступили в силу нужно перезапустить php:

/etc/init.d/php8.0-fpm restart 

или

sudo service php8.0-fpm restart

Скрипт для проверки opcache

Вот скрипт с githab. Создайте файл в корне вашего сайта, например так:

sudo touch /var/www/mysite.ru/opcache.php && sudo nano /var/www/mysite.ru/opcache.php

И вставьте вот этот код:

<?php
/*
OCP - Opcache Control Panel   (aka Zend Optimizer+ Control Panel for PHP)
Author: _ck_   (with contributions by GK, stasilok)
Version: 0.1.7
Free for any kind of use or modification, I am not responsible for anything, please share your improvements

* revision history
0.1.7  2015-09-01  regex fix for PHP7 phpinfo
0.1.6  2013-04-12  moved meta to footer so graphs can be higher and reduce clutter
0.1.5  2013-04-12  added graphs to visualize cache state, please report any browser/style bugs
0.1.4  2013-04-09  added "recheck" to update files when using large revalidate_freq (or validate_timestamps=Off)
0.1.3  2013-03-30  show host and php version, can bookmark with hashtag ie. #statistics - needs new layout asap
0.1.2  2013-03-25  show optimization levels, number formatting, support for start_time in 7.0.2
0.1.1  2013-03-18  today Zend completely renamed Optimizer+ to OPcache, adjusted OCP to keep working
0.1.0  2013-03-17  added group/sort indicators, replaced "accelerator_" functions with "opcache_"
0.0.6  2013-03-16  transition support as Zend renames product and functions for PHP 5.5 (stasilok)
0.0.5  2013-03-10  added refresh button (GK)
0.0.4  2013-02-18  added file grouping and sorting (click on headers) - code needs cleanup but gets the job done
0.0.2  2013-02-14  first public release

* known problems/limitations:
Unlike APC, the Zend OPcache API
 - cannot determine when a file was put into the cache
 - cannot change settings on the fly
 - cannot protect opcache functions by restricting execution to only specific scripts/paths

* todo:
Extract variables for prefered ordering and better layout instead of just dumping into tables
File list filter

*/

// ini_set('display_errors',1); error_reporting(-1);
if ( count(get_included_files())>1 || php_sapi_name()=='cli' || empty($_SERVER['REMOTE_ADDR']) ) { die; }  // weak block against indirect access

$time=time();
define('CACHEPREFIX',function_exists('opcache_reset')?'opcache_':(function_exists('accelerator_reset')?'accelerator_':''));

if ( !empty($_GET['RESET']) ) {	
	if ( function_exists(CACHEPREFIX.'reset') ) { call_user_func(CACHEPREFIX.'reset'); }
	header( 'Location: '.str_replace('?'.$_SERVER['QUERY_STRING'],'',$_SERVER['REQUEST_URI']) ); 
	exit;
}

if ( !empty($_GET['RECHECK']) ) {
	if ( function_exists(CACHEPREFIX.'invalidate') ) { 
		$recheck=trim($_GET['RECHECK']); $files=call_user_func(CACHEPREFIX.'get_status');
		if (!empty($files['scripts'])) { 
			foreach ($files['scripts'] as $file=>$value) { 
				if ( $recheck==='1' || strpos($file,$recheck)===0 )  call_user_func(CACHEPREFIX.'invalidate',$file); 
			} 
		}
		header( 'Location: '.str_replace('?'.$_SERVER['QUERY_STRING'],'',$_SERVER['REQUEST_URI']) ); 
	} else { echo 'Sorry, this feature requires Zend Opcache newer than April 8th 2013'; }
	exit;
}

?><!DOCTYPE html>
<html>
<head>
	<title>OCP - Opcache Control Panel</title>
	<meta name="ROBOTS" content="NOINDEX,NOFOLLOW,NOARCHIVE" />

<style type="text/css">
	body {background-color: #fff; color: #000;}
	body, td, th, h1, h2 {font-family: sans-serif;}
	pre {margin: 0px; font-family: monospace;}
	a:link,a:visited {color: #000099; text-decoration: none;}
	a:hover {text-decoration: underline;}
	table {border-collapse: collapse; width: 600px; }
	.center {text-align: center;}
	.center table { margin-left: auto; margin-right: auto; text-align: left;}
	.center th { text-align: center !important; }
	.middle {vertical-align:middle;}
	td, th { border: 1px solid #000; font-size: 75%; vertical-align: baseline; padding: 3px; } 
	h1 {font-size: 150%;}
	h2 {font-size: 125%;}
	.p {text-align: left;}
	.e {background-color: #ccccff; font-weight: bold; color: #000; width:50%; white-space:nowrap;}
	.h {background-color: #9999cc; font-weight: bold; color: #000;}
	.v {background-color: #cccccc; color: #000;}
	.vr {background-color: #cccccc; text-align: right; color: #000; white-space: nowrap;}
	.b {font-weight:bold;}
	.white, .white a {color:#fff;} 	
	img {float: right; border: 0px;}
	hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000;}
	.meta, .small {font-size: 75%; }
	.meta {margin: 2em 0;}
	.meta a, th a {padding: 10px; white-space:nowrap; }
	.buttons {margin:0 0 1em;}
	.buttons a {margin:0 15px; background-color: #9999cc; color:#fff; text-decoration:none; padding:1px; border:1px solid #000; display:inline-block; width:5em; text-align:center;}
	#files td.v a {font-weight:bold; color:#9999cc; margin:0 10px 0 5px; text-decoration:none; font-size:120%;}
	#files td.v a:hover {font-weight:bold; color:#ee0000;}
	.graph {display:inline-block; width:145px; margin:1em 0 1em 1px; border:0; vertical-align:top;}
	.graph table {width:100%; height:150px; border:0; padding:0; margin:5px 0 0 0; position:relative;}
	.graph td {vertical-align:middle; border:0; padding:0 0 0 5px;}
	.graph .bar {width:25px; text-align:right; padding:0 2px; color:#fff;}
	.graph .total {width:34px; text-align:center; padding:0 5px 0 0;}
	.graph .total div {border:1px dashed #888; border-right:0; height:99%; width:12px; position:absolute; bottom:0; left:17px; z-index:-1;}
	.graph .total span {background:#fff; font-weight:bold;}
	.graph .actual {text-align:right; font-weight:bold; padding:0 5px 0 0;} 
	.graph .red {background:#ee0000;}
	.graph .green {background:#00cc00;}
	.graph .brown {background:#8B4513;}
</style>
<!--[if lt IE 9]><script type="text/javascript" defer="defer">
window.onload=function(){var i,t=document.getElementsByTagName('table');for(i=0;i<t.length;i++){if(t[i].parentNode.className=='graph')t[i].style.height=150-(t[i].clientHeight-150)+'px';}}
</script><![endif]--> 
</head>

<body>
<div class="center">

<h1><a href="?">Opcache Control Panel</a></h1>

<div class="buttons">
	<a href="?ALL=1">Details</a>
	<a href="?FILES=1&GROUP=2&SORT=3">Files</a>
	<a href="?RESET=1" onclick="return confirm('RESET cache ?')">Reset</a>
	<?php if ( function_exists(CACHEPREFIX.'invalidate') ) { ?>
	<a href="?RECHECK=1" onclick="return confirm('Recheck all files in the cache ?')">Recheck</a>
	<?php } ?>
	<a href="?" onclick="window.location.reload(true); return false">Refresh</a>
</div>

<?php 

if ( !function_exists(CACHEPREFIX.'get_status') ) { echo '<h2>Opcache not detected?</h2>'; die; }

if ( !empty($_GET['FILES']) ) { echo '<h2>files cached</h2>'; files_display(); echo '</div></body></html>'; exit; }

if ( !(isset($_REQUEST['GRAPHS']) && !$_REQUEST['GRAPHS']) && CACHEPREFIX=='opcache_') { graphs_display(); if ( !empty($_REQUEST['GRAPHS']) ) { exit; } }

ob_start(); phpinfo(8); $phpinfo = ob_get_contents(); ob_end_clean(); 		 // some info is only available via phpinfo? sadly buffering capture has to be used
if ( !preg_match( '/module\_Zend.(Optimizer\+|OPcache).+?(\<table[^>]*\>.+?\<\/table\>).+?(\<table[^>]*\>.+?\<\/table\>)/is', $phpinfo, $opcache) ) { }  // todo

if ( function_exists(CACHEPREFIX.'get_configuration') ) { echo '<h2>general</h2>'; $configuration=call_user_func(CACHEPREFIX.'get_configuration'); }

$host=function_exists('gethostname')?@gethostname():@php_uname('n'); if (empty($host)) { $host=empty($_SERVER['SERVER_NAME'])?$_SERVER['HOST_NAME']:$_SERVER['SERVER_NAME']; }
$version=array('Host'=>$host);
$version['PHP Version']='PHP '.(defined('PHP_VERSION')?PHP_VERSION:'???').' '.(defined('PHP_SAPI')?PHP_SAPI:'').' '.(defined('PHP_OS')?' '.PHP_OS:'');
$version['Opcache Version']=empty($configuration['version']['version'])?'???':$configuration['version'][CACHEPREFIX.'product_name'].' '.$configuration['version']['version']; 
print_table($version);

if ( !empty($opcache[2]) ) { echo preg_replace('/\<tr\>\<td class\="e"\>[^>]+\<\/td\>\<td class\="v"\>[0-9\,\. ]+\<\/td\>\<\/tr\>/','',$opcache[2]); }

if ( function_exists(CACHEPREFIX.'get_status') && $status=call_user_func(CACHEPREFIX.'get_status') ) {
	$uptime=array();
	if ( !empty($status[CACHEPREFIX.'statistics']['start_time']) ) { 
		$uptime['uptime']=time_since($time,$status[CACHEPREFIX.'statistics']['start_time'],1,'');
	}
	if ( !empty($status[CACHEPREFIX.'statistics']['last_restart_time']) ) { 
		$uptime['last_restart']=time_since($time,$status[CACHEPREFIX.'statistics']['last_restart_time']); 		
	}
	if (!empty($uptime)) {print_table($uptime);}
	
	if ( !empty($status['cache_full']) ) { $status['memory_usage']['cache_full']=$status['cache_full']; }
	
	echo '<h2 id="memory">memory</h2>';
	print_table($status['memory_usage']);
	unset($status[CACHEPREFIX.'statistics']['start_time'],$status[CACHEPREFIX.'statistics']['last_restart_time']);
	echo '<h2 id="statistics">statistics</h2>';
	print_table($status[CACHEPREFIX.'statistics']);
}

if ( empty($_GET['ALL']) ) { meta_display(); exit; }
  
if ( !empty($configuration['blacklist']) ) { echo '<h2 id="blacklist">blacklist</h2>'; print_table($configuration['blacklist']); }

if ( !empty($opcache[3]) ) { echo '<h2 id="runtime">runtime</h2>'; echo $opcache[3]; }

$name='zend opcache'; $functions=get_extension_funcs($name); 
if (!$functions) { $name='zend optimizer+'; $functions=get_extension_funcs($name); }
if ($functions) { echo '<h2 id="functions">functions</h2>'; print_table($functions);  } else { $name=''; }

$level=trim(CACHEPREFIX,'_').'.optimization_level';
if (isset($configuration['directives'][$level])) {
	echo '<h2 id="optimization">optimization levels</h2>';		
	$levelset=strrev(base_convert($configuration['directives'][$level], 10, 2));
	$levels=array(
    	1=>'<a href="http://wikipedia.org/wiki/Common_subexpression_elimination">Constants subexpressions elimination</a> (CSE) true, false, null, etc.<br />Optimize series of ADD_STRING / ADD_CHAR<br />Convert CAST(IS_BOOL,x) into BOOL(x)<br />Convert <a href="http://www.php.net/manual/internals2.opcodes.init-fcall-by-name.php">INIT_FCALL_BY_NAME</a> + <a href="http://www.php.net/manual/internals2.opcodes.do-fcall-by-name.php">DO_FCALL_BY_NAME</a> into <a href="http://www.php.net/manual/internals2.opcodes.do-fcall.php">DO_FCALL</a>',
    	2=>'Convert constant operands to expected types<br />Convert conditional <a href="http://php.net/manual/internals2.opcodes.jmp.php">JMP</a>  with constant operands<br />Optimize static <a href="http://php.net/manual/internals2.opcodes.brk.php">BRK</a> and <a href="<a href="http://php.net/manual/internals2.opcodes.cont.php">CONT</a>',
    	3=>'Convert $a = $a + expr into $a += expr<br />Convert $a++ into ++$a<br />Optimize series of <a href="http://php.net/manual/internals2.opcodes.jmp.php">JMP</a>',
    	4=>'PRINT and ECHO optimization (<a href="https://github.com/zend-dev/ZendOptimizerPlus/issues/73">defunct</a>)',
	5=>'Block Optimization - most expensive pass<br />Performs many different optimization patterns based on <a href="http://wikipedia.org/wiki/Control_flow_graph">control flow graph</a> (CFG)',
	9=>'Optimize <a href="http://wikipedia.org/wiki/Register_allocation">register allocation</a> (allows re-usage of temporary variables)',
	10=>'Remove NOPs'
	);
	echo '<table width="600" border="0" cellpadding="3"><tbody><tr class="h"><th>Pass</th><th>Description</th></tr>';
	foreach ($levels as $pass=>$description) {
		$disabled=substr($levelset,$pass-1,1)!=='1' || $pass==4 ? ' white':'';
		echo '<tr><td class="v center middle'.$disabled.'">'.$pass.'</td><td class="v'.$disabled.'">'.$description.'</td></tr>';
	}
	echo '</table>';
}

if ( isset($_GET['DUMP']) ) { 
	if ($name) { echo '<h2 id="ini">ini</h2>'; print_table(ini_get_all($name,true)); } 
	foreach ($configuration as $key=>$value) { echo '<h2>',$key,'</h2>'; print_table($configuration[$key]); } 
	exit;
}

meta_display();

echo '</div></body></html>';

exit;

function time_since($time,$original,$extended=0,$text='ago') {	
	$time =  $time - $original; 
	$day = $extended? floor($time/86400) : round($time/86400,0); 
	$amount=0; $unit='';
	if ( $time < 86400) {
		if ( $time < 60)		{ $amount=$time; $unit='second'; }
		elseif ( $time < 3600) { $amount=floor($time/60); $unit='minute'; }
		else				{ $amount=floor($time/3600); $unit='hour'; }			
	} 
	elseif ( $day < 14) 	{ $amount=$day; $unit='day'; }
	elseif ( $day < 56) 	{ $amount=floor($day/7); $unit='week'; }
	elseif ( $day < 672) { $amount=floor($day/30); $unit='month'; }
	else {			  $amount=intval(2*($day/365))/2; $unit='year'; }
	
	if ( $amount!=1) {$unit.='s';}	
	if ($extended && $time>60) { $text=' and '.time_since($time,$time<86400?($time<3600?$amount*60:$amount*3600):$day*86400,0,'').$text; }
	
	return $amount.' '.$unit.' '.$text;
}

function print_table($array,$headers=false) {
	if ( empty($array) || !is_array($array) ) {return;} 
  	echo '<table border="0" cellpadding="3" width="600">';
  	if (!empty($headers)) {
  		if (!is_array($headers)) {$headers=array_keys(reset($array));}
  		echo '<tr class="h">';
  		foreach ($headers as $value) { echo '<th>',$value,'</th>'; }
  		echo '</tr>';  			
  	}
  	foreach ($array as $key=>$value) {
    		echo '<tr>';
    		if ( !is_numeric($key) ) { 
      			$key=ucwords(str_replace('_',' ',$key));
      			echo '<td class="e">',$key,'</td>'; 
      			if ( is_numeric($value) ) {
        				if ( $value>1048576) { $value=round($value/1048576,1).'M'; }
        				elseif ( is_float($value) ) { $value=round($value,1); }
      			}
    		}
    		if ( is_array($value) ) {
      			foreach ($value as $column) {
         			echo '<td class="v">',$column,'</td>';
      			}
      			echo '</tr>';
    		}
    		else { echo '<td class="v">',$value,'</td></tr>'; } 
	}
 	echo '</table>';
}

function files_display() {			
	$status=call_user_func(CACHEPREFIX.'get_status');
	if ( empty($status['scripts']) ) {return;}
	if ( isset($_GET['DUMP']) ) { print_table($status['scripts']); exit;}
    	$time=time(); $sort=0; 
	$nogroup=preg_replace('/\&?GROUP\=[\-0-9]+/','',$_SERVER['REQUEST_URI']);
	$nosort=preg_replace('/\&?SORT\=[\-0-9]+/','',$_SERVER['REQUEST_URI']);
	$group=empty($_GET['GROUP'])?0:intval($_GET['GROUP']); if ( $group<0 || $group>9) { $group=1;}
	$groupset=array_fill(0,9,''); $groupset[$group]=' class="b" ';
	
	echo '<div class="meta">	
		<a ',$groupset[0],'href="',$nogroup,'">ungroup</a> | 
		<a ',$groupset[1],'href="',$nogroup,'&GROUP=1">1</a> | 
		<a ',$groupset[2],'href="',$nogroup,'&GROUP=2">2</a> | 
		<a ',$groupset[3],'href="',$nogroup,'&GROUP=3">3</a> | 
		<a ',$groupset[4],'href="',$nogroup,'&GROUP=4">4</a> | 
		<a ',$groupset[5],'href="',$nogroup,'&GROUP=5">5</a> 
	</div>';
		
	if ( !$group ) { $files =& $status['scripts']; }
	else {		
		$files=array(); 
		foreach ($status['scripts'] as $data) { 
			if ( preg_match('@^[/]([^/]+[/]){'.$group.'}@',$data['full_path'],$path) ) { 
				if ( empty($files[$path[0]])) { $files[$path[0]]=array('full_path'=>'','files'=>0,'hits'=>0,'memory_consumption'=>0,'last_used_timestamp'=>'','timestamp'=>''); }
				$files[$path[0]]['full_path']=$path[0];
				$files[$path[0]]['files']++;
				$files[$path[0]]['memory_consumption']+=$data['memory_consumption'];						
				$files[$path[0]]['hits']+=$data['hits'];
				if ( $data['last_used_timestamp']>$files[$path[0]]['last_used_timestamp']) {$files[$path[0]]['last_used_timestamp']=$data['last_used_timestamp'];}
				if ( $data['timestamp']>$files[$path[0]]['timestamp']) {$files[$path[0]]['timestamp']=$data['timestamp'];}							
			}					
		}
	}
		
	if ( !empty($_GET['SORT']) ) {
		$keys=array(
			'full_path'=>SORT_STRING,
			'files'=>SORT_NUMERIC,
			'memory_consumption'=>SORT_NUMERIC,
			'hits'=>SORT_NUMERIC,
			'last_used_timestamp'=>SORT_NUMERIC,
			'timestamp'=>SORT_NUMERIC
		);
		$titles=array('','path',$group?'files':'','size','hits','last used','created');
		$offsets=array_keys($keys);
		$key=intval($_GET['SORT']);
		$direction=$key>0?1:-1;
		$key=abs($key)-1;
		$key=isset($offsets[$key])&&!($key==1&&empty($group))?$offsets[$key]:reset($offsets);
		$sort=array_search($key,$offsets)+1;
		$sortflip=range(0,7); $sortflip[$sort]=-$direction*$sort;
		if ( $keys[$key]==SORT_STRING) {$direction=-$direction; }
		$arrow=array_fill(0,7,''); $arrow[$sort]=$direction>0?' &#x25BC;':' &#x25B2;';
		$direction=$direction>0?SORT_DESC:SORT_ASC;
		$column=array(); foreach ($files as $data) { $column[]=$data[$key]; }
		array_multisort($column, $keys[$key], $direction, $files);
	}

	echo '<table border="0" cellpadding="3" width="960" id="files">
         		<tr class="h">';
         foreach ($titles as $column=>$title) {
         	if ($title) echo '<th><a href="',$nosort,'&SORT=',$sortflip[$column],'">',$title,$arrow[$column],'</a></th>';
         }
         echo '	</tr>';
    	foreach ($files as $data) {
    		echo '<tr>
    				<td class="v" nowrap><a title="recheck" href="?RECHECK=',rawurlencode($data['full_path']),'">x</a>',$data['full_path'],'</td>',
      				($group?'<td class="vr">'.number_format($data['files']).'</td>':''),
         			'<td class="vr">',number_format(round($data['memory_consumption']/1024)),'K</td>',
         			'<td class="vr">',number_format($data['hits']),'</td>',              					
         			'<td class="vr">',time_since($time,$data['last_used_timestamp']),'</td>',
         			'<td class="vr">',empty($data['timestamp'])?'':time_since($time,$data['timestamp']),'</td>
         		</tr>';
	}
	echo '</table>';
}

function graphs_display() {
	$graphs=array();
	$colors=array('green','brown','red');
	$primes=array(223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987);
	$configuration=call_user_func(CACHEPREFIX.'get_configuration'); 
	$status=call_user_func(CACHEPREFIX.'get_status');

	$graphs['memory']['total']=$configuration['directives']['opcache.memory_consumption'];
	$graphs['memory']['free']=$status['memory_usage']['free_memory'];
	$graphs['memory']['used']=$status['memory_usage']['used_memory'];
	$graphs['memory']['wasted']=$status['memory_usage']['wasted_memory'];

	$graphs['keys']['total']=$status[CACHEPREFIX.'statistics']['max_cached_keys'];	
	foreach ($primes as $prime) { if ($prime>=$graphs['keys']['total']) { $graphs['keys']['total']=$prime; break;} }
	$graphs['keys']['free']=$graphs['keys']['total']-$status[CACHEPREFIX.'statistics']['num_cached_keys'];
	$graphs['keys']['scripts']=$status[CACHEPREFIX.'statistics']['num_cached_scripts'];
	$graphs['keys']['wasted']=$status[CACHEPREFIX.'statistics']['num_cached_keys']-$status[CACHEPREFIX.'statistics']['num_cached_scripts'];

	$graphs['hits']['total']=0;
	$graphs['hits']['hits']=$status[CACHEPREFIX.'statistics']['hits'];
	$graphs['hits']['misses']=$status[CACHEPREFIX.'statistics']['misses'];
	$graphs['hits']['blacklist']=$status[CACHEPREFIX.'statistics']['blacklist_misses'];
	$graphs['hits']['total']=array_sum($graphs['hits']);

	$graphs['restarts']['total']=0;
	$graphs['restarts']['manual']=$status[CACHEPREFIX.'statistics']['manual_restarts'];
	$graphs['restarts']['keys']=$status[CACHEPREFIX.'statistics']['hash_restarts'];
	$graphs['restarts']['memory']=$status[CACHEPREFIX.'statistics']['oom_restarts'];
	$graphs['restarts']['total']=array_sum($graphs['restarts']);

	foreach ( $graphs as $caption=>$graph) {
	echo '<div class="graph"><div class="h">',$caption,'</div><table border="0" cellpadding="0" cellspacing="0">';	
	foreach ($graph as $label=>$value) {
		if ($label=='total') { $key=0; $total=$value; $totaldisplay='<td rowspan="3" class="total"><span>'.($total>999999?round($total/1024/1024).'M':($total>9999?round($total/1024).'K':$total)).'</span><div></div></td>'; continue;}
		$percent=$total?floor($value*100/$total):''; $percent=!$percent||$percent>99?'':$percent.'%';
		echo '<tr>',$totaldisplay,'<td class="actual">', ($value>999999?round($value/1024/1024).'M':($value>9999?round($value/1024).'K':$value)),'</td><td class="bar ',$colors[$key],'" height="',$percent,'">',$percent,'</td><td>',$label,'</td></tr>';
		$key++; $totaldisplay='';
	}
	echo '</table></div>',"\n";
	}
}

function meta_display() {
?>
<div class="meta">
	<a href="http://files.zend.com/help/Zend-Server-6/content/zendoptimizerplus.html">directives guide</a> | 
	<a href="http://files.zend.com/help/Zend-Server-6/content/zend_optimizer+_-_php_api.htm">functions guide</a> | 
	<a href="https://wiki.php.net/rfc/optimizerplus">wiki.php.net</a> |
	<a href="http://pecl.php.net/package/ZendOpcache">pecl</a> | 
	<a href="https://github.com/zend-dev/ZendOptimizerPlus/">Zend source</a> | 		
	<a href="https://gist.github.com/ck-on/4959032/?ocp.php">OCP latest</a>
</div>
<?php
}

Теперь нужно открыть в браузере данную страничку и лицезреть статистику:

https://mysite.ru/opcache.php

Ссылка на источник Opcache Control Panel

Изменение скорости работы сайта после установки акселератора PHP

Блог на WordPress, до настройке Zend OPcache, страница генерировалась за 0,37 сек., потребление памяти составляло 34 МБ.

После установки акселератора Zend OPcache скорость генерации страницы снизилась до 0,22 сек, потребление памяти при этом составило 30 МБ.

Комментарии излишни. Использование PHP акселератора положительно сказывается на скорости работы сайта и снижает потребление памяти.

Если есть вопросы, то пишем в комментариях.

Также можете вступить в Телеграм канал, ВК или подписаться на Twitter. Ссылки в шапки страницы.
Заранее всем спасибо!!!

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

[РЕШЕНО] В конфигурационном файле необходимо задать парольную фразу (blowfish_secret).
phpmyadmin-logo

Сегодня разберёмся с ошибкой в phpMyAdmin «В конфигурационном файле необходимо задать парольную фразу (blowfish_secret).»

Настраиваем HTTP заголовки WEB-сервера Nginx
nginx-logo

Сегодня в статье поговорим как Настроить HTTP заголовки WEB-сервера Nginx и обезопасить ваш сервер от различных атак.

Ошибка «PHP Startup: Unable to load dynamic library ‘xmlrpc.so’ «
php-logo

NextCloud на Ubuntu Server в журнале первого выходила постоянная Ошибка "PHP Startup: Unable to load dynamic library 'xmlrpc.so' "

Настраиваем LNMP на Ubuntu Server 18.04 | 19.04 | 20.04
lnmp

В сегодняшней статье рассмотрим базовую настройку LNMP(LEMP) (Linux Nginx MySQL PHP) на Ubuntu Server. В Качестве подопытного я использую VDS Читать

4 4 голоса
Рейтинг статьи

Подписаться
Уведомление о
guest

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

2 комментариев
новее
старее большинство голосов
Inline Feedbacks
Просмотреть все комментарии
Антон
Антон
16.12.2021 01:12

Первое. Меняем настройки php, а перезапускаем nginx. Он тут при чем? php-fpm надо перезапускать. Второе, «потребление памяти при этом составило 11 МБ». Ну после перезапуска nginx opcache тут даже не включился. Мы как минимум аллоцировали в opcache.interned_strings_buffer 128 мегайбайт памяти и оно по определению не может быть меньше в потреблении,… Подробнее »

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам:

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов cookie) с использованием трекеров "Google Analytics" и "Yandex.Metrics". Порядок обработки Ваших персональных данных, а также реализуемые требования к их защите, содержатся в Политике конфиденциальности.
Принять