Maybe I just expected "three-tier architecture" to deliver a little more than just a clean separation of responsibilities in the source code (see here)...
My expectations to such a beast that can safely call its self "three-tier architecture" are a lot higher... so, here they are:
If you were to build something like a "three tier architecture" system but this time with these, additional requirements and constraints:
-
Up and running at all times from a Users point of view
- Expect when the UI gets replaced
- When other parts of the system are down, the UI has to handle that
-
Never get into a undefined state or one from which the system cannot recover automatically
- The system has to be "pausable"
-
The middle-tier has to contain all the business logic
- Obviously using an underlying Database, itself in the data-tier (if you like)
-
The business logic can use a big array of core services (here in the data-tier, not directly accessible by the UI, only through business logic tier facade)
- Can be unavailable at times
- Can be available as many parallel running, identical processes
- The UI's may not contain any state other than the session in case of web UI's and possibly transient view baking models
- Presentation-tier, logic-tier and data/core-services-tier have to be scalable independently
- The only thing you can take for granted is the network
Note: The mentioned "core services" are heavy-weight components that access various external systems within the enterprise. An example would be the connection to an Active Directory or to a "stock market ticker"...
1. How would you do it?
If you don't have an answer right now, maybe read on and let me know what you think about this:
- Sync considered harmful. Ties your system together in a bad way (Think: "weakest link"). Thread blocked while waiting for timeout. Not easy to recover from.
- Use asynchronous messaging for all inter-process communication (between all tiers). Allows to suspend the system anytime you like. When part of the system is down, no timeout happens.
- Have central routing component where all requests get routed through and core services can register themselves.
- Add heartbeat component that can e.g. inform the UI that a component is not currently available.
- State is a necessary evil: Allow no state other than in the business logic tier. This way the beast becomes manageable. While the core services might well need to access data themselves, all that data should be fed in by the calling middle tier. This way the core services can be implemented in a fire and forget fashion.
2. What do you think about this "solution"?