Here's my presentation I gave June 9, 2008, at the Twin Cities MySQL and PHP User Group about my highly available cluster using DRBD and Heartbeat.
I added a few slides and cleaned things up a bit. The presentation went well and we had a lot of good questions.
The MySQL and PHP User Group will be taking some time off over the summer. There will be another meetup mid-summer to come up with some ideas for future meetings.
Apache has a neat module called mod_dbd that allows your Apache modules to connect to a database. mod_dbd interfaces with apr_dbd, an Apache Portable Runtime (APR) abstraction layer around database specific drivers.
Back when Ubuntu 7.04 (fiesty) was released, a MySQL driver was not bundled with Apache for licensing concerns. So, in order to use mod_dbd to connect to a MySQL database, you need to get the MySQL driver source code from WebThing (apr_dbd_mysql.c) and manually re-compile apr-utils.
You also need the source code for Apache 2.2.3 (which includes apr-utils 1.2.7) from the Ubuntu 7.04 repositories, then copy the apr_dbd_mysql.c file into the Apache source apr-utils/dbd directory. The Ubuntu guys made a nice INSTALL.MySQL file in the apr-utils with some basic instructions.
What they don't tell you is you need to install the MySQL source. To make matters worse, once you install it, the apr-utils 1.2.7 configure script can't find it, even if you tell it where it is.
<snip> configure: checking for mysql in /usr/src/mysql-dfsg-5.0-5.0.38/include checking mysql.h usability... no checking mysql.h presence... no checking for mysql.h... no <snip>
This apparently was a known issue and was fixed in apr-utils 1.2.8.
Starting with apr-utils 1.2.11, the MySQL driver is bundled with it. Unfortunately, even Ubuntu 7.10 (gutsy) still ships with apr-utils 1.2.7. So, you are forced to download the source and compile.
Or, you can wait a couple days and Ubuntu 8.04 (hardy) which has Apache 2.2.8 and apr-utils 1.2.11. In theory the MySQL driver will work out of the box.
As for me, I'll be compiling Apache, PHP, MySQL, memcached, and <insert essential infrastructure software> from source like I should have done in the beginning.
The Apache HTTP Web Server is a powerful and extensible web server that is the "A" in "LAMP". One of the neat things about Apache is its API for writing custom modules.
Nick Kew wrote an excellent book called The Apache Modules Book. Anyone who is serious about Apache module development must buy this book.
Modules can be written a number of ways, but the most common way is to use the C programming language. For an C/C++ development IDE, I use KDevelop. It is pretty easy to use once you figure out what you need to do.
It is possible to write modules in C++, but I don't recommend it if your module's source can't be contained in a single source file. There's all sorts of interesting issues with exported symbols and static function declarations. Another reason to stick with C is pretty much all core modules and examples are written using C. You may give it a try and determine that it works just fine for your project.
Before you begin, there is a handful of applications and libraries you must have installed:
Launch KDevelop and select "New Project" from the Project menu. Since we are focusing on using C, select "Simple Hello world program" under the "C" folder. Give your module an "Application name" and specify the location to create the project.

On the next page of the wizard, you must enter your name, but your email address is not required.

The next couple wizard screens ask about version control and source templates. After finishing the wizard, you will be back at the IDE with the new project created.

Delete all of the source code that the editor created. Next paste the following code which originated from Nick's version on The Apache Modules Book Companion site.
#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>
static int helloworld_handler(request_rec* r)
{
if (!r->handler || strcmp(r->handler, "helloworld"))
return DECLINED;
if (r->method_number != M_GET)
return HTTP_METHOD_NOT_ALLOWED;
ap_set_content_type(r, "text/html;charset=ascii");
ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n", r);
ap_rputs("<html><head><title>Hello World!</title></head>", r);
ap_rputs("<body><h1>Hello World!</h1></body></html>", r);
return OK;
}
static void register_hooks(apr_pool_t* pool)
{
ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks
};
Next we need to reconfigure the build target to create a library instead of a normal program. Right-click the build target and click "Remove":

When the dialog displays, uncheck the "Also remove from disk" option before clicking "OK". Now we need to add a new build target. Right-click the "src" folder and select "Add Target":

From the "Add Target" dialog, change the type to "Libtool Library" and enter the name of the module. Also check the "-avoid-version" and "-module" options.

As soon as the target is created, right-click on it and make sure the checked options saved properly. Right-click on the target again and select "Make Target Active":

Edit the project's options by right-clicking the "src" folder and selecting "Options":

Since this is a C project, we want to add the following options to the "CFLAGS" field:
-DLINUX=2 -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -D_REENTRANT -pthread

From the "Includes" tab, add the following outside include directories:

Reorder the include paths so that "$(all_includes)" is first. Due to a bug or poor design, you must edit the two paths you just added and prepend a "-I":


Since we deleted the old build target, we need to add the source files to the target by right-clicking the target and selecting "Add Existing Files":

From the dialog, drag and drop the files you want to be apart of the target. For this simple example, we only move the "mod_helloworld.c" file.

We are all set to compile the project. From the "Build" menu, select "Build Active Target":

If this is the first time you are performing the build, KDevelop will prompt you whether or not you want to run automake. Click the "Run Them" button to continue.

When the build is finished, the "Messages" panel will show up and display the build results. If everything went as planned, the output will say the build was successful.

The build process put the shared library file in the following location (assuming debug build):
/path/to/mod_helloworld/debug/src/.libs/libmod_helloworld
We need to install that file in the Apache modules directory which on Ubuntu is:
/usr/lib/apache2/modules
From a terminal, run the following command as root or sudo:
cp /path/to/mod_helloworld/debug/src/.libs/libmod_helloworld \
/usr/lib/apache2/modules/mod_helloworld.soNext you'll need to edit the Apache configuration file. In Ubuntu, the file is located at:
/etc/apache2/apache2.conf
You need to add the LoadModule and <Location> directives so Apache knows when to invoke the module.
LoadModule helloworld_module /usr/lib/apache2/modules/mod_helloworld.so
<Location /helloworld>
SetHandler helloworld
</Location>I've had spotty luck where to actually insert those settings. After the LogLevel, but before any other LoadModule entries seems to work for me. After you save the changes, restart Apache using the following command as root or sudo:
apache2ctl restart
If your Apache acts funny, try restarting it again.
The last step is to test the module. Open up your favorite web browser and hit http://localhost/helloworld:

If everything worked, you should see something similar to the image above.
We have only scratched the surface. The Apache Portable Runtime (APR) provides a ton of functionality that makes developing modules much easier. The Apache Modules Book dives into several topics such as configuration settings, content generators, filters, and database connectivity.
Another great resource is Apache's own module source code in their Subversion repository: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/.
Recent comments
2 weeks 4 days ago
5 weeks 1 day ago
6 weeks 5 days ago
6 weeks 6 days ago
7 weeks 6 days ago
9 weeks 6 days ago
9 weeks 6 days ago
10 weeks 1 day ago
10 weeks 5 days ago
10 weeks 5 days ago