Wednesday, January 18, 2012

Deploy Java Web application on the fly on JBoss AS in Eclipse

Introduction


To improve the productivity of development, you can take advantage of the auto deployment in JBoss AS. You can check your work immediately after code changes.

In this article, I will demonstrate how to configure the JBoss AS 7.1 for the auto deployment. Since JBoss AS 7.0 release, the server architecture has been changed, including deployment configuration and location. So the following steps won't work on the previous major versions.

JBoss has two types of servers, standalone and domain. In this article, I will use the standalone server as an example.

Standalone Server


In the standalone server, the configuration file is in standalone/configuration/standalone.xml. The application will be deployed to standalone/deployements folder. The JBoss will create a folder called YourApplicationName.war for a Java Dynamic Web application.

To understand the above structure is important as the configuration is changed based on that theory.

Configuration Change


I assume you have already created a JBoss 7.1 server in Eclipse. If you don't know how to do so, please check the JBoss Eclipse Plugin section at the end of this article.

Before going into the configuration change, you need to change your WebContent folder to YourApplicationName.war, ie. helloWorldApp.war (helloWorldApp is the project name).

Now expand your JBoss server in the Server tab in eclipse, you will see XML Configuration, expand that, you will see JBoss Management. Double click "JBoss Management", it will open the configuraiton file standalone.xml which is copied from the main one in the JBoss installation directory.

Then search for deployment-scanner XML tag in the standalone.xml file. You will see the default deployment path in the path attribute and its relative parent directory in relative-to attribute. Now do the following:
*Change the path to your absolute project path, ie: c:/workspace/helloWorldApp.
*Remove relative-to attritute and its value.
*Add attribute auto-deploy-exploded="true".

After the above change, it should look like the following configuration.
<subsystem xmlns="urn:jboss:domain:deployment-scanner:1.0" >
deployment-scanner name="default" path="c:\workspaces\helloWorldApp" scan-enabled="true" scan-interval="5000" auto-deploy-exploded="true" deployment-timeout="60" />
</subsystem>


You now can restart your server and enjoy the deployment on the fly for your development.

JBoss Eclipse Plugin


The eclipse update url for indigo Eclipse is: http://download.jboss.org/jbosstools/updates/development/indigo/.

There are many plugins offered by JBoss, only select JBossAS plugin under "JBoss Web and Java EE Development"

Saturday, October 9, 2010

ActiveMQ Messaging server

Introduction

A robust, reliable, scalable, secure, compatible and maintainable system is the key to the success for the business.

Using a middleware for messaging gives the software development loosely coupled, more flexible and easy to scale and maintain.

Apache ActiveMQ is a message broker (middleware) for remote communication between different systems in different environment. Although ActiveMQ is written in Java, it supports many protocols and provides APIs for many other languages, including C/C++, .NET, Perl, PHP, Python, Ruby and more. It can be seen as a general messaging solution for a variety of development platforms.

It provides high performance, reliability, scalability, security, compatibility, and maintainability. In this document, I will overview these areas.

Concepts

Before going through those areas, here are the concepts used in the document.

*Producer - Message generator which has a one-to-one relationship with consumer
*Consumer - Message receiver which has a one-to-one relationship with producer
*Publisher - Message genertor which has a one-to-many relationship with subscribers
*Subscriber - Message receiver who receives publisher's messages
*Queue -A Queue implements point-to-point (PTP) messaging semantics. A single message will be received by exactly one consumer. If there are no consumers available at the time the message is sent it will be kept until a consumer is available that can process the message.
*Topic - A Topic implements publish and subscribe semantics. When you publish a message it goes to all the subscribers who are interested.
*Broker - A server delivering messages
*Destination - A unique identifier for sending and receiving messages.

Performance

ActiveMQ offical test produces 21-22,000 messages/second for 1-2K data delivery [1]. I test on my machine, it delivers about 7,000/second [2]. Of course, the broker, consumer and producer are all in the same machine.

According to ActiveMQ, a single broker can handle over 10,000 concurrent users, even just using ajax approach (jetty as its underline technology) [3].

Reliability

ActiveMQ provides several mechsnisms to ensure reliable message delivery. It has failover configuration, which has a master broker and slave brokers backup. Once the master broker fails, one slave takes over the role to become a master to continue message delivery.

It can be done by only one line xml configureation as following:
failover://(tcp://masterhost:61616,tcp://slavehost:61616)


It also provides message cache to ensure a message is delivered to the consumer when the consumer's connection is temporarily failed for some reason, such as mobile connection lost signal.
This configuration uses a XML format configurable policy for deciding which types of messages should be cached, how many and for how long.

You can even configure more complicated broker networks to have local and remote master, local and remote slave.

Scalability

ActiveMQ provides three ways to scale the messaging system, Vertical, Horizontal scaling and Traffic Partitioning.

The vertical scaling will improve connections and numbers of Queues on a single broker to achieve thousands of connections and Queues. The horizontal scaling will increase the number further to ensure tens of thousands of connections concurrently. Finally the traffic partitioning will balance scaling and performance.

Vertical Scaling

Vertical scaling increases the number of connections and load on a single ActiveMQ broker, so the borker can handle both a large number of concurrent connections and a large number of Queues.

By default, ActiveMQ will use blocking I/O to handle transport connections, which results in one thread per connection. ActiveMQ can be configured to use Non-blocking I/O, which creates a thread pool for dispatching messages for multiple client connections.

You can also control memory size allocation through configuration to ensure there is enough capacity for large traffic.

The default Queue configuration uses a separate thread for paging messages from the store into the Queue to be dispatched. For a large number of Queues, you can disable this to avoid out of memory.

Horizontal Scaling

Apart from scaling a single broker, you can use a broker cluster network to increase the number of ActiveMQ brokers available for a busy system.

As the network automatically pass messages to connected brokers that have interested consumers.

Traffic Partitioning

ActiveMQ also provides an application level splitting of destinations, or traffic partitioning. The client application decides what traffic should go to which broker(s).

Security

Apart from basic authentication to use ActiveMQ. It also provides two level of authorization, operation level authorization and message level authorization.

Operation Level Authorization

It defines three roles, Read, Write, and Admin.
  • Read - The ability to receive messages from the destination
  • Write - The ability to send messages to the destination
  • Admin - The ability to administer the destination

Message Level Authorization

In some situations you might want to authorize access to only particular messages in a destination. You can create a message level authorization, which will check if the consumer has the right to receive certain messages.

Broker Level Operations

Broker operations includes such items as adding consumers and producers to the broker, committing transactions in the broker, adding and removing connections to the broker, etc. This gives the flexibility for clients to add their whitelabels.

Compatability

ActiveMQ supports many different transport protocols HTTP, HTTPS, SSL, Websocket, TCP, and many message protocols, Openwire, REST, RSS, XMPP, STOMP(Streaming Text Orientated Messaging Protocol). For instance, the server-side publishes messages via TCP, the front-end can choose HTTPS or Websocket to connect to the broker. This gives many choices for the clients to use depending on their environment. On the message protocol, for example, a C++ or Java client can use high performance binary protocol, Openwire, to send/receive messages, while, for scripting languages, such as PHP, Python, can use STOMP.

Mantanability

ActiveMQ provides messaging support system. You can monitor how many consumers are currently connected. How many messages are received and delivered.

It has Advisory messages, which are system messages generated by brokers. Typically, an advisory message will be generated every time a new administered object (Connection, Destination, Consumer, Producer) joins or leaves the broker. It can also report a warning about the ActiveMQ broker reaching system limits.

References

[1] ActiveMQ performance http://activemq.apache.org/performance.html

[2] JMS (ActiveMQ) Performance Verification http://liukeye.blogspot.com/2010/10/jms-activemq-performance-verification.html

[3] Jetty Continuations http://docs.codehaus.org/display/JETTY/Continuations

JMS (ActiveMQ) Performance Verification

Here is the performance report from my local machine.

Specs:
* Machine: Fedora 11, Quad CPU, 4GB DDR2 667MHz RAM, 2.1GB of which is already used.
* JDK version: 1.6
* Message size: 1024 bytes (1kb)

The Broker ran with:
* Two Transport Connectors
* One Message Producer
* Two Message Consumer (One Java and One PHP)

broker.addConnector("tcp://localhost:61616");
broker.addConnector("stomp://localhost:61613");


20,000 messages are produced in two different languages, Java and PHP. The result is shown on Table 1 and 2.

As you can see, overall, Java performs better. Although PHP as a message producer can generate more messages (about 7000 per second), the latency is too much for consuming message as PHP is a single threaded language.

Java produced less message per second, however, this is due to ActiveMQ Broker, and both message producer and consumer (three instances) are running on the same JVM. When I only run JAVA producer, which still share JVM with the Broker, the rate is about the same as PHP, about 7000 per second.

Also, PHP can only use STOMP (Streaming Text Orientated Messaging Protocol), but Java can use TCP, SSL, NIO (New I/O), UDP, multicast and VM (Virtual Machine) protocol. According to ActiveMQ documentation, NIO should performance better as it uses less resources when the traffic is heavy.

Table 1 Java as Message Producer

TypeProtocolNo. of MsgStart Timestamp
(ms)
End Timestamp
(ms)
First Msg
Latency (ms)
Last Msg
Latency (ms)
Total Time to
handle 20,000 msg(ms)

Rate
(msg/sec)
Java ProducerTCP20,00012699687511301269968755299 41694797
Java ConsumerTCP20,0001269968751176 126996875529946less than 141234850
PHP ConsumerSTOMP20,0001269968751143126996875875513345676122627

Table 2 PHP as Message Producer

TypeProtocolNo. of MsgStart Timestamp
(ms)

End Timestamp
(ms)
First Msg
Latency (ms)
Last Msg
Latency (ms)
Total Time to
handle 20,000 msg(ms)

Rate
(msg/sec)
PHP ProducerSTOMP20,00012699690492871269969052019 27327321
PHP ConsumerSTOMP20,0001269969049383126996905637596435669922860
JAVA ConsumerTCP20,000126996904932912699690521274210827987148

Tuesday, July 6, 2010

HTTP Basic Authentication with PHP Session

Today my challenge is to protect HTML files using PHP Session detection. Here is my case. We have a Wiki system, so our clients can login the Wiki to read all documents written on the Wiki system. We also have API documentation which are generated by PHPDoc automatically and in HTML format. We don't want the client to login again using HTTP Basic Authentication pop-up window. In other words, we would like the single sign-on (SSO) for our clients to read all documentations in different systems.

Once clients login, there is Wiki session is available for authenticating apache protected HTML folders. Here is how I did.

1. Turn on Apache .htaccess check by setting the following line in httpd.conf.

AllowOverride All

For instance,

<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>

Then, restart Apache.

2. Create a .htaccess under a folder where HTML files are located and are required to be protected, and add the following handler:

AddHandler mywrapper .html
Action mywrapper /authenticate.php


3. Create an authenticate.php file under the web root with the following content:

<?php
session_start();
$url = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI'];
if(!strstr($url, ".html")) $url.= "index.html";
if($_SESSION['username']) {
include($url);
exit();
} else {
echo 'Please login first. <a href="#">Login</a>';
die();
}
?>


If you get PHP error on the above code as following:

PHP Parse error: syntax error, unexpected T_STRING

You may change include($url); to readfile($url);

That is all. It is a simple solution for HTTP Basic Authentication using PHP Session.

Monday, January 18, 2010

ExtJS 3.1 Preformance review

ExtJS 3.1 Memory leak verification

The following result shows two memory use, library itself and Ext.Window.

ExtJS library

I attached the library ext-base.js and ext-all.js with ext-all.css, but without doing any creation. In other words, only ExtJS global variables and functions are created. The result is as following table.

BrowsersBrowser use (blank page) (KB)Initial ExtJS use(KB)Use after 20 browser refreshing(KB)
IE611,26030,71235,504
IE8(two threads)14,14829,48037,468
17,23618,05218,012
Firefox 3.535,16443,08059,824
Chrome 3.0(two threads)20,86434,28034,296
7,8048,90024,408

The above table shows the library itself memory leak. When the page is unloaded, the memory used by ExtJS can not be released by all tested browsers.

Ext.Window memory use

I created very simple Ext.Window with "Hello World" text using the new v3.1 library and attached it to a normal html button. The memory leak is shown on both Firefox 3.5 and IE6 as below.

BrowsersFirst Window use (KB)Use after 30 windows creation (KB)Use after closing all 30 windows
IE629,71243,30039,102
Firefox 3.555,01262,50160,800

ExtJS 2.1 and ExtJS 3.1 Performance Comparison

The following table shows the performance comparison between using v2.1 and v3.1 on our Front-End.

The profiling was conducted on the same machine with the Apache environment.

The result shows that the v3.1 memory use and its Javascript performance is degraded on all browsers comparing with v2.1.

IE 6

The V3.1 on IE6 is significantly slower. It took 90 seconds to switch between the product tab panels and the price updating is noticeably lagging. The CPU is intensively used for updating prices. It hardly can be used.

IE 7

Events V2.1V3.1
Memory use(KB)Loading timeAverage (S)Memory use(KB)Loading timeAverage (S)
Initial Loading55,5724.565,0525.8
Ext.Window Creation60,1201.072,4401.0
Tab switching63,2003.074,3725.9
Browser Refreshing78,9765.492,5606.3
2nd Browser Refreshing79,50093,564

IE 8

Events V2.1V3.1
Memory use(KB)Loading timeAverage (S)Memory use(KB)Loading timeAverage (S)
Initial Loading 48,3043.654,4644.2
Ext.Window Creation53,6600.662,3760.7
Tab switching56,5161.165,2202.4
Browser Refreshing69,0883.688,3003.6
2nd Browser Refreshing59,75281,564

Firefox 2.0

Events V2.1V3.1
Memory use(KB)Loading timeAverage (S)Memory use(KB)Loading timeAverage (S)
Initial Loading31,5925.235,3447.1
Ext.Window Creation32,2481.335,6201.3
Tab switching36,592139,4043.3
Browser Refreshing40,5845.343,5526.8
2nd Browser Refreshing40,39243,468

Firefox 3.5

Events V2.1V3.1
Memory use(KB)Loading timeAverage (S)Memory use(KB)Loading timeAverage (S)
Initial Loading57,1044.266,2924.6
Ext.Window Creation57,6720.667,3160.7
Tab switching63,0520.671,6761.7
Browser Refreshing65,2724.177,2484.5
2nd Browser Refreshing63,94473,352