I have experience creating web applications using MS Asp.Net Stack (Asp.Net MVC / Web API), using 3-tier architecture (Monoliths)
I want to learn how to make applications scalable and maintainable, and want to clarify certain confusions with buzz-words.
- Distributed vs. SOA - I believe a scalable/maintainable application means segregating service layers (persistence, security, caching, etc.), and moving them to separate tiers. This is advocated by both distributed and SOA, so what's the difference b/w two?
- Service implementation, deployment and management - How to do it practically? I sense 2 types of services exist - Active and Passive.
- Passive Services - These kinds of services are essentially functions/methods that can be called to perform some operation. They can be implemented as WCF or Web API. With say 10 such services in hand, how do we implement, deploy (host) and manage them? How to know if any of service host goes down or malfunctions?
- Active Services - These kinds of services are active executables, and might be listening to a message-broker to fetch queued work. So, again, with say 10 such services in hand, how do we implement, deploy (host) and manage them? Do we create separate window services for each?
- Service Communication - with services segregated to different tiers, how to decide if they should communicate synchronously (web api) or asynchronously through message-broker (pub-sub)?
2 Answers
Answers 1
Here my perspective. Before I get to your questions let me address the general conception of monolith vs microservice: The difference lies in how the code is separated and what the goal is. For a monolith you try to apply techniques that aim to make it possible for a very large team (say 100s of engineers) to work on a single code base for an application. This means the introduction of layers and a lot of abstraction work typically to separate modules. And sometimes there is a lot of over-engineering in the design to promote reuse and separate layers at the same time. Usually it is easy for new employees to mess something up or not adhere to the complex architecture. Additionally there is often a large graph of dependencies between modules. The microservices philosophy now comes and tries to enforce modularity by having separate teams responsible for different services and not allowing them to share data persistency. In other words it tries to address the issues stemming from "Architecture follows Organization" (Conway's Law) by organizing teams by architecture and not the other way round. From my personal experience this is very fundamental to many issues in large organizations developing software and something that people often misunderstand when someone uses the buzzword microservices. For more information I recommend reading the works of Fowler. So the technology (.Net, Java, golang, etc.) does not play as much a role and the traditional "tiering" of services is an architectural decision that is still relevant but has to be seen less from a perspective of monolithic tiers but rather as tiers of clustered, scalable services (more about that below).
So now to your questions:
Distributed vs. SOA: These are different viewing angles onto architecture and only intersect with the difference of monolith vs microservices in that a distributed architecture promotes techniques that are relevant for the devops required to build, test, deploy and scale (micro)services. And a SOA does not imply a monolith or microservices in itself. Simplified it just promotes the usage of clearly defined APIs and standardization of communication protocols between services. Some people also imply self-containment, which in this case the overlap to the microservices intention is larger. But others call the front services that their monolith provides also SOA. So you always have to look into the details.
Service implementation, deployment and management. Beside the buzzwords there are a few actually useful techniques that are relevant here: Containerized applications (see Docker), which then enable clustered, orchestrated deployment (see kubernetes), which in combination with stateless application containers allow seamless scalability of services (see auto-scaling). Additionally scalable databases are coming more and more into the picture (see cockroachdb and various NoSQLs). And everything can be automated / tested / controlled from CICD servers (continuous integration / continuous deployment) - See Jenkins for example. All these make large application deployments so much easier and also allow for zero-outage updates if done right (see the topic of rolling updates). A cluster system will also typically contain functionality to detect the application health (for example endpoint testing). Unhealthy containers can be excluded from servicing client requests and replaced in an automated fashion by the container orchestration system.
and
Active/Passive Services: This distinction is not quite as useful. In the world of clusterized applications you think of each deployed application as a server providing services (usually formalized in a deployment description) or as a simple task/workload without services. But each may have dependencies to the outside world. In other words each deployed application could be active/passive or both but all will have some executable portion. I recommend looking into how a deployment is formalized with kubernetes for example.
Communication: Typically most communication will be asynchronous with the caveat that the service implemention often includes techniques to allow for treating an asynchronous call almost as if it was synchronous in the code (e.g. promises, observables). This is due to the fact that humans cannot think asynchronously very well.
Let me know if that answers some of your questions or if it only adds to the confusion.
Answers 2
Some of the very basic requirement for transitioning a monolith service to a distributed service is:
Get rid of the state in your application. By this I mean you should avoid having static fields & any information which is restricted to a single JVM. Rather move out all the information which specific servers are holding to a central memory like HazelCast or Memcache. So that all your servers share common information. This will enable your app to be consistent when any of your server goes down.
The same rule holds good when using sessions. Move all the sessions to a central memory.
P.S. I work on Java Stack so you can look for similar .NET tech.
Moving down to your questions
- Distributed vs. SOA : The difference between the two is very subtle. A Service Oriented Architecture means there are several independent services running with respective responsibilities. They are all components of a single application. Read about Web Services. For an instance Billing can be one service. Booking Tickets can be another service working in conjunction. SOA makes the system more manageable.
Distributed means splitting/partitioning a service into multiple chunks to achieve scalability & availability. Now this concept can be applied both at a higher level or on individual services in the SOA. The service runs on several nodes/servers. If one node goes down the entire Billing service doesn't go down.
Service implementation, deployment and management: A distributed system ideally runs on cloud. Go through Google Cloud & Amazon Cloud docs. You'll get an understanding how the entire flow works. Also read about SQL vs NOSQL. CAP Theorem. ACID vs BASE. Can't write everything here. The answer will become humongous.
Active/Passive Services: Stated above cloud docs. will help you get an understanding about these services. Also look into Zookeeper.
Service Communication: Communicating synchronously or asynchronously entirely depends upon the application design. You would require a messaging service like RabbitMQ or Kafqa if you are communicating with other services.
You have a lot to read. GoodLuck :)
0 comments:
Post a Comment