Hi, I am for the first time facing the developpement of large-scale application that will have the following requirements:
- 24/7 service with no interruption at any time (even during updates)
- a constantly increasing number of users and therefore increasing load on the application server
- development of a web service (used by a mobile application)
- many automated tasks
- fast-growing application with future development of many new modules and other client applications interacting with the core components of the systen
I have been investigating and reading tons of tutorials and articles I could find on the web, but technology is evolving fast and the choice of framework for every tier of my application is vast, so here is what I could put together, I would like to know if I am heading in the right direction or in wall.
I chose EJB3.1 running on a J2EE server for the following reasons:
- EJB3 is a standard
- easy to scale/cluster (load balancing) the system to handle higher load
- easy to turn an EJB interface into a web service
- use of EJB Timers for automated tasks
a few things are still unclear to me however, if you could help me to understand:
- I could also balance the load separating the web application from the business logic on 2 different servers, but in this case I would need to use remote interfaces for my EJBs? which from what I understand is a loss of performance compared to using local interfaces if the web app resides on the same machine/JVM. Using local interfaces and keep the web and business tier on the same JVM seems to me the most efficient solution, what do you think? and I would use remote interfaces only for any future distributed client application.
I chose JPA 2.0 with Hibernate because I already have knowledge and many in-house tools developed.
I am still undecided for the web tier, there are so many different frameworks.
Which web framework is mostly used for the web tier? I read that Struts is not a good option anymore, and there are many others like Spring, Tapestry, Wicket, JSF... I have knowledge in Spring3, can it be used only for the web tier to take advantages of Spring Security, Spring Social and many other Spring features. I think I should be easily able to call EJBs from my Spring controllers? Is it good practice to do that?
So my current orientation for now is a Spring + EJB3 + Hibernate system running on a J2EE server (Glassfish or JBoss). The application's availabilty, scalability and performance is critical in this project as the load will quickly increase.
I am not very experienced with such big scale projects, but I am really eager to learn and I hope I could use your experience to guide me in the right direction.
Thanks a lot for your precious help!
The answers to your questions depend quite a lot on one's opinion. I will give you my opinion on it, because I find this an interesting question and one I've answered quite a few times.
My preferred business tier is EJB 3.1 or simply just CDI beans if you don't need transactions. EJBs are handy for DAOs as they can give you transactions but otherwise just using beans is usually sufficient.
For data tier I like JPA 2 but with EclipseLink. Having worked with both over the years, I've found EclipseLink to be more forgiving and output more understandable logs.
For webservices I like JAX-RS with RestEasy, assuming your clients are OK with REST. Mobile clients usually are, but larger enterprisey clients usually want SOAP based webservices.
This is all assuming you're using a JEE6/7 application server and CDI for dependency injection. Many people still like to use Spring for DI, but CDI really integrates easier and ties these things all together.
Now the question about load-balancing, failover, high availability veers out of the realm of JEE standards and more is a question of commercial vendor preference. Yes EJB can be used for remote interfaces for the backend, but I've never had much luck with that, and it's generally believed to be slow and messy. Slow is relative of course.
My preference is to use Resin as the application server, run the JSF/CDI/JPA/EJB all in the same JVM, and let Resin do the clustering, scaling, and failover. The "web-tier" in this case is a fairly thin layer that load-balances to the app-tier, handles failover, and caches static content locally. That way you only need to update your webapp on one layer, but after the first request for static content, it will be served from the web-tier.
Each application server vendor has their own high-availability solution, and this is for the most part what you pay for in a commercial application server. Many people start on Tomcat or Jetty, but these don't scale or support high availability without customization. Putting Apache or a hardware load-balancer in front of a Tomcat "cluster" works for some people, but how well depends on how statefull your application is and your downtime tolerance as failover events occur. Commercial app server typically support persistent distributed sessions so a machine failure won't result in the loss of a user's session. Also, Resin for example supports versioned webapp updates, meaning it can run 2 versions of the webapp at the same time. New users are directed to the new version, and the old version is removed once all the active sessions complete. But I'm sure other vendors have similar features to support very high availability systems.