Otimizando aplicações php com opcache.

O que é o Opcache?

O OpCache aumenta a performance de execução de código php (> 5.5) guardando um cache compartilhado em memória do código pré-compilado a partir dos scripts da aplicação.

Uma das soluções de métricas que tenho utilizado é o new relic (também pode usar o xdebug + kCachegrind em dev, mas o xdebug deixa o tempo de resposta mais lento). Com base no agente do new relic, tenho acesso ao tempo de resposta das máquinas sem considerar a latência da rede.

Após colocarmos em produção uma loja com magento2 em uma aws c4.2xlarge, com php7, efetuei a configuração do OpCache.

zend_extension=opcache.so
opcache.enable=1
opcache.validate_timestamps=0
opcache.max_accelerated_files=65406
opcache.memory_consumption=256

opcache.interned_strings_buffer=12
opcache.fast_shutdown=1
opcache.enable_file_override=1
opcache.error_log=/var/log/php-opcache-error.log

Basicamente, temos:

enable: Ativa o OpCache.
validate_timestamps: Esta definição informa se o php deve ficar reavaliando se o arquivo do script foi atualizado, deve ser ativado apenas em produção. Ao realizar novos deploys, é necessário reiniciar o webserver(nginx ou apache). Do contrário o OpCache vai ignorar as alterações de arquivos.
max_accelerated_files: A quantidade de arquivos que o OpCache deve guardar em memória, deve-se tomar cuidado, calcula-se a quantidade de arquivos, incluindo seus vendor packages. 
memory_consumption: A quantidade de memória disponível que o OpCache poderá alocar para guardar os arquivos em memória.
interned_strings_buffer: A quantidade de memória que o OpCache utilizará para bufferizar strings.sua
enable_file_override: Se o opcache não deve validar a existência do arquivo origem do script cacheado.
fast_shutdown: Permite a zend engine memory manager gerenciar a opcache.max_accelerated_files=3000alocação de variáveis da requisição.
error_log: Um arquivo de log para erros oriundos da utilização do OpCache.

Resultado:

De praticamente 500ms passou para algo em torno de 150ms. As condições de troughput eram em torno de 50–60 requests por minuto da home da loja.

Além do magento2, ajustei outra api construída com o microframework silex, rodando também em php7 (fpm). As configurações mudam pouco, muito menos arquivos e memória para alocar.

zend_extension=opcache.so
opcache.enable=1
opcache.validate_timestamps=0
opcache.max_accelerated_files=3000
opcache.memory_consumption=64

opcache.interned_strings_buffer=12
opcache.fast_shutdown=1
opcache.enable_file_override=1
opcache.error_log=/var/log/php-opcache-error.log

Este foi o resultado:

De ~125ms passou para ~25ms em uma aws m3.medium (sem considerar os picos do banco de dados em amarelo). O endpoint estático de checagem da saúde da api responde em 8ms depois da configuração (antes respondia em ~28ms).

Resumo: Fácil de configurar, fácil de ver resultados logo após a configuração, só alegria.

Referências:

Opcache: http://php.net/manual/en/book.opcache.php

Definições de configuração completas do OpCache: http://php.net/manual/en/opcache.configuration.php