Years ago I discovered a very comfortable way of uploading PHP files after editing them, a VBScript named “vbsFTP”. Copied into the “SendTo” folder and updated with some connection information, any file inside the base location on my harddisc could be uploaded to the corresponding remote location with just two clicks whilre preserving the local directory structure (C:\MyLocalHtdocs\a\b\c.php -> /var/www/htdocs/a/b/c.php).

However, this script is using the FTP protocol and ftp.exe integrated into Windows, so that I’m very sure, security comes short.

While installing new servers the last few days, I decided to doom the FTP servers from our brand new debian boxes and came up with my own VBScript that is using PSCP.exe (file copy over SSH, capable of private key authentication) from the Putty package instead:

Installation instructions:

  1. Get the script (and PSCP if you do not have it yet)
  2. Save the script to “C:\Documents\YourWindowsLoginName\SendTo” (XP) or “C:\Users\UserWindowsLoginName\AppData\Roaming\Microsoft\Windows\SendTo” (Vista)
  3. Open it, edit the configuration section at the beginning and save
  4. Make sure the local and the remote directory exist, then switch to the local directory, create or select a file, click right and select “Upload”.

That’s it! The file will be silently uploaded in the background. For creating directories you will still need to do so in the old fashioned way or you add the “-r” parameter in front of “-i” or “-pw” - but I’d not recommend that (may take a long time when accidentally clicking on a big directory). Of course you can install several copies of the script at once.

Happy coding!

Added Varnish, just works.

October 17th, 2008

Till today I used Lighttpd to distribute the load to multiple FastCGI backends. This worked “ok” until now but I’m really impressed about the performance gained by adding Varnish 2.0 (a high performance HTTP reverse proxy) in front of the web cluster. Additionally this is much easier than always fixing the FastCGI stuff when it is broken again.

However, Varnish 2.0 was released just 2 days ago, so there are still some issues. It seems that the random director (directors are used to distribute the load to multiple backend webservers) is broken currently but round-robin is working fine and should last for a while. As a workaround for using the random .weight option you can just add a backend more than once to the round-robin director.

There was also a problem with the varnishstat Munin plugin at Munin Exchange, so I uploaded a fixed version here and also added some installation instructions.

Do you wonder why Varnish seems not to cache anything?

For me (in fact I think for most people) the default varnish configuration is a bit too restrictive when it comes to cookies. All requests that contain a “Cookie” request header will not be cached - never.  As soon as a cookie is set by the site, also all static files like images, scripts and styles will no longer be cached cause the cookie is sent along with every client request, even to static files. In most situations (for almost every site that requires a login or uses adsense or similar and sets a cookie) this will render Varnish absolutely useless. A better approach is to let the dynamic pages always set a cookie, so that a “Set-Cookie” response header is created every time. Varnish also will not cache when a “Set-Cookie” response header is present so we don’t need to care about the “Cookie” request header anymore. Knowing this, all we need to do is make Varnish ignore the cookies for static files - and this is easy:

# in vcl_recv
if (req.url ~ “\.(png|gif|jpg|swf|css|js)$”) {
unset req.http.Cookie;
}

This should work for 99% of all somewhat modern websites where users can log in. Because of this I think the documentation should mention this more clearly. Also don’t forget to set etag.use-inode = “disable” in lighttpd.conf to sync the ETags when using multiple backend servers. Anyhow, Varnish is great, so have fun! :)

Not long ago, Sun released a bundled package of their “Sun Java System Application Server” (Glassfish) and MySQL. I took this as the reason to try out PHP on Glassfish with enabled MySQL support. The initial installation was quite simple but there were some problems with documentation about the usage of MySQL. For those of you who already have a MySQL server running and just want ot test your application on Glassfish, the installation basically is:

  1. Download Glassfish/MySQL Bundle
    Or if you already have glassfish, add the Mysql Connector/J (the jar from the archive) to GLASSFISH/lib
  2. Download Quercus (most recent) and unpack the following files from the archives:
    quercus.jar
    resin-util.jar           to       GLASSFISH/domains/domain1/lib
    script-10.jar
  3. Add the following to GLASSFISH/domains/domain1/config/default-web.xml:
      <servlet>
        <servlet-name>Quercus Servlet</servlet-name>
        <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
        <init-param>
          <param-name>script-encoding</param-name>
          <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
          <param-name>database</param-name>
          <param-value>ExampleMySQL</param-value><!– See below –>
        </init-param>
      </servlet>
      <servlet-mapping>
        <servlet-name>Quercus Servlet</servlet-name>
        <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
        <url-pattern>*.php</url-pattern>
        <init>
          <!– <php-ini>
            <sendmail_from>my_email_address</sendmail_from>
            <smtp_username>my_email_username</smtp_username>
            <smtp_password>my_email_password</smtp_password>
          </php-ini> –>
        </init>
      </servlet-mapping>
  4. Launch Glassfish and log in to the administration interface (by default: http://localhost:4848)
    Howto: Glassfish Quickstart Quide
  5. On Resources / JDBC / … in the administration interface add a new connection pool of type MySQL and set User/Password/Port/URI etc. in its properties (look through them when creating and don’t leave them blank). When done, “ping” (the button) your MySQL server from the connection pool view to test if it worked.
    Also add a new “JDBC Resource” that links to the pool and give it a name, in this case ExampleMySQL.
  6. Add a PHP file of your choice to GLASSFISH/domains/domain1/docroot and maybe restart Glassfish once to be sure the database changes are live.
  7. Run your MySQL-enabled PHP script (e.g. http://localhost:8080/index.php).

That’s basically everything. It took me some time to find out about the correct MySQL configuration (it seems that other tutorials I discovered at Google are quite outdated). Now, go and have fun!

Errrm: There are also enterprise clustering features implemented into Glassfish. I am wondering if this can scale a huge PHP site as well as lighttpd/php-fcgi. If anyone knows more details about this, please let me know. And mh: Just a thought: What about Glassfish + Quercus + MySQL + GridGain to scale at least the Webserver part into new dimensions? ;-)