quinta-feira, 1 de julho de 2010

PHP, FCGID and Apache - a confusion of upload related limits

There is a number of web hosting situations where PHP applications appear to misbehave during large upload operations. This may happen, for example, when dealing with attachments via webmail clients like roundcube or during the upload of files to document management applications.

Things get more difficult if we are talking about shared hosting on an apache + mod_fcgid + php environment, as there are several different parameters to be tuned in order for large uploads to work.

As far as we could see, there's a lot of people hitting different limits in their applications and looking for solutions, but no handy summary of where to make the necessary changes.

Architecture recap

Traditionally the PHP interpreter ran inside the apache process. Apache would load the PHP library (mod_php.so) and use it to parse the PHP based pages. Using a wrapper for the execution of PHP opens new possibilities. This is how the mod_fcgid developers see their approach to the problem:

mod_fcgid is a high performance alternative to mod_cgi or mod_cgid, which starts a sufficient number instances of the CGI program to handle concurrent requests, and these programs remain running to handle further incoming requests. It is favored by the PHP developers, for example, as a preferred alternative to running mod_php in-process, delivering very similar performance.

Not going into lengthy performance discussions (performance is cheap these days) we see see security as the main reason for adopting a mod_fcgi based architecture. In fact, it can be combined with SuExec to have each apache virtual host executing PHP as a different user. This is truly a life saver in terms of preventing damage and analyzing evidence from hacking attempts.

A detailed howto can be found here. A very nice tool for web hosting that integrates Apache, PHP and SuExec on RHEL/CentOS can be found here.

Time related parameters

The following PHP variables are involved:

max_execution_time - This sets the maximum CPU time in seconds a script is allowed to run

max_input_time - This sets the maximum time in seconds a script is allowed to parse input data, like POST, GET and file uploads

These variables can be tuned on the vhost specific php.ini file, eg

/home/DOMAINNAME/etc/php/php.ini

The exact path to each php.ini depends on your system.

The following Apache and mod_fcgid variables are also involved and should be appropriately set in the vhost directive in httpd.conf:

Timeout - Apache variable that is used for several different things, including "the length of time to wait for output from a CGI script". This defaults do 300 seconds and is used at apache level regardless of how PHP or other scripts are configured.

IPCCommTimeout / FcgidIOTimeout - This is specific to mod_fcgid and does NOT override any other settings. The default is 40 seconds

Notes: FcgidIOTimeout replaces the initial IPCCommTimeout for the same purpose. See the definition here. There is a bug related to mod_fcgid 2.2.x explained here.

Thus, if, from the client upstream bandwidth and the file sizes to support, the expected upload time is up to 10 minutes, you should set on php.ini

max_input_time = 600

and on the corresponding vhost on httpd.conf

IPCCommTimeout 600
Timeout 600
For example, if the client wants to upload 50MB over an ADSL line with an announced upstream rate of 1Mbps, the upload time in ideal conditions would be:

t = ( 50 * 1024 * 1024 * 8 ) / (1 * 1000 * 1000 * 0.8 ) ~ 524.29 s

In the previous formula 0.8 roughly accounts for the ADSL overhead and it is assumed that traffic on the ADSL "neighborhood" is low enough not to interfere with this file transfer.

As for max_execution_time it is harder to estimate as it's CPU time (ie, only counts when the process is actually running, not waiting for I/O) but you can start using the default which is 30. Depending on the total server load this may or may not have to be changed.

Size related parameters

The following PHP variables are involved:

upload_max_filesize - The maximum size of an uploaded file via PHP (uses HTTP upload)

post_max_size - Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize.

memory_limit - the memory limit for individual PHP scripts

Thus, to support files up to, say, 50M you should set something like:

post_max_size = 51M
upload_max_filesize = 50M

The memory_limit value is harder to estimate as it depends on what the script does with the file. For example for roundcube there was a popular bug regarding the amount of memory consumed by attachments (see here) but generally applications aren't so demanding.

The PHP documentation recomends memory_limit larger than post_max_size, so as a rule of thumb starting with 16 + post_max_size (16M is the default PHP value) should be enough. However, we think the documentation is wrong / outdated. To run things tight one can perfectly start with the default value of 16M and see if anything fails. Examining error_log will make clear if the script runs out of memory:

[warn] mod_fcgid: stderr: PHP Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 4864 bytes)...

During our tests we realized that a simple file management web application could upload large files under the default PHP 16M memory_limit without any problems (tested on RHEL with php 5.1 - see similar comments here, here, and here).

Other parameters

The apache directive LimitRequestBody can also prevent large uploads. However, it defaults to 0 and is usually not present on httpd.cond, which means no limit is enforced by default.

References

max_execution_time
max_input_time
upload_max_filesize
post_max_size
memory_limit
Timeout (apache)
LimitRequestBody (apache)
FcgidIOTimeout (mod_fcgid)
PHP File Uploads
.

terça-feira, 29 de junho de 2010

Momento Zen

Momento Zen do dia, via Rui Gouveia. Com actores portugueses este filme teria um toque ainda mais realista.



.

quarta-feira, 14 de abril de 2010

Gente com fibra


Diz-se que a comunicação da malta das comunicações não é famosa. Pode ser verdade (ainda não foi desmentido) mas se calhar não é só isso que conta. Ao que se diz, toda a gente merece uma segunda oportunidade: "já que não é inteligente, ao menos seja bonita" ou "já que não sabe falar, que ao menos tenha bom aspecto". Será esse o caso? Este blog foi ver os enredos e concluiu que rolos maiores do que nas cabeças de helpdesk só mesmo no esparguete de fibra e cabos com que as telecomunicações de última geração adornam as melhores fachadas de Lisboa. E o resultado, naturalmente, não é bonito.

Segue-se uma mini reportagem fotográfica, no coração da capital.

Como destruir uma fachada cinquentista

Pormenor de execução


Ó fibra a quanto obrigas...


Pormenor de execução


Pormenor de execução


O verdadeiro "polvo" afinal era este


Nota: nunca esquecer o significado original da palavra "net"


A expressão de Engenheiro "reserved for future use" ganha aqui todo um novo significado


O verdadeiro cabo "co-axial"

quinta-feira, 18 de março de 2010

Comunicações em Português Suave - artigo de inverno

Na sequência do artigo de verão publicámos em parceria com o tek um novo artigo de opinião. Acompanha com tinto a 18ºC, queixo de cabra e (arrghhh) música de compasso de espera de call-center.

Votos de uma agradável leitura e um breve Inverno sem falhas de comunicação.

terça-feira, 2 de fevereiro de 2010

Firefox 3.6 na Caixa Mágica 12 e 14


Está disponível via Apt / Synaptic / Sofware Updater o Firefox 3.6 para a Caixa Mágica 12. Isto significa que os milhares de utilizadores das escolas (eescolas, Kit Tecnológico da Educação), individuais ou de empresas terão uma forma rápida e simples de fazer a actualização. Está igualmente disponível o Firefox 3.6 para Caixa Mágica 14 desde que o repositório das contribuições esteja activo (na CM14 o update oficial ainda é da série 3.0.0.x).

Como esta versão do Firefox representa um avanço considerável sobre as anteriores (performance, personas e estabilidade...) achamos o facto digno de menção.

upgrade via Synaptic na CM12

Firefox 3.6 com o tema Crystal Chrome


quarta-feira, 27 de janeiro de 2010

testing Gigabit Ethernet networks with Linux laptops

How useful is to contract the implementation of a Gigabit ethernet LAN if we are unable to test its performance? It is well known that performance on LANs is easily affected by bad cabling or connector problems. Besides that, acceptance tests are part of every engineer's life.

Whereas testing a 100Mbit LAN is somewhat of a trivial task, testing Gbe is a bit trickier since harddrive to memory transfers can't keep up with such rates. Fortunately, we can put it to test using two Linux laptops with Gbe network interfaces. The process involves creating a reasonably large ramdisk on each laptop (the default size is not enough) and tranferring information between ramdisks using netcat. One laptop should be connected directly to the switch and the other one will be connected to each wall plug.

Here's a brief recipe of how to perform the test.

Preparing ramdisks on both the sender and receiver

- boot with option on lilo or grub: ramdisk_size=5000000
- login as root and issue:
mknod -m 660 /dev/ram b 1 1
mkfs.ext2 /dev/ram
mount -t ext2 /dev/ram /mnt/ramdisk
cd /mnt/ramdisk

On the sender generate a random file with dd
dd if=/dev/urandom of=/mnt/ramdisk/file.bin bs=1k count=500k
(dd will stop if the ramdisk is smaller than needed and will output the created file size)

Prepare the receiver to accept the file via netcat
nc -lp 1234 >file.bin

On the sender side push the file and measure the transfer time
time cat file.bin | nc RECEIVER_IP 1234

The send+receive steps should be repeated a number of times for each wall plug to check for stability of the measured times. The file transfer rate is then computed easily as
file transfer rate [MB/s] = (FILE SIZE [MB] ) / AVERAGE TIME

The network transfer rate is obtained by taking into account the Ethernet + TCP/IP overhead introduced by netcat, which is around 5%
network transfer rate [Mbps] = [ (FILE SIZE [MB] * 8) / AVERAGE TIME ] / 0.95

In our tests a acheived an average transfer time of 4.5s and a network transfer rate of 934 Mbps.

segunda-feira, 18 de janeiro de 2010

Ser profissional é opcional

Talvez tenha reparado quem recebe por RSS os artigos deste blog que últimamente não tem cá aparecido muita coisa. O que se passa é que o tempo que habitualmente sobra para reflexões e partilha de ideias com a comunidade tem sido ultimamente consumido, perdão vorazmente canibalizado, por uma onda da mais gritante incompetência. Dir-se-ia que neste país ser profissional é opcional.

Vejamos... nos últimos dois meses já tivemos: comunicações interrompidas por causa da chuva (a infra-estrutura não está preparada porque só este inverno é que choveu), jogo do empurra-empurra entre um ISP e o operador incumbente com um problema de packet loss que aparentemente só o cliente é que tinha capacidade de monitorizar (demorou mês e meio a ser resolvido), uma linha ADSL + Voz em que a Voz está há dois meses com ruído extremo e o ISP não resolve, um equipamento que o ISP garantiu fornecer em bridged mas afinal não suportava bridged ao qual se seguiu um segundo equipamento que - esse sim - viria em bridged mas afinal também não vinha, um conjunto de novas impressoras iguais todas, excepto uma, a funcionar bem em que a marca não recebe a impressora defeituosa se o cliente não fizer alterações no firmware (!) e até o upgrade de um ERP a correr da pior maneira possível: tudo ficou lento após o upgrade e o fornecedor atirou as culpas precisamente para aquilo que não tinha mudado, ie, a rede e o servidor.

E o que é que faz uma equipa competente nestas situações? Tenta não perder a paciência. Tenta absorver todos estes impactos e almofadar o cliente, isolando-o da incapacidade generalizada que se instalou no nosso país e continua a "atrapalhar" impunemente tudo e todos. Tenta que o cliente consiga sobreviver o melhor possível. Mas com este (mau) ambiente de trabalho torna-se muito, muito mais, difícil manter os níveis de eficiência que os profissionais devem exigir de si mesmos. Este ambiente é o travão da inovação, um balde inteiro de areia vertido descaradamente sobre as melhores engrenagens.

É tentador para muitos atribuir isto à falta de meios e aos problemas económicos do país, etc, etc. Ora isso é a mais evidente falácia. O país tem excesso de meios tecnológicos e poder económico mais do que suficiente para olear a maioria dos serviços. A dura e politicamente incorrecta realidade é que o estado das coisas se deve aos seres humanos que desenham, participam e implementam os processos. Será que é por falta de CRMs (até os há Open Source..) que os ISPs só tratam dos assuntos por telefone? Será que é por falta de software de monitorização (também os há Open Source...) que não conseguem compreender problemas intermitentes? Será por falta de vergonha que um fabricante acha normal mandar um cliente fazer upgrades de firmware numa impressora avariada que custou algumas centenas de EUR?

Não há mais ninguém a culpar: são compatriotas nossos - portugueses - que originam e perpetuam este estado das coisas. Culpado, é quem contrata pessoas para funções alegadamente "simples" e não lhes dá formação. E quem é contratado e não quer aprender.

Mas a solução é simples: dar formação aos interessados e despedir os desinteressados. A quem não sabe trabalhar não se dê hipótese de atrapalhar.


.