Viewing by Category: JRun / Main
November 14, 2007
Early this year I wrote a blog article about using IP2Location to identify a users location and ISP based upon their IP. You can find the previous articles here:
http://www.bpurcell.org/blog/index.cfm?mode=entry&entry=1078 http://www.bpurcell.org/viewcontent.cfm?contentID=147
The flaw with this approach is that the data was stored into a database of 4 million rows and it was very expensive to do the lookups even with the performance optimizations of splitting the data up across multiple tables. Recent research has turned up a more optimal approach using GeoIP with a binary based solution that will support several hundred requests per second. Yes that is right, several hundred requests per second. The initial setup and configuration takes a bit of time to get going but it is very simple to update and maintain.
GeoIP is a technology from MaxMind that provides developers with a non-invasive way to determine geographical and other information about their Internet visitors in real-time. When a person visits your website, GeoIP can determine which country, region, city, postal code, area code the visitor is coming from. Furthermore, GeoIP can provide information such as longitude/latitude, connection speed, ISP, company name, domain name, and whether the IP address is an anonymous proxy or satellite provider. In my findings and experimentation I have found that GeoIP is also more accurate than IP2Location.
GeoIP features multiple binary files with different features available based on the price that you pay. A listing of the different versions can be found here. For my practical purposes I used both the City and ISP versions. Another great thing that MaxMind offers is a GeoLite City version that is free that you can use to test integration with your system. All of the API's are exactly the same but it is less accurate than the version you purchase.
The final selling point for me with GeoIP is the different API's that they support. You can integrate it with almost any system using (Java, C, Perl, PHP, VB.net, MS Com....and many others). Since I was using ColdFusion I chose to go the Java route. If you are not experienced with Java you may stumble a bit here but I plan on posting the Jar that I built for integration along with sample code to make it very easy to first try the Lite version then use the full version if it works well for you. You can find the Java source here along with the GeoLite version.
If you are experienced with Java and ColdFusion it is pretty straightforward to get up and running. You will just need to compile the java source and build a jar, then place it in the classpath of ColdFusion. It is as easy as instantiating the Java object from CF then making calls to retrieve the information. I recommend encapsulating this into a function and loading the reference to the Java object in an application scope variable that is loaded when the application starts. I did have to work around a few issues in the Java source to get it working properly with CF but there were not too many changes needed.
I have posted a very easy to follow step by step set of instructions on this posting http://www.bpurcell.org/blog/index.cfm?mode=entry&entry=1100 so that you can use to get GeoIP up and running on your site.
March 23, 2007
This was something that I meant to write about a while ago but never got around to it. I recieved a question recently by email and wanted to provide some tips and tricks when using ISAPI Rewrite in a multi-tiered load balanced environment. I wrote an article with Frank DeRienzo several years ago about using a multi-tiered load balanced enviroment. I followed this up later with a blog entry on my site for Using ISAPI Rewrite with ColdFusion.
If you are using ISAPI Rewrite to proxy requests from your webserver (IIS) to you ColdFusion server or through a load balancer you will run into issues when accessing various CGI variables. When proxying the ColdFusion server sees the web server as the end client and therefore variables like CGI.HTTP_HOST are set to the IP or hostname of the webserver. To get around this I inject custom headers with ISAPI rewrite, parse them in CF and then stored them in the request scope.
First I start by adding the headers to the main httpd.ini Start->All Programs->Helicon->ISAPI_Rewrite->httpd.ini (you may need to change the read only flag in order to save the file)
#Due to the proxy we add these headers to use in cf through #GetHttpRequestData().headers.HEADERNAME RewriteCond %REMOTE_ADDR (.*) RewriteHeader CLIENT_REMOTE_ADDR: ^$ $1
RewriteCond %SCRIPT_NAME (.*) RewriteHeader CLIENT_SCRIPT_NAME: ^$ $1
RewriteCond %SERVER_NAME (.*) RewriteHeader CLIENT_SERVER_NAME: ^$ $1
RewriteCond %SERVER_PORT (.*) RewriteHeader CLIENT_SERVER_PORT: ^$ $1
RewriteCond %HTTP_HOST (.*) RewriteHeader CLIENT_HTTP_HOST: ^$ $1
RewriteCond %SERVER_PROTOCOL (.*) RewriteHeader CLIENT_SERVER_PROTOCOL: ^$ $1
#stores the original URL before any rewriting in a custom header RewriteCond URL (.*) RewriteHeader x_rewrite_url_original: ^$ $1
RewriteCond X-Rewrite-Proxy (.*) RewriteHeader x_rewrite_proxy: ^$ $1
I then create a page in CF called httpheaders.cfm and include it early on in my CF code within Appplication.cfm or within onRequest of Application.cfc
<cfsilent>
<!--- this page is added to handle the custom headers we write with
ISAPI Rewrite due to the issues we see with proxying requests.
--->
<cfset httpheaders=GetHttpRequestData().headers>
<cfset REQUEST.proxyheaders=structNew()>
<cfif isdefined("httpheaders.CLIENT_REMOTE_ADDR")>
<cfset REQUEST.proxyheaders.REMOTE_ADDR=httpheaders.CLIENT_REMOTE_ADDR>
<cfelse>
<cfset REQUEST.proxyheaders.REMOTE_ADDR=CGI.REMOTE_ADDR>
</cfif>
<!--- I need to find a way to handle SCRIPT_NAME better, with ISAPI
Rewrite and JRun ones are different --->
<cfif isdefined("httpheaders.CLIENT_SCRIPT_NAME")>
<!--- <cfset
REQUEST.proxyheaders.SCRIPT_NAME=httpheaders.CLIENT_SCRIPT_NAME> --->
<cfset REQUEST.proxyheaders.SCRIPT_NAME=CGI.SCRIPT_NAME>
<cfelse>
<cfset REQUEST.proxyheaders.SCRIPT_NAME=CGI.SCRIPT_NAME>
</cfif>
<cfif isdefined("httpheaders.CLIENT_SERVER_NAME")>
<cfset REQUEST.proxyheaders.SERVER_NAME=httpheaders.CLIENT_SERVER_NAME>
<cfelse>
<cfset REQUEST.proxyheaders.SERVER_NAME=CGI.SERVER_NAME>
</cfif>
<cfif isdefined("httpheaders.CLIENT_SERVER_PORT")>
<cfset REQUEST.proxyheaders.SERVER_PORT=httpheaders.CLIENT_SERVER_PORT>
<cfelse>
<cfset REQUEST.proxyheaders.SERVER_PORT=CGI.SERVER_PORT>
</cfif>
<cfif isdefined("httpheaders.CLIENT_SERVER_PROTOCOL")>
<cfset
REQUEST.proxyheaders.SERVER_PROTOCOL=httpheaders.CLIENT_SERVER_PROTOCOL>
<cfelse>
<cfset REQUEST.proxyheaders.SERVER_PROTOCOL=CGI.SERVER_PROTOCOL>
</cfif>
<cfif isdefined("httpheaders.CLIENT_HTTP_HOST")>
<cfset REQUEST.proxyheaders.HTTP_HOST=httpheaders.CLIENT_HTTP_HOST>
<cfelse>
<cfset REQUEST.proxyheaders.HTTP_HOST=CGI.HTTP_HOST>
</cfif>
</cfsilent>
After including this code you can access the client's IP with "REQUEST.proxyheaders.REMOTE_ADDR".
One other challenge is detecting if a user is using HTTPS if you have front ended your site with a load balancer and use the SSL accelerator of BIG-IP or Cisco CSS. To the app it looks exactlyt he same. I will save that discussion for another blog posting. Let me know if you have any questions.
There should be a similar solution with mod_proxy in apache by adding headers I just have not researched it. If you have the information post your findings and I will add it to the blog.
May 1, 2006
Although it has been quite a while since JRun 4.0 was released the next release is right around the corner. The JRun team has asked me to post the following message to find developers that are interested in test driving the next release of JRun.
The beta release of next version of JRun appserver, code named Cheetah, is available. Adobe JRun Team is inviting serious evaluators to give feedback on this beta release. Contact vrreddy@adobe.com to be included in the Beta program.
We believe Beta of JRun Cheetah is reasonably stable and reliable. And we plan to reward those who prove otherwise. We intend to give away fully functional JRun licenses to the users who report highest quality issues during the Beta.
What More ! We are throwing open a JRun Sample Apps Challenge. We invite the beta users to develop sample applications exploiting the new JRun Cheetah feature sets. The best apps developed by you will be rewarded, and on qualification, will be featured as part JRun releases in samples section.
Write Code, find Bugs ! Help us serve you better.
Regards, Vijayan Reddy, Adobe JRun Team.
March 24, 2006
February 7, 2006
I recently was encountered with a problem where I needed to find what location a user was logging in from based on their IP. There were several reasons why such a system was needed that I highlight below.
Benefits of building such a system
- Targeting fraudulent users that share their accounts
- Reducing credit card fraud
- Display native language and currency
- Redirect web pages based on geographical region
- Filter access from countries you do not do business with
- Geographical targeting for in house ad serving
I first started looking for third party solutions that could be accessed through a webservice but quickly arrived at IP2Location.com. IP2Location offers a downloadable CSV database that you can run on your own system. The cost is not significant depending on the amount of data you need. They offer IP-Country-Region-City-Latitude-Longitude-ZIPCode-ISP-Domain Database if you need that level of information. Anyways&on to the technical part.
The CSV format that is provided is simple to import into any database, I was using MS SQL server and imported the data using DTS. There are over 4 million rows in the table so it does not make sense to query directly against the data that was imported for performance reasons. Instead to make the queries very quick that return location data I split the main table out into 20 tables, this left 200,000 rows in each table and proved to scale much better. Since IP2Location offers regular updates I wanted to be able to handle the update process and splitting of the data with very little work on my part. To do that I created two stored procedures.
1. IP2RangeTable The first stored procedure looks at the main table containing 4 million records and divides it into 20 different ranges. Those ranges are then stored in a range table containing the start, end and table name that will store the data. 2. The second stored procedure uses the IP2RangeTable created previously and bulk inserts the range of data from the main table into the range tables. They were simply called range1 - range20.
Both of the stored procedures were written in such a way that the data could be broken out into X number of tables. It just takes the number of tables as a parameter. In this case I used 20. The further you break it out the better it will perform.
Next, I created a UDF in ColdFusion (could be done in a stored proc as well) that takes an IP as an argument. The IP is converted to an IP Number. IP Numbers are used in the database to store the IP2Location content. An example for conversion follows.
IP Number = 16777216*w + 65536*x + 256*y + z (1) where IP Address = w.x.y.z
For example, if IP address is "202.186.13.4", then its IP Number "3401190660" is based on the formula (1).
IP Address = 202.186.13.4
So, w = 202, x = 186, y = 13 and z = 4
IP Number = 16777216*202 + 65536*186 + 256*13 + 4 = 3388997632 + 12189696 + 3328 + 4 = 3401190660 looks at the IP2Range
Once we have the IP number we need to find what table the record is stored in within the range1-rangeX tables. A query retrieves the values stored in IPRangeTable, from that data we can find the correct range table. Next a query is used against the range table to retrieve the location data.
This may sound complicated but it is really simple. Unlimately you could just query the original table that you imported from the CSV but I found the queries to take way to long and caused a lot of stress on the db server under load. Even with the right indexes in place. By breaking the data out into range tables you increase the scalablity exponentially.
Let me know if you have any other questions about this process and the benefits that the data provides.
Later I will explain how the event gateway was used to log this information for every user that logged into the site as a background process.
You can find the technical information in this article
November 3, 2005
ISAPI Rewrite is an IIS ISAPI filter that I have recommended in the past in place of the JRun connector to cluster with a hardware load balancer in between the application server and web server. I outlined the usage in the following article. ISAPI Rewrite can also be used in conjunction with the JRun connector for several different useful features.
In order to use ISAPI Rewrite in conjunction with the connector it will need to be loaded as an ISAPI filter with a higher priority than the JRun connector. The ISAPI Rewrite filter examines requests before the JRun connector processes them so we can perform pre processing (rewriting, proxying, or blocking requests) among other things. I will provide a quick overview of the structure of the configuration files for ISAPI rewrite as well. After you install ISAPI Rewrite it installs the ISAPI Rewrite filter into IIS at the master level so that it affects all sites on that server. All configurations that you want to affect all sites will go into c:\Program Files\Helicon\ISAPI Rewrite\httpd.ini. ISAPI Rewrite also allows you to configure individual settings for each virtual site on the server. By placing a httpd.ini file in the webroot of a site the filter will process it as well, the master file will be processed first then the configuration in the virtual site.
Back to the many uses of ISAPI Rewrite, at least ones that I have discovered you may have more to contribute. If you have questions on the regular expressions I am using take a look at the ISAPI Rewrite documentation.
Blocking URL's
I have used this approach to secure web based administration tools including the ColdFusion administrator. If you wanted to prevent external access to the ColdFusion Administrator and allow access behind your firewall on a private IP you could do the following. Enable the JRun Webserver (default instance runs on port 8500) and access the administrator through http://internalIP:8500/CFIDE/administrator/index.cfm. With IIS configured to the JRun server you would still have external access to the administrator. This is where ISAPI Rewrite comes in. Within the httpd.ini file we can add the following rule that blocks external access to /CFIDE/administrator/
#Block ColdFusion Administrator RewriteRule /CFIDE/administrator.* [F,I,O]
We could also block RDS using this same approach
#Block ColdFusion RDS RewriteRule /CFIDE/main/ide.cfm.* [F,I,O]
You can use this approach to block any URL all that is needed is a simple regular expression.
Rewriting SES (Search Engine Safe) URL's
The following rule will convert search engine safe (SES) URL to a standard URL so you don't have to handle them in your ColdFusion code.
#Convert SES URLs to standard URLs before passing them to ColdFusion RewriteRule (.*?\.cfm)(\?[^/]*)?/([^/]*)/([^/]*)(.+?)? $1(?2$2&:\?)$3=$4?5$5: [N,I] RewriteRule (.*?\.cfc)(\?[^/]*)?/([^/]*)/([^/]*)(.+?)? $1(?2$2&:\?)$3=$4?5$5: [N,I]
For example the following URL gets converted
http://host/page.cfm/var1/value1/var2/value2 -> http://host/page.cfm?var1=value1&var2=value2
Rewriting URL's for SEO optimization
I am not going to go into depth on search engine optimization (SEO) as I could spend a year just writing about it. One of the common things I have found is that a URL with keywords early after the hostname is rated better than including them in the query string at the end. You can create URL's that are easier to read as well and make it look like the pages the user is surfing is static content although it is generated on the fly. The following is not a real world example but I will say that I have used this approach with much success for data drill down applications to get search engines to rate the content highly. I don't want to give away any secrets though :-)
Let say we wanted a search engine to crawl our site for specific keyword that would be common search terms. If this were a dynamic ColdFusion page the URL's would look something like this.
http://host/search.cfm?keyword=keyword1 http://host/search.cfm?keyword=keyword1
With the following rule in httpd.ini we could rewrite the above URL
RewriteRule /search/(.*)\.htm /search.cfm\?keyword=$1 [I,O]
The following URL's http://host/search/keyword1.htm -> http://host/search.cfm?keyword=keyword1 http://host/search/keyword2.htm -> http://host/search.cfm?keyword=keyword2 gets rewritten to the URL's that we examined in the beginning, to ColdFusion it doesn't know the difference. We could provide a page with links to all of the common keywords and let the search engine walk through and index them. It may not seem apparent right away how this is such a cool thing but with a little imagination you can use this approach for a lot of things
Rewriting URL's to hide the file extension
This is similar to the example above except we are just hiding the actual file extension. For example we could rewrite .html requests to .cfm requests.
RewriteRule (.*)/(.*)\.html(.*) /$2.cfm [I]
Proxying Requests to Other Hosts
Lets say you had a single web server and host and multiple backend systems that you wanted to integrate through the same hostname. One system running ColdFusion, another system that is servlet based running on Tomcat. Of course you could integrate them but lets assume that is not an option. With J2EE applications you normally have a context root or prefix to every request. Lets assume that we have a context root of /myapp so all requests look like the following http://host/myapp/page.jsp. Lets also assume that this application is running on a different server other than the one ColdFusion or JRun is running on (192.168.1.50 on port 8080). The following rule would proxy requests from IIS to the server running our other application.
RewriteProxy (/.*myapp.*) http\://192.168.1.50\:8080$1 [I]
Proxying requests to remove the JRun connector
This is the approach I used in my article for JRun clustering with a hardware load balancer in between the webserver and application server. Since the standard protocol for the JRun connector is JRPP it does not work well through a hardware based load balancer. If you are using a context root in your ColdFusion application of / you will need to proxy by extension and can use the following rules. This will handle nearly every extension that CF needs and passes them to the JWS
#Rewrites to proxy requests back to the appserver level (CF) RewriteProxy (/.*\.cfm.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/.*\.cfc.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/.*\.jsp.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/.*\.jws.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/.*\.jst.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/flashservices.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/.*servlet.*) http\://192.168.1.1\:8501$1 [I] RewriteProxy (/.*CFIDE/GraphData.*) http\://192.168.1.1\:8501$1 [I]
One issue I ran into with this configuration is that a request for http://host will not use the default document in IIS of index.cfm so you can use the following rule to map http://host to http://host/index.cfm
#Fix final slash for /dir RewriteCond Host: (.*) RewriteRule ([^.?]+[^.?/]) http\://$1$2/ [R]
#Append index.cfm to any dir RewriteRule ((?!.+\.cfm).*/) $1index.cfm [I,O]
I would like to mention that I do not recommend removing the JRun connector unless you expect to handle supporting this configuration yourself. This approach is not directly supported by Macromedia but it does work as I have used it in the past. Don't expect Macromedia support to assist you with issues regarding this configuration.
It is worth mentioning that I am a big fan of Apache and you can do all of this with Apache and never have to buy a third party plug in. Apache has mod_rewrite and mod_proxy to accomplish the same tasks.
November 1, 2005
I have given this presentation several times in the past and wanted to share it with the general public. This explains how to measure performance, load test and tune your server to squeeze out every last drop of speed.
In this presentation I discuss my experience from lessons learned working with countless customers through the Macromedia professional services and support organizations. The tuning process is described in detail along with information specific to tuning ColdFusion application code and server settings. This includes the process of
- Monitoring Performance
- Finding bottlenecks
- Running load tests
- Systematically finding optimizations
- Tuning J2EE application server settings
The content is written for CFMX 6.1 as I haven't had time to adopt it to 7.0 but the concepts apply either way. You can view the PDF version of the presentation here.
August 26, 2005
I do a lot of testing with SSL and many times I don't want to configure an external web server. It seems like everytime I need to configure a JRun web server (JWS) for SSL I never have the steps available to do it. I have done testing with Flash Remoting, Flex and other various apps for SSL testing. The certificate is not a signed certificate but it will work for testing purposes. There are only two things you need - a keystore and a section in your jrun.xml telling JRun to use it....
The keystore:
To create your own keystore it is pretty simple just follow the instructions below. At a command prompt run the following line:
keytool -genkey -alias {name} -validity 9999 -keyalg RSA -keystore c:\my.keystore -keypass changeit -storepass changeit
Chose your -alias based on the hostname you will use SSL through. For instance, if you are accessing this locally use the alias localhost.
You will then be prompted for more information. At the first prompt enter the same name that you used in the command above. The rest is arbitrary.
This will create a keystore containing a certificate for your server. Configuring JRun
- Put your keystore file (either canned or that you created) into JRun4/lib.
- Open up your jrun.xml file (in JRun4/servers/{your server}/SERVER-INF) and add this SSLService declaration after the WebService declaration. The two items that are of most interest are keyStore and port. If you created your own keystore then replace localhost.keystore with the name of yours (my.keystore in the example above).
<service class="jrun.servlet.http.SSLService" name="SSLService"> <attribute name="port">9100</attribute> <attribute name="keyStore">{jrun.rootdir}/lib/localhost.keystore</attribute> <attribute name="keyStorePassword">changeit</attribute> <attribute name="trustStore">{jrun.rootdir}/lib/trustStore</attribute> <attribute name="socketFactoryName">jrun.servlet.http.JRunSSLServerSocketFactory</attribute> <attribute name="deactivated">false</attribute> <attribute name="bindAddress">*</attribute> <attribute name="interface">*</attribute> <attribute name="clientAuth">false</attribute> </service>
- Restart JRun and request a page using https://{your server}:9100
August 3, 2005
One challenge I have always ran into with ColdFusion or JRun is that when the server hung on windows there was no easy way to take a thread dump. While jrun.exe is running as a service there is no direct way to send a signal to the JVM to signal a thread dump. Most of the time you have to start it from a console window and let it run there. When you do that though you run the risk of someone closing you user session and having the server die. It is much safer to run it as a service. This takes us back to the problem at hand.....if the server hangs how do I obtain a thread dump? Mike Collins recently pointed me in the direction of a utility that you could use to obtain a thread dump even while running as a service.
The tool is called StackTrace and it is a swing based utility the provides hooks into a java process running as a service. In order to run it you may need to download the latest 1.4 JDK and run the install, it should ask you during the install if you want to install the JRE to Internet Explorer. Check the box and proceed with the install and it will start when you invoke it from the website.
When you open the StackTrace utility you can browse the running java processes and it should look something like this.
If you have multiple servers running it may be difficult to identify which processID is mapped to a particular JRun server there is another utility that I use called Process Explorer from SysInternals. Once you download Process Explorer and open it, select Options > Highlight Services to see what you're running. Right-clicking on a service and selecting Properties gives you all the information you need on the resources it is using. The following screenshot provides an example of the JRun CFusion server. The process ID is 348 and we could choose this process in the StackTrace utility to obtain a thread dump.

One limitation that you need to be aware of is that you cannot use this utility from Terminal Services. This is not a limitation of the product it is a limitation of windows since the utility cannot attach to process running in a terminal window. You must instead use PC Anywhere or VNC to run the utility or run it directly at the console of the server.
I have not used this utility extensively so I do not know how stable it is nor do I directly endorse it. It was something cool that was pointed out to me so proceed at your own risk.
March 24, 2005
JRun 4 Updater 5 was released today. You can find a listing of the issues it addresses here. There are several fixes for the connector that you should check out, especially if you are using connector clustering.
October 14, 2004
Google launched the Beta of its long anticipated Desktop Search tool for Windows today. The application acts as your own personal Google Server and indexes the contents your system by file name, or in the case of select file formats, by the contents of the file. It runs on Windows XP and Windows 2000 (with Service Pack 3).
The free download indexes the full text of email created in Outlook or Outlook Express, Word documents, Excel spreadsheets, PowerPoint presentations, AOL Instant Messages, and caches the pages you view in Internet Explorer so you can revisit the page later "even if its live content has changed or you're offline."
The install is really simple and after you install it starts indexing. If you are working on your system then it will take a while to index. As soon as it realizes the machine is idle it starts churning away. After it indexes the data you are presented with a browser based interface much like the google we all know. Yes is it lightening fast, typing in JRun on my machine turned up 24,107 entries for files and 27,823 for web history, all that in .5 seconds. It looks through basically anything on your machine and indexes it. For free you can't beat this. it is on my short list of the best windows utilities I have ever used.
You can download it here.
August 23, 2004
Sorry for the inactivity on the blog in the last month but Flex has kept me quite busy lately.
I know that many developers use CFMX on their desktop or laptop for development. Changes in XP SP2 lock down the network functionality of JRun and CFMX. The following technote will walk you through the process of getting CFMX and JRun working properly after installing XP SP2.
Enabling ColdFusion MX with Windows XP SP2
August 10, 2004
I recently updated my article on configuring Installing and Configuring ColdFusion MX 6.1 Multiple Instances with IIS and Apache Virtual Hosts. There was a problem with the Apache configuration causing errors. There was an issue highlighted on Steven Erat's blog pointing out that the JRunConfig Apialloc setting must be set in the Virtual Host for second instance, and must be set to false. If not, one in every 4 or 5 requests will return an Apache Internal Server Error to the client with a 500 status code and the Apache error log will record a message such as:
[Thu Jun 24 15:09:33 2004] [notice] jrApache[1635] JRun will not accept request. Check JRun web server configuration and JRun mappings on JRun server.
The article can be found on macromedia.com. There was only one page updated that dealt with the apache configuration.
June 12, 2004
ColdFusion, JRun and Flex TechNotes are now available as RSS feeds at the following URLs:
May 11, 2004
| Macromedia is celebrating our customer community by hosting Community Week, May 17-21, an opportunity to learn, network and interact with Macromedia product managers and our customer community. There will be free online presentations and a worldwide meeting on Wednesday. Go to www.macromedia.com/community for more information. |
 |
May 10, 2004
I recently received the question below on Enterprise clustering with ColdFusion MX 6.1 and wanted to share my response.
"I was hoping you could point me in the right direction as far as which options you would recommend. I am setting up an enterprise environment for an application using CFMX J2EE and hardware load balancing. There will be 2 hardware load balancers, 2 webservers running Linux/Apache and 3 app servers running CFMX 6.1. In one of your articles you describe the situation where the hardware load balancers are used to balance the load for the web servers and the connectors are clustered using JRun's connector clustering. In another you describe a situation where there is a load balancer in front of the webservers and a load balancer in front of the app servers. I was hoping you could advise me on which of these are best suited for an enterprise level architecture, I was initially thinking of going for the first option but now I am condsidering the second. Also, from your experience, which HLB would you recommend?"
In the two articles in the links below I outline two different architectures. The first architecture has a hardware load balancer in front of the web servers and uses the JRun web server connector to handle failover and load balancing to the application servers. The second architecture uses a hardware load balancer both in front of the web server and between the web server and application server.
The first architecture is the easiest to setup and scales pretty well. The one pitfall I find is that the JRun connector clustering feature does not offer application awareness. Basically if your application hangs on a ColdFusion server the connector will continue sending requests to it. The most scalable and redundant option is to use multi-tier hardware. It is by far the most difficult to configure but it is worth it if you want to minimize downtime. The multi-tier hardware option gives you true application level failover and load balancing using probes and custom load balancing algorithms. You really only need a single F5 or CSS to accomplish this as well. You can set up a single BigIP to handle all traffic. Basically, traffic flows from the internet into the BigIP then it is sent to the pool of web servers, then proxied back to the BigIP then sent to the pool of ColdFusion servers. This is outlined in the multi-tier hardware article. That is how Frank and I configured our BigIP for the article mentioned below. If you have a second box you can put them in a master/slave setup so if the hardware device fails it will fail over. With a master/slave configuration and multiple web, application and db servers you should 99.9% uptime with your site.
As far as my hardware recomendations, I have primarily worked with only the Cisco CSS and F5 BigIP devices. The CSS is a great box and if you are already familiar with Cisco products it is a great fit. By far though my favorite is the F5 BigIP device. It does almost anything you want and is really easy to use either through the web based admin or command line. It also offers Icontrol which is a really powerful addition worth taking a look at.
Referenced Articles:
- Clustering ColdFusion MX 6.1 Enterprise on JRun
- Multi-Tier Hardware Load Balancing with ColdFusion MX 6.1
April 22, 2004
Frank DeRienzo and I have had a lot of requests for an article on integrating Microsoft NLB and ColdFusion/JRun clustering. Frank and I set this up in the lab a few months back and sat down to write up the steps. I have to be honest though. I am not a big fan of NLB as a clustering technology because of the lack of application level monitoring. Then again it is provided free with Windows 2003. There are less options now that Cluster CATS is being deprecated so NLB is one of the new software based options. Of course if you are looking for the best solution always go with hardware.
After the editing process is complete this article will be featured on the macromedia.com website. You can view the current article here. This process will work for ColdFusion MX 6.1 Enterprise or JRun 4. Feel free to post comments below.....
The latest revision of the article is now live on the macromedia.com website.
April 1, 2004
Macromedia just release the updated DataDirect JDBC version 3.3 drivers which resolve a large list of issues from earlier versions of the drivers. The new drivers provided in the TechNote should replace the 3.2 drivers shipped in ColdFusion MX 6.1 or the 3.1+ drivers.
For a full list of the issues and to download the drivers see the technote on the macromedia.com website.
March 25, 2004
The JRun Closed Connection error can cause a lot of frustration but if you understand how to debug and find the issue that is causing it, then you can resolve the problem quickly. The JRun Closed Connection error is caused by an issue that occurs in the JVM that causes the JVM to close the socket that is open from the external webserver connector (IIS, Apache, Iplanet) to JRun. The JVM problem can occur due to several different issues
- outOfMemory or the JVM approaches the max heap
- Native code in a CFX or COM objects causes an error in the JVM
The memory condition can occur in several different cases
- If debugging is left on in production with CF (make sure you have it turned off in production not just masking the IP's)
- Large resultsets are returned from the database taking up a significant amount of memory (reduce the size of database results you are returning)
Diagnosing the issue: In order to diagnose this issue there are several areas to start. By turning on metrics and JVM Verbose GC output you can monitor the memory and find out if memory utilization is the problem. In some cases the memory spikes very quickly and comes back down. A large recordset returned from a query can cause this behavior. The recordset will populate into memory and GC will clean it up quickly. If the size of the recordset pushes the heap beyond the max heap you will see a problem. Although you may not see an outOfMemory error everytime. Any connections that were in use during this spike will get a JRun connection closed error. If you look in the webserver connector logs you may find connection reset by peer errors as well.
Also review all of your logs for long running pages and errors in the Application.log. If you have a number of errors correct each issue also identify and fix any long running pages.
You can also provide a better user experience by modifying the page that displays when the error occurs. Without modifying the connector errorurl the user will get a white HTML page that says "JRun Connection Closed". You can replace this with an HTML page that just asks them to refresh or place javascript in the page that will refresh automatically. In either the httpd.conf or jrun.ini file modify the errorurl to point to an html page on the webroot of the web server.
For example with IIS you need to uncomment the #errorurl parameter and set it to the html page errorurl=/errorpage.html
While I have not covered every possible issue that can cause JRun Connection Closed errors I have at least provided some quick debugging steps. I will continue to update this entry as I find more approaches for debugging this problem.
March 15, 2004
Product support has been busy cranking out technotes during the month of March. Here is an up to day listing of the latest technotes from March 2004 for JRun and ColdFusion.
March 11, 2004
JRun updater 3 was released today. There are many bug fixes and updates to JRun in this release, you can see a full list of the updates and bug fixes here.
Important Update April 22 2004: If you downloaded the JRun U3 updater before April 14th then you should go back and download it again. There have been several fixes to the connector in this latest update. Specifically the fix that breaks the connector with CF deployed to /. The latest download can be found here.
February 5, 2004
The next major revision to the Java platform and language, version 1.5.0, is now available in beta. J2SE 1.5 has been developed under the Java Community Process as Java Specification Request (JSR) 176, which is led by Sun and an expert group of industry-recognized corporate and individual developers.
New features incorporated since the last "major" release - 1.4.0. - include:
- New language updates: Metadata, Generics, Enumerated types, Autoboxing of primitive types
- New JVM Monitoring and Mangement API
- Improved out-of-box performance
There are several additions to the language, you can view a quick overview here. There is improved scalability and performance in this release and improved startup times. One of the changes that will help me most in my day to day job is the new Monitoring and Manageability. JMX is packaged with this release and the JVM Monitoring & Management API (JSR-174) specifies a comprehensive set of JVM internals that can be monitored from a running JVM. This information is accessed through JMX (JSR-003) MBeans and can also be accessed remotely using the JMX remote interface (JSR-160) and through industry standard SNMP tools. One of the most useful features is a low memory detector. JMX MBeans can notify registered listeners when the threshold is crossed, see javax.management and java.lang.management for details.
The release also contains a more powerful native profiling API called JVMTI. JVMTI is intended to cover the full range of native in-process tools access, which in addition to profiling, includes monitoring, debugging and a potentially a wide variety of other code analysis tools.
We are always having customers generate thread dumps when problems occur. It always needed to be done from the console before and that is akward. This release contains two new APIs, getStackTrace and Thread.getAllStackTraces provide this information programmatically. It is as simple as the following: StackTraceElement e[]=Thread.currentThread().getStackTrace();
for (int i=0; i <e.length; i++) {
System.out.println(e[i]);
}
System.out.println("\n"+Thread.getAllStackTraces());
Also in the case of a JVM crash the Hotspot JVM includes a fatal error hander that can run a user-supplied script or program if the JVM aborts. A debug tool can also connect to a hung JVM or core file using the Hotspot JVM serviceability agent connector.
Many of these features more than likelyy will help improve JRun and ColdFusion in the future.
January 7, 2004
I have always found search engines interesting and based on some of the statistics I collect from referring pages I wrote some code that displays the latest referrals from the google search engine. I also like to see where my pages rank and what topics are most viewed on my site. I collect the data by using the cgi.HTTP_REFERER variable and storing it in a db. I parse out the google querystring using a UDF called GetGoogleKeywords from http://www.cflib.org.
You can view the realtime google keyword searches on this page.
January 5, 2004
January 2, 2004
If you have clustered JRun or ColdFusion running on JRun then you may have ran into an issue with sticky sessions. This little technical tidbit may help you out and you will better understand how JRun handles sticky sessions. Many people think that the connector handles sticky sessions with a table of current sessions. Well, it is much simpler than that and here is how it works.
Sticky sessions hinge off of the jsessionid but not the entire id. When you create a JRun cluster the first time the server starts after it is added to a cluster a file called {cfusion}/servers/{servername}/SERVER-INF/connector.properties is created and the file contents look something like this:
#Sat Nov 22 07:36:43 EST 2003 server.id=c830
The server.id is a 4 character string that is used to pre-pend on the front of every jsessionid that is created by that server. The connector has a listing of all server id's for all servers in a cluster and looks at the jsessionid and determines which server to route the request to. So a jsessionid created by the server with the id c830 will look something like this c830xxxxxxxxxxxxxxxx. By default sticky sessions are set to on even though the JRun documentation states otherwise. You can disable sticky sessions by modifying the jrun.xml with the following XML.
<service class="jrun.servlet.jrpp.JRunProxyService" name="ProxyService"> ............ <attribute name="StickySessions">false</attribute> ............ </service>
You should really leave sticky sessions on unless you are not using the session scope at all. If you are using in-memory session replication you should leave sticky sessions on as well.
If you run into a problem with sticky sessions the first thing to look at is the users jsessionid, make sure it has the first four characters of a valid server.id. If it does not all requests with that session id will be round robined across all servers in the JRun cluster.
December 29, 2003
If you are looking for a JDBC driver to use in JRun or CFMX chances are you will find one here on the the Sun site. At the current time there are 197 drivers available in this listing.
November 26, 2003
In the past Microsoft rebranded the Data Direct JDBC driver for their own just like Macromedia does with ColdFusion MX. As of sometime in early 2003 they started building their own driver. As of Nov 2003 the SP2 version was available. Data Direct has a comparison data between the Microsoft driver and Data Direct drivers. This would apply to the Macromedia drivers as well since they brand the latest drivers from Data Direct.
Steps for configuring the Microsoft SQL 2000 driver:
- Go to the download page or registration page you may need to log in with a Microsoft Passport to gain access to the file.
- Scroll to the bottom of the download page and download the setup.exe
- Run the setup.exe program. It will install to C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC
- Under C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib copy the files msbase.jar, mssqlserver.jar, msutil.jar to the JRun4/servers/lib or CFusionMX/runtime/servers/lib directory. (depending on how you installed CF). In some cases if you installed standalone you will not have a CFusionMX/servers/lib directory, if you do not go ahead and create it.
- Restart CF
- Open up the ColdFusion Administrator and click on Data Sources
- Enter a Datasource name and choose "other" in the dropdown menu for the driver
- Enter the following information for the driver details
JDBC URL: jdbc:microsoft:sqlserver://hostname:port;databasename=dbname (my example jdbc:microsoft:sqlserver://192.169.1.71:1433;databasename=tacwebdb) Driver Class: com.microsoft.jdbc.sqlserver.SQLServerDriver Driver Name: com.microsoft.jdbc.sqlserver.SQLServerDriver Username: dbusername Password: dbpassword
- Click Submit and the datasource should verify correctly if you have all the parameters correct
Thanks to Sarge for assisting with the steps.
In some cases you may run into an issue with the packaged MySQL driver that comes packaged with ColdFusion. You have the option of configuring a third party driver or the latest driver from the mysql website. The MySQLwebsite contains several different drivers that you can use in different cases. For ColdFusionMX you are best off using the latest production ready JDBC driver (MySQL Connector/J). The driver is available for download at http://www.mysql.com/downloads/api-jdbc-stable.html
Steps for configuring the mySQL driver:
- Go to the download page and scroll down until you get the Source and Binaries section. Click on Download for either the .zip (windows) or tar.gz (unix).
- Extract the file with winzip (windows) or gzip then tar on unix
- After extraction you will see the file mysql-connector-java-3.0.9-stable-bin.jar place the file in the the JRun4/servers/lib or CFusionMX/servers/lib directory. (depending on how you installed CF). In some cases if you installed standalone you will not have a CFusionMX/servers/lib directory, if you do not go ahead and create it.
- Restart CF
- Open up the ColdFusion Administrator and click on Data Sources
- Enter a Datasource name and choose "other" in the dropdown menu for the driver
- Enter the following information for the driver details
JDBC URL: jdbc:mysql://servername:port/dbname (I used jdbc:mysql://ps-gamay:3306/scott) Driver Class: com.mysql.jdbc.Driver Driver Name: com.mysql.jdbc.Driver Username: dbusername Password: dbpassword
- Click Submit and the datasource should verify correctly if you have all the parameters correct
November 17, 2003
If you have configured CFHTTP or CFLDAP to communicate securly then you have worked with the command line KeyTool. If you are new to the command line tool then I suggest a GUI version called KeyTool GUI.
KeyTool GUI is a GUI version of the command-line keytool provided with the Java SDK. KeyTool GUI can be used to create JKS/JCEKS type keystores, generate and store keys and their associated X.509 certificates, generate CSRs, import and store trusted certificates and perform maintenance on keystore entries. A complete list of KeyTool GUI's functionality is included below:
- Create, load, save and change the password of JKS, JCEKS, PKCS #12, BKS and UBER type KeyStores.
- Conversion between the aforementioned types.
- Generate DSA and RSA key pair entires with self-signed Version 1 X.509 certificates.
- Generate Certificate Signing Requests (CSRs).
- Import Certificate Authority (CA) replies.
- Import X.509 certificate files as trusted certificates.
- Import key pairs from PKCS #12 files.
- View the details of certificates contained within keystore entries and certificate files.
- Export KeyStore entries in a variety of formats.
- Delete or rename KeyStore entries.
- Clone and change the password of key pair entries.
- View the details of Certificate Revocation List (CRL) files.
You can download the tool here
I make some references to Garbage Collection Tuning in my Performance Tuning and Monitoring Coldfusion or JRun. Beyond that there are many references available on GC tuning. One that I find interesting is the " Frequently Asked Questions about Garbage Collection in the HotspotTM JavaTM Virtual Machine" article on the Sun website. Make sure you fully load test any JVM argument that you try. I have ran into some that have had major side effects, from stability problems to uncontrolled memory growth.
November 6, 2003
Java Remote Rebugger Interface (JPDA) is another tool you can put in your toolbox when debugging CFMX and JRun. It is pretty simple to setup and get running with JRun/ColdFusionMX.
Described at http://java.sun.com/j2se/1.4.2/docs/guide/jpda/
Here are the steps:
- Create a copy of jvm.config (I called mine debug.jvm.config) and open this new config file for editing
- remove the switch -XX:+UseParallelGC (this isn't compatible with debugging)
- add these two debugging switches:
-Xdebug -Xrunjdwp:transport=dt_shmem,server=y,suspend=n
- Run CFMX from the command line
- With standalone type {cf_root}\runtime\bin\jrun -config debug.jvm.config -start default
- With JRun type {jrun_root}\bin\jrun debug.jvm.config -start servername
note that it starts up saying "Listening for transport dt_shmem at address: javadebug"
- from a DOS window, with the Sun 1.4.2 jdk in your path,
jdb -attach javadebug
Here is an example C:\j2sdk1.4.2_02\bin>jdb -attach javadebug Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable Initializing jdb ... >
CFMX is still running while you are attached.
Some useful jdb commands:
- threads - shows all the thread names
- suspend - stops CFMX ( so you can get a thread dump)
- where - the all familiar thread dump
- resume - CFMX resumes execution
- help - all the myriad jdb commands...
One of the problems I found is that the output dumps out to the console and it is hard to read. I found that it is much easier to direct the output to a file using the following approach
C:\j2sdk1.4.2_02\bin>jdb -attach javadebug > c:\jdblog.log
You still type your commands in the console but the output gets sent to the log. You can use wintail.exe or tail -f to follow the log.
Thanks to Tom Donovan for this Tip
October 31, 2003
Many times I visit customers for performance tuning engagements and I have a process that I go before I start load testing. This process allows me to really see what is happening inside the server. After running a few tests and monitoring this data I can make adjustments to JRun, CFMX, and the JVM. Unless you know what is going on you are really guessing with performance turning. These steps should get you started in the right direction. I plan on working on several other articles geared around load testing, performance tuning, and JVM optimization. Feel free to leave a comment if you have any suggestions for things you would like to learn more about.
You should also review the following presentation.
Use the following steps to configure CFMX 6.1 with the JRun install. It is a bit different with the standalone install.
- Enable JRun Metrics in /jrun4/servers/{servername}/SERVER-INF/jrun.xml
Uncomment the entry <service class="jrunx.metrics.MetricsService" name="MetricsService"> <attribute name="bindToJNDI">true</attribute> </service>
Inside of <service class="jrunx.logger.LoggerService" name="LoggerService"> modify <attribute name="metricsEnabled">true</attribute> <attribute name="metricsLogFrequency">5</attribute>
By setting the metrics Log Frequentcy to 5 the metrics data will be logged every 5 second with the following format 10/24 12:34:51 metrics Web threads (busy/total) 0/1 Sessions: 0 Total Memory=12032 Free=5880
- Configure Logging to log to separate files by modifying the entry
<attribute name="filename">{jrun.rootdir}/logs/{jrun.server.name}-event.log</attribute> in jrun.xml. Change it to the following <attribute name="filename">{jrun.rootdir}/logs/{jrun.server.name}- {log.level}. log</attribute>
- On Unix create a custom start script so JVM out stream gets logged to a file
Script name: start-cfusion /web/jrun4/bin/jrun -nohup -start cfusion 1>/web/jrun4/logs/cfusion-out.log 2>/web/jrun4/logs/cfusion-err.log
This script will log all console output to logs and allow you to capture thread dumps and other data from the logging stream.
On Windows you need you can follow the following technote
- Enable GC details (only available in JVM 1.4.x/CFMX 6.1 ships with 1.4.2 and this works)
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC
For more details see Tuning Garbage Collection
Areas to monitor under load
- JRun Metrics - /jrun4/logs/servername-metrics.log
Monitor the total and in-use threads, also used for monitoring free memory in the JVM
- GC Logs - /jrun4/logs/servername-out.log
After enabling the verbose garbage collection options you can monitor GC times and heap memory allocation. This is the kind of data you will use to tune the JVM arguments.
Example Verbose Output: See Tuning Garbage Collection for details
Heap PSYoungGen total 3584K, used 3583K [0x027f0000, 0x02bf0000, 0x060d0000) eden space 3072K, 99% used [0x27f0000,0x2aeffe8,0x2af0000) from space 512K, 100% used [0x2b70000,0x2bf0000,0x2bf0000) to space 512K, 0% used [0x2af0000,0x2af0000,0x2b70000) PSOldGen total 1408K, used 1287K [0x060d0000, 0x06230000, 0x227f0000) object space 1408K, 91% used [0x60d0000,0x6211d10,0x6230000) PSPermGen total 6528K, used 6489K [0x227f0000, 0x22e50000, 0x2a7f0000) object space 6528K, 99% used [0x227f0000,0x22e46470,0x22e50000) 6.47463: [GC 4871K->2199K(5376K), 0.0118130 secs] Heap after GC invocations=7:
- Server CPU
Top or grstat on Unix Task Manager on Windows
- ColdFusion Logs (Application, Exception) located in /jrun4/servers/{servername}/{cfusionhome}/WEB-INF/cfusion/logs
Look for Application errors or any out of the ordinary messages in the logs
Troubleshooting:
Under load the application server can appear to slow down and even in some cases hang. Using the data above and JVM Thread Dumps we can quickly diagnose and identify the problems. If a server stops responding to requests you will need to take a thread dump. You should also take one in a case where the thread count in metrics does not return to 0 after a load test ends.
The following document can assist in steps for obtaining the thread dump and diagnosing the results
http://www.macromedia.com/support/jrun/ts/documents/tn18362.htm Steps for diagnosing a hung JRun Server: http://www.macromedia.com/support/jrun/ts/documents/4.0_unresponsive.htm
October 27, 2003
There have been questions around the longevity of JRun as a J2EE application server and its future in the Macromedia product line. JRun serves as the core of ColdFusion and the Breeze product and continues to evolve on its own. Recently NEC signed a three year agreement to use JRun as an OEM product with their ActiveGlobe application server product line along with e-learning and StarOffic offerings. You can read more about the deal at the following site...
Between this and the recently renewed J2EE license agreement with Sun any questions around Macromedia's commitment to JRun should be answered.
When you add a new instance of JRun on windows you are forced to start it throught the command line. You can add the instance as a service so that it starts when the machine starts. To do this go to you C:\JRun4\bin directory and issue the following command and it will give you all of the options
C:\JRun4\bin\jrunsvc -?
Usage: jrunsvc -install <jrun-server> [service-name [service-display [service-description]]] [- <jrun-option>...] or -remove service-name or -start service-name or -startimeout <seconds> service-name or -stop service-name or -stoptimeout <seconds> service-name or -status service-name or -console service-name [-<jrun-option>...]
If I had a server named server1 I would issue the following command
c:\JRun4\bin\jrunsvc -install server1 "Macromedia JRun Server1" "Macromedia JRun Server1"
There is a little known trick when configuring multiple instances with ColdFusion and JRun. You can use different jvm.config files for each instance thereby giving you the flexibility to configure unique classpaths and memory/heap settings.
This technote explains how to do it.
October 10, 2003
If you have any questions whether or not you are on a supported version of Macromedia software you can see the following page: http://www.macromedia.com/support/programs/supported_products.html
October 3, 2003
Some applications claim to be platform independent, I will explain to you why I think CFMX 6.1 truly is. I will walk through the steps of deploying the java only install of CF onto windows, do some development work. Then jar CFMX and the CFML files up into an ear file and deploy right onto linux (or any other OS you choose). All without running any installer for CF on linux. Truly a write once deploy anywhere scenario. Pretty Cool eh?
The first step that needs to be taken is do download the java (jar based) install of CF. This install does not contain platform dependant files (verity, CFX, COM) but does include the core files of CFMX. When you go to http://www.macromedia.com/downloads download the AIX install of CFMX. It is not just for AIX it runs on any OS with a J2EE application server, the file extension for the file is .jar.
To run the installer enter the command java -jar coldfusion-macr-java.jar (this will bring up the GUI)
You can also run this installer in the console by adding the options i console. For a full listing of the options type -? In this example I will run in GUI and let the installer build an ear for me that I will deploy onto JRun. Here are the steps that I followed, while these steps apply to JRun they may be a little different based on the application server you are using.
- Run the CFMX 6.1 installer java -jar coldfusion-macr-java.jar
- Choose the ear file J2EE installation
- Create a new JRun server through the JMC
- Delete the default-ear from the server you just created in {jrun-root}/server/{serverroot}/default-ear
- Under the JRun servers root {jrun-root}/server/{serverroot}/ create a directory called cfusion-ear
- Copy the cfusion.ear from the installed directory to {jrun-root}/server/{serverroot}/cfusion-ear/
- Within the directory {jrun-root}/server/{serverroot}/cfusion-ear/ Extract the ear with the following command jar xvf cfusion.ear
- Within the directory {jrun-root}/server/{serverroot}/cfusion-ear/ create a cfusion-war directory and move cfusion.war to cfusion-war.
- Within the directory {jrun-root}/server/{serverroot}/cfusion-ear/cfusion-war extract the war file with the following command jar xvf cfusion.war
- Within the directory {jrun-root}/server/{serverroot}/cfusion-ear/META-INF open the application.xml and change
<web-uri>cfusion.war</web-uri> to <web-uri>cfusion-war</web-uri>
- Delete both cfusion.ear and cfusion.war
- Start JRun and CF will deploy, hit the CF admin. The CFadmin URL will be dependant by the port you setup JRun to run on and the context root you chose during installation. I have the port 8101 and a context root of / for my install so my url is:
http://127.0.0.1:8101/CFIDE/administrator/index.cfm
- Walk through the Configuration wizard
At this point we are ready to start development. You also have the option of configuring CF to work with an external webserver. For this example I will create a few simple CF pages and setup a few datasources in the admin. The next step is to jar this entire install up and move it over to a Linux box and extract the ear into place.
Now in order to deploy the ColdFusion ear onto any OS/J2EE server combination of your choosing you will first need to jar it up.
- Make sure JRun is shut down
- Within the directory {jrun-root}/server/{serverroot}/cfusion-ear/ run the following command to package CF up
jar cvf cfusion-package.ear *.*
I have JRun installed on RH 8.0 Linux and that is where I will move and deploy this file but the fact is you could deploy this file anywhere you wanted.
- On my linux box I have JRun 4 installed and I have created a JRun server to deploy onto
- In the JRun server root of the linux box {jrun-root}/server/{serverroot}/ create a cfusion-ear directory
- In the directory {jrun-root}/server/{serverroot}/cfusion-ear/ copy the cfusion-package.ear from Windows to the Linux box
- Extract the ear file on the linux box in the directory {jrun-root}/server/{serverroot}/cfusion-ear/ with the following command
jar xvf cfusion-package.ear
- Delete cfusion-package.ear
- Start the JRun server on the linux box and you are in business
Using this approach you can build one ear file that could be deployed on any developers machine regardless of operating system. All you need is a J2EE server and JRun for developers is free. After doing development you can jar up CF and move it to another environment for testing then onto production for deployment. Let me know what you think about this approach.
October 1, 2003
Using the wsconfig.exe or wsconfig.jar utility that ships with JRun and CFMX you can configure external webservers to work with either product. This tool can either work perfect for you or cause you to beat your head against your desk. If you run into an issue where either the GUI hangs or through the command line the prompt never returns then you may find the information below helpful.
When wsconfig first runs it does a port scan from 2900-3000 to list any JRun servers that are running. In some cases it will hang when the port scan occurs. In the GUI this occurs when you click the add button. In the command line version it occurs when it searches for the servers and the prompt never returns. To test if this is the problem try the following command
wsconfig -host localhost -list (using the executable version) C:\CFusionMX\runtime\jre\bin\java -jar C:\CFusionMX\runtime\lib\wsconfig.jar -host localhost -list
This command should provide a listing of all running servers if it does not return to the command prompt and hangs then you can follow the procedure below
By narrowing the ports that are scanned by wsconfig you can prevent the hang. By default CFMX uses port 2901 for the jndi port. This port can be found in C:\CFusionMX\runtime\servers\default\SERVER-INF\jndi.properties under the entry java.naming.provider.url=localhost:2901. If you are running multiple instance of JRun then you can look in each servers SERVER-INF\jndi.properties file for the range of jndi ports to scan.
To reduce the ports that are scanned use the following java arguments -DWSConfig.PortScanStartPort=startport -DWSConfig.PortScanCount=portrange
If I had multiple instance and the JNDI ports started at 2901 and ended at 2905 then I would use the following command to list the jrun instances.
C:\JRun4\runtime\jre\bin\java -DWSConfig.PortScanStartPort=2901 -DWSConfig.PortScanCount=5 -jar C:\JRun4\lib\wsconfig.jar -host localhost -list
To run the GUI and only scan those ports enter the following command: C:\JRun4\runtime\jre\bin\java -DWSConfig.PortScanStartPort=2901 -DWSConfig.PortScanCount=5 -jar C:\JRun4\lib\wsconfig.jar Modify the ports to your range of JNDI ports and the GUI should work without hanging.
Here are a few other articles that can help with wsconfig debugging http://www.macromedia.com/support/jrun/ts/documents/tn18287.htm http://www.macromedia.com/support/coldfusion/ts/documents/connector_install_faq.htm
I ran into a case where a customer wanted to start JRun as a different user on Solaris so I wrote a quick script that allows you to do this. Just put the following in a file, modify the RUNTIME_USER to a user of your choosing and the JRUN_DIR to your JRun install directory. Then modify default to whatever server you want. Upload the file to Solaris, change the permissions so it can execute and run it. I could make this more generic but time is short :-)
PATH=/usr/xpg4/bin:/bin:/sbin:/usr/bin:/usr/sbin:$PATH RUNTIME_USER=""nobody"" JRUN_DIR="/opt/jrun4"
su $RUNTIME_USER -c "PATH=$PATH:$JRUN_DIR/bin; export PATH; $JRUN_DIR/bin/jrun -start -nohup default
September 3, 2003
If you want to switch the XML parser that JRun or CFMX uses it is pretty simple. Crimson is the default parser that is used and it is packaged with JRun. To use the Xerces parser rather than the Crimson parser follow the following procedure (thanks to Tom Donovan):
- Get the Xerces kit at http://xml.apache.org/dist/xerces-j/Xerces-J-bin.1.4.4.zip
- extract xerces.jar and place it in the classpath ahead of jrun.jar (for example, in runtime/servers/lib)
- add these switches to the JVM arguments in CF Administrator (or in jvm.config for JRun). Note that this is one long line, not three lines -
Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl
- restart CFMX ( JRun)
September 2, 2003
August 29, 2003
After deploying the J2EE version of ColdFusion MX to JRun you are stuck with a document root located in {jrun}/servers/{servername}/cufion/ What if you want this docroot to be located somewhere else? I will tell you exactly how to do it. If you are clustering you can have multiple servers share this docroot. Unfortunately, it's not entirely straightforward so follow along. To do this, we have to edit XML files to make all this happen. For each server instance, edit the jrun-web.xml file in {jrun.home}/servers/<instance>/cfusion/WEB-INF/ (assuming your context root is /cfusion). <virtual-mapping> <resource-path>/</resource-path> <system-path/> </virtual-mapping> <context-root>/cfusion</context-root> <compile>false</compile> <reload>false</reload> <uri-character-encoding>UTF-8</uri-character-encoding> <virtual-mapping> <resource-path>/*</resource-path> <system-path>{cfmx}/wwwroot</system-path> </virtual-mapping> <virtual-mapping> <resource-path>/WEB-INF/*</resource-path> <system-path>{jrun.home}/servers/<instance>/cfusion/WEB-INF</system-path> </virtual-mapping> </jrun-web-app>
First, remove the section in red. {cfmx} should be replaced by the common document root you've chosen for CFMX, {jrun.home} should be replaced by the JRun install directory and <instance> should be replaced by the name of the server instance whose XML file you are editing.
If the section in black isn't present, you can add it although it represents the defaults. This removes the default document root mapping (in red) and adds two new mappings (in blue): a document root mapping to the shared document root a WEB-INF mapping to ensure each server instance can find its own private library files I typically add a third mapping (of /CFIDE/*) to the instance's CFIDE directory - to save having to copy the CF Administrator code from the CFMX for J2EE install out to the common document root.
A recent case study on the Macromedia website proves the value and worth of JRun with mission critical systems.
Kronos needed to deploy a turnkey native-web solution for workforce management without heavy expenses and support requirements. Kronos selected and embedded Macromedia JRun as the underlying Java application server for Workforce Timekeeper(tm), a complete solution for tracking employee attendance, producing accurate payroll, and monitoring labor activities.
Case Study Highlights:
- JRun embeds seamlessly and works invisibly in the background.
- Lower licensing costs and overall faster time to market for Kronos
- Kronos developed a proof-of-concept in two days. Completed the entire embedding process in only two weeks.
- JRun provides the scalability and performance required for enterprise deployments. Performed well with load testing of thousands of concurrent users.
Quote: "The best thing about this conversion to JRun - it was completely invisible to our customers. They don't need to know Java. They don't need to license, install, learn, and support a separate product. JRun just works silently and invisibly in the background. That's not a trivial matter because, with our application, if it doesn't work, our customers' employees don't get paid. It doesn't get much more mission-critical than that - you don't want to mess with other people's paychecks." - Ian Holland, Vice President of Architecture and Systems Engineering, Kronos Incorporated
Read More: http://dynamic.macromedia.com/bin/MM/showcase/scripts/showcase_cs_cover.jsp?Showcase_OID=954782
Any questions about the future of JRun can be answered with Macromedia's commitiment to Java with JRun recently renewing its J2EE licensing agreement with Sun Microsystems
|
A java thread is an execution context or a lightweight process. It is a single sequential flow of control within a program. Programmer may use java thread mechanism to execute multiple tasks at the same time. |
|
Thread class and run() Method
- Basic support for threads is in the java.lang.Thread class. It provides a thread API and all the generic behavior for threads. These behaviors include starting, sleeping, running, yielding, and having a priority.
- The run() method gives a thread something to do. Its code should implement the thread's running behavior.
There are two ways of creating a customized thread:
- Sub classing java.lang.Thread and Overriding run() method.
- Implementing the java.lang.Runnable Interface.
|
|
Thread Scheduling
- When we say that threads are running concurrently, in practice it may not be so. On a computer with single CPU, threads actually run one at a time giving an illusion of concurrency.
- The execution of multiple threads on a single CPU based on some algorithm is called thread scheduling.
- Thread scheduler maintains a pool of all the ready-to-run threads. Based on fixed priority algorithm, it allocates free CPU to one of these threads.
|
|
The Life Cycle of a Thread The following diagram illustrates the various states that a Java thread can be in at any point during its life and which method calls cause a transition to another state.
- Ready-to-run
A thread starts its life cycle with a call to start(). For example
MyThread aThread = new MyThread();
aThread.start();
A call to start() will not immediately start thread's execution but rather will move it to pool of threads waiting for their turn to be picked for execution. The thread scheduler picks one of the ready-to-run threads based on thread priorities.
- Running
The thread code is being actively executed by the processor. It runs until it is swapped out, becomes blocked, or voluntarily give up its turn with this static method Thread.yield();
Please note that yield() is a static method. Even if it is called on any thread object, it causes the currently executing thread to give up the CPU.
- Waiting
A call to java.lang.Object's wait() method causes the current thread object to wait. The thread remains in "Waiting" state until some another thread invokes notify() or the notifyAll() method of this object. The current thread must own this object's monitor for calling the wait().
- Sleeping
Java thread may be forced to sleep (suspended) for some predefined time.
Thread.sleep(milliseconds);
Thread.sleep(milliseconds, nanoseconds);
Please note that static method sleep() only guarantees that the thread will sleep for predefined time and be running some time after the predefined time has been elapsed. For example, a call to sleep(60) will cause the currently executing thread to sleep for 60 milliseconds. This thread will be in ready-to-run state after that. It will be in "Running" state only when the scheduler will pick it for execution. Thus we can only say that the thread will run some time after 60 milliseconds.
- Blocked on I/O.
A java thread may enter this state while waiting for data from the IO device. The thread will move to Ready-to-Run after I/O condition changes (such as reading a byte of data).
- Blocked on Synchronization.
A java thread may enter this state while waiting for object lock. The thread will move to Ready-to-Run when a lock is acquired.
- Dead
A java thread may enter this state when it is finished working. It may also enter this state if the thread is terminated by an unrecoverable error condition. |
|
Thread Synchronization Problems may occur when two threads are trying to access/modify the same object. To prevent such problems, Java uses monitors and the synchronized keyword to control access to an object by a thread.
- Monitor
- Monitor is any class with synchronized code in it.
- Monitor controls its client threads using, wait() and notify() ( or notifyAll() ) methods.
- wait() and notify() methods must be called in synchronized code.
- Monitor asks client threads to wait if it is unavailable.
- Normally a call to wait() is placed in while loop. The condition of while loop generally tests the availability of monitor. After waiting, thread resumes execution from the point it left.
- Synchronized code and Locks
- Object lock
Each Object has a lock. This lock can be controlled by at most one thread at time. Lock controls the access to the synchronized code.
- When an executing thread encounters a synchronized statement, it goes in blocked state and waits until it acquires the object lock. After that, it executes the code block and then releases the lock. While the executing thread owns the lock, no other thread can acquire the lock. Thus the locks and synchronization mechanism ensures proper exceution of code in multiple threading.
|
|
Thread Priority A thread's priority is specified with an integer from 1 (the lowest) to 10 (the highest), Constants Thread.MIN_PRIORITY and Thread.MAX_PRIORITY can also be used. By default, the setPriority() method sets the thread priority to 5, which is the Thread.NORM_PRIORITY.
Thread aThread = Thread.currentThread();
int currentPriority;
currentPriority = aThread.getPriority();
aThread.setPriority( currentPriority + 1 ); | | |