Microservices: Technology

 icon-arrow-left Microservices: Design |  Microservices: Brownfield: Approachicon-arrow-right 

 

Communication

We have synchronous and asynchronous communication between the micro-services and/or clients.

Note: In real world applications, we use a combination of both.

 

Communication: Synchronous

This communication is based on making a request and waiting for a response.

  • Communication can happens between services, with clients and with external services.
  • Remote Procedure Call
    • It makes it look like you are calling a method when in reality you are calling a remote method on a remote services.
    • Use Remote Procedure Call libraries 
      • Help to Create distributed client-server programs
      • Provide functionality that do the work while shielding all the details regarding the network protocols and its communication protocols.
        • HTTP communication protocol (it is firewall friendly)
          • POST, PUT, GET, DELETE (Create, update, retrieve, and delete)
            • Create using POST
            • Update using PUT
            • Retrieve using GET
            • Delete using DELETE
            • Map to CRUD operations
    • Disadvantages: 
      • It is sensitive to change (including at the server end); therefore, it breaks.
        • i.e.: Changing the method signatures
  • Can use Request Response Synchronous 
    • REST
      • Open communication protocol
      • Natural decoupling
      • JSON/XML format
      • CRUD using HTTP verbs
      • Can access using endpoint URLs which are map to our entities.
      • Hypermedia As The Engine of Application States (HATEOAS)
        • Provides information to navigate the site’s REST interface by using hypermedia links with the responses.
        • At different of SOA-based systems and WSDL-driven interfaces, its interface is dynamic which means that there is no fixed specifications that may be staged somewhere else on the site.
  • Synchronous disadvantages:
    • Communication only available when both parties are available.
    • One micro-service must wait for the other microservice to response before it can carry on.
    • If one micro-service slow down, the entire transaction slow down.
    • It makes it speed dependent of the network speed.
      • This would make responses from the micro-services to arrive slowly.
    • Micro-services must know the location of that service (host and port).
      • Note: This issue can be solved by implementing a service registration and discovery pattern.

 

 

Communication: Asynchronous

Asynchronous communications means event-based communications. Instead of having our services connecting directly to another service to carry out a task, the service creates an event and micro-services that can carry on that task out will automatically pick that event up.

  • There is no need for a client and server connection. Client and server are decoupled.
  • A message queuing protocol is used where the events created by a micro-service (the publisher) will be send as messages, and the service which carries out the tasks in response to that event (the subscriber).
  • All  messages from publishers are stored and buffered by a message broker (i.e. RabbitMQ, Microsoft Message Queuing, ATOM) until a subscriber picks the message up.
    • The publisher only knows of the message broker.
    • Publisher and subscriber are decoupled; therefore, they don’t need to know each other’s location.
    • Note: ATOM use HTTP to propagate events.
  • This communication protocol is perfect for micro-services architecture because we can swap different version of a micro-service without having to affect other micro-services.
    • This is because they only need to know about the message broker and communicate using a message queuing protocol.
  • You can have multiple subscribers acting on the same message.
  • Multiple vendors provide message queuing protocols.
  • Asynchronous communication disadvantages:
    • It’s complicated when using distributed transactions.
    • The system relies on a message broker which is one point of failure for the whole system.
    • Visibility of transactions can be a problem.
    • The transactions are not completing in a synchronous way.
    • To manage messaging queue, you are required to learn new tools and techniques.
    • We need to make sure to handled property the messaging queue.
    • The performance of the system may be affected if you have queuing issues.

 

Virtualization

One way to host micro-services is virtualization which means that we are going to use virtual machines as host in order to run our micro-service

  • There is no need to run our micro-services on physical machines. We can run a self-contained machine with our micro-service in it.
    • Spin a virtual machine
    • Install micro-service
    • Done
  • Virtual machines are entire instances of operating systems (plus any extra software required).
  • Hardware is simulated in software.
  • One physical machine can run multiple virtual machines.
    • Each virtual machine runs as they are physical machines themselves.
  • Virtual machines can be cloned.
    • When you have a virtual machine ready with your micro-service, you can clone several copies of that virtual machine.
  • Virtual machines are the foundation of close platforms.
  • As your demand increases, you can create multiple virtual machines with your complete architecture. 
  • There are platforms that allow you to create your own cloud.
  • They take time to be set up, as well as time to load, and resources.
  • You can take snapshot of a virtual machine. Such snapshot can be restore later.
  • Current virtualization technology is standardized and very mature.

 

Containers

Containers are a different kind of virtualization. While they do not run an operative system within the container, they run the minimal amount of requirements needed for your micro-service to run.

  • It allow to isolating services from each other.
  • It is a good practice to run only one service, one micro-service within a container.
  • They use less resources than a virtual machine.
  • You can have more containers on a host machine than virtual machines.
  • They are faster than virtual machines.
  • They boot faster than virtual machines.
  • Since containers are lightweight and fast, they are faster to create new instances.
  • Clod platform support for them is growing. i.e. Microsoft Azure Platform, Amazon Web Services.
  • Currently only supported on Linux but soon other operating systems will join.
  • They are not quite yet establish and standardized as virtual machines.
  • Quite complex to set up.
  • Docker, Rocker and Glassware are examples of containers.

 

Hosting Platforms

Self-hosting can be an option you may pursue. While, cloud services allow you to control the whole project via a portal in a simpler way (and there is no need for physical machines or specialized staff), you may want to implement your own cloud service using your own IT infrastructure. This means that you will be implementing your own virtualization platform or implementing your own containers. 

When implementing your own cloud have the following as consideration:

  • Think in long-term maintenance of your could platform.
  • Think about the need for technicians who will be supporting your cloud platform.
  • Train your existent staff.
  • Reserve or expand space for extra servers.
  • Scaling will not be immediate (as buying an external service) due purchases of new machines and configuration required.

 

Registration and Discovery

When we connect to a micro-service we need to find out:

  • Where the micro-service is.
  • What host the micro-service is running on.
  • What port it is listening on.
  • What version of the micro-service is running.

One way to store this information (plus making such data available) is having (or implementing) a service registry database. Therefore, when we implement a new micro-service or we implement a new instance of a micro-service,  we make sure our micro-service register itself on startup in this database. This is called register on startup.

In addition, we can make our system smart enough to recognize when a micro-service stop responding. In this way, the system deregister that instance of that micro-service from the service registry database. This is called deregister service on failure.

By doing these steps, new client requests will not connect to micro-services instances that are not available and/or experiencing problems.

The way our micro-services will register themselves in the service registry database is by:

  • Option 1: Our micro-services register themselves to the registry database on startup.
  • Option 2: (Third Party) software that detects new instances of micro-services and register them to the registry database.

The way our client learn about all the locations of our micro-services and micro-services instances is by:

  • Option 1: Directly connecting to the service registry database in order to obtain the location of specific instance of our micro-services. This is called Client-side discovery.
  • Option 2: Connecting to a gateway (or load balancer) which retrieves the location from the service registry database. This is called Server-side discovery.

 

Monitoring Technology for Observable Micro-Services

At our disposition we have monitoring centralised tools such as Nagios, PRTG, Sensu, Zabbix and mist.io; as well as other components such as load balancers. Also, there are online services such as New Relic, Uptime cloud monitoring, Ruxit, Site 24×7,  which allows you to look into your system and monitor it.

Key features:

  • Metrics across servers: Gather metrics across servers then aggregate and visualize data.
  • Automatic and minimal configuration for new instances of our micro-services.
  • Tools to allow us to use client libraries to send metrics.
  • Tools to send test transactions, as well as to monitor those test transactions.
  • Tools that send alerts when something being monitored is failing.
  • Tools to monitor network and network transactions.
  • Monitoring real time.

Note: We need to make sure that monitoring is standardized across the whole system. This means that we need to ensure all our hosts, virtual machines and/or containers are pre-configured with all the requirements for monitoring.

 

Logging Technology for Observable Micro-Services

We need a portal for centralised logging data so we can deal with the logging of specific events within our system. All logs get push into these centralised logging tools which store the data into a central database. Later, our portal should allows us to query and find patterns within this logging data. For example, we can use a Correlation ID and Transaction ID to verify the journey of a process (and/or transaction) through all our micro-services in our system. In this way, we can query such IDs within our centralised logging tool. 

Remember that in our micro-services, we will need to implement a client logging library for the purpose of sending the logs into our centralised logging tool. An example is Serilog, Splunk, LogStash, Fluentd, Logmatic.io, and Graylog.

Key features:

  • Support structured logging.
  • Query logs.
  • Minimal useful information.
  • Logging across servers; therefore, accept data from multiple servers.
  • Automatic or minimal in terms of configuration.
  • It must allow to log a Correlation and/or Context ID.
  • Allow for standardization of our logging.
    • We can use a template for our client libraries.
    • Ensure that the format of the log must be an standard across the system.


Scaling

When the performance requirements for our micro-service increases, which makes our micro-service performance to degrades, we must increase the number of instances of our micro-service and/or increase our resources. 

 

  • Create multiple instances of the micro-service
  • Add extra resources such as:
    • Increase the number of CPU calls available.
    • Increase the number of memory available.
    • Increase the amount disk space.
    • Increase the amount of bandwidth available.
    • Increase number of virtualization and/or containers.
    • Increase number of host servers.
  • Amount of instances and/or resources available might be automated or based on-demand (manually).
    • Some of the on-demand resources may need to be increased in the hardware manually.
    • PAAS auto-scaling options.
  • Load balancers
    • API Gateway
  • Only scale up when
    • There is performance issues.
    • The monitoring data shows that there are performance issues.
    • The capacity planning shows that you will have performance issues.

 

Data Caching

The performance of your micro-services architecture system can be improved by implementing caching of data. This is done by detecting multiple calls towards the same thing. So, instead of honoring each request individually, we can retrieve the data and use it over and over again while the request received is the same. In other words, we retrieve the data and keep it alive in order to satisfy all the other requests; therefore, improving performance by reducing the client calls to that specific service, service calls to a database, and/or service to service calls.

The API Gateway level or the proxy server level are the ideal place to do caching since it became “invisible”. This will reduce the number of calls to your micro-service (and database), plus it will reduce the amount of traffic within your own network. 

Another way to do caching is at the client side by downloading most of the data they need to work. In that way, only when it is needed that a call is done to your system.

Caching can also be done at the service level. In that way when a call done to a micro-service (lets call it service A) equals the call of another micro-service (lets call it service B), then the first micro-service (A) can take care of both requests using the same data.

Our caching system must be simple to set up, managed and easy to implement.

When working with caching, we must be aware of data leaks. We don’t wish to present the wrong data to the wrong call.

 

API Gateways

API Gateways are the central point into the system. All the client applications must access via our API Gateway. We can use our API Gateway to improve performance by applying load balancing functionality, as well as caching functionality. The fact that our API Gateway is the central point of access, help us to simplify the implementation of caching and load balancing. For the rest of the system, the API Gateways becomes “invincible” since they don’t need to know how the load balancing and caching works.

  • API Gateways provide one interface for many services.
  • They take care of the load balancing and caching.
  • It allows the scaling of micro-services without the client noticing.
  • It allows to move micro-services around in terms of location without the client noticing.
    • It helps with dynamic location of services.
  • The API Gateway can be configured to route specific calls to specific instances of a micro-service.
  • The API Gateway can be configured to look up for the location of micro-services in the service registry database in which all micro-services register.
    • This helps with load balancing.
  • The API Gateway provide a level of security for the overall system.
    • We can provide authentication and authorization.
    • Central security versus service security level.
      • We can have a dedicated service for authentication and authorization working in the background.
      • We can have a service dedicated to the security for authentication and authorization.

 

Automation Tools

When making a decision for automation tools such as continuous integration, see if you can find the following features:

  • The tool should be cross platform.
    • The tool must have the correct cross-platform builders.
  • The tool should integrate with the chosen source control system (such as Git, SVN, Perforce).
    • It should detect a code change and trigger off the build.
  • The tool should be able to send notifications.
  • The ability to map a micro-service to a CI build.
    • Code change to a specific micro-service will only trigger the build for that specific micro-service.
    • We can place our micro-service in a specific place, helping us with the continuous deployment.
  • Build and test should run quicker.
  • There should be quick feedback.
  • Separate code repository for service.
    • We prevent two or more micro-services to change accidentally at the same time.
  • We can configure the CI build to test the database for changes. 
    • This allows us to ensure that the micro-service and the database are upgraded.
  • Note: Avoid having one CI build for all services since you will loose all the advantages previously described.
    • Each micro-service should have its own CI build.
    • Reminder: All micro-services should be independently changeable and deployable; therefore, we must have one CI build for each micro-service.

For tools such as continuous deployment, we wish.

  • The tool should be cross platform and support multiple environments.
  • Central control panel.
  • Easy to add deployment targets to deliver our software.
  • Allow for scripting when just copying files across in not enough.
  • Allow for additional ad-hoc tasks.
  • Build statuses highlighting things such as failing tests and such.
  • Integration with CI tool.
  • This tool can released to a cloud-based hosted system.
  • Support for PAAS
Share
Leave a comment

Microservices: Design

 icon-angle-left Micro-services: Design Principles Introduction | Microservices: Technology icon-arrow-right 

Summary of Principles to Implement

  • High Cohesion: Small micro-service focused and single functionality.
    • Single focus.
    • Do a single thing and do it well done.
  • Autonomous: Allow upgrade of different part without risking other parts in the system.
    • Independently changeable.
    • Independently deployable.
  • Business Domain Centric: aligned with the overall organization structure.
    • Represent a business function or domain.
  • Resilience:
    • Embrace failure.
    • Degrade or default functionality when failure detected.
  • Observable: so we can have an overall view of the health of the system.;
    • Centralized Monitoring.
    • Centralized Logging.
  • Automation: in order to administrate the complex system.
    • Tools:
      • Testing.
      • Feedback.
      • Deployment.

High Cohesion Design Principle

In order to implement a micro-service with high cohesion, we need to:

  1. Identify a single focus.
    • It might be in a form of a business function.
      • e.: A function to generate invoice for the account system.
        • Notices that it has clear inputs and outputs.
      • It might be in a form of a business domain.
        • e. micro-service focus in creating, updating, retrieving, and deleting data related with a part of the organization such as the accounting deparment.
      • We should not crowd the micro-service with both types of focus.
        • Example of no high cohesion:
          no-high-cohesion
        • Example of high cohesion:
          high-cohesion
  2. Split into more smaller services

    Avoid the thinking of “It’s kind of the same” mentality and begin
    coupling multiple business functions into one micro-service.

    1. We wish to avoid one business function breaking another business function.
    2. A micro-service should only have one reason to change.
    3. Don’t be lazy. Even if it requires an extra effort, make sure to create an extra micro-service or split an existent micro-service.
    4. Remember the overall objective which is to have a system which is reliable, flexible and scalable.
    5. We want our system being in separate parts so we can deploy them as specific parts.
    6. Laziness will only lead us to a system which would be monolithic in nature; therefore, introducing all the disadvantage of such.
    7. As you create micro-services in an incremental way, you will be learning how to maintain them and monitor these micro-services.
  3. Ensure your micro-services have high cohesion.
    1. Continuously question the design of micro-services.
      1.  i.e.: Is there a reason why a new micro-service has to change?

Autonomous
Our micro-services must be independently deployable and changeable.

Autonomous: Loosely Couple

  • Each micro-services should depend on each other in the most minimal way possible.
  • They should have the least amount of knowledge of each other.
  • They shouldn’t be connected physically to each other directly, but use a medium such as the network in order to talk to each other.
    • Communication can be synchronous.

      • A micro-service calls another and waits for a reply.
      • Advantage is to know that if our communication was successful or not due the status of response.
      • In order to work, the micro-service receiving the request should respond right away even before it perform and completed its actual task for the request.
        • This allow the micro-service doing the request to carry out its own task while waiting.
        • When the micro-service doing the work, finish, it will call back the micro-service requestor indicating that the task is completed.
        • The original request should include a callback address.
          • In this way, the micro-service knows who to notify when the job is done.
    • Communication can be asynchronous.

      • Instead of having the micro-services making requests between each other, the micro-services public events in a form of messages.
        • These events are queue by a message broker such as RabbitMQ.
        • All micro-services listen out for these events and carry out tasks if any of those event correspond to them.
          • If they are interested in the message they pick it up. Process them. Then send an event so the other micro-services interested pick the result.
        • Micro-services subscribe to events
      • Use open communication protocols in such way that we obtain a technology agnostic API.
        • Example of communication protocol: REST over HTTP and data in JSON
        • This allow for micro-services to work on different technology stacks instead of forcing them to work on the same technology stack.
          • i.e.: Using REST JSON, we can have a .NET-based service communicate with a Java-based service.
  • Avoid the use of client libraries.
    • A consumer of your micro-services requires the implementation of a client library in order for the consumer to talk to your micro-service.
    • Client libraries increase coupling because it force your micro-services and clients to change when its client library changes.
    • It forces the use of a specific technology platform at the consuming end.
  • Micro-services should implement Order Shared Model which means that the micro-services should have a contract between them.
    • Fixed and agreed interfaces between the services.
      • Method signatures and the format of the data that is exchanged.
    • We always use Share models of the data that are unlikely to change when any of the micro-services is enhanced.
      • The shared models should be different from the internal representation of the data within the micro-service.
      • Keep the internal representation of data separate from data that is going to be exchanges using the shared model.
    • These contracts and interfaces are important for multiple teams since it help to have a clear view of the known inputs and outputs of each micro-service.
  • Avoid chatty exchange between micro-services.
  • The sharing of things like databases between two micro-services should avoided.
    • While it may seems like a good idea to share data such a database, but a change in the shared database will result in both micro-services having to change (i.e. new schema change)
      • This can lead to have to deploy both micro-services instead of one.
    • Force both micro-services to use the same database technology.
  • Minimize the use of shared libraries within the microservice.
    • i.e.: A bug fixed in a shared library would force us to deploy both micro-services.
    • Perhaps that shared library should be a micro-service itself serving other micro-services.

Autonomous: Ownership and Versioning

  • Each micro-service is owned by a team
  • Small micro-services allow for small teams
    • Small teams will be better retention of knowledge about the micro-service.
  • It encourage small teams to build and maintain the micro-service autonomous.
  • Teams are responsible to:
    • Design a micro-service that is independently changeable and deployable.
    • Agreeing the contract between the micro-services.
    • How the micro-services interact.
    • Maintain the contract so future changes don’t break contracts with other micro-services.
    • Long-term maintenance of the micro-service.
  • Ownership encourage to:
    • Collaborate with other teams.
    • Communicate contract requirements.
    • Communicate data requirements.
    • Concurrent development.
  • Multiple teams can work on different micro-services at the same time plus agree in the interaction between these micro-services.
  • When creating a new version of the micro-service, think about the versioning strategy for that micro-service.
    • Create a new version of the micro-service avoiding breaking other micro-services by changing the contract.
  • All new changes should be backwards compatible.
    • Other micro-services should be able to continue working without any change.
    • Honor the original contract that was agreed.
    • Ensure your new micro-services is not and will not break any existing contracts.
  • Use integration tests to test the change of the micro-service for inputs and outputs, plus shared models.
    • Test if the original contract is still intact.
  • If a new version of your micro-service includes breaking changes, then you have concurrent versions of your micro-service running.
    • An old and new version of your micro-service could be running at the same time.
    • This allow a period of transition from the old micro-service and the new micro-service.
  • Use semantic versioning where the version number is made up of three numbers: Major.Minor.Patch
    • The major number increments if the new version of the micro-service is not backward compatible.
    • The minor number increments while the new version of the micro-service is backward compatible.
    • The path number increments if the new version of the micro-service have a defect fix
      • Plus, the overall micro-service is still backwards compatible.
  • When you with to include both old and new code in the new version of the micro-service, we can have coexisting endpoints.
    • The original endpoint which points at the original code (old version), and have a new endpoint pointing at the new version.
    • Consumer can slowly migrate from the old endpoint to the new endpoint.
    • We can have a new version of a micro-service which has the old endpoint; however, the old endpoint can have a wrapper for the new endpoint.
      • In other words, you could have the old endpoint redirect the calls to the new endpoint.

Business Domain Centric

Micro-services should represent a business function or business domain.

  • Define these business domains in a coarse manner.
  • These business domains should represent departments or areas of the organization.
  • Split each area into business functions or business areas.
  • Have in consideration to review the benefits of splitting the micro-service further.
  • Remember to have high cohesion.
    • A micro-service must
      • Do one thing and do it well.
      • Have a single focus.
      • Only one reason for it to change.
  • See micro-services as components
    • Maps to different components.
    • Functions within the organization.
  • When parts of the organization change, we know which specific micro-service should be affected.
  • Agree to a common language.
  • Fix incorrect boundaries.
    • Be ready to split a micro-service further.
  • Merge two or more micro-service into one if they are doing the same thing.
  • Consider the inputs and outputs and the contracts existent between the micro-services.
  • We can split the system by technical boundaries.
    • For example, we need a special micro-service for accessing data or improve performance.

Resilience

The entire system shouldn’t go down for one failure; therefore, we must design our micro-services for all known failures.

  • Known Failures:
    • Downstream systems: Micro-services that carry our specific task
      • Internal and/or external services.
      • Network outages and network latencies.
      • Timeouts.
  • Micro-service should degrade or default functionality on failure detection.
  • Do not hang or delay a transaction. System should fail fast and recover fast.
  • Use standard timeout length functionality between services communication.
  • Our system should continuously monitor our timeouts and log our timeouts.
    • This can help to workout specific behaviors related.
  • Make issues transparent for health checks.

Observable: Centralized Monitor

Our system will consist of multiple micro-services and instances of micro-services; therefore, we must implement a centralized monitor system that allows us to see the system health.

  • Monitor data in real time.
  • Monitor health of the host
    • CPU usage, memory usage, and disk usage.
    • Response times.
    • Timeouts and number of timeout errors.
    • Exceptions and errors.
  • Monitor service itself. Expose metrics within your service.
  • Expand to include business data related metrics.
    • Number of orders.
    • Average time from basket to checkout.
  • Collect and aggregate monitoring data.
    • From trends and history to details.
    • Drill down options.
  • Visualize trends to spot patterns and potential problems.
  • Compare data across servers.
  • Trigger alerts
    • For example, trigger alarm when a measures exceeds a threshold.

Observable: Centralized Logging

We are recording detailed information about events. It is key for problem solving in a system of distributed transactions.

  • Log when our micro-services start up and/or shut down.
  • Log code path milestones. For example:
    • Received a request
    • Code decisions
    • Give responses
  • Log timeouts, exceptions and errors
  • Information logged should be structured and be consistent across the system.
    • A log may contain:
      • Level of information.
      • Information state.
      • Information regarding an error
      • Debug information.
      • Statistics that’s have being recorded.
      • Date and time when event happened.
      • Correlation ID so we can trace distributed transactions across our logs.
        • A unique ID which is assigned to every transactions.
        • When the transaction becomes distributed, we can follow that transaction across our micro-services.
      • Host name so we know where the log entry came from.
      • Service name and service instance so we know which micro-service made the log entry.
      • A message which is the key information whic is associated with the event.
        • i.e.: Callstack details regarding the exception.
  • Keep structured logging format consistent.
    • This allows us to query the logging information.
    • We can search for specific patterns and specific issues.
  • It allows to make transactions more traceable.

Automation: Continuous Integration Tools

The Continuous Integration tools provide an automatic way to do testing and feedback of your software changes.

  • These tools work with the source control.
  • Test software after check-in and change into the source control.
  • Run unit tests and integration tests that have begin written.
    • Unit test and integration test are designed to test our production code.
    • They test that a change or enhancement in the code hasn’t break the existing and new requirements.
  • Provide quick feedback.
    • If a micro-services breaks (itself or anything else that may use any of those micro-services), we will receive a quick feedback so we can fix it.
  • Provide useful Information on the quality of integration.
  • Prevent issues to pile up.
    • Automatic feedback is sent to its respective teams so they can quickly fix the issue.
  • Culture Note: All teams should stop development until all the issues reported have being fixed.
  • Integration tools can be use to build our software 
    • Test Driven Development

Automation: Continuous Deployment Tools

These tools automate the software deployment.

  • The Continuous Integration tool creates the build that the Continuous Deployment tool will deploy.
  • There could be multiple micro-services and multiple instances of those micro-services on different servers.
    • Each server could be running a different technology stack (i.e. Microsoft, Linux, Unix, etc)
  • It is time consuming to configure this tool; however, it is done once. In the long run, this tools saves a ton of time.
    • When a new version of a micro-service is available, the same configuration is used to re-deploy automatically.
  • As long as all the continuous integration test pass, the new version will be deployed.
  • This tools provide the ability to release anytime upgrades.
  • It allows to deploy new version of your software to the market in a quick and reliable way.
    • This improve customer experience.
Share
Leave a comment

Microservices: Design Principles Introduction

 icon-angle-left Microservices | Microservices: Design icon-angle-right 

Design Criteria

In order for a service to be a microservice, it must match the following criteria:

  • It needs to be have high cohesion.
  • It needs to be autonomous.
  • It must be business domain centric.
  • It must have resilience.
  • It must be observable.
  • Automation should be used throughout the development process.

High Cohesion

  • The microservices functionality and content in terms of input and output must be coherent.
    • It must have a single focus, and do it well.
      • This principle allows to control the size of the service.
      • It prevent to create a monolithic service by attaching other behaviors into the microservice which may not be related.
    • It must follow the Single Responsibility Principle.
      • A class can only change for one reason.
        • A business function.
        • A business domain.
      • Check SOLID principles for more information.
    • e.: If your microservice takes care of the postage, then all the input, output and process should be focus around the postage.
  • It is like encapsulation principle from OOP programming principles.
    • Take all the data and functionality that’s related and put them together in one package.
  • This principle makes the microservice easier to rewrite.
  • This makes the system highly scalable, flexible and reliable.
    • We can scale up individual microservices which represent a specific business function or business domain.
    • The system is more flexible because we can change or upgrade the functionality of specific business functions or domains.
    • The system have reliability because we are changing specific small parts with in the system without affecting the other parts.

 

Autonomus

  • The interaction with an external systems should not make the microservice subject of change.
  • There should be loose coupling between the microservices and/or clients
    • A change to a microservice should not force other microservices and/or clients to change.
      • Microservices should honor interfaces and contracts to other services and/or clients.
      • The way the input and output are formatted should not change between versions.
      • There should be a clear definition of the input and output of the microservice.
    • A microservice should be stateless,
      • No need to remember previous interactions in order to carry out the current request.
      • They should be independently deployable (if they honor the contracts and interfaces).
    • Services should always be backwards compatible.

Business Domain Centric

A service should represent a business function and/or business domain.

  • Scope of service.
  • This idea have being taken from domain driven design.
  • Define a bounded context which contains all the functionality related to a specific part of the business to a business function or business domain.
  • Define bounded context by defining boundaries and seams within code.
  • Shuffle code when it is required so that code ends in the right place where it makes sense and belongs in term of business function and/or business domain.
  • Aim to high cohesion.
  • Microservices should be business domain centrist or responsible to business change.

 

Resilience

Embrace failure.

microservice-resilient

  • Failure takes many forms:
    • It can be a service not responding to your service.
    • A connection line gone down.
    • A third party system failing.
  • When failure is found, the microservice should degrade the functionality within or use a default functionality. It shouldn’t cascade the failure. It shouldn’t crash.
    • Decide when you should degrade functionality and/or when you should default functionality.
    • Example of degrade functionality: The service can decide to not display a page
    • Example of default functionality: The service decide to display a default page with a message.
  • Make the microservice resilient by having multiple instance of microservices.
    • Each microservice should register themselves as they star up.
    • If any of these microservices fails, they will deregister themselves.
  • Be aware of different types of failures:
    • Exceptions and/or errors.
    • Delays in replying request.
    • Unavailability of a microservices.
    • Network failures.
      • Remember, we are using distributed transactions. One service may use several other services before it actually completes.
    • Validate microservice input from services and clients.
      • The microservice shouldn’t fail due wrong formatted data.

 

Observable

Microservices should being observable. We need a way to observe our system health and status so we can quick solve any problems.

observable-microservice

  • Current system activity.
  • Error currently happened.
  • Monitoring and logging (logs) needs to be centralized so there in one place to go in order to view information about the system health.
    • Centralized monitoring
    • Centralized Logging
    • Remember the system use distributed transactions across the network and several services.
    • System health:
      • Logs
      • Status
      • Information
      • Warnings
      • Errors
  • Need a quick way of getting feedback in response to deployment.
  • Data collected can be used for capacity planning and scaling up system.
    • Monitor business data.
  • Demand can be easily spotted.
  • Easy to make specific measurements.

Automation

Automation is done in a form of tools since micro-services have many “moving parts”; therefore, testing can become complex. So, we create automated tools for testing. For example, the purpose of automating testing is to reduce the amount of time:

  • Required for manual regression testing.
  • For test integration between services and clients.
  • To set up test environments.

These automated testing tools should provide us with a quick feedback, confirm that changes integrates with the entire system, to test integrations (also known as continuous integrations), to help with the pipeline to deployment, to indicate our microservice deployment status (is it ready?), to check in a microservice, to provide a way a way to move the build to the target machine (or the target cloud system), and any other functionality that may help.

The concept of using tools for deployments belongs to the continuous deployment category. The use of continuous integration tools allows the microservice architecture, which is a complex distributed system with multiple instances of the services, to be organized.Since manual deployment would be too time consuming and unreliable.

Share
Leave a comment

Microservices

Microservices: Design Principles Introduction icon-angle-right 

What is a Service?

A service is a piece of software that provides functionality to another pieces of software.

what-is-a-service

 

 

 

 

 

 

 

  • Provide reusability of functionality.
  • A service can provide functionality to any application.
    • Such a web server, mobile, or desktop application
  • A service can be use by another service
  • Service-oriented Architecture (SOA)
    • Instead of using package modules within each client application, we have a service which provide the same functionality to different client applications.
    • Allow for new services and application to use the same functionality, reusing it, in the future.
    • Allows for scale up our software when demand increasing.
      • i.e. Load balancer which have multiple copies of the same service on multiple servers. When demand increases, we increase the instance of the service running across servers.
  • As long as the signature of a service, contract and interface, doesn’t change when the service changes, we can upgrade our service without having to update our clients.
  • A service is stateless. When a request comes in, that instance of the service does not have to remember the previous request from that specific client.

Microservice Architecture

Traditional SOA resulted in monolithic services. You needed to know how to size a service. The micro sized services provide an efficiently, flexible, and high performance applications.

A microservice architecture is an application which is powered by multiple microservices, in which each microservice provides a set of functions (or related functions) to a specific part of the application.

A microservice have a single focus. It does one thing only and it does it well.

Microservice architecture are used in lightweight and quick communication mechanisms (such as REST) between client and services; as well as, service to service.

A microservice needs technology agnostic API which mean to use an open communication so it doesn’t dictate the technology that the client needs to use.

At difference to a monolithic service where there is a central database used to share data between applications and services, in microservices architecture, each microservice has its own data storage.

Monolithic Service Example
monolithic
Microservice Example
microservice

A microservice is independently changeable. This means that we can upgrade or fix a microservice without forcing any changes to the clients or services.

A microservice needs to be independently deployable. You should be able to deploy a microservice without having to deploy anything else.

dialog-warning-2 Note: You may need a centralized tooling for management of microservices.

 

The Monolithic System

Typical Enterprise Application:

  • Large website with all modules packaged in together into one package.
  • A service which talks to a website in which the service itself is a large service with all modules packaged together as one executable.
  • As you add features and stuff, your application keeps growing.
  • There is no restriction in size; as well as, there is no division.
  • There is always one package which basically contains everything.
  • Large code base which makes it harder and time consuming to add new functionality.
  • Code can become intertwined making difficult to make changes without creating side effects to other parts of the systems.
  • Testing can be challenging.
  • Features may be in deep in the system that they can be utilized for external use.
  • Commonly stuck with one technology stack which may bring restriction such as implementing some new technology that may be different to the current
  • technology stack.
  • The system is less competitive because it restrict the adoption of new technology.
  • Large package with high levels of coupling which means that changes may produce a ripple effect (side effects). This coupling happens in all levels such as modules, services, and objects.
  • A failure in one part of the system may affect the whole system.
  • Duplication of the whole may require scaling.
  • The system may requires a long time to compile. The larger the system gets, the longer the compilation time required.
  • Any changes, no matter how minor, may requires a complete rebuild.
Monolithic System Example

Emergence of Microservices

  • Need to respond to change quickly.
  • Can split a large system into parts that can be upgraded and enhanced individually
  • The entire system will not break if one part breaks.
  • It allows for business domain-driven design.
  • It takes advantage of automated test tools.
  • Since transactions are distributed, each transaction will be processed by multiple services before it’s completed.
    • The integration between those services requires to be tested.
    • Instead of testing these microservices manually, we can automated the test.
  • Release and deployment of microservices may become complex; however, there are tools available to easier the work.
  • We can host microservices using on-demand technology such using virtual machines to host our microservice.
    • Physical servers are no longer required in order to deploy our software.
    • On-demand hosting is simpler in these days with cloud services available.
    • We can clone these virtual machines.
  • We can move our microservice from one technology stack to another technology stack.
  • It allows for asynchronous communication technology.
    • The distributed transaction do not have to wait for other services to complete their task.
  • We have simpler server side and client side technology, as well as many open communication protocols available which allows communication between different technology stacks.

Key Benefits

  • Shorter development times
  • The split up of the system allows to work individually in one part or assign different parts to different people and/or teams.
  • Due the size and the concept of single focus, an individual or team has less to worry about in terms of scope.
  • They only need to focus on their scope and not the whole system
    • As long as the contracts (interfaces) between the services remain.
  • Developers can rework, change and deploy individual components without affecting the system (or need to redeploy everything) since the services are loosely coupled.
  • Deployment is more reliable and faster.
  • Allows for shorter development times, reliable and faster deployment; therefore, frequent updates.
    • Frequent updates provide a competitive edge.
  • It allows us to decouple changeable parts.
  • Increases security since each microservice has its own database and its own security mechanism.
    • Data is distributed which makes the data more secure.
    • The monolithic system may have one database. By hacking that one system, you can gain access to the data.
  • Quicker to identify which service is having the problem.
  • Highly scalable and better performance.
    • Scale part individually instead of the whole system.
  • Easier to change ownership of each microservice.
  • Each microservice have their own database and code base.
  • Enables distributed teams.

 

 

 

 

Share
Leave a comment

Architectural Principles

Service Autonomy Principles

  • One service should not depend and/or rely on any other service to do its work.
    • Any service failing should not affect other services.
  • Any external service should be considered unstable and be expected to fail
    • If any external service fails then there should not be a cascade of these failures into our service, we should instead degrade the functionality so that such failure doesn’t become catastrophic to our service.
  • Each service update should be dependent without requiring any other service to coordinate updates as well. In other words, the update of any service should affect the rest of services.
  • Services should have the ability to be changes and deployed any time

No Coordinated Transactions Principles

  • One service should not be forced to enroll in a transaction which is owned by another service.
    • The service should not rely on other services
    • The service should not be allowed to do complex transactions, be involved with multiple services changing continuously of states, and/or interacting with multiple services and/or objects.

Microchanges Priciples

  • ACID 2.0 model.
    • Commutative. Idempotent. Distributed.
    • Achieving high throughput by altering our data model.
  • Create as small of database transactions as is logical.
  • Change as little as possible.
  • As events, capture user-intent rather than data objects

Change Tolerant Principles

  • Defensive coding.
  • How tolerant is your service in respect to other services changing?
    • How the service will react to failures?
    • How the service will react with changes in another service’s API?
    • How the service will react with changes in events and/or messages it receive?

Articles Related

  • ACID 2.0 Article:

    Jimmi Bogard. “ACID 2.0 in action.” Los Techies. . (2013): . . https://lostechies.com/jimmybogard/2013/06/06/acid-2-0-in-action/

Share
Leave a comment