Independence and Autonomy

The emotion and passion that accompany a grass-roots push for creating microservices can be viewed as a mutiny against monolithic environments. We believe this is due to a broad range of reasons, two of which are:

  • Infrequent, expensive, all-or-nothing maintenance windows.
  • Constrained technology choice due to well-intentioned, but heavy-handed, centralized governance.

In these environments, change cannot be made without significant risk because everything is interrelated with everything else: it is the opposite of an agile ecosystem.

A dominant factor in creating and preserving agility lies in ensuring each service is independent and autonomous. Each service must be capable of being started, stopped, or replaced at any time without tight coupling to other services. Many other characteristics of microservice architectures follow from this single factor.

Microservices should act as encapsulations (or bounded contexts, as will be discussed in Chapter 2, “Creating Microservices in Java” on page 9, guarding the implementation details of the application. This allows the service’s implementation to be revised and improved (or even rewritten) over time. Data sources, especially, must be private to the service, as will be discussed in depth in Chapter 5, “Handling Data” on page 41.

If deploying changes requires simultaneous or time-sensitive updates to multiple services, "you are doing it wrong". There may be good, pragmatic, reasons behind requiring these updates, but it should prompt a review of the relationships between your services. There are a few possible outcomes:

  • You need to revise your versioning strategy to preserve the independent lifecycle of services.
  • The current service boundaries are not drawn properly, and services should be refactored into properly independent pieces.

Refactoring services will happen, especially when creating an application from scratch. Identifying services will be discussed more in Chapter 2, “Creating Microservices in Java” on page 9, but take it as a given that you will get some things wrong. The ability to react and refactor services as problems are discovered is a benefit of the microservices approach.

A quick note about polyglot and language-agnostic protocols

Polyglot is a frequently cited benefit of microservice-based architectures. On the one hand, the ability to choose the appropriate language or data store a service is providing can be very powerful, and can bring a lot of efficiency. On the other hand, the use of obscure technologies can complicate long-term maintenance and inhibit the movement of developers between teams. Create a balance between the two by creating a list of supported technologies to choose from at the outset, with a defined policy for extending the list with new technologies over time. Ensure that non-functional or regulatory requirements like maintainability, auditability, and data security can be satisfied, while preserving agility and supporting innovation through experimentation.

Polyglot applications are only possible with language-agnostic protocols. Representational State Transfer (REST) architecture patterns define guidelines for creating uniform interfaces that separate the on-the-wire data representation from the implementation of the service5. RESTful architectures require request state to be maintained by the client, allowing the server to be stateless. The shared concepts between REST and microservices should be apparent.

Hyper Text Transfer Protocol (HTTP) is the lingua franca of the internet, providing a common communication language for all applications. It has an expressive set of verbs and return codes that are only just beginning to realize their potential with the adoption of REST.

REST/HTTP interactions are inherently synchronous (request/response) in nature. Asynchronous communications also play a significant role in maintaining loose coupling between microservices. Again, language-agnostic protocols come to the forefront, with standards like AMQP (Advanced Message Queueing Protocol) and MQTT (MessageQueuing Telemetry Transport) edging out language-specific mechanisms like JMS (Java Message Service). Chapter 3, “Locating services” on page 25 will explore the differences between synchronous and asynchronous interaction patterns in more detail.

JavaScript Object Notation (JSON) has emerged in microservices architectures as the wire-format of choice for text-based data, displacing Extensible Markup Language (XML) with its comparative simplicity and conciseness. Binary serialization frameworks do exist (Apache Avro6, Apache Thrift7, Google Protocol Buffers8), but use of these protocols should be limited to internal services and deferred until the interactions between services are well understood.

results matching ""

    No results matching ""