PHP
Article

Appserver – Server Configuration, Dir Structure and Threads

By Scott Molinari

Mastering Appserver

In the first part of our Appserver series, we discussed the very high level differences of Appserver’s architecture to standard web server stacks and got you up and running with an Appserver instance. If you missed that part, please take the time to read it.

Appserver node diagram

In this part, we will be exploring the Appserver architecture a bit more in depth. We will go through the concepts of the different contexts and the parts of Appserver you get out of the box, which cover some of the ground most of the popular PHP frameworks offer. We will also configure the web server and look into an application’s structure. Once we are finished, you should have a fair understanding about Appserver’s contexts in relation to threading, the web server, and its setup.

In subsequent parts, we’ll continue to go over the servlet engine in more detail, the persistence container, beans, the messaging system and the timer module. (Note: as this series evolved, the direction also changed, in order to include more practical information to break up the dry theory.)

The Contexts and Threading

As we had discussed in the first part, in today’s standard web server scenario, you will have a web server and either a web server module (mod_php) or a php process manager (PHP-FPM), to serve the PHP scripts/applications. The web server and the PHP process manager or module both handle their own work and threading to serve either the web page or the PHP application.

Server module gif

In this same respect, Appserver also handles threading for the client developer. However, the usage of the threads is somewhat different. The contents built within a thread aren’t constantly built and destroyed during the time appserver is running. In other words, as long as the appserver is running, the code you have given it to run, will continue to run (stay in memory) for each request. This fundamental difference is being repeated, as it is very important for understanding everything else we’ll be diving into.

We went over threads in the last post. Now you might be asking, what is a context? The definition of a context in Appserver is “the runtime environment of a thread”. Thus, each thread has its own context. The advantage of a thread and its context, above a general process, is its ability to share its contents with other threads and still be “thread safe”. One can call this an advantage, but left uncontrolled, it can become a nightmare. So, in order to avoid the nightmare, Appserver controls sharing for you, and it is done through context or thread inheritance.

Appserver offers a number of standard contexts. Once Appserver is started and running, it will have constructed a hierarchy or tree of contexts, with the root context being the top level or parent context. From there, you will have the container context and below that the server context, were the web server resides. The web server builds worker contexts (the number of workers is configurable). It is the worker contexts which allow the parallel processing of requests, which are built and controlled within each worker.

Worker contexts

The child contexts can inherit instances, configuration values, constants, functions, class definitions and even comments from their parents in a selective way. The forming of contexts also allows for clear separation of concerns, where necessary. Though, please don’t confuse this inheritance with the usual OOP inheritance. It isn’t quite the same.

The sharing of data between contexts, and the fact the contexts aren’t destroyed with each request, is the capability within Appserver, which promises a boost in performance of an application specifically built for Appserver. Things like the results of the initialization of an application (bootstrapping), which is often considered one of the most costly processes in a PHP application, can now reside in memory. Also, work can be passed off to other contexts, so the application process doesn’t have to wait for the accomplishment of that work (asynchronous programming). These are some of the greater advantages given to a web developer using Appserver.

Before we get into the deep end of appserver’s modules and programming for them, we need to cover some of the programming concepts it uses.

Programming Concepts and Techniques within Appserver

Annotations

Annotations in use

One important and probably controversial technique used throughout Appserver is annotations. The core idea behind using annotations is “keep Appserver easy to configure” or rather, “keep Appserver easy to program for”. Annotations play a major role in programming within Appserver’s environment from routing, to declaring beans and setting up servlets.

Although annotations are a core part of appserver’s configuration system, it is still possible for the client developer to configure with XML files. In fact, practically everything that is annotated can also be set and even overridden through a web.xml file found in the application’s directory (/WEB-INF). So, for those who’d rather not have annotations peppered in the code, you can use the XML file to set things up.

AOP – Aspect Oriented Programming

Aspect oriented programming diagram

The fundamental programming paradigm used within Appserver is AOP or Aspect Oriented Programming. You aren’t locked into this, but it is a modern way of programming also followed by the likes of Laravel, probably the most popular PHP framework currently. Thus, this paradigm of OOP is well worth looking into. Understanding the meaning of cross-cutting concerns or aspects, weaving, and join points will help you understand some of the underpinnings behind the design and proper usage of Appserver.

Design by Contract

Design by contract is also followed within Appserver. This is handy, as it enforces stricter typing between all the modules. Appserver uses the commented type annotations for parameters and return values of methods (something standard in most IDEs) and uses them to enforce stricter typing. If typing is not properly followed during runtime, exceptions can be thrown. Exceptions, which you can also create yourself. It is also possible to log these exceptions. We’ll show an example of this later.

Now let’s go down into each of the modules available.

The Web Server

One of the main goals of Appserver is to offer a relatively easy to use, but enterprise ready web server stack for PHP developers. It does this by also offering a good bit of functionality found in most PHP frameworks, which form the basis for a more rapid PHP development environment. In fact, a “built in” web server is actually an important part missing from these frameworks.

The web server in Appserver is part of the server framework. It is a web server written purely in PHP. Yes! PHP! It also represents the main module of the server context of Appserver. Currently, connectivity to the web server is possible over HTTP 1.1. Support for HTTP 2.0 is planned for a future version, currently 1.3.0 or possibly 2.0.

A core functionality, which most of you probably recognize from most of the popular frameworks, comes from the web server in the form of the $request and $response objects. Since Appserver follows AOP, the objects will actually be called though an interface like HttpServletRequestInterface. We’ll get into using the request and response objects in our review of the example app installed with Appserver in the next part.

From the Appserver user’s or client developer’s perspective, the web server’s configuration and usage is similar to that of the Apache web server. Things like rewrites, virtual hosts, setting environment variables and HTTP authentication are all possible within the web server module.

The most important config files for the server context are under /etc/appserver. There, you will find the appserver.xml file for the server, web server and container settings and the /conf.d/virtual-hosts.xml files, where your virtual host definitions will be added. There is an example file already installed, which will help you set up a virtual host.

Let’s set up a virtual host in appserver’s webserver now.

Creating a Virtual Host

Hopefully you’ve followed the directions from the first part of this series and have Appserver running on your handy local VM. In the past blog post, we were using a Debian Wheezy VM. The installation should have set you up with the example app, which you can find under the URL http://my-app.com:9080/example. We’re going to set up Appserver to serve the example app under the URL http://my-app.com (my-app.com representing the name you’ve set up for the server, should it be different than what Bruno suggested in his article). This short process will give you a feel for setting up a virtual host.

Step 1 – Change the Port (One Time Change)

Not completely necessary, but still handy. We will get rid of the need to enter the port number :9080 with every URL. First, make sure no other web server is blocking port 80 by stopping the service, with something like:

service nginx stop

or

service apache2 stop

Then go to the /opt/appserver/etc/appserver directory and open appserver.xml. Search for the following lines.

<server 
    name="http"
    type="\AppserverIo\Server\Servers\MultiThreadedServer"

Below them, look for the port parameter.

<param name="port" type="integer">9080</param>

And change 9080 to 80.

Step 2 – Change/ Add the Virtual Host

Now go to the /conf.d directory and open the virtual-hosts.xml file. It should look like this.

<?xml version="1.0" encoding="UTF-8"?>
<!--
 ! The following is a basic showcase example for a virtual host configuration.
 ! Some more examples can be found at:
 !
 ! http://appserver.io/get-started/documentation/webserver.html#virtualhost-examples
 -->
<virtualHosts xmlns="http://www.appserver.io/appserver">
    <virtualHost name="example.local www.example.local">
        <params>
           <param name="admin" type="string">info@appserver.io</param>
           <param name="documentRoot" type="string">webapps/example</param>
        </params>
        <rewrites>
            <rewrite condition="-d{OR}-f{OR}-l" target="" flag="L" />
        </rewrites>
        <accesses>
            <access type="allow">
                <params>
                    <param name="X_REQUEST_URI" type="string">^.*
                    </param>
                </params>
            </access>
        </accesses>
        </virtualHost>
            <virtualHost name="dbadmin.awesome.dev">
                <params>
                    <param name="admin" type="string">info@appserver.io</param>
                    <param name="documentRoot" type="string">webapps/phpmyadmin</param>
                </params>
            <rewrites>
                <rewrite condition="-d{OR}-f{OR}-l" target="" flag="L" />   
            </rewrites>
        <accesses>
            <access type="allow">
                <params>
                    <param name="X_REQUEST_URI" type="string">^.*
                    </param>
                </params>
            </access>
        </accesses>
    </virtualHost>
</virtualHosts>

Important to note are the different areas of the file like, virtualHost, accesses and rewrites. These are the common configurations you’ll be dealing with per virtual host. Also notice the documentRoot parameter. This will now help us avoid adding the directory /example to the URL.

Change the virtualHost name to look like this.

 <virtualHost name="my-app.com www.my-app.com">

Again, my-app.com is the name you created with the Vagrant box. We are also adding www.my-app.com here too, as we are simulating a proper website with access to a www. sub-domain.

For these changes to take effect, you now need to restart Appserver.

service appserver restart

If you wanted to (and you should), you could add a rewrite rule, which will intercept any call to the www. subdomain and reroute it to the main domain or vice versa. We’ll go with the former, www. subdomain to the main domain. This follows a very important and fairly standard rule of SEO. The same content should never be accessible under different URLs!

To create this rule, under <rewites> add the following line below the rewrite condition already present.

<rewrite condition="^www\.@$HTTP_HOST" target="$REQUEST_SCHEME://my-app.com$X_REQUEST_URI" flag="R,L" />

This condition looks for any URL prefixed with www. and reroutes it to the target scheme, which is our main domain. Notice also, we can simply add the variable $X_REQUEST_URI, instead of a backreference. This saves a bit of computing for a regex. You can use any $_SERVER array values normally available from PHP in the rewrite rules. That is handy, isn’t it?

Check to see if you can now see the example app under your domain name. In our example, it will be under:

http://my-app.com

If all has gone well, you should see the example app.

Example app running

One last note, before we dig into servlets. Appserver also comes with its own PHP-FPM, currently 5.5.x running on port 9010. You can also run with your own FPM by changing the port in the appserver.xml file. Also, Appserver currently doesn’t start its FPM service automatically, so remember to also start it, should you need to run apps not directly built for Appserver (like WordPress). To start the service, in your shell console enter

service appserver-php5-fpm start

If you need to make any changes to Appserver’s PHP settings, you’ll also find the related .ini file under /opt/appserver/etc.

The Servlet Engine

If you can imagine the web server is the eyes, ears and mouth of Appserver, then the servlet engine is the temporal lobe of the brain. Those of you fond of Java may also recognize the similarities between Appserver’s servlets and Java servlets. In theory and practice, they are pretty much the same thing.

The Painful Bootstrap Process No Longer

One of the most costly processes all major frameworks or heavy duty web applications have with current PHP web server stacks is the bootstrapping process. This process is where configuration is read and the runtime environment is set up. Since this process must be done with each request, it is a source for performance loss and is often compensated for with some sort of caching scheme, which adds complexity to the application. With appserver, the bootstrapping process is done only once, at server start-up, so basically automatically cached. The bootstrapped code, like the servlets in the servlet engine, is held in memory, until appserver is stopped. This initialization portion of appserver is quite important and one of its major benefits.

Appserver File Structure

Before we go any further, we first need to understand the file and directory structure of an Appserver application. It is different than the normal file structure you might find in most PHP projects. The actual applications are found under the directory /webapps. In our Appserver installation, you should see the example app under the /example directory. Under this directory, you’ll find the following directory structure.

Example file structure

Here is a quick synopsis of the important directories in an Appserver application.

/WEB-INF – this directory holds the client facing PHP classes. You’ll notice in the example app there are both examples for servlets (which aren’t directly used in the app) and also “action” classes, which are used in the app. These classes form the controllers of the application.

/META-INF – this directory holds the code for the back-end services. This is where aspects and any entry code for the domain models should be held.

/common – This directory holds common classes shared between META-INF and WEB-INF classes.

/vendor – This directory holds any libraries you may have imported into your project with Composer. Appserver supports Composer and PSR-0 for class autoloading. PSR-4 isn’t supported, due to the custom directory structure required.

/static – This directory is home for all the static resources (i.e. JS, CSS and image files), which are necessary for the web application to render properly.

The above directories are the default directory structure. The structure can also be customized over an additional context.xml file in either META-INF or WEB-INF. If you do intend to break from the default structure, more information on doing so can be found in the appserver docs.

Important to Note – Communication between classes used within the servlet engine (WEB-INF) and the persistence container (META-INF) can be done with proxy objects. These objects can be communicated over a network, similar to remote method invocation in Java. This means it is possible to extrapolate these two layers into their own machines and have them run as services in an SOA based system. This ability to send objects across the network allows for asymmetrical scaling of Appservers, which is another one of its built in features.

Conclusion

We’ve covered contexts and threading in Appserver and how Appserver takes care of the “dirty work” for you with threading, by pre-building the necessary modules within contexts of threads. We’ve briefly covered the different programming tools and paradigms on offer, such as AOP or design by contract. We’ve gotten you up and running with Appserver’s web server, and explained how an app file structure should look like. We also dived into the configuration of the web server.

Phew!

And, we haven’t even scratched the surface of Appserver, really. It is a great platform and offers a new chance to build more powerful and easily scalable web applications in PHP.

In the following parts, we’ll be diving into the other modules offered out-of-the-box, like the servlet engine and the message queue.

As always, your great comments, critique and requests to cover any areas missed are highly welcomed!

Note: The above post was made with appserver version 1.0.6. The newest version, 1.1.0 was released just before this post was put into the publication process. We’ll make sure to cover the new features, as much as possible, in the next parts of this series.

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

  • michelle25

    my parents inlaw just got Nissan Pathfinder Hybrid by working part time online. you can find out more….

    ——>> payability.AT.CR

    qap

  • Mitch J.V.

    Quote: “In this same respect, Appserver also handles threading for the client developer. However, the usage of the threads is somewhat different. The contents built within a thread aren’t constantly built and destroyed during the time appserver is running.”

    Am I wrong in concluding that you are stating that “standard” web servers or standard way of serving PHP doesn’t operate in this way?

    • http://www.skooppa.com s.molinari

      Hmmm….

      Let’s put it another way. There is no (standard) way to handle objects or state between any two requests within a standard PHP web stack (i.e. Nginx or Apache and PHP-FPM). Handling objects and state across two requests is possible within appserver.

      Scott

      • Mitch J.V.

        But the wasn’t what I was referring to. I’ll use another sentence you wrote: “In other words, as long as the appserver is running, the code you have given it to run, will continue to run (stay in memory) for each request”. This implies that, for example, PHP-FPM doesn’t do that when the truth is – it does exactly that, and then some more.

        Now, you mentioned that Appserver will handle state of objects between two requests. That implies you can’t cluster it since maintaining state of an PHP construct means that each HTTP request has to hit the machine that has the construct in memory.

        Correct me if I’m wrong in thinking but – how is that something that’s desirable? That locks me into running a single instance of Appserver. With nginx and fpm I can have as many nginx servers as I want to, distributing requests to as many FPMs’ as I want to, giving me horizontal scalability to no end.

        Also, I noticed one other thing in the text you wrote: “This process is where configuration is read and the runtime environment is set up. Since this process must be done with each request, it is a source for performance loss and is often compensated for with some sort of caching scheme, which adds complexity to the application”.

        Now, if you take php-fpm, boot it up with strace and then hit it a few times with several requests, you will notice that fpm will happily read parsed opcode from cache – from what I read, future releases of PHP 7 might use JIT (in a much better way than HHVM) which will bring its execution speed really, really high up. It will also cache connections to services such as MySQL, therefore it won’t repeat the work you outlined on every request.

        I’m just surprised that I read a comparison of a php-only program that acts as a web and application server and it’s labelled as “enterprise ready” when we have tools such as nginx and php-fpm. What would be the reason for using this thing whatsoever? It just makes no sense, bundling an application into a web server is going back 20 years in technology. Coupling = bad. Decoupling = performance and fault tolerance. Given the fact it doesn’t even support http 2.0, I must wonder what’s the point to this? From the text I’ve read, I would gain exactly nothing if I swap out nginx / php7 stack for this one. I might be silly or considered rude, but why put effort into this kind of software instead of help nginx or even php guys to achieve performance?

        From economical POV, it’s unlikely this project will gain traction, especially with new nginx which supports http2.0 and upcoming PHP releases.

  • Mitch J.V.

    Hello Scott, thank you very much for your reply.

    I know I sounded negative and like one of those people who can’t wait to smear negativity over something that’s been carefully polished, but I can’t stop thinking about the use scenario for appserver.

    It simply doesn’t fit anywhere and the negative sides outweigh the potential benefits. I won’t get into the discussion about whether PHP is an enterprise ready language. The word “enterprise” has this bad ring to it in the first place. Any turing-complete language in the hands of a smart, non-egoistic programmer is a tool that can be used to build wonders.

    What I am interested in is – what do I actually gain if I use appserver instead of tools that I have at my disposal.

    It can’t cluster and its selling point is that it’s not destroying objects upon request being served – that’s not exactly that big of a deal, given the fact it’s a simple daemon which never exits, thus php never invokes it’s GC procedure – hence, objects are in memory and you need to target the specific thread holding that object in order to re-use it if you want to maintain the state. Given the fact that pthreads will load the entire environment and interpreter into a given thread, I don’t see what advantage multithreading offers here except for some resource sharing between those threads (and from what I’ve read, you can’t share everything – for example, MySQL connections).

    And then there’s this notion of threading – I know threading sounds great, but in this case threads represent the means of holding the connection, loading the interpreter and “keeping” the object(s) in memory until next request, there’s nothing being said about parallelism. For some reason, many developers forget that threading’s biggest advantage is the parallelism and in web environment – there’s rarely, if ever, need for parallel calculation in order to speed up a lengthy algorithmic process so threads are being used for silly things.

    Without the option to cluster, without the option for http2 and without the option to be 100% certain that server will resume work even if I produced a piece of code that brings a particular thread down (quite easy, just SELECT * from a huge table and fetch all, common mistake), I just don’t see the use.

    Sure, you can’t use PHP-FPM for message queuing, but you can use PHP-CLI for that and you can connect the two PHP SAPI’s via ZeroMQ or even plain, old sockets.

    I just don’t see this huge advantage that I gain by using appserver. Web server is used to serve HTTP traffic. PHP is used to perform server-side processing. Coupling the two sounds like a bad idea, due to the disadvantages it brings. That’s how I see it and I would like to be proven wrong, I really would.

    Until the advantage of using appserver is presented clearly, I don’t think it will gain a greater momentum. Mentioning threads, persistence containers or “inbuilt message queue” means nothing if it’s not instantly clear how that helps, in which scenario, where it fills the void that exists if one uses nginx + fpm and what potential for apps it creates.

    I’m apologizing once more for being negative, but these are the questions that anyone would ask and hopefully – you or the authors can help clear them up. Maybe the project gains momentum after that. Thank you once more for your time and good luck to the maintainers of this project.

    • http://www.skooppa.com s.molinari

      Thank Mitch. I can actually really appreciate this reply and the questions you raise.

      I can only let you in on my personal views and why I like the technology and what I see is in it, for me. I didn’t want to add that in the articles, because nobody really cares about me. LOL! But, I’ll explain my views to you. Maybe you can tell me I am wrong or my thinking isn’t quite right or maybe I might open your eyes a bit. Who knows. I am still searching for the right answers too.

      Currently in PHP, we have what I consider a “closed world application” view in development and usage. What I mean by this is, we don’t look past getting a basic application working and only for one business and only for one set of users. Even Facebook is built like this, if you think about it.

      Now think of an application world, which allows multiple user bases and multiple businesses, sharing code bases too. This is what I consider true multi-tenancy PaaS within cloud computing. Multi-tenancy, in this form, can only happen, when resources, like dev platforms, code and infrastructure, are (wisely) shared.

      Although cloud computing infrastructure allows the breaking up of resources down to a certain level, a user of this infrastructure always ends up with a bit of overkill, mainly when it comes to computing.

      In fact, most hosting companies take advantage of their customers, because they always “overload” servers in the hope that the tenants, their customers, will never really be using the system as their web space packages have promised. You can also see a lot of hosters moving away from this scenario too (because it is actually dishonest, to a degree), and moving more towards cloud infrastructure and actually giving their customers their own personal virtual servers, which is the better solution, but still not perfect. For instance, the customer is often left to scale the infrastructure on their own, if they need to.

      Also, going even deeper into these shared or even virtual web server scenarios, you have a whole lot of wasted resources, because the tenants are possibly copying a lot of the same code and doing a lot of the same things. Think of 20 tenants in a virtualized group of servers all using WordPress to make a website.

      Now imagine they are all on a different server, an appserver, yet the basic WordPress code base, or rather the objects that make it run, are shared between all the tenants. You could save a good bit of resources. In fact, think about this. Because the code base is the same for everyone, (and in the overall picture the underlying infrastructure is also completely controlled by you) you have a lot of simplification in your development. No exotic bugs to worry about, because a user loaded the software in some strange webspace with who knows what powering it. You don’t have to worry so much about BC. You can run with the most up-to-date infrastructure and the development of the software can be extremely accelerated, because there isn’t anything holding it back, like hosters, who are reluctant to upgrade because their users are still on old versions of the software. This simply isn’t a problem anymore. Technical debt is reduced extremely too.

      Theoretically, one could also just give every customer a copy of a base software and run it off of standard PHP stacks, but that would become a serious nightmare with anything at scale (like 1000s of customers) and it is still the old “closed world application” mentality, with its wasted resources. It is why also why this kind of software is still left up to the user to install on their own. That, in itself, is a ton of wasted effort.

      And, when it comes to troubleshooting such systems, the question of “what went wrong and where” is a lot harder to answer, even when the underlying environment is controlled.

      The last point I’d like to make is, appserver is completely PHP driven, but in that (albeit controversial) threaded nature. This offers a whole world of flexibility for PHP devs. And, the PHP developer community has to be one of the biggest, if not THE biggest in the world. The potential is huge.

      I also feel, no matter what technologies are brought to the PHP table, the fact there is even the choice strengthens the community overall, because it pushes the envelopes. Facebook being a great example.

      So yes. My overall perspective goes far beyond just one guy or gal using an appserver and wondering what it will do for him or her. It is the door to a new world of application development and usage. Maybe I am crazy, but this is the only platform that I can even imagine something like what I just described could even work.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.