{"id":83746,"date":"2019-04-04T08:58:23","date_gmt":"2019-04-04T08:58:23","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=83746"},"modified":"2019-04-04T09:06:38","modified_gmt":"2019-04-04T09:06:38","slug":"how-did-we-get-to-service-meshes","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/how-did-we-get-to-service-meshes\/","title":{"rendered":"How did we get to service meshes?"},"content":{"rendered":"<p>If you\u2019ve been to a conference over the last few years, you\u2019ve probably come across <a href=\"https:\/\/microservices.io\/\" target=\"_blank\" rel=\"noopener\">microservices<\/a>. A microservice architecture consists of many highly decoupled services that are independently deployable and organized around business capabilities. This isn\u2019t a new idea, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Service-oriented_architecture\" target=\"_blank\" rel=\"noopener\">SOA<\/a> had similar ideas in the 90\u2019s but the technology around it was clunky (it seemed to involve an awful lot of XML\u200a\u2014\u200anever a good start!).<\/p>\n<p>Individually microservices are simple\u200a\u2014\u200athey are small and do one thing. However, imagine you\u2019ve got a few hundred and now you need to start managing those messages, get some consistency and put some standard functionality in (think orchestration, transformation, routing, circuit breaking etc.). How do you do this consistently?<\/p>\n<h2>Solving the problems around service communication<\/h2>\n<p>The first option is a <em>message queue<\/em>. Instead of point-to-point communication use a central store (Enterprise Service Bus) and everything communicate through that broker. A broker service like <a href=\"https:\/\/www.rabbitmq.com\/\" target=\"_blank\" rel=\"noopener\">RabbitMQ<\/a> can support multiple protocols\/transport and do all this out of the box. Message buses also help with scalability, but this comes at a cost. The centralised bus is a single point of failure (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Single_point_of_failure\" target=\"_blank\" rel=\"noopener\">SPOF<\/a>). To address this, message buses are typically clustered for reliability and resilience. This therefore has a high operational cost.<\/p>\n<p>Another option for managing microservice communications is an <em>API gateway<\/em>. An API gateway can make client code (that consumes microservices) easier to write by effectively bundling APIs together to present a uniform interface for clients. Imagine a reverse proxy on steroids. API Gateways run on the edge (the boundary between services and clients) and give consistency through API management (versioning etc), security and SLA management. Examples of this include <a href=\"https:\/\/cloud.google.com\/apigee\/\" target=\"_blank\" rel=\"noopener\">APIGee<\/a> (acquired by Google) and <a href=\"https:\/\/apiary.io\/\" target=\"_blank\" rel=\"noopener\">Apiary<\/a> (acquired by Oracle). One anti-pattern around API Gateways (as noted by <a href=\"https:\/\/www.thoughtworks.com\/radar\/platforms\/overambitious-api-gateways\" target=\"_blank\" rel=\"noopener\">Thoughtworks<\/a>) is a tendency for the API gateway to grow in functionality to the point that\u2019s it\u2019s complexity outweighs the benefits. It\u2019s still a SPOF and requires specialist skills to maintain.<\/p>\n<p>Lately, and quickly, a new breed of technology has been developed that offers another choice. A <em>service-mesh <\/em>offers consistent discovery, security, tracing, monitoring and failure handling without the need for a shared asset like an API gateway or message bus.<\/p>\n<h2>Deriving a\u00a0Mesh<\/h2>\n<p>That sounds like a desirable solution, but how\u2019d you achieve that? Let\u2019s try and walk through a very simplified example. We\u2019ve got three services A, B, C and they work together to build <a href=\"https:\/\/en.wikipedia.org\/wiki\/Acme_Corporation\" target=\"_blank\" rel=\"noopener\">ACME<\/a>\u2019s first web based service (it probably sells Anvils on Demand). Here\u2019s our \u201carchitecture\u201d<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"447\" height=\"224\" class=\"wp-image-83747\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/04\/https-cdn-images-1-medium-com-max-1200-17xmkswq.png\" alt=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*7XMkSwQL0j7GDKd5Qf4c2w.png\" \/><\/p>\n<p>ACME. Inc Architecture<\/p>\n<p>We\u2019ve got a few problems with this. Services A, B and C and the ACME application all have some common code to communicate with each other. This is starting to get complicated\u200a\u2014\u200ahow do the servers find each other? What does Service B do when Service C goes down? And how do we get the metrics in a sensible way?<\/p>\n<p>One option would be to build a library that encapsulates all this functionality. That\u2019s an option but then we get into the dreaded world of versioning. That library is going to either be very good at versioning (can anyone do <a href=\"https:\/\/semver.org\/\" target=\"_blank\" rel=\"noopener\">semantic-versioning<\/a> right?) or it\u2019s going to be set in stone and never updated. Any bugs or crashes in this library are going to cause service outage and building it into the application will compromise the single purpose principle of services.<\/p>\n<p>As David Wheeler says, \u201cAll problems can be solved with another layer of indirection\u201d. The answer is to factor this logic out and run it as a separate process. Let\u2019s look at our architecture now.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"398\" height=\"251\" class=\"wp-image-83748\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/04\/https-cdn-images-1-medium-com-max-1200-1zvqvatu.png\" alt=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*ZvQVATuuGNERAJTcUfF_lQ.png\" \/><\/p>\n<p>Another layer of indirection!<\/p>\n<p>This is known as the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/sidecar\" target=\"_blank\" rel=\"noopener\">Sidecar pattern<\/a>. This pattern allows us to deploy more of our components as separate process\/containers and reduces the amount of business logic needed in each service.<\/p>\n<p>This is still a complicated set up\u200a\u2014\u200awhat does this indirection really give us? We\u2019ve still got to write the same amount of code we did before. But do we?<\/p>\n<p>What if we didn\u2019t have to write these sidecars? What if we developed a common sidecar at a higher-level of abstraction that provided this common functionality like service discovery, authentication and diagnostics. That\u2019s exactly what a service mesh, such as <a href=\"https:\/\/www.hashicorp.com\/products\/consul\" target=\"_blank\" rel=\"noopener\">Consul<\/a>, <a href=\"https:\/\/linkerd.io\/\" target=\"_blank\" rel=\"noopener\">LinkerD<\/a> and <a href=\"https:\/\/istio.io\/\" target=\"_blank\" rel=\"noopener\">Istio<\/a> is!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"540\" class=\"wp-image-83749\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/04\/https-cdn-images-1-medium-com-max-1200-0ihp8zf8.jpeg\" alt=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*IhP8Zf8ihFzSjizD.jpg\" \/><\/p>\n<p>Meshes are resilient!<\/p>\n<h2>So, what is a service\u00a0mesh?<\/h2>\n<p>A service mesh is logically split into two different types. The <em>data plane <\/em>mediates and controls network communication between services. The <em>control plane<\/em> is the meta level that manages and configures the sidecars themselves.<\/p>\n<p>Typically the control plane is managed using a decentralised peer-to-peer approach (typically implemented by a <em>distributed consensus protocol<\/em>, such as <a href=\"https:\/\/raft.github.io\/\" target=\"_blank\" rel=\"noopener\">Raft<\/a> or the wickedly complicated <a href=\"https:\/\/en.wikipedia.org\/wiki\/Paxos_%28computer_science%29\" target=\"_blank\" rel=\"noopener\">Paxos<\/a> algorithm). For the data plane, events are often distributed using a <a href=\"https:\/\/flopezluis.github.io\/gossip-simulator\/\" target=\"_blank\" rel=\"noopener\"><em>Gossip Protocol<\/em><\/a><em>.<\/em><\/p>\n<p>So in summary, you\u2019d use the <a href=\"https:\/\/microservices.io\/patterns\/deployment\/service-mesh.html\" target=\"_blank\" rel=\"noopener\">Service Mesh pattern<\/a> when you\u2019ve got cross-cutting concerns (configuration, service discovery, monitoring etc.) that you want to centralise. You solve these by using a <em>service mesh<\/em> that mediates all communication in and out of each service.<\/p>\n<p>If you\u2019ve noticed any errors in the description above, please let me know and I\u2019ll update!<\/p>\n<p>In the meantime, if you\u2019ve read this far I should mention we are <a href=\"https:\/\/www.red-gate.com\/our-company\/careers\/current-opportunities\/\" target=\"_blank\" rel=\"noopener\">hiring for engineers<\/a> in our Cambridge office. Feel free to <a href=\"mailto:jeff.foster@red-gate.com\" target=\"_blank\" rel=\"noopener\">reach out to me<\/a> if you\u2019d like to know more.<\/p>\n<p><span lang=\"EN-GB\"><span style=\"font-family: Calibri;\"><i><span style=\"color: #000000;\">This post was first published on Redgate\u2019s product development blog, <\/span><a href=\"https:\/\/medium.com\/ingeniouslysimple\">Ingeniously Simple<\/a><span style=\"color: #000000;\">.<\/span><\/i><\/span><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve been to a conference over the last few years, you\u2019ve probably come across microservices. A microservice architecture consists of many highly decoupled services that are independently deployable and organized around business capabilities. This isn\u2019t a new idea, SOA had similar ideas in the 90\u2019s but the technology around it was clunky (it seemed&#8230;&hellip;<\/p>\n","protected":false},"author":96657,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[50377],"class_list":["post-83746","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83746","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/96657"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=83746"}],"version-history":[{"count":4,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83746\/revisions"}],"predecessor-version":[{"id":83753,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/83746\/revisions\/83753"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=83746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=83746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=83746"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=83746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}