Introduction:
Azure Service Fabric is an open-source project, and it powers core Azure infrastructure as well as other Microsoft services such as Skype for Business, Intune, Azure Event Hubs, Azure Data Factory, Azure Cosmos DB, Azure SQL Database, Dynamics 365, and Cortana. Azure Service Fabric is a distributed systems platform for deploying and managing scalable and reliable microservices and containers. Service Fabric can be used as a platform for decomposing monolithic applications. It provides an iterative approach to decompose an IIS/ASP.NET website into an application composed of multiple, manageable microservices.
Moving from a monolithic to microservice architecture provides the following benefits:
- You can change one small, understandable unit of code and deploy only that unit.
- Each code unit requires just a few minutes or less to deploy.
- If there is an error in that small unit, only that unit stops working, not the whole application.
- Small units of code can be distributed easily and discretely among multiple development teams.
- New developers can quickly and easily grasp the discrete functionality of each unit.
Using Service Fabric as the hosting platform, we can convert a large IIS website into a collection of microservices as shown below:
In the picture above, we decomposed all the parts of a large IIS application into:
- A routing or gateway service that accepts incoming browser requests, parses them to determine what service should handle them and forwards the request to that service.
- Four ASP.NET Core applications that were formally virtual directories under the single IIS site running as ASP.NET applications. The applications were separated into their own independent microservices. The effect is that they can be changed, versioned, and upgraded separately. In this example, we rewrote each application using .Net Core and ASP.NET Core. These were written as Reliable Services so they can natively access the full-Service Fabric platform capabilities and benefits (communication services, health reports, notifications, etc.).
- A Windows service called Indexing Service is placed in a Windows container so that it no longer makes direct changes to the registry of the underlying server but can run self-contained and be deployed with all its dependencies as a single unit.
- An Archive service is just an executable that runs according to a schedule and performs some tasks for the sites. It is hosted directly as a stand-alone executable because we determined it does what it needs to do without modification, and it is not worth the investment to change.
Using Reliable Services:
An Azure Service Fabric application contains one or more services that run your code. This guide shows you how to create both stateless and stateful Service Fabric applications with Reliable Services. To get started with Reliable Services, you only need to understand a few basic concepts:
- Service type: This is your service implementation. It is defined by the class you write that extends StatelessService and any other code or dependencies used therein, along with a name and a version number.
- Named service instance: To run your service, you create named instances of your service type, much like you create object instances of a class type. A service instance has a name in the form of a URI using the “fabric:/” scheme, such as “fabric:/MyApp/MyService”.
- Service host: The named service instances you create need to run inside a host process. The service host is just a process where instances of your service can run.
- Service registration: Registration brings everything together. The service type must be registered with the Service Fabric runtime in a service host to allow Service Fabric to create instances of it to run.
Stateless Services
A stateless service is a type of service that is currently the norm in cloud applications. It is considered stateless because the service itself does not contain data that needs to be stored reliably or made available. If an instance of a stateless service shuts down, all its internal state is lost. In this type of service, the state must be persisted to an external store, such as Azure Tables or SQL Database, for it to be made available and reliable.
Follow steps from this URL to build it: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-quick-start
A simple Proof of Concept (PoC) output looks like this-
The platform calls this method when an instance of a service is placed and ready to execute. For a stateless service, that simply means when the service instance is opened. A cancellation token is provided to coordinate when your service instance needs to be closed. In Service Fabric, this open/close cycle of a service instance can occur many times over the lifetime of the service. This can happen for several reasons, including:
- The system moves your service instances for resource balancing.
- Faults occur in your code.
- The application or system is upgraded.
- The underlying hardware experiences an outage.
This orchestration is managed by the system to keep your service available and perfectly balanced.
RunAsync() is the start point of these services. It should not block synchronously. Your implementation of RunAsync should return a Task or await on any long-running or blocking operations to allow the runtime to continue. Note in the while(true) loop in the previous example, a Task-returning await Task.Delay() is used. If your workload must block synchronously, you should schedule a new Task with Task.Run() in your RunAsync implementation.
Cancellation of your workload is a cooperative effort orchestrated by the provided cancellation token. The system will wait for your task to end (by successful completion, cancellation, or fault) before it moves on. It is important to honor the cancellation token, finish any work, and exit RunAsync() as quickly as possible when the system requests cancellation.
In this stateless service example, the count is stored in a local variable. But because this is a stateless service, the value that is stored exists only for the current lifecycle of its service instance. When the service moves or restarts, the value is lost.
Stateful Services
Service Fabric introduces a new kind of service that is stateful. A stateful service can maintain the state reliably within the service itself, co-located with the code that is using it. The state is made available by Service Fabric without the need to persist state to an external store.
To convert a counter value from stateless to highly available and persistent, even when the service moves or restarts, you need a stateful service.
Follow steps from this URL to build it: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-quick-start
A simple POC output looks like below:
RunAsync() operates similarly in stateful and stateless services. However, in a stateful service, the platform performs additional work on your behalf before it executes RunAsync(). This work can include ensuring that the Reliable State Manager and Reliable Collections are ready to use.
Basic sample POC: https://github.com/Netwoven/WebsiteSamples/tree/master/ReliableServiceApp
References to sample projects: https://thecloudblog.net/post/hands-on-with-azure-service-fabric-reliable-services/ , https://www.innominds.com/blog/azure-service-fabric-and-stateless-services-the-gateway-to-development-and-management-of-microservices , https://www.c-sharpcorner.com/article/creating-services-with-azure-service-fabric/
Which One to Choose
Stateless reliable services are remarkably similar to what you may already know as Cloud Services.
- They can be used to implement background, headless worker processes (like worker roles), or online services that you can connect to, i.e., web servers (like web roles). This distinction does not actually exist in Service Fabric as a reliable service can be implemented as a worker and/or web service.
- As with Cloud Services, you define an instance count, and the runtime will create as many instances as possible of your service over the nodes of the cluster. If an instance fails or crashes, a new one will be automatically launched.
- To implement a web service, you define which endpoints (port + protocol) you want to open, and the runtime will load-balance the requests between all running instances.
- Service Fabric is currently web server agnostic, which means that there is no interface with IIS, and you have to self-host your own web server.
Stateful reliable services
Same concept as the stateless version, but with persistent storage implemented directly in the service.
- State storage is performed through reliable collections, which are generic collections that ensure reliable storage of the data over the nodes running the service. There are currently 2 such collections available: a dictionary and a queue.
- No instance counts here, but you must define the number of replicas that the runtime will create; the goal of those replicas is to ensure high availability and reliable persistence of state.
- At any point in time, there is among your replicas a primary one, and the other ones run as secondary replicas. If the primary replica crashes, the runtime promotes a secondary to primary.
- By default, all requests are routed by the runtime to the primary replica only and all updates to the state (reliable collections) are replicated to secondary replicas. That is a core difference between stateless and stateful reliable services: with stateless services, all instances can serve requests (as they do not share a state, or at least not within the Service Fabric) whereas, with stateful services, only the primary replica is “active” (by default).
- It is possible to configure a stateful service to route requests to secondary replicas, but it is forbidden to update states on those (for obvious data consistency reasons)
Conclusion:
Azure fabric reliable services are extremely useful to modularize monolithic projects and in microservices architecture. A Stateless Service is ideally used for data transformation operations where no state needs to be persisted in the service itself. Note that this does not mean that it cannot save any state in a centralized data store. It can. Having said that, the data store cannot be owned by the service. For example, an image transformation service will just transform the image, with the logging, analytics, and other information being sent to either a centralized data store or to other services.
Thank you for reading the blog; we hope you found this useful in learning in detail about Azure Service Fabric Reliable services. Please reach out to us so that we can put our decades of Microsoft technologies experience and capabilities to work for your organization’s Digital Transformation.