Thanks to Hugh McKee, Developer Advocate at Lightbend, for sharing his insights on microservices in advance of his presentation, “Building Microservices that Scale and Do Not Fail,” on Friday, October 10 at the Reactive Summit in Austin, TX. Click here to register.
Hugh has a long career building applications that evolved slowly, that inefficiently used their infrastructure, and that were brittle and prone to failure. That all changed when we started building reactive, asynchronous, actor-based systems. This radically new way of building applications rocked his world. As an added benefit, building application systems became way more fun than it had ever been. Now he is focused on helping others to discover the significant advantages and joys of building responsive, resilient, elastic, message-based applications.
Q: What do you see as the most important elements of a successful microservices strategy?
A: I start by finding out what the client considers to be their microservices environment. Where are they in their modernization journey from monolithic to microservices. How close are they to: 1) independent deployment; 2) each microservice owns its schema; and, 3) accessing their data through APIs? The big challenge I see is accessing the data since many companies are talking to a legacy database. Enterprise legacy data is hard to decompose and decouple so individual microservices achieve the nimbleness and velocity necessary to handle all of the changes they’re facing. The majority of companies typically implement what we call “microliths” or distributed monoliths – when they are unable to decompose their monolithic databases.
Q: Which programming languages, frameworks, and tools do you use for microservices?
A: We use JVM, both Java and Scala. We see a lot of use of open source with the Akka toolkit and the Play framework. All of our open source tools, Akka, Play and Lagom, support both Java and Scala. Most of what we see is in the JVM and Java space with the biggest being Spring Boot and other tools that focus on microservice development. We’re also seeing Lagom getting good traction. Lagom is an open source microservices framework developed by Lightbend. One of Lagom’s primary goals is to ease the coding and architecture load on developers. It’s relatively easy to build microservices that use the traditional data models. Event sourcing and CQRS (Command Query Response Segregation) is an alternative approach for persisting data that is supported with Lagom. With Event Sourcing and CQRS the approach is that commands come into as a request to perform an operation, if that command is a valid legitimate request an event is created that is time-based. In effect, commands are wish or request for something to happen while events are a statement of fact about something that has happened in the past. Events are never deleted so you have a complete history. The event log is the write side. The query side is the read side with data stored in the most optimal way for queries. The query or read side approach opens up the possibility to store data in the most optimal way for reading. For example, using SQL and something like ElasticSearch or Lucene to search documents. That’s a different way of handling data that increases performance tuning the database for read/write – adding to the log and keeping up with events.
Q: How have microservices changed application development?
A: They’re working to meet current users’ demands and lack of patience. The microservices approach breaks apart the system to eliminate bottlenecks both at the business level and at the architectural level. When you have high traffic volumes, you run into ceilings that limit how fast the application can scale. That’s why microservices decompose the application onto smaller models with higher performance ceilings.
Microservices also provide an excellent platform for much greater resilience. As an example, Netflix is a leader in microservices. When one of their microsystems goes down, the system is still operational. The other microservices compensate for these failures and pick up the slack of the failed microservice. In many cases, at the users of the system are unaware of these failures. The UX also compensates what is presented to the user. The opportunity for bulkhead systems to do other services so the application can continue running is tremendous. In a monolithic app, if one part goes out, the entire app can come down.
Q: What kind of security techniques and tools do you find most effective for microservices?
A: With service on the edge at the API level, APIs must be secure. We protect the perimeter of the system but still need to protect within the bubble. This is maturing. With more containers, applications are inherently more secure as they are decomposed within containers so there’s little for hackers to access or affect. Of course, security is extremely important and the options available for microservice-based systems is evolving rapidly.
Q: What are some real-world problems being solved with microservices?
A: Exchange of events, messages, and commands between microservices leaving the comfortable world of transactions with relational databases. By decomposing the system, you are decomposing the transaction as well. For example, an order microservice emit order created events, the order state is persisted by the order microservice. The propagation of events, such as order created, from order to event is not transactional. In this example say the order created events must be delivered to a customer microservice. In this example, these messages have to be delivered. That’s a new dynamic with these types of considerations. When things break, there is a risk that you may lose some events. Is 99.9% good enough, probably not. You need to implement message delivery systems that guarantee that every single message is delivered. Systems need to catch up and self-heal.
Q: What’s the future of microservices, where do the greatest opportunities lie?
A: Self-healing apps already exist. Kafka is great for delivering messages but you also have to consider the synaptic gap between Kafka and what’s going into your system. With systems that have state changes, you have to consider the non-transactional gaps and you must consider how you will handle failures. It could be one event out of many falling through the cracks but you may not see that you have lost some messages until after the outage has occurred. Everyone needs to take failure handling seriously. Our recommended strategy is to face failure head on from the initial design phase all of the way through development and deployment to production. There are elegant strategies for solving these problems but you need to know what the problems are to solve them and people typically shy away from failure.
Netflix is an example of a company that has the guts to face failure head-on by building systems where they “test in anger”, that is they perform failure tests in production. They simulate many of the typical failures that actually do happen so they can see how the architecture handles these outages when they really happen in production. The result is that they have instituted a philosophy that results in extremely resilient systems. At Lightbend we encourage a similar philosophy of “let is crash”. Again, the idea is to make failure handling a core architectural feature of your systems design and implementation.
Q: What do developers need to keep in mind when developing and deploying microservices?
A: It’s a challenge to internalize concepts and to gain a level of intuition but that’s what’s required to become proficient with microservices. Constant coaching and iteration is a good way to go. When you are able to decouple the components of your systems to sufficient levels, that’s where you are able to test in anger. That is implement something, deploy it and see what works and what needs to be improved. When problems are discovered, go back, make the necessary changes and test again and deploy the improved service to production. You will learn at a much more rapid pace. Pay for your mistakes, fix them, and recycle. The ultimate test is are you kind-of doing microservices that are decoupled and independently deployable to production? How quickly you are able to re-release changes to the microservices will give you the answer.