Developer’s Corner: OpenLiteSpeed’s PHP Module
We’ve been working on a PHP module.
PHP, a server-side scripting language, was designed for web development but it does double duty as a general-purpose programming language. This makes it popular among internet developers who embed it into HTML code, or use it in web publishing frameworks and content management systems. PHP code is interpreted by either a web server module or a Common Gateway Interface (CGI) executable.
As a CGI executable, it’s familiar to most LiteSpeed users as lsphp, lsphp5 or lsphp7 (if there’s a specific version dependency). For Apache there are corresponding programs: mod_php and php-cgi.
Drawback of CGI Executables
LiteSpeed does a lot of work to make lsphp fast. Once loaded, it will be reused for the same connection for as many applications as want to use it. This allows the PHP opcache to be reused and the speed to thus increase.
Sounds good, but not ideal. Whenever an older connection times out and the process terminates or a new connection is started, a separate instance of lsphp is used and the opcache starts from scratch. In the future, there will be a CRIU (CheckPoint restore In Userspace) version of lsphp which will reload the opcache enabled code (and is CloudLinux aware), but that’s for a future article.
The Module Approach
Each time a separate instance is started, it causes performance lag. The module approach addresses this issue by loading in one instance for the entire server at server startup time. There are lots of reasons this is great:
- The amount of memory and CPU necessary to run each PHP process is reduced.
- The startup time to run a PHP process is reduced.
- The opcache is available to all, which should make the applications progressively faster as they get compiled into opcache.
But module usage also comes with some issues that are not necessarily easy to address:
- Because both Apache and LiteSpeed* are multi-threaded applications, PHP has to be able to operate multi-threaded. This has only been true since PHP 7.2 has been released (November 2017). There were PHP implementations that claimed to be thread-safe, but they were not and have been deprecated for thread use by the PHP team.
- Building mod_lsphp is quite a chore. It requires access to both OpenLiteSpeed module headers and a full PHP installation. The result of the compile is the entire PHP stack as a shared library. There are wiki instructions on how to do the build, but it can be tricky.
- The existing SAPI module is highly optimized, both by the LiteSpeed developers and the PHP developers. Mod_lsphp may actually not be faster than lsphp so you may want to benchmark it. If lsphp is faster, obviously you should stay with it.
- An errant module will crash the server. A PHP application can not. Mod_lsphp has been extensively tested, but it is possible. We recommend running mod_lsphp in isolation before putting it into full production.
The Solution for You
So why go through all of this trouble? The module may perform better on your server. And when the server is under a heavy load, it may perform even better. If your web site is PHP heavy and perhaps PHP bound, it’s really worth your while to go through whatever you can think of to improve its performance.
Perhaps do a bit of homework before starting the process:
- Make sure that your applications are compatible with PHP 7.2 or higher. This is a requirement.
- You can use system tools (like the top program, for example) to see which processes are the most expensive in CPU utilization during your load peaks. In particular look for lsphp high on the list.
- Verify that you’re not just simply low on memory. The free program can be helpful here. If a memory upgrade or an increase in swap space will address your problems you should start there.
If you find that PHP is your problem, then mod_lsphp may be the solution for you.
We should mention, this is a pioneering effort. We are still building this multi-threaded framework (more on that in a future article), and mod_lsphp is currently in beta. We encourage you to try it and share your feedback and any contributions you may have. Help us to make this module the best it can be!
* The latest version (1.5) of OpenLiteSpeed is now multi-threaded and exports a detailed and robust set of APIs, all of which are thread-aware. Note that this is threading internal to the web server – it’s not PHP threading. That is still unavailable for web applications and is likely to remain that way.