- Core:
- Full documentation:
- Deployer:
-
Extras:
- JMX Remote jar (pgp, md5)
- Web services jar (pgp, md5)
- JULI adapters jar (pgp, md5)
- JULI log4j jar (pgp, md5)
I installed apache tomcat 6 on my server and created my first index page in the ROOT folder and everything worked perfectly. But as soon as I started to attempt to tweek the page to make it look how I wanted it to I noticed that the changes where not being reflected in the borwser and the old page continues to be displayed. Does anyone know why it does this and how it can be fixed so I can see changes immediately?
There are a number of settings which may apply to your situation.
If the file you are editing is a small 'static' file, Tomcat may be caching it in memory. The attribute values of the Context element which govern this are: cacheMaxSize, cacheObjectMaxSize, cacheTTL and cachingAllowed.
You can find more details about their values in the Tomcat Documentation at: http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
If the resource you are editing is a JSP file, then you should check to see if the attributes of org.apache.jasper.servlet.JspServlet in apache-tomcat-6.x/conf/web.xml have been adjusted - it's usual to disable attributes associated with file recompilation during development, before placing the server into production.
Each attribute is well documented in the configuration file, it's worth reading the whole of the standard web.xml to understand more about how Tomcat works.
I'm using Tomcat 6 and am having trouble getting large pages to load. We've developed a page for a site that gets generated for specific cities. When I test it on my IDE, it works without a hitch. However, when I deploy the app to our server running tomcat 6, on locations with a small amount of information seem to work. I've isolated that it related to the size of what is being generated. Is there a way to increase the size of the files that tomcat will generate from jsps?
There is a restriction on the size of a compiled method, which is 64kb of bytecode - but this must not be confused with the size of the data output from a method.
I'd expect it to be a low probability that you've run into this restriction, but if you have then it shouldn't be too hard to refactor the JSP to get around it.
From the limited information you provide it's nearly impossible to tell what the likely source of the problem is. I'd be looking for Exceptions in the Tomcat logs and examining whether the page was failing because it depended on other resources which are unable to deliver large amounts of information in a timely fashion.
If the problem is reproducible then it should be relatively easy to narrow down the portion of the code which causes the problem; even if this means selectively commenting out section of the JSP and testing each part of it separately.
You have a few problems, the cause of them is not entirely clear.
One thing to bear in mind is this: when you're using Apache HTTPD in front of Tomcat, if you can get it working under normal HTTP then configuring HTTPS should be simple.
HTTP and HTTPS in Apache HTTPD are treated as separate VirtualHosts, so it should just be a case of ensuring that whatever configuration you've applied to the HTTP virtual host is also applied to the HTTPS host.
This can be achieved with ease, by placing all of the mod_jk or mod_proxy (in your case) configuration in an external file and using the 'include' mechanism.
The HTTP address you provide is using the port 8080, which Tomcat specifies as the default port for it's own HTTP connector - suggesting that you're not connecting via Apache HTTPD when you make that request.
The ProxyPass statements point both /abc and / to the same path, which is a subpath of the application /abc - this seems unusual. I'd expect to see the path http://server:8080/abc, without the '/implement' extension, this may be the source of some of the missing images.
The last issue, regarding the message "line 56 Object expected" is likely to be a Javascript problem, possibly caused by a script file experiencing the same 404 as the images.
In order to debug the problem, it would be better to start with a fresh configuration - discard whatever you have so far, or copy it to a backup.
The Fiddler or ieHttpHeader plugins for Internet Explorer will make it easier to examine which resources are, or are not being served correctly.
You will need to examine both the Apache HTTPD and Tomcat access logs to see which server is serving each request and check that the result is the expected one.
Configure the HTTP instance and test it thoroughly before attempting the HTTPS configuration.
How many "simultaneous users" can a Tomcat server support and where do I find this setting? I've read on the internet that Tomcat is limited to 15 "simultaneous users" and that Tomcat supports "unlimited numbers" of users. What's the real story?
Tomcat doesn't have such a setting and you shouldn't trust everything you read on the internet!
A limitation like 15 simultaneous users would make the large scale, high availability Tomcat deployments that are already powering banks, government applications and large corporations completely impossible. On the Apache Tomcat Users mailing list, for example, we see people fairly frequently who are debugging their applications under load tests simulating thousands of concurrent users.
One of the advantages of using software like Tomcat is that it provides the Servlet Spec environment, (which is usually enough to support most applications with a few Apache Commons libraries or the use of frameworks like Struts and Spring), but it's lightweight and uses comparatively little in the way of system resources itself.
The amount of concurrent users will depend on the server hardware (processors, memory), the types of resources being used within the application and what your application is actually doing. A fictional application which generates PDF reports on demand from large amounts of data, taking minutes for each request is going to need substantially more server resources to support a similar number of users to an application which is serving largely static or cached resources.
In Tomcat versions 6.0 and up, the best way to configure the number of threads the Connector uses is via the Executor element. http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html
The default setting for the maxThreads attribute is 200, which should be enough to get most applications started. In fact, in my experience you'll need to add more servers to scale up because of application memory usage before the maxThreads attribute gets too high.
So, to answer each question: Tomcat is not limited to 15 users; it will support however many concurrent users your application(s) can support.
How do you gracefully restart Tomcat? It will be good to have a standard way doing this. We created a health check url for the load balancer (e.g. /health). This url returns 200 status to indicate this service is up. There is a prob.txt under tomcat dir. If we delete this file, the health check will start returning 404. Thus, remove this box from load balancer. Wait for 2 to 3 mins before shutting it down the process to ensure all request have been processed.
Tomcat, unlike Apache HTTPD, does not have a graceful restart function, largely because of the consequences of it being an application server rather than a web server.
The restart time for server itself largely depends on how long it takes your application to start up, you should be able to start a fresh Tomcat instance in a few seconds - it's worth noting how long it takes to start up on your system, before you customise the configuration.
Instead of restarting the server, you can restart individual applications, which is nearer to the concept of a graceful restart and wouldn't incur the overhead of restarting all of the applications.
An appropriately secured* Manager application instance in each Host, will enable you to selectively restart an application. Automated requests can be sent to the /manager/text component using the same request structure as the /manager/html component, but with smaller output.
* The Manager application should be secured by adding the RemoteIpValve to it's Context definition, with only the specific IP addresses you'll administer the server from enabled.
You've spent a lot of time setting up a private cloud of servers. Everything's virtualized and you have it organized by function. Your messaging VMs run on these hosts and your web servers run on those hosts. You've tested it extensively and you're happy with how everything talks to each other. The worst is over, right? Wrong. Now you have to move past the theoretical and actually use this thing in production. It's time to start deploying the applications you're building into this cloud of virtualized resources. It's time to develop some scheme to keep your applications updated when changes are made. Keep in mind, whatever mistakes you inject at this point will be multiplied by the number of machines that deploys to.
Scared yet?
Don't be! It's really not that hard. In this article, I'll introduce you to some concepts I used in developing the fairly simple system of messages and scripts that deploy artifacts into our private cloud. This won't be a technical HOWTO so much as it will be a casual dinner conversation about the pitfalls and rewards. Above all, I want to get across that having a bunch of virtual machines that do the same thing doesn't have to keep you up at night.
Grails is a rapid application development framework for web applications on the Java platform. It's similar in many respects to Ruby on Rails, but it's based on Java libraries, like Spring and Hibernate, and the Groovy language. It also produces standard WAR files that can be deployed to a servlet container like Tomcat. That means you can deploy Grails applications to a Tomcat cluster and in this article I'll show you how.
In order to demonstrate clustering, we need an application to deploy. Assuming that Grails is installed (I was using Grails 1.3.3 - the latest) we can create a brand new application with the command
grails create-app my-cluster-app
This will create a my-cluster-app directory containing the project. If we then switch to that directory, we can generate a WAR file straight away by running
grails war
Of course, the application doesn't do anything yet. Nor is it ready for clustering.
It used to be common practice to "spare" the Tomcat server the drudgery of serving static content like images, CSS stylesheets, and JavaScript because it was faster to do that with Apache. That really hasn't been the case for quite a while now. With Tomcat adopting NIO and some of the really low-level performance improvements of sendfile and Asynchronous IO (AIO), it's not strictly necessary to have Apache in front of Tomcat any more.
We're probably like a lot of folks, though, and we have to have an Apache server somewhere to support the PHP applications we have (bad idea, long story). Since we already have an Apache server, we also use it to serve our static resources, just like everyone's been doing for years. We started with mod_jk because that was the only viable option at the time. When mod_proxy got AJP support, we switched to using Apache's mod_proxy and saw a nice performance boost. We stayed with this configuration for several years just because it's not terribly complicated and it just works.
But fronting Tomcat servers with Apache is pretty limiting when you start talking private cloud architectures. I discovered some big problems when I first fired up our SpringSource tcServer instances fronted by a couple of DNS round-robin load-balanced Apache servers. Tomcat was getting confused because requests were coming through different front-end proxies. I wrote my own session manager, which I discussed recently in two blog posts (Part I & Part II), to get around this problem. But I still had the limitation of forcing users to go to an Apache server before being able to access the dynamic resources located in my tcServer backends. This created issues when I needed to take down the server Apache was running on.
I’ve been sharing some thoughts about what’s become a significant trend in many IT organizations, and in particular with my clients…converting Java applications from JEE Application Servers to Tomcat, and more typically Tomcat+add-ons.
Many IT organizations are re-thinking their commitment to commercial JEE Application Servers, due to both challenging business environments that drive the need for more cost effective application architectures and the need to transition to more responsive/agile applications development. When IT organizations talk about “migrating” their applications, I’ve noted that they generally are focusing on one or more of three distinct situations. These are:
I’ve been focusing on the migration of existing JEE applications to the most popular of the light weight containers, Tomcat. There are many excellent reasons to consider moving applications off of the commercial JEE servers sold by Oracle/BEA, IBM, etc. While we are focusing on the migration process, many of the business and technical decision factors apply equally well to the second and third situations.
This time, I will be discussing the technologies involved in migrating JEE application code from commercial JEE servers to Tomcat. I’d like to thank the kind (and very expert) folks at SpringSource, as well as a number of other friends around the industry, for their valuable insight regarding the technologies involved. Any errors (and opinions) are mine alone. Additionally, some of the material draws on information published by SpringSource and other open source materials found on the internet.
In my first article on taking advantage of RabbitMQ's asynchronous messaging to implement a cloud-friendly session manager, I covered the method behind the madness and introduced you to some of the functions a session manager has to perform in the course of doing its job. In this, the second of two articles covering this topic, I'll describe how loading and updating session objects is handled and, in the interest of fairness, give some disclaimers and acknowledge the trade-offs made to get here.
Whenever code wants to interact with a user session, whether that be to load it into its own memory or to replicate attributes on that session, it sends these messages to a queue whose name contains the session ID. The pattern used to create the queue name is configurable so you can partition user sessions by application, or even by something more fine-grained (without resorting to using multiple, non-clustered RabbitMQ servers).
The session store first checks its internal Map to see if the requested session happens to be local to this store. If it is, the store simply hands that session back to the manager. If it's not, then the store sends a "load" message to the session's queue. It doesn't just fire off a message, though. It turns out that a user's session can be requested from the store many times during the course of a request. If one were to send a load message every time this happens, then we would see a serious performance degradation. To get around this, before a load message is sent, the store checks to see if it's already trying to load this session. If it is, it simply waits until that process is finished and uses the session being loaded in that other thread.
Popular Links