How would you architect a three-tiered web application to limit downtime? - distributed-computing

My specific questions are :
1) How would you architect a three-tiered web application to limit downtime?
2) How to eliminate point of failures from a 3 tiered architecture
I could not find any resources that specifically answer these questions. I would like to the opinion of the community

Regardless of which architecture you choose failure could happen and would happen. the real question isn't elimination of fault but reducing.
In 3 tier you may have ui, business layer and db access layer. any of these is single point of failure. so one goes down whole app stops working.
You have to rely on redundancy. You may need to deploy mutiple copies of each tier. the more copies you deploy the more fault tolerant it is. generally each tier talks to load balancer to talk to down stream services. and load balancer will be balancing multiple copies on each tier.

Related

Tradeoff between building own distributed system and using kubernetes to deploy my application

I’m proposing a project to my school supervisor, which is to improve our current server to be more fault tolerant, easily scaling and able to handle high traffic.
I have a plan to build a distributed system starting from deploying our server to different PCs and implement caching and load balancing, etc.
But I want to know whether Kubernetes already can satisfy my objective? what are the tradeoff between using Kubernetes and building own distributed system to deploy applications?
Our applications are built with Django and most are likely used by students such course planner or search/recommend systems.
You didn't give any details of your app, so I'll provide some generic thoughts. Shortly speaking, Kubernetes gives you scheduling, load balancing and (sort of) high availability for free. You still have to plan proper application architecture but Kubernetes gives you a good starting point where you can say like "ok, I want this number of app containers to run on this number of nodes". It also gives you internal load balancing and DNS resolution.
Of course, the tradeoff is that you have to learn Kubernetes and Docker up to some certain point. But I wouldn't say it's too hard for enthusiast.
I’m proposing a project to my school supervisor, which is to improve our current server to be more fault tolerant, easily scaling and able to handle high traffic.
This is a great idea. What you really want to do here is to use as many existing tools as you can, to let you focus on improving the core functionality of your current server - e.g. serving your users with your business logic and data and increase availability of this.
Focusing on your core functionality means that you should NOT do, e.g.
NOT write your own memory allocation algorithm or garbage collection
NOT write you own operating system
NOT write your own container scheduler (e.g. what Kubernetes can do for you)
I have a plan to build a distributed system starting from deploying our server to different PCs and implement caching and load balancing
Most applications deployed on Kubernetes or that have your availability requirements actually should be a distributed system - e.g. be composed of more than one instance, designed for elasticity and resiliency.
what are the tradeoff between using Kubernetes and building own distributed system to deploy applications?
Kubernetes is a tool, almost an distributed operating system that e.g. schedules containerized apps to a server farm. It is a tool that can help you a lot when developing and designing your distribued application that should follow the Twelve Factor principles.

Service Oriented Architecture approach

Is SOA solution by making a centralized service which works as a central backbone service for all other services is a good approach?
Its doable, but you need to consider service granularity.
Incorrect granularity could mean that a service covers too much functionality or too little functionality.
Incorrect granularity of services in your SOA can lead to bad performance, low reuse possibilities, leaky abstractions and services without added business value.
Other problems:
You're not able to explain to business people (e.g. sales/marketing) what the service does. It simply does not fit in their understanding of the business the company is in. The services are at a level of detail that is irrelevant from a business perspective.
Many different services are needed to achieve something of value to the business.
There is no clear ownership of the service, multiple department feel they should own the service (or parts of it).

Difference between Hub, Spoke and ESB

I know theres already a good question on this, but it doesn't really answer what I'm looking for.
From what I understand:
1.both are used as a central focal point between applications
2.both can use routing/mediation/transformation etc. between services/apps
But the only difference i can really see is that hub and spoke typically have many different formats entering the hub(SOAP/REST/XML/JSON...) while ESB typically has a standard format(Usually just SOAP.)
Also I keep reading that hub and spoke introduces a single point of failure compared to an ESB. So is the physical deployment the difference here? Where a hub has every possible endpoint and as ESB has endpoints deployed across multiple hubs? So an ESB is just multiple hubs(for want of better words)?
Can anyone help clear this up for me?
There is no exact answer here, since you can talk about ESB as a specific design pattern, or as the discourse about the evolution of software integration tools and SOA.
ESB as a design pattern means that you manage communication between different services using a bus where clients can easily plug in and out. This is usually done by forcing them to use standard data formats and protocols, whereas with Hub and Spoke you might use custom connectors and data transformations for each client. This limits the number of problems you may have with running multiple integrations, but you may still have a single point of failure in ESB.
ESB as a discourse (or marketing term) is a more complex issue, where people argue over what is "True ESB". Some people say you need to have a modular architecture where you can select which components you deploy, or you need to be able to distribute the components across different machines to allow scaling and fault tolerance. In the extreme definition you would need to deploy even your data transformers as distributed services.
From Here
The ESB is the next generation of enterprise integration technology, taking over where EAI(hub-spoke) leaves off.
Smarter Endpoints : The ESB enables architectures in which more intelligence is placed at the point
where the application interfaces with the outside world. The ESB allows each endpoint to present
itself as a service using standards such as WSDL and obviates the need for a unique interface written
for each application. Integration intelligence can be deployed natively on the end-points (clients and
servers) themselves. Canonical formats are bypassed in favor of directly formatting the payload to
the targeted format. This approach effectively removes much of the complexity inherent in EAI
products.
Distributed Architecture : Where EAI is a purely hub and spoke approach, ESB is a lightweight
distributed architecture. A centralized hub made sense when each interaction among programs had
to be converted to a canonical format. An ESB, distributes much more of the
processing logic to the end points.
No integration stacks : As customers used EAI products to solve more problems, each vendor added
stacks of proprietary features wedded to the EAI product. Over time these integration stacks got
monolithic and require deep expertise to use. ESBs, in contrast, are a relatively thin layer of software
to which other processing layers can be applied using open standards. For example, if an ESB user
wants to deploy a particular business process management tool, it can be easily integrated with the
ESB using industry standard interfaces such as BPEL for coordinating business processes.
The immediate short-term advantage of the ESB approach is that it achieves the same overall effect
as the EAI(hub-spoke) approach, but at a much lower total-cost-of-ownership. These savings are realized not
only through reduced hardware and software expenses, but also via labor savings that are realized by
using a framework that is distributed and flexible.
I don't know if you mean this when you say is physical deployment the difference here? but actually the main difference between Hubs and ESP is that, its communication system is in different Layer.
When we talking about an ESP we are reffering to a software architecture model where as a hub is reffering to a strict hardware connecting topology.
Profiously this hardware topology, (a collection of hubs) implements an ESP, but there is a distinct line in communication layers between the two.

Erlang/OTP architecture: RESTful protocol for SOAish services

Let us imagine we have an orders processing system for a pizza shop to design and build.
The requirements are:
R1. The system should be client- and use-case-agnostic, which means that the system can be accessed by a client which was not taken into account during the initial design. For example, if the pizza shop decides that many of its customers use the Samsung Bada smartphones later, writing a client for Bada OS will not require rewriting the system's API and the system itself; or for instance, if it turns out that using iPads instead of Android devices is somehow better for delivery drivers, then it would be easy to create an iPad client and will not affect the system's API in any way;
R2. Reusability, which means that the system can be easily reconfigured without rewriting much code if the business process changes. For example, if later the pizza shop will start accepting payments online along with accepting cash by delivery drivers (accepting a payment before taking an order VS accepting a payment on delivery), then it would be easy to adapt the system to the new business process;
R3. High-availability and fault-tolerance, which means that the system should be online and should accept orders 24/7.
So, in order to meet R3 we could use Erlang/OTP and have the following architecture:
The problem here is that this kind of architecture has a lot of "hard-coded" functionality in it. If, for example, the pizza shop will move from accepting cash payments on delivery to accepting online payments before the order is placed, then it will take a lot of time and effort to rewrite the whole system and modify the system's API.
Moreover, if the pizza shop will need some enhancements to its CRM client, then again we would have to rewrite the API, the clients and the system itself.
So, the following architecture is aimed to solve those problems and thus to help meeting R1, R2 and R3:
Each 'service' in the system is a Webmachine webserver with a RESTful API. Such an approach has the following benefits:
all goodness of Erlang/OTP, since each Webmachine is an Erlang application, which can be supervised and can be put into an Erlang release;
service oriented architecture with all the benefits of SOA;
easy adaptable to changes in the business process;
easy to add new clients and new functions to clients (e.g. to the CRM client), because a client can use RESTful APIs of all the services in the system instead of one 'central' API (Service composability in terms of SOA).
So, essentially, the system architecture proposed in the second picture is a Service Oriented Architecture where each service has a RESTful API instead of a WSDL contract and where each service is an Erlang/OTP application.
And here are my questions:
Picture 2: Am I trying to reinvent the wheel here? Should I just stick with the pure Erlang/OTP architecture instead? ("Pure Erlang" means Erlang applications packed into a release, talking to each other via
gen_server:call and gen_server:cast function calls);
Can you name any disadvantages in suggested approach? (Picture 2)
Do you think it would be easier to maintain and grow (R1 and R2) a system like this (Picture 2) than a truly Erlang/OTP one?
The security of such a system (Picture 2) could be an issue, since there are many entry points open to the web (RESTful APIs of all services) instead of just one entry point (Picture 1), isn't it so?
Is it ok to have several 'orchestrating modules' in such a system or maybe some better practice exists? ("Accept orders", "CRM" and "Dispatch orders" services on Picture 2);
Does pure Erlang/OTP (Picture 1) have any advantages over this approach (Picture 2) in terms of message passing and the limitations of the protocol? (partly discussed in my previous similar question, gen_server:call VS HTTP RESTful calls)
The thing to keep in mind regarding SOA is that the architecture is not about the technology (REST, WS* ). So you can get a good SOA in place with endpoints of several types if/when needed (what I call an Edge component - separating business logic from other concerns like communications and protocols)
Also it is important to note that service boundary is a trust boundary so when you cross it you may need to authenticate and authorize, cross network etc. Additionally, separation into layers (like data and logic) shouldn't drive the way you partition your services.
So from what I am reading in your questions, I'd probably partition the services into more coarse grained services (see below). communications within the boundary of the service can be whatever, where-as communications across services uses a public API (REST or Erlang native is up to you, but the point is that it is managed, versioned, secured etc.) - again, a service may have endpoints in multiple technologies to facilitate different users (sometimes you'd use an ESB to mediate between services and protocols but the need for that depends on size and complexity of your system)
Regarding your specific questions
1 As noted above, I think theres a place to expose more public APIs
than just a single entry point, I am not sure that exposing each and
every capability as a service with public-api is the right way to go
see.
2&3 The disadvantages of exposing every little thing is
management overhead, decreased performance (e.g. you'd have to
authenticate on these calls). You get nano-services services
whose overhead is more than their utility.
One thing to add about the security is that the fact that some service has a REST API does not have to translate to having that API available to the general public. Deployment-wise you can keep it behind a firewall and restrict the access to it for known addresses
etc.
5 It is ok to have several orchestrating modules, though if you get beyond a few you should probably consider some orchestration module (and ESB or an Orchestration engine) alternatively you can use event based integration and get choreography based integration which is more flexible (but somewhat less manageable )
6 The first option has the advantage of easy development and probably better performance (if that's an issue). The hard-coded integration layer can prove harder to maintain over time. The erlang services, if you wrote them write should be able to evolve independently if you keep API integration and message passing between them (luckily Erland makes it relatively easy to get this right by its inherent features (e.g. immutability))
I'd introduce the third way that is rather more cost effective and change-reactive. The architecture definitely should be service oriented because you have services explicitly. But there's no requirement to expose each service as Restful or WSDL-defined one. I'm not an Erlang developer but I believe there's a way to invoke local and remote processes by messaging and thus avoid unnecessary serialisation/serialisation activities for internal calls. But one day you will be faced with new integration issue. For example you will be to integrate accounting or logistic system. Then if you designed architecture well regarding SOA principles the most efforts will be related to exposing existing service with RESTful front-end wrapper with no effort to refactor existing connections to other services. But the issue is to keep domain of responsibilities clean. I mean each service should be responsible to the activity it was originally designed.
The security issue you mentioned is known one. You should have authentication/authorization in all exposed services using tokens for example.

Best Practices for deployments on a 24x7 system asp.net platform

We have built an enterprise web application on asp.net platform which is well load balanced across several servers. We are struggling a bit in terms of doing regular deployments as the application has been defined with an SLA of zero downtime.
Any guidance / tips would be highly appreciated for Implementing best practices to support uninterrupted deployment.
My two favorite books that cover some of these topics are Continuous Delivery by Humble/Farley and Web Operations by Allspaw/Robbins.
I think the "easy" part here is to do a rolling deployment where you pull a node out of the load balancer, upgrade it, run smoke tests, and place it back in the load balancer. Different users will encounter different versions of the app, but you get zero downtime.
The hard part is the backend system / database that these web-apps are likely hitting. You basically need to have both old and new schemas available concurrently which is challenging. Look at techniques like the expand / contract database pattern as an approach to pulling this off.