Wednesday, June 29, 2016

rumprun php7 experiment results

I forked rumprun-packages to build its php7 package with more features by default.  The original says it’s an “unmodified PHP 7.0.3” build, but it uses --disable-all to build with a minimal number of extensions by default, and that’s not really great for showing just what could work on rumprun.

I made a “mega” build which contains everything I can possibly include into it, including packaging up libjpeg-turbo and libpng so that this PHP can use gd.

I have been unable to get the memcached extension to work, though.  libmemcached-1.0 is written in C++ and depends on some exception-handling symbols.  PHP links with $(CC), which doesn’t include any C++ support.

I’d probably be more disappointed in this, except that I don’t know if rumprun PHP is all that useful.  Options are the single-threaded CLI HTTP server (not intended for production), or using ye olde php-cgi SAPI… which is also not a multithreaded option.  It expects to run single-threaded child processes under a FastCGI process manager.  (php-fpm simply integrates a process manager, so that you don’t need to find a separate one and integrate it; it’s also multi-process.)

And rumprun doesn’t have processes.  It’s a unikernel.

I don’t think there’s any threaded request manager I can put into the unikernel, and having one outside begs the question of why there’s a unikernel, instead of just processes on the request manager system.  Wouldn’t it be higher throughput and lower latency to skip going through a hypervisor for IPC?

I checked into ReactPHP’s http server, but it’s unstable and under-featured.  It doesn’t have gzip encoding, keep-alive, or PSR-7 messages yet.  Even if I could get this up and running, the classic PHP model wouldn’t work because I can’t redefine “a request’s global variables table” from userspace.  Everyone would get the same globals, that is, the globals of the server and its run-loop.

This could be made to work for a bespoke app that avoids globals and any PHP code that also uses globals like the plague, but it doesn’t really fit my goal of running, say, an unmodified Drupal unikernel.

I think that means the most effective unikernel setup for PHP would be… threaded apache2 with mod_php!  Apache would be configured with identical Min/Max/Spare threads, equaling ThreadsPerProcess, to create a single-process Apache with embedded PHP.  All the libraries would have to be thread-safe, but most libraries isolate their state into a “context” struct, allocated and destroyed on the heap through library functions, and don’t use process-global state.

(I remember a certain amount of FUD around threaded PHP ten years ago.  But nobody ever proved to me, now or since, that threaded PHP has any issues with any library whatsoever.)

Regardless, I don’t feel like building a threaded apache/php server, and even if I did, that would do nothing for the memcached problem.

No comments: