I got the task to design a distributed system that basically consists of one centrally shared database and multiple fat clients (Swing based GUIs) that should interact with this database. I basically want to administrate some addresses, deadlines, tasks, etc. I am currently using Java 6 SE, JPA (eclipse-link), and a MySQL database. Now I am facing some problems:
How is client 2 informed about data changes committed to the database by client 1? Is it a good idea to use an RMI approach for messaging?
I am dealing with stale data, since the JPA EntityManager caches the query results. Does it make sense to broadcast "db-change"-messages to all active clients so that they may refresh the locally cached entity objects?
Is there a much simpler approach to achieve these goals by using an application server like GlassFish? Or is the usage of Java EE application servers only convenient for web development? (sorry for these newbie questions, but I really didn't find any clear answers by reading the Java EE docs, or I simply didn't get it :-/ ...)
Any help is highly appreciated - many thanks in advance!
Is there a much simpler approach to achieve these goals by using an application server like GlassFish ?
That is the precise point of an application server (which is distinct from a web-server) in a 3-tier setup. Certainly you can poll and/or use messaging to provide additional hooks for meta-data (e.g. db change event) communication, but you will end up poorly reinventing a very well known (and non-trivial) wheel (e.g. data synchronization in a distributed tier).
If you can live without caching query results in the client and latencies of accessing the server (2nd tier) for data access are acceptable, then clearly that is the way to go.
[below is a fairly late p.s. but happened to read this and the question again today and personally felt it required clarification.]
Java EE is a distributed container/component based architecture for the enterprise tier. Putting aside the failure of a component market to emerge for J2EE (though some did try) what is remains is the fact of its COA and its inherent support for distribution as a foundational concern of the architecture. Note that the web profile (e.g. "web-server") of Java EE is also part of the same architecture.
So what do you get when you use one of these Java EE application servers and how would it address your requirement/design concerns.
Two important key aspects of the support for distribution offered by Java EE are its (a) distributed name-space (JNDI), and (b) its menu of offerings for connectivity across tiers (pure RMI (where you roll your own distributed RPC based system), Enterprise Beans aka EJBs (remotely and locally exposed component interfaces with well defined semantics in terms of lookup and life-cycle in distributable containers). Of the EJB flavors, in terms of connection semantics, you have messaging (JMS) and straight-up RPC.
For your case, you could, for example, opt for a JMS message bus with both fat-client JMS end-points and MessageDrivenBean EJBs. You c/would design a messaging domain with both topic/subscription based and straight up Queues. These can be declaratively configured to be durable, or not, etc.
Your application server c/would provide this JMS provider, or you could opt for a best of breed, e.g. TIBCO, for your needs, per your requirements.
You are not reinventing any of the above very non-trivial concerns. Your focus remains your domain requirements, and you have all the tools you need to create, within certain reasonable SLAs, your platform.
A viable alternative to this is to compose what boils down to the same exact thing minus the COA approach of Java EE (which both gets you declarative magic and pita development ceremony) with stand alone OSS software e.g. ØMQ for your bus, REST remote RPC, and possibly REDIS for beefing up persistence guarantees for your messages and for coordinating (no JNDI ..) your distributed balls in the air.
I personally prefer that latter, given that it is more fun for me. Also efficiencies gained due to more direct control over the distribution layer allows for scalability gains given very stringent requirements (e.g. a tiny minority of requirements out there).
A distributed system design for the enterprise ("have been tasked") needs to consider business requirements beyond merely the application domain. That is part of the equation.
Hope this is helpful (and timely ;)
Since you are using JPA you could benefit from its entity locking and concurrency mechanisms.
There are two main concepts for JPA (Quoted from Java EE 6 tutorial):
Optimistic locking:
By default, persistence providers use optimistic locking, where,
before committing changes to the data, the persistence provider checks
that no other transaction has modified or deleted the data since the
data was read. This is accomplished by a version column in the
database table, with a corresponding version attribute in the entity
class. When a row is modified, the version value is incremented.
Pessimistic locking:
Pessimistic locking goes further than optimistic locking. With
pessimistic locking, the persistence provider creates a transaction
that obtains a long-term lock on the data until the transaction is
completed, which prevents other transactions from modifying or
deleting the data until the lock has ended. Pessimistic locking is a
better strategy than optimistic locking when the underlying data is
frequently accessed and modified by many transactions.
Choose the strategy that fits best to your application behavior and functional requirements.
the fat clients can poll on a configured interval. This is similar to mail clients like outlook, which poll for new e-mail messages.
Your clients conceptually connect to a "middle-tier" which contains the "business logic".
You clients send all requests to the "middle-tier" and the "middle-tier" preforms them. This means that if a middle tier cares about coordinating clients, the middle-tier can remember which clients have "looked at" an important object, and (provided the technology supports it) can transmit an update to the appropriate clients.
Clients mainly contain code to present the data under this scenario, and the code they contain to accept requests mostly proxies the request to the middle tier.
Related
Is Hibernate less effective in some environments, like a polygot company where several distributed systems are accessing the same db? If Acme Company has a python website reading from and writing to the same database as a java web app (web services), will Hibernate be a poor choice for the java web services app? In other words, does Hibernate caching and session management assume all db transactions for Acme will be using Hibernate? Do I need to be sensitive to certain ORM concerns at a company where several programming languages are writing a lot of updates to the same data concurrently? Is Hibernate more advantageous for a strict java shop using a java ee app server for nearly all of its business operations?
Hibernate does have some performance overhead over pure JDBC, but if you're using it cautiously it should be fine for most of use cases.
Hibernate does not assume that it handles all operations itself. The only thing I would worry about is second level cache if you need it. You won't have a way to keep it in sync if other apps access the same DB (but you don't have to use it).
Having said that, I must add that having multiple apps write to the same DB is not a good practice. I'd rather create one app that handles this DB and have others communicate with this one - this way it's much easier to keep the database consistent.
Hi guys: I've "simplistic" workflow management tricks (like rotating file queues, controller threads, etc...) work in a wide variety of producer/consumer contexts... Where files are simply renamed, deleted, and created in a systematic manner; or where a "main" thread is calls and coordinates workers.
In contrast, I've also "played" with JMS in some toy applications, and I can see how it might be used to coordinate a complex application workflow.
I was wondering: What do messaging services like JMS offer over standard producer/consumer workflows (of course, if I'm missing something here, or have the wrong idea of when/why JMS is used, feel free to correct me)?
In particular, what type of applications require enterprise-grade messaging frameworks?
What do messaging services like JMS offer over standard producer/consumer workflows?
Scalability, availability, transparency, manageability. In point-to-point communication sender is bound to the receiver and vice versa. You, as the application developer, are responsible for thinking what to do when traffic increases and implement the necessary changes. Your application must be aware of the environment in which it works and must be changed every time the environment changes. You are forced to reinvent the wheel while solving typical messaging problems, for example, temporary congestion (what to do when the consumer can't keep the pace with the producer for a while?). You have to provide your own means of monitoring the current situation, if something does not work as expected. The list goes on...
Now imagine you have to wire 10 different systems this way. Obviously, you'll need to come up with a fairly universal solution so that you don't implement each connection logic from scratch — that would be terribly expensive to produce, not to mention maintaining it. A JMS message broker is one of such possible general solutions.
In particular, what type of applications require enterprise-grade messaging frameworks?
Complicated, in short. I work for a company that has a network of about 70 systems, some of them 30 years old. New systems are added to the network as time passes and the old systems don't need to be changed, neither must new systems be aware of ancient data exchange protocols — a centralized cluster of message brokers can translate a JMS message into some mainframe message format I have no idea about, and same way back with the answer.
Let's say you want to build a web application with high scalability (over 10,000 simultanious users). How do you guarantee good and steady performance? What design patterns are recommendable? What are most frequent mistakes?
Are there frameworks that force yourself to write scalable code? Would you maybe consider php as frontend and Java as backend technology? Or is let's say JSF reasonable as well and it's all about your architecture? And how good is developing with Grails in that context?
Hope this thread is not too subjective but I like to gather some experiences of you :-)
If you want to build a highly scalable application then it should be stateless and use shared nothing architecture as much as possible. If you share nothing between nodes and a node dont have a state then synchronization is minimum. There are several good web frameworks suitable for your requirements (Play Framework and Lift for Java, Django for Python, Ruby on Rails for Ruby).
As for JSF and related technologies, I dont think it would be wise to use them in your case. A good old request-responce is better.
If you want your application to scale nicely and perform well then you need to have a Distributed Cache. Distributed cache can incredibly boost up application performance and for this purpose you can use any third party distributed cache like NCache.
With so many simultaneous users (a situation I confess I've never encountered myself), what I think is the most important is to be able to load-balance your charge across many web servers.
If you want failover (which is probably a must-have), this means that you must be very careful about state : the more state you have, the more memory you need, and the more difficult it is to handle failover between servers : either you need to persist the session state in a location that is common to all the servers, or you need to replicate the state across servers.
So, I would choose an architecture where you don't need too much state on the server. IMHO, an action based framework is more suited to this kind of architecture than a component-based one, unless the state is handled at client side, with rich JavaScript components.
To transfer data from one system to another, through data interface, by web services, we normally get a result set by SQL query, and format them as a web service endpoint, and allow it to be retrieved by another side.
With EJB 3.0, it seems we can replace the result set by stateless session bean. So are there any advantages over the SQL-based web services? And when should we use it?
This is a very broad question on the system architect level. I will try to answer with my best knowledge without starting a flame war (FYI, I have used both ejb and spring).
As you know, building a stable/robust software application requires many building blocks, such as logging, connection pool, etc. Usually, you can find libraries of these building blocks, but not all of them have common api, so they may require integration. In the worst case, you may have to lock into some vendors. The main idea of EJB 3 (or Java EE) is to provide a more complete set of building blocks (via API, annotation or config), so developers can start working on the core business logic right away with an industry standard API/spec/config without training on the proprietary APIs. Additionally, you can change vendor without changing your codes since API/config are really the industry standard (well, your mileage may vary a lot in the real life. hopefully, the new Java EE will fix it).
Your application may already have some of the main elements that EJB 3 already provides. However, EJB 3 promises to provide more such as ORM mapping, RMI, Load balancing, failover, transactions, dynamic redeployment, logging, system management, thread managing, resource pooling (db connection), security, caching.
As you have an working application already, you can really consider if it is worth of your efford to migrate your codes to a standard system to gain more functionality vs integrate new functionality individually. Additionally, EJB 3.0 (or Java EE) is not really the framework that you can pick. You can also look into other framework, such as Spring.
My suggestion is to really figure what your system requirements, and then pick the right technologies instead of picking up the coolest technologies first.
Good luck
I wonder how is the best way to integrate Java modules developed as separate J(2)EE applications. Each of those modules exposes Java interfaces. The POJO entities (Hibernate) are being used along with those Java interfaces, there is no DTO objects. What would be the best way to integrate those modules i.e. one module calling the other module interface remotely?
I was thinking about: EJB3, Hessian, SOAP, JMS. there are pros and cons of each of the approaches.
Folks, what is your opinion or your experiences?
Having dabbled with a few of the remoting technologies and found them universally unfun I would now use Spring remoting as an abstraction from the implementation.
It allows you to concentrate on writing your functionality and let Spring handle the remote part with some config. you have the choice of several implementations (RMI, Spring's HTTP invoker, Hessian, Burlap and JMS). The abstraction means you can pick one implementation and simply swap it if your needs change.
See the SpringSource docs for more information.
The standard approach would be to use plain RMI between the various service components but this brings issues of sharing your Java interfaces and versioning changes to your domain model especially if you have lots of components using the same classes.
Are you really running each service in a separate VM? If these EJBs are always talking to each other then you're best off putting them into the same VM and avoiding any remote procedure calls as these services can use their LocalInterfaces.
The other thing that may bite you is using Hibernate POJOs. You may think that these are simple POJOs but behind the scenes Hibernate has been busy with CGLib trying to do things like allow lazy initialization. If these beans are serialzed and passed over remote boundaries then you may end up with odd Hibernate Exception getting thown. Personally I'd prefer to create simple DTOs or write the POJOs out as XML to pass between components. My colleagues would go one step further and write custom wire protocols for transferring the data for performance reasons.
Recently I have been using the MULE ESB to integrate various service components. It's quite nice as you can have a mix of RMI, sockets, web services etc without having to write most of the boiler plate code.
http://www.mulesource.org/display/COMMUNITY/Home
Why would you go with anything other than the simplest thing that works?
In your case that sounds like EJB3 or maybe JMS, depending on whether the communication needs to be synchronous or asynchronous.
EJB3 is by far these easiest being built on top of RMI with the container providing all the additional features you might need - security, transactions, etc. Presumably your POJOs are in a shared jar and therefore can simply be passed between your EJBs, although I tend towards passing value objects myself. The other benefit of EJB is, when done right, that it's the most performant (that's just my opinion btw ;-).
JMS is a little more involved, but not much and a system based on asynchronous communication affords certain niceties in terms of parallelizing tasks, etc.
The performance overhead of web-services, the inevitable extra config and additional points of failure make them, IMHO, not worth the hassle unless you've a requirement that mandates their use - I'm thinking interop with non-Java clients or providing data to external parties here.
If you need network communication between Java-only applications, Java RMI is the way to go. It has the best integration, most transparency and the least overhead.
If, however, some of your clients aren't Java-based, you should probably consider other options (Java RMI actually have an IIOP-dialect, which allows it to interact with CORBA, however - I wouldn't recommend doing this, unless it's for some legacy-code integration). Depending on your needs, webservices are probably your friend. If you are conserned with the networkload, you could go webservices over Hessian.
You literally mean remotely? As in running in a different environment with therefore different availability characteristics? With network overheads?
Assuming "yes" my first step would be to take a service approach, set aside the invocation technology for a moment. Just consider the design and meaning of your services. You know they are comparativley expensive to invoke, hence small busy interfaces tend to be a bad thing. You know that the service system might fail between invocations, so you may favour stateless services. You may need to retry requests after failure, so you may favour idempotent service designs.
Then consider availability relationships. Can your client work without the remote system. In some cases you simply can't progress if the remote system isn't available (eg. can't enable the employee if you can't get to the HR system) in other cases you can adopt a "fire-and-tell-me-later" philosophy; queue up the requests and process responses later.
Where there is an availability depdency, then simply exposing a synchronous interface seems to fit. You can do that with SLSB EJBs, if everything is Java EE, that works. I tend to generalise expecting that if my services are useful then non Java EE clients may want them too. So SOAP (or REST) tends to be useful. These days adding a web service interface to your SLSB is pretty trivial.
But my pet theory is that any sufficiently large IT system ends up needing aynch communications: you need to decouple the availability contraints. So I would tend to look for a JMS-style relationship. An MDB facade in front of your services, or SOAP/JMS is not too hard to do. Such an approach tends to highlight the failure-case design issues that were probably lurking anyway, JMS tends to make you think: "suppose I don't get an answer? suppose my answer comes late?"
I would go for SOAP.
JMS would be more efficient but you would need to code up an message driven bean for each interface.
SOAP on the other hand comes with lots of useful toolkits that will generate your message definition (WSDL) and all the neccesary handlers (client and server) when given an EJB.
With soap you can (but dont have to) deal with certificate security and secure connections over public networks. As the default protocol is HTTP over port 80 you will have minimal pain with firewalls etc. SOAP is also great for hetrogenious clients (in your case anything that isn't J2EE) with good support for most common languages on most common platforms.