Showing posts with label Micro services. Show all posts
Showing posts with label Micro services. Show all posts

Wednesday, 5 October 2016

Serverless Delivery Architecture


Serverless Delivery Architecture

Serverless computing has gained momentum as more than just the hot topic of the moment. It attempts to build and deploy applications and services by abstracting away infrastructure, OS, availability and scalability issues.  it’s quickly becoming a must have for the modern enterprise. It will soon be a competitive advantage for those already implementing it.
While the name itself is a misnomer as serverless architecture doesn’t mean getting rid of the data center through some form of magic that powers compute cycles in thin air.The basic idea behind it seems is make the unit of compute a single function, effectively providing a lightweight and dynamically scalable compute environment. It is a way of decoupling application components as independent microservices that automatically run when a predetermined event occurs. 

While event-driven computing patterns have existed for some time, the serverless trend really caught on with the introduction of AWS Lambda in late 2014. Microsoft has a similar offer with WebJobs, and Google recently announced its version with Google Functions. 

So what is the advantage of using a serveless architecture:-


So here is an example of a typical server architecture.




This would be how a serverless architecture would look like






Obviously this approach would simplify architecture considerably. 

Lets look at the design patterns that enable a serverless architecture

The server less architecture is primarily based on two important design patterns CQRS and Event Sourcing. Both the patterns pretty much emerged at the same time, and the community of people that were working on them was much interwoven and the two things were not so clearly delineated. But there are two distinct architectural concepts there. They often work well together but it’s useful to think of them separate concepts. In essence, CQRS says that you break your system into components that either are read-only things or they are things that process updates.

As an example when a new request comes in, in CQRS we’d put that in the form of a command. A command meaning the C in CQRS. And the command would be “Create an User”.  Now, it goes to some microservice,  whose job is to take this kind of command and see if it can be done; like it might say, “I’m not going to execute this as you do not an admin.” So commands, as they ‘redefined in CQRS, you can say no. So that would be the response to that.Let’s say, okay, we do go ahead and we process the request and we create a user in DB, we link the user to some roles, send a email confirmation etc. Some events come out: some events that say things like “the email has been send” and another event that says “User has been provisioned”. This is the responsibility of that command processing part. Now the query, that’s the “Q”, sometimes you’d say, "Give me the status of user".  So this is the Q part.  And the idea is that this part of the system would be kept very simple. There would be a part of the system where you’d have to figure out how to create an user. But once the provisioning has started, you’d update the status in a query part that would say the status of the provisioning. So queries that way can scale differently than the command processing. And in a system where you have to do a lot we can scale them independently, we can recognize that queries take less processing power perhaps; that since there’s no change happening, we don’t have to worry about consistency rules. So the query part is very simple and fast and scales that way. The command part is where we have to deal with all the issues of, well, what if a command came in to inactivate the user during the provisioning what are the rules around that? Does the command still get processed? I mean it will get processed but does its till get cancelled? On and on.


You could have an event source system that was not CQRS. So for example, you could just have a module that responds to queries and also can process commands, and if you had that you wouldn’t really be practicing CQRS because you wouldn’t be separating them. 

However the event-driven methods for instantiating workloads also means to take care of what happens once invoked. If there are too many events generated it may lead to system overload or resource maxing if not careful. If each event is treated as an API endpoint, then one must ensure that the right policies in place for authentication, authorization, rate limiting, error handling, and more.It’s important to understand where different events can be sourced. When triggered, the job is posted to a queue that either pushes the message to a running worker node, or holds the message until a worker node is available.




Benefits of Serverless

The primary reason is  Efficiency / Cost
You only pay for the time that your function(s) are running and since you don’t have to run an app 24/7 anymore, this can be a good cost savings.  

Challenges of Serverless

  •  Functions are deployed to containers in isolation, so sharing code or libraries between function is not trivial.  Serverless solves this by allowing us to configure the specific directory level we want to include in the deployment package. As a result, you can include code in your function from a folder at a higher directory, which could also be used by other functions, and the included files will be zipped up with your deployment package.
  • It is difficult to have environment variables for example a DB connection string or encryption key without inlining them in your code and making them visible to users of your repo. One option is to store environmental variable definitions in JSON files in a gitignored _meta folder and inlines the values into your functions as part of the deployment process.
  • Long running jobs (high minutes to hours) are not a good fit, typical expectations are in the second’s range. 
  • Logging and monitoring are a big challenge as and log aggregation capabilities are required


Applications of Serverless

One of the most natural applications for Serverless is the Internet of Things.Most IoT devices are essentially sensors combined with some control points.
In a typical IoT use cases one would gather data from sensors and  aggregate it in some form of gateway, possibly doing some basic control actions, and then the data is submitted to a system where it is processed and events triggered.

Serverless functions would be ideal fit for this kind event processing.


Conclusion

Serverless compute is here to stay, however, rather than viewing it as a silver bullet, applicable to all sorts of use cases it should be perceived as  design pattern meant for specific cases. 

Thursday, 18 June 2015

Microservices



Recently, there has been a large push away from monolithic application in favor of small, composable, purpose-built micro-services. To me, micro-services are autonomous services that take full responsibility for one business capability. Full responsibility includes presentation, API, data storage and business logic.

Each micro-service is aligned with a specific business function, and only defines the operations necessary to that business function. This may sound exactly like service-oriented architecture (SOA), and indeed, micro-services architecture and SOA share some common characteristics. Both architectures organize code into services, and both define clear boundaries representing the points at which a service should be decoupled from another. However, SOA arose from the need to integrate monolithic applications that exposed an API (usually SOAP-based) with one another. In SOA, integration relies heavily on middle-ware, in particular enterprise service bus (ESB). Micro-services architecture may often make use of a message bus, but there is no logic in the messaging layer whatsoever—it is purely used as a transport for messages from one service to another. This differs dramatically from ESB, which contains substantial logic for message routing, schema validation, message translation, and business rules. As a result, micro-services architectures are substantially less cumbersome than traditional SOA, and don’t require the same level of governance and canonical data modeling to define the interface between services. With micro-services, development is rapid and services evolve alongside the needs of the business.
Moreover the focus of SOA is separation of concern at interface level where micro-services describe the entire deployment scenario.

Another key advantage of the micro-services architecture is that a service can be individually scaled based on its resource requirements. Rather than having to run large servers with lots of CPU and RAM, micro-services can be deployed on smaller hosts containing only those resources required by that service.

As micro-services architecture is a significant shift from monolithic approach it may require restructuring of several components of the architecture landscape. In this article we we discuss some of the more significant ones.

Authentication :

In traditional monolithic application a user would provide a username,password which would be verified and and a user session would be created. All messaging withing the application is usually in context of this user session. In micro-service architecture the entire flow cannot be encapsulated under an user session as it would make the whole application stateful. It needs to be split into external (the API gateway), and internal (between services) authentication. External authentication with user would be handled by an authentication micro-services which can verify a user and issue an authentication token. This token can be passed between micro services to establish authentication.

However this would mean multiple micro services relying on auth server in order to authorize resources. At some point it can run into performance issues due to too many round trips to authentication server. There may be also scalability issues for auth server as number of micro services increases. An alternate approach is to split micro-services into frontend and backend micro-services. Frontend micro-services can use authentication token mechanisms as discussed. Backend micro-services will use App-specific API tokens for each backend service . Every backend micro-service will have its own AppId which can be locally validated by other micro-services.

Service Lookup:

When building micro-services, you have to naturally distribute your application around a network. That means that your services need to be reconfigured with the location of the other services they need to connect to. This reconfiguration needs to be able to happen on the fly, so that when a new service instance is created, the rest of the network can automatically find it and start to communication with it. This process is called Service Discovery.

Apache ZooKeeper is one of tool that can be used for service discovery as it provides a distributed, eventually consistent hierarchical configuration store.

Deployment:

As number of micro-services grow it can be difficult to keep track of which hosts are running certain services. Also if services are implemented in different programming languages, this means the deployment of each service will require a completely different set of libraries and frameworks, making deployment to a server complex.A container technology like Docker provides an ideal solution for this scenario as it creates containers that comprise of just the application and its dependencies. It is this isolation between containers running on the same host that makes deploying micro-service code developed using different languages and frameworks very easy.

Persistence:
In micro-services like isolation of service it is also important to have isolation of data. To ensure loose coupling, each service has its own database (schema). Moreover, different services might use different types of database – a so-called polyglot persistence architecture. For example, a service that needs ACID transactions might use a relational database, whereas a service that is manipulating a social network might use a graph database.
If there is some data that is needed in more than 1 service, there will be one service that is the owner of the data and exposes it over an API.

Tracing & Auditing:
As there are different servers so just looking and finding problem in logs can become big pain.What we need to do is  tag each request and each event with a request-id. This id can be generated when the first request enters the system and can be used for every event and request that is triggered after that. That request-id can be used as a tag in the logs. Logstash with Kibana are open source tools that can be be utilized here.Logstash allow to aggregate logs into one location, and Kibana allow to search log files.So we can trace the entire flow in Kibana using the request-id tag.


Hopefully this high level overview is helpful when designing your own micro-service architectures
There are various strategies for incrementally evolving an existing monolithic application to a micro-service architecture. It also makes sense to iteratively identify components to extract from the monolith and turn into services. While the evolution is not easy, it’s better than trying to develop and maintain an unwieldy monolithic application.