github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/docs/blog/_posts/2016-04-18-micro-architecture.md (about)

     1  ---
     2  layout: post
     3  title:  Micro architecture & design patterns for microservices
     4  date:   2016-04-18 09:00:00
     5  ---
     6  <br>
     7  We've had a lot of questions about the micro architecture and design patterns for microservices over the past few months. So today we'll try cover both.
     8  
     9  ###### About Micro
    10  
    11  [**Micro**](https://github.com/tickoalcantara12/micro) is a microservices toolkit. It was built to be opinionated in it's features and interfaces while 
    12  providing a powerful pluggable architecture allowing the underlying dependencies to be swapped out.
    13  
    14  Micro is focused on addressing the fundamental requirements for building microservices and has looked to do this by taking a thoughtful and measured 
    15  approach to it's design.
    16  
    17  If you would like to read up on the Micro toolkit check out the previous blog post [here]({{ site.baseurl }}{{ site.baseurl }}/2016/03/20/micro.html) or if you would like to learn 
    18  more about the concept of microservices look [here]({{ site.baseurl }}/2016/03/17/introduction.html).
    19  
    20  We'll quickly recap on the features of Micro before delving into further architecture discussion.
    21  
    22  ###### The Toolkit
    23  
    24  [**Go Micro**](https://github.com/micro/go-micro) is a pluggable RPC framework for writing microservices in Go. It provides libraries for 
    25  service discovery, client side load balancing, encoding, synchronous and asynchronous communication.
    26  
    27  [**Micro API**](https://github.com/tickoalcantara12/micro/tree/master/api) is an API Gateway that serves HTTP and routes requests to appropriate micro services. 
    28  It acts as a single entry point and can either be used as a reverse proxy or translate HTTP requests to RPC.
    29  
    30  [**Micro Web**](https://github.com/tickoalcantara12/micro/tree/master/web) is a web dashboard and reverse proxy for micro web applications. We believe that 
    31  web apps should be built as microservices and therefore treated as a first class citizen in a microservice world. It behaves much the like the API 
    32  reverse proxy but also includes support for web sockets.
    33  
    34  [**Micro Sidecar**](https://github.com/tickoalcantara12/micro/tree/master/car) provides all the features of go-micro as a HTTP service. While we love Go and 
    35  believe it's a great language to build microservices, you may also want to use other languages, so the Sidecar provides a way to integrate 
    36  your other apps into the Micro world.
    37  
    38  [**Micro CLI**](https://github.com/tickoalcantara12/micro/tree/master/cli) is a straight forward command line interface to interact with your micro services. 
    39  It also allows you to leverage the Sidecar as a proxy where you may not want to directly connect to the service registry.
    40  
    41  That's the quick recap. Now let's go deeper.
    42  
    43  ###### RPC, REST, Proto...
    44  
    45  So the first thing you might be thinking is why RPC, why not REST? Our belief is that RPC is a more appropriate choice for inter-service communication. 
    46  Or more specifically RPC using protobuf encoding and APIs defined with protobuf IDL. This combination allows the creation of strongly defined 
    47  API interfaces and an efficient message encoding format on the wire. RPC is a straight forward, no frills, protocol for communication.
    48  
    49  We're not alone in this belief.
    50  
    51  Google is creator protobuf, uses RPC internally and more recently open sourced gRPC, an 
    52  RPC framework. Hailo was also a strong advocate of RPC/Protobuf and benefited tremendously, interestingly more so in cross team development than systems performance.
    53  Uber choosing their own path has gone on to develop a framing protocol for RPC called [TChannel](http://uber.github.io/tchannel/).
    54  
    55  
    56  Personally we think the APIs of the future will be built using RPC because of their well defined structured format, propensity for use with efficient encoding
    57  protocols such as protobuf with the combination offering strongly defined APIs and performant communication.
    58  
    59  ###### HTTP to RPC, API...
    60  
    61  In reality though, we're a long way from RPC on the web. While its perfect inside the datacenter, serving public facing traffic e.g websites and mobile 
    62  APIs, is a whole other deal. Let's face it, it's going to be a while before we move away from HTTP. This is one of the reasons why micro includes 
    63  an API gateway, to serve and translate HTTP requests.
    64  
    65  The API gateway is a pattern used for microservice architectures. It acts as a single entry point for the outside world and routes to an appropriate service based 
    66  on the request. This allows a HTTP API itself to be composed of different microservices.
    67  
    68  This is a powerful architecture pattern. Gone are the days where a single change to one part of your API could bring down the entire monolith. 
    69  
    70  The micro API uses path-to-service resolution so that each unique request path can be served by a different API micro service e.g. /user => user api, 
    71  /order => order api.
    72  
    73  Here's an example. A request to **/customer/orders** will be sent to the API service **go.micro.api.customer** with method **Customer.Orders**.
    74  
    75  <p align="center">
    76   <img src="{{ site.baseurl }}/blog/images/api.png" style="width: 100%; height: auto;" />
    77  </p>
    78  
    79  You might be wondering what the heck an API service is. Now is about the right time to discuss the different types of services.
    80  
    81  ###### Types of Services
    82  
    83  The concept of Microservices is all about separation of concerns and borrows a lot from the unix philosophy of doing one thing and doing it well. 
    84  Partly for that reason we think there needs to be a logical and architectural separation between services with differing responsibilities.
    85  
    86  I'll acknowledge right now that these concepts are nothing new but they are compelling given they've been proven in very large successful technology companies. 
    87  Our goals are to spread these development philosophies and guide design decisions via tooling.
    88  
    89  So here's the types of services we currently define.
    90  
    91  **API** - Served by the **micro api**, an API service sits at the edge of your infrastructure, most likely serving public facing traffic and your 
    92  mobile or web apps. You can either build it with HTTP handlers and run the micro api in reverse proxy mode or by default handle a specific RPC API request response 
    93  format which can be found [here](https://github.com/tickoalcantara12/micro/blob/master/api/proto/api.proto).
    94  
    95  **Web** - Served by the **micro web**, a Web service focuses on serving html content and dashboards. The micro web reverse proxies HTTP and WebSockets. 
    96  These are the only protocols supported for the moment but that may be extended in the future. As mentioned before, we believe in web apps as microservices.
    97  
    98  **SRV** - These are backend RPC based services. They're primarily focused on providing the core functionality for your system and are most likely not be 
    99  public facing. You can still access them via the micro api or web using the /rpc endpoint if you like but it's more likely API, Web and other SRV services use 
   100  the go-micro client to call them directly.
   101  
   102  <p align="center">
   103   <img src="{{ site.baseurl }}/blog/images/arch.png" />
   104  </p>
   105  
   106  Based on past experiences we've found this type of architecture pattern to be extremely powerful and seen it scale to many hundreds of services. 
   107  By building it into the Micro architecture we feel it provides a great foundation for microservice development.
   108  
   109  ###### Namespacing
   110  
   111  So you might wonder, what's to stop the micro api from talking to web services or the micro web talking to api services. We use logical namespacing 
   112  to separate these. By prefixing a namespace to a service name we clearly identify it's purpose and place in the system. It's a simple but effective 
   113  pattern that has served us well.
   114  
   115  The micro api and web will compose a service name of the namespace and first path of a request path e.g. request to api **/customer** becomes **go.micro.api.customer**.
   116  
   117  The default namespaces are:
   118  
   119  - **API** - go.micro.api
   120  - **Web** - go.micro.web
   121  - **SRV** - go.micro.srv
   122  
   123  You should set these to your domain e.g *com.example.{api, web, srv}*. The micro api and micro web can be configured at runtime to route to your namespace.
   124  
   125  ###### Sync vs Async
   126  
   127  You'll often hear microservices in the same sentence as reactive patterns. For many, microservices is about creating event driven architectures and designing services 
   128  that interact primarily through asynchronous communication.
   129  
   130  Micro treats asynchronous communication as a first class citizen and a fundamental building block for microservices. Communicating events through asynchronous 
   131  messaging allows anyone to consume and act upon them. New standalone services can be built without any modification to other aspects of the system. It's a 
   132  powerful design pattern and for this reason we've included the [Broker](https://godoc.org/github.com/micro/go-micro/broker#Broker) interface in go-micro. 
   133  
   134  <p align="center">
   135   <img src="{{ site.baseurl }}/blog/images/pub-sub.png" />
   136  </p>
   137  
   138  Synchronous and asynchronous communication are addressed as separate requirements in Micro. The [Transport](https://godoc.org/github.com/micro/go-micro/transport#Transport) 
   139  interface is used to create a point to point connection between services. The go-micro client and server build upon the transport to perform request-response RPC and provide 
   140  the capability of bidirectional streaming.
   141  
   142  <p align="center">
   143   <img src="{{ site.baseurl }}/blog/images/request-response.png" />
   144  </p>
   145  
   146  Both patterns of communication should be used when building systems but it's key to understand when and where each is appropriate. In a lot of cases there's 
   147  not right or wrong but instead certain tradeoffs will be made.
   148  
   149  An example of where the broker and asynchronous communication could potentially be used is in an audit trail system for keeping track of customer event history.
   150  
   151  <p align="center">
   152   <img src="{{ site.baseurl }}/blog/images/audit.png"  style="width: 100%; height: auto;" />
   153  </p>
   154  
   155  In this example every API or service publishes an event when some action occurs such as a customer logs in, update their profile or places an order. The audit service will 
   156  subscribe for these events and store them in a time series database of some kind. An admin or anyone else can then view the history of events that 
   157  have taken place within the system for any user.
   158  
   159  If this was done as a synchronous call we could easily overwhelm the audit service when there's high traffic or as the number of bespoke services increases.
   160  If the audit service was taken offline for some reason or a call failed we would essentially lose this history. By publishing these events to the broker 
   161  we can persist them asynchronously. This is a common pattern in event driven architectures and for microservices.
   162  
   163  ###### OK wait, brief pause, but what defines a microservice?
   164  
   165  We're covering a lot of what the Micro toolkit provides for microservices and we've defined the types of services (API, WEB, SRV) but there's nothing really 
   166  about what a microservice actually is.
   167  
   168  How does it differ from any other kind of application? What gives it this special name of a "microservice".
   169  
   170  There's varying definitions and interpretations but here's a couple that fit best in the Micro world.
   171  
   172  
   173  > Loosely coupled service oriented architecture with a bounded context <br/>
   174  > <sub>Adrian Cockcroft</sub>
   175  
   176  <p/>
   177  
   178  > An approach to developing a single application as a suite of small services, 
   179  each running in its own process and communicating with lightweight mechanisms <br/>
   180  > <sub>Martin Fowler</sub>
   181  
   182  And because we love the unix philosophy and feel it fits perfectly with the microservice philosophy.
   183  
   184  > Do one thing and do it well <br/>
   185  > <sub>Doug McIlroy</sub>
   186  
   187  Our belief and the idea we build on is that a microservice is an application focused on a single type of entity or domain, which it provides access to 
   188  via a strongly defined API.
   189  
   190  Let's use a real world example such as a social network.
   191  
   192  <p align="center">
   193    <img src="{{ site.baseurl }}/blog/images/facebook.png" style="width: 100%; height: auto;" />
   194  </p>
   195  
   196  A well defined software architecture pattern that became popular with the rise of Ruby on Rails was 
   197  [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) - Model-View-Controller.
   198  
   199  In the MVC world each entity or domain would be represented a model which in turn abstracts away the database. The model may have relationships with 
   200  other models such as one to many or many to many. The controller processes in coming requests, retrieves data from the models and passes it to the 
   201  view to be rendered to the user.
   202  
   203  Now take the same example as a microservice architecture. Each of these models is instead a service and delivers its data through an API. User requests, 
   204  data gathering and rendering is handled by a number of different web services. 
   205  
   206  Each service has a single focus. When we want to add new features or entities we can simply change the one service concerned with that feature 
   207  or write a new service. This separation of concerns provides a pattern for scalable software development. 
   208  
   209  Now back to our regularly scheduled program.
   210  
   211  ###### Versioning
   212  
   213  <p align="center">
   214    <img src="{{ site.baseurl }}/blog/images/versioning.png" style="width: 100%; height: auto;" />
   215  </p>
   216  
   217  Versioning is an important part of developing real world software. In the microservice world it's critical given the API and business logic is split 
   218  across many different services. For this reason its important that service versioning be part of the core tooling, allowing finer grained control over 
   219  updates and traffic shaping.
   220  
   221  In go-micro a service is defined with a Name and Version. The [Registry](https://godoc.org/github.com/micro/go-micro/registry#Registry) returns a service 
   222  as a list, splitting the nodes by the version they were registered with.
   223  
   224  This is our building block for version based routing.
   225  
   226  ```
   227  type Service struct {
   228  	Name      string
   229  	Version   string
   230  	Metadata  map[string]string
   231  	Endpoints []*Endpoint
   232  	Nodes     []*Node
   233  }
   234  ```
   235  
   236  This in combination with the [Selector](https://godoc.org/github.com/micro/go-micro/selector#Selector), a client side load balancer, within go-micro ensures 
   237  that requests are distributed across versions accordingly.
   238  
   239  The selector is a powerful interface which we're building on to provide different types of routing 
   240  algorithms; random (default), round robin, label based, latency based, etc. 
   241  
   242  By using the default random hashed load balancing algorithm and gradually adding instances of a new service version you can perform blue-green deployment and 
   243  do canary testing.
   244  
   245  <p align="center">
   246    <img src="{{ site.baseurl }}/blog/images/selector.png" />
   247  </p>
   248  
   249  In the future we'll look to implement a global service load balancer which ties into the selector allowing for routing decisions based on historic trends 
   250  within a running system. It will also be capable of adjusting the percentage of traffic sent to each version of a service at runtime and dynamically 
   251  adding metadata or labels to a service, which label based routing decisions can be made on.
   252  
   253  ###### Scaling
   254  
   255  The above commentary on versioning begins to hint at the foundational patterns for scaling a service. While the registry is used as a mechanism for storing 
   256  information about a service, we separate the concern of routing and load balancing using the selector.
   257  
   258  Again the notion of separation of concerns and doing one thing well. Scaling infrastructure as well as code is very much about simplicity, strongly defined 
   259  APIs and a layered architecture. By creating these building blocks we allow ourselves to construct more scalable software and address higher level concerns 
   260  elsewhere.
   261  
   262  This is something fundamental to the way Micro is written and how we hope to guide software development in a microservices world.
   263  
   264  We've briefly discussed cloud architecture patterns in a previous post about [Micro on NATS]({{ site.baseurl }}/2016/04/11/micro-on-nats.html#scaling-micro-on-nats) 
   265  and will re-address some of the ideas here.
   266  
   267  When deploying services in a production setting you'll be looking to build something scalable, fault tolerant and performant. Cloud computing now gives us 
   268  access to pretty much unlimited scale but nothing is impervious to failure. In fact failure is one of the key aspects that we look to 
   269  address when building distributed systems and you should take this into consideration when building your infrastructure.
   270  
   271  In the world of the cloud, we want to be tolerant of Availability Zone (datacenter) failures and even entire Region (Multi DC) outages. In past days, we used to 
   272  talk about warm and cold standby systems or disaster recovery plans. Today the most advanced technology companies operate in a global manner, where multiple copies 
   273  of every application is running in a number datacenters across the world.
   274  
   275  We need to learn from the likes of Google, Facebook, Netflix and Twitter. We must build systems capable of tolerating an AZ failure without any impact on the user and in 
   276  most cases dealing with region failures within minutes or less.
   277  
   278  Micro enables you to build this kind of architecture. By providing pluggable interfaces we can leverage the most appropriate distributed systems for each 
   279  requirement of the micro toolkit.
   280  
   281  Service discovery and the registry are the building block of Micro. It can be used to isolate and discover a set of services within an AZ or Region or any 
   282  configuration you so choose. The Micro API can then be used to route and balance a number of services and their instances within that topology.
   283  
   284  <p align="center">
   285    <img src="{{ site.baseurl }}/blog/images/regions.png" style="width: 100%; height: auto;" />
   286  </p>
   287  
   288  ###### Summary
   289  
   290  Hopefully this blog post provides clarity on the architecture of Micro and how it enables scalable design patterns for microservices.
   291  
   292  Microservices is first and foremost about software design patterns. We can enable certain foundational patterns through tooling while providing flexibility for 
   293  other patterns to emerge or be used.
   294  
   295  Because Micro is a pluggable architecture it's a powerful enabler of a variety of design patterns and can be appropriately used in many scenarios. For 
   296  example if you're building video streaming infrastructure you may opt for the HTTP transport for point to point communication. If you are not latency 
   297  sensitive then you may choose a transport plugin such as NATS or RabbitMQ instead.
   298  
   299  The future of software development with a tool such as Micro is very exciting.
   300  
   301  If you want to learn more about the services we offer or microservices, check out the [blog](/), the  website 
   302  [micro.mu](https://m3o.com) or the github [repo](https://github.com/tickoalcantara12/micro).
   303  
   304  Follow us on Twitter at [@MicroHQ](https://twitter.com/m3ocloud) or join the [Slack](https://slack.m3o.com) 
   305  community [here](http://slack.m3o.com).
   306