Introduction to Microservices

原文出自:http://nginx.com/blog/introduction-to-microservices 。我在其中加入了简单的翻译和自己的一些看法。 


This is a guest post by Chris Richardson. Chris is the founder of the original CloudFoundry.com, an early Java PaaS (Platform-as-a-Service) for Amazon EC2. He now consults with organizations to improve how they develop and deploy applications. He also blogs regularly about microservices at http://microservices.io.

==============

Microservices are currently getting a lot of attention: articles, blogs, discussions on social media, and conference presentations. 微服务是最近一两年在架构领域非常流行的一个话题。They are rapidly heading towards the peak of inflated expectations on the Gartner Hype cycle. At the same time, there are skeptics in the software community who dismiss microservices as nothing new. Naysayers claim that the idea is just a rebranding of SOA. 反对者说微服务只是 SOA 的一个翻版。However, despite both the hype and the skepticism, the Microservice architecture pattern has significant benefits – especially when it comes to enabling the agile development and delivery of complex enterprise applications. 当采用敏捷开发和交付复杂的企业应用时,微服务更能体现出它的优点。

This blog post is the first in a 7-part series about designing, building, and deploying microservices. You will learn about the approach and how it compares to the more traditional Monolithic architecture pattern. This series will describe the various elements of the Microservice architecture. You will learn about the benefits and drawbacks of the Microservice architecture pattern, whether it makes sense for your project, and how to apply it.

Let’s first look at why you should consider using microservices.

Building Monolithic Applications

Let’s imagine that you were starting to build a brand new taxi-hailing application intended to compete with Uber and Hailo. 举个例子,构建一个滴滴、快的这样的打车软件 After some preliminary meetings and requirements gathering, you would create a new project either manually or by using a generator that comes with Rails, Spring Boot, Play, or Maven. This new application would have a modular hexagonal architecture, like in the following diagram:

At the core of the application is the business logic, which is implemented by modules that define services, domain objects, and events. Surrounding the core are adapters that interface with the external world. Examples of adapters include database access components, messaging components that produce and consume messages, and web components that either expose APIs or implement a UI. 描述了这个网站的核心业务要包含哪些元素(服务、实体、事件),提供哪些功能(REST API、界面、数据库访问、访问第三方服务等等)

Despite having a logically modular architecture, the application is packaged and deployed as a monolith. 尽管有逻辑的模块,但这个应用确实按照一个整体打包部署。The actual format depends on the application’s language and framework. For example, many Java applications are packaged as WAR files and deployed on application servers such as Tomcat or Jetty. Other Java applications are packaged as self-contained executable JARs. Similarly, Rails and Node.js applications are packaged as a directory hierarchy.

Applications written in this style are extremely common. They are simple to develop since our IDEs and other tools are focused on building a single application. These kinds of applications are also simple to test. You can implement end-to-end testing by simply launching the application and testing the UI with Selenium. Monolithic applications are also simple to deploy. You just have to copy the packaged application to a server. You can also scale the application by running multiple copies behind a load balancer. In the early stages of the project it works well. 在项目早期阶段,这样的应用开发简单、测试简单、部署简单、伸缩简单。

Marching Towards Monolithic Hell 单体应用的地狱

Unfortunately, this simple approach has a huge limitation. Successful applications have a habit of growing over time and eventually becoming huge. 成功的应用总会不断地成长,最终变得巨大。During each sprint, your development team implements a few more stories, which, of course, means adding many lines of code. After a few years, your small, simple application will have grown into a monstrous monolith. To give an extreme example, I recently spoke to a developer who was writing a tool to analyze the dependencies between the thousands of JARs in their multi-million line of code (LOC) application. I’m sure it took the concerted effort of a large number of developers over many years to create such a beast.

Once your application has become a large, complex monolith, your development organization is probably in a world of pain. 一旦你的应用变成巨大复杂的单体应用,你的开发团队将饱尝痛苦。Any attempts at agile development and delivery will flounder. 任何在敏捷开发部署上的尝试都变得举步维艰。One major problem is that the application is overwhelmingly complex. 一个主要原因是你的应用过度复杂。It’s simply too large for any single developer to fully understand. As a result, fixing bugs and implementing new features correctly becomes difficult and time consuming. 你的应用将过于庞大,任何一个程序员都难以完全理解。这导致修改 bug 和正确地开发新功能都变得困难和耗时。 What’s more, this tends to be a downwards spiral. If the codebase is difficult to understand, then changes won’t be made correctly. You will end up with a monstrous, incomprehensible big ball of mud.

The sheer size of the application will also slow down development. The larger the application, the longer the start-up time is. For example, in a recent survey some developers reported start-up times as long as 12 minutes. I’ve also heard anecdotes of applications taking as long as 40 minutes to start up. If developers regularly have to restart the application server, then a large part of their day will be spent waiting around and their productivity will suffer. 编译启动的时间也会变长

Another problem with a large, complex monolithic application is that it is an obstacle to continuous deployment. Today, the state of the art for SaaS applications is to push changes into production many times a day. This is extremely difficult to do with a complex monolith since you must redeploy the entire application in order to update any one part of it. The lengthy start-up times that I mentioned earlier won’t help either. Also, since the impact of a change is usually not very well understood, it is likely that you have to do extensive manual testing. Consequently, continuous deployment is next to impossible to do. 持续部署将变得困难

Monolithic applications can also be difficult to scale when different modules have conflicting resource requirements. For example, one module might implement CPU-intensive image processing logic and would ideally be deployed in AWS EC2 Compute Optimized instances. Another module might be an in-memory database and best suited forEC2 Memory-optimized instances. However, because these modules are deployed together you have to compromise on the choice of hardware.  伸缩性将变差

Another problem with monolithic applications is reliability. Because all modules are running within the same process, a bug in any module, such as a memory leak, can potentially bring down the entire process. Moreover, since all instances of the application are identical, that bug will impact the availability of the entire application. 可靠性变得很差,不同功能将相互影响。一个模块中的 bug,例如内存溢出等问题将拖垮整个应用。

Last but not least, monolithic applications make it extremely difficult to adopt new frameworks and languages. For example, let’s imagine that you have 2 million lines of code written using the XYZ framework. It would be extremely expensive (in both time and cost) to rewrite the entire application to use the newer ABC framework, even if that framework was considerably better. As a result, there is a huge barrier to adopting new technologies. You are stuck with whatever technology choices you made at the start of the project. 最后,采用新语言和新技术将变得非常困难。

To summarize: you have a successful business-critical application that has grown into a monstrous monolith that very few, if any, developers understand. It is written using obsolete, unproductive technology that makes hiring talented developers difficult. The application is difficult to scale and is unreliable. As a result, agile development and delivery of applications is impossible.

So what can you do about it?

Microservices – Tackling the Complexity 微服务 —— 破解复杂

Many organizations, such as Amazon, eBay, and Netflix, have solved this problem by adopting what is now known as the Microservice architecture pattern. Instead of building a single monstrous, monolithic application, the idea is to split your application into set of smaller, interconnected services. 很多组织采用了微服务

A service typically implements a set of distinct features or functionality, such as order management, customer management, etc. Each microservice is a mini-application that has its own hexagonal architecture consisting of business logic along with various adapters. Some microservices would expose an API that’s consumed by other microservices or by the application’s clients. Other microservices might implement a web UI. At runtime, each instance is often a cloud VM or a Docker container. 每个服务实现一组特定的功能,例如订单管理、客户管理。每个微服务暴露自己的 API 给其它微服务或者客户端使用。运行时,每个实例是一个虚拟机或者 Docker 容器。

For example, a possible decomposition of the system described earlier is shown in the following diagram:

Each functional area of the application is now implemented by its own microservice. Moreover, the web application is split into a set of simpler web applications (such as one for passengers and one for drivers in our taxi-hailing example). This makes it easier to deploy distinct experiences for specific users, devices, or specialized use cases.

Each back-end service exposes a REST API and most services consume APIs provided by other services. For example, Driver Management uses the Notification server to tell an available driver about a potential trip. The UI services invoke the other services in order to render web pages. Services might also use asynchronous, message-based communication. Inter-service communication will be covered in more detail later in this series.每个后端服务暴露 REST API(也可以是其它形式的 API,比如基于 TCP/UDP 的远程调用)。服务也可使用异步的,基于消息的通讯。服务间通讯将在后续章节详细介绍。

Some REST APIs are also exposed to the mobile apps used by the drivers and passengers. The apps don’t, however, have direct access to the back-end services. Instead, communication is mediated by an intermediary known as an API Gateway. The API Gateway is responsible for tasks such as load balancing, caching, access control, API metering, and monitoring, and can be implemented effectively using NGINX. Later articles in the series will cover the API Gateway. 一些 REST API 是提供给移动应用的。但是移动应用并不是直接访问后端服务,而是通过一个可以被认为是 API 网关的中介去实现。这个 API 网关提供了例如负载均衡、访问控制、缓存、API 监控等功能(一个更重要的功能是整合 API 调用请求,使其更适合移动网络环境。在服务间调用中,有时也需要负载均衡等功能)

The Microservice architecture pattern corresponds to the Y-axis scaling of the Scale Cube, which is a 3D model of scalability from the excellent book The Art of Scalability. The other two scaling axes are X-axis scaling, which consists of running multiple identical copies of the application behind a load balancer, and Z-axis scaling (or data partitioning), where an attribute of the request (for example, the primary key of a row or identity of a customer) is used to route the request to a particular server.

Applications typically use the three types of scaling together. Y-axis scaling decomposes the application into microservices as shown above in the first figure in this section. At runtime, X-axis scaling runs multiple instances of each service behind a load balancer for throughput and availability. Some applications might also use Z-axis scaling to partition the services. The following diagram shows how the Trip Management service might be deployed with Docker running on AWS EC2. 系统伸缩性的三个方向,微服务对应于 Y 轴

At runtime, the Trip Management service consists of multiple service instances. Each service instance is a Docker container. In order to be highly available, the containers are running on multiple Cloud VMs. In front of the service instances is a load balancer such as NGINX that distributes requests across the instances. The load balancer might also handle other concerns such as cachingaccess controlAPI metering, and monitoring.

The Microservice architecture pattern significantly impacts the relationship between the application and the database. Rather than sharing a single database schema with other services, each service has its own database schema. On the one hand, this approach is at odds with the idea of an enterprise-wide data model. Also, it often results in duplication of some data. However, having a database schema per service is essential if you want to benefit from microservices, because it ensures loose coupling. The following diagram shows the database architecture for the example application. 微服务架构将显著影响应用和数据库之间的关系。每个服务将有自己的数据库,而不是通向同一个数据库。(注意数据库和数据库服务器的不同)。当然,这会导致一些重复数据,但是每个服务使用独立的数据库是必要的。因为微服务强调解耦。(而共享数据库将使微服务之间建立一种强大紧密的关联关系)

Each of the services has its own database. Moreover, a service can use a type of database that is best suited to its needs, the so-called polyglot persistence architecture. For example, Driver Management, which finds drivers close to a potential passenger, must use a database that supports efficient geo-queries. 每个服务使用不同的数据库,可以使服务选择适合其的数据库产品

On the surface, the Microservice architecture pattern is similar to SOA. With both approaches, the architecture consists of a set of services. However, one way to think about the Microservice architecture pattern is that it’s SOA without the commercialization and perceived baggage of web service specifications (WS-) and an Enterprise Service Bus (ESB). Microservice-based applications favor simpler, lightweight protocols such as REST, rather than WS-. They also very much avoid using ESBs and instead implement ESB-like functionality in the microservices themselves. The Microservice architecture pattern also rejects other parts of SOA, such as the concept of a canonical schema. 表面上微服务架构模式类似 SOA。不同点在于 SOA 使用了 Web Service 规范组 (WS-*) 和 企业服务总线 (ESB)。微服务偏爱简单轻量的协议,而不是像 SOAP 这样重量级的技术。(随着技术的发展,程序员可以用比过去少得多的代码开发出一样,甚至更好的功能来)

The Benefits of Microservices 微服务的好处

The Microservice architecture pattern has a number of important benefits. First, it tackles the problem of complexity. It decomposes what would otherwise be a monstrous monolithic application into a set of services. While the total amount of functionality is unchanged, the application has been broken up into manageable chunks or services. Each service has a well-defined boundary in the form of an RPC- or message-driven API. The Microservice architecture pattern enforces a level of modularity that in practice is extremely difficult to achieve with a monolithic code base. Consequently, individual services are much faster to develop, and much easier to understand and maintain. 微服务将复杂的单体应用分解为一组小的服务。微服务促进了模块化,这在单体应用中难以实现(并非指单体应用技术上难以实现模块化,而是之单体应用的模块化设计容易堕落为混乱的状态)。每个服务更容易开发、理解和维护。

Second, this architecture enables each service to be developed independently by a team that is focused on that service. The developers are free to choose whatever technologies make sense, provided that the service honors the API contract. Of course, most organizations would want to avoid complete anarchy and limit technology options. However, this freedom means that developers are no longer obligated to use the possibly obsolete technologies that existed at the start of a new project. When writing a new service, they have the option of using current technology. Moreover, since services are relatively small it becomes feasible to rewrite an old service using current technology. 这个架构使得每个服务容易被一个团队专注地开发。开发者可以自由选择适合的技术。小的服务也使得用新的技术重写变得更为可行。

Third, the Microservice architecture pattern enables each microservice to be deployed independently. Developers never need to coordinate the deployment of changes that are local to their service. These kinds of changes can be deployed as soon as they have been tested. The UI team can, for example, perform A|B testing and rapidly iterate on UI changes. The Microservice architecture pattern makes continuous deployment possible. 微服务架构使得每个服务可以被独立地部署。一个服务一旦完成测试就能被部署。例如,UI 团队可以使用 AB 测试,快速地迭代 UI 变化。微服务架构使得持续部署变为可能。

Finally, the Microservice architecture pattern enables each service to be scaled independently. You can deploy just the number of instances of each service that satisfy its capacity and availability constraints. Moreover, you can use the hardware that best matches a service’s resource requirements. For example, you can deploy a CPU-intensive image processing service on EC2 Compute Optimized instances and deploy an in-memory database service on EC2 Memory-optimizedinstances. 微服务使得每个服务可以被单独地伸缩扩展。可以按照每个服务不同的容量和可用性要去部署。每个服务不同的资源要求也能被满足。

The Drawbacks of Microservices 微服务的缺点

As Fred Brooks wrote almost 30 years ago, there are no silver bullets. Like every other technology, the Microservice architecture has drawbacks. One drawback is the name itself. The term microservice places excessive emphasis on service size. In fact, there are some developers who advocate for building extremely fine-grained 10-100 LOC services. While small services are preferable, it’s important to remember that they are a means to an end and not the primary goal. The goal of microservices is to sufficiently decompose the application in order to facilitate agile application development and deployment. 微服务不是银弹。微服务的微只是结果,而非主要的目的

Another major drawback of microservices is the complexity that arises from the fact that a microservices application is a distributed system. Developers need to choose and implement an inter-process communication mechanism based on either messaging or RPC. Moreover, they must also write code to handle partial failure since the destination of a request might be slow or unavailable. While none of this is rocket science, it’s much more complex than in a monolithic application where modules invoke one another via language-level method/procedure calls. 因为微服务本质上是一个分布式系统,这会增加系统技术上的复杂性。开发人员要考虑如何实现跨进程通信。进一步,还要处理处理更复杂的失败场景。虽然这不是高深的技术,但是显然要难于单体应用。

Another challenge with microservices is the partitioned database architecture. Business transactions that update multiple business entities are fairly common. These kinds of transactions are trivial to implement in a monolithic application because there is a single database. In a microservices-based application, however, you need to update multiple databases owned by different services. Using distributed transactions is usually not an option, and not only because of the CAP theorem. They simply are not supported by many of today’s highly scalable NoSQL databases and messaging brokers. You end up having to use an eventual consistency based approach, which is more challenging for developers. 另一个挑战来源于事务性,因为服务使用的数据库彼此分离。ACID 不再像单体应用那样容易实现。这不仅是因为分布式的 CAP 理论,也来源于很多 NoSQL 和消息队列并不支持强一致性。你最终能选择的只是实现最终一致性。

Testing a microservices application is also much more complex. For example, with a modern framework such as Spring Boot it is trivial to write a test class that starts up a monolithic web application and tests its REST API. In contrast, a similar test class for a service would need to launch that service and any services that it depends upon (or at least configure stubs for those services). Once again, this is not rocket science but it’s important to not underestimate the complexity of doing this. 测试也会更为复杂呢。例如,使用像 Spring Boot 这样的现代框架测试开发一个单体的 Web 应用的 REST API 非常简单。但是如果是微服务架构,你将要运行一系列你所依赖的服务进行测试(这里作者没有区分单元测试和集成测试,一个复杂的单体应用的集成测试并不比微服务架构的应用简单多少)

Another major challenge with the Microservice architecture pattern is implementing changes that span multiple services. For example, let’s imagine that you are implementing a story that requires changes to services A, B, and C, where A depends upon B and B depends upon C. In a monolithic application you could simply change the corresponding modules, integrate the changes, and deploy them in one go. In contrast, in a Microservice architecture pattern you need to carefully plan and coordinate the rollout of changes to each of the services. For example, you would need to update service C, followed by service B, and then finally service A. Fortunately, most changes typically impact only one service and multi-service changes that require coordination are relatively rare. 在微服务中,改变功能之后的部署要更加小心

Deploying a microservices-based application is also much more complex. A monolithic application is simply deployed on a set of identical servers behind a traditional load balancer. Each application instance is configured with the locations (host and ports) of infrastructure services such as the database and a message broker. In contrast, a microservice application typically consists of a large number of services. For example, Hailo has 160 different services and Netflix has over 600 according to Adrian Cockcroft. Each service will have multiple runtime instances. That’s many more moving parts that need to be configured, deployed, scaled, and monitored. In addition, you will also need to implement a service discovery mechanism (discussed in a later post) that enables a service to discover the locations (hosts and ports) of any other services it needs to communicate with. Traditional trouble ticket-based and manual approaches to operations cannot scale to this level of complexity. Consequently, successfully deploying a microservices application requires greater control of deployment methods by developers, and a high level of automation. 微服务在部署方面存在它自己的难点。单体服务的部署难点在于慢,微服务的部署难点在于乱。但是微服务部署难点是可以通过例如 Chef 这样的 IT 自动化工具来解决的,在解决之后,微服务就能实现更快的部署频率。这一点是单体应用难以实现的。这一段除了部署本身以外,还提到了要实现微服务架构的应用,还必须实现一套服务发现机制。单体应用虽然不存在这样的技术难度,但需要认识到的是微服务架构的应用往往是比单体应用能实现更大的部署规模。换句话说单体应用不需要服务发现的机制是因为其难以实现比微服务架构更大更复杂的分布式集群。

One approach to automation is to use an off-the-shelf PaaS such as Cloud Foundry. A PaaS provides developers with an easy way to deploy and manage their microservices. It insulates them from concerns such as procuring and configuring IT resources. At the same time, the systems and network professionals who configure the PaaS can ensure compliance with best practices and with company policies. Another way to automate the deployment of microservices is to develop what is essentially your own PaaS. One typical starting point is to use a clustering solution, such as Mesos or Kubernetes in conjunction with a technology such as Docker. Later in this series we will look at how software-based application delivery approaches such as NGINX, which easily handles caching, access control, API metering, and monitoring at the microservice level, can help solve this problem. 其实 CloudFoundry 这样 PaaS 平台不是一个好选择。实现微服务平台的更好选择是 Docker,以及在 Docker 生态圈中的 Apache Mesos 或者 Kubernetes 容器管理平台技术。

Summary

Building complex applications is inherently difficult. A Monolithic architecture only makes sense for simple, lightweight applications. You will end up in a world of pain if you use it for complex applications. The Microservice architecture pattern is the better choice for complex, evolving applications despite the drawbacks and implementation challenges. 单体架构只适合简单轻量的应用。如果用其实现复杂应用往往会使你深陷痛苦。

In later blog posts, I’ll dive into the details of various aspects of the Microservice architecture pattern and discuss topics such as service discovery, service deployment options, and strategies for refactoring a monolithic application into services. 接下来,“我”将深入介绍和讨论例如服务发现、服务部署、单体应用如何重构成微服务应用等话题。

Stay tuned…

时间: 05-26

Introduction to Microservices的相关文章

微服务架构下的服务发现

编者的话]这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三篇描述了微服务架构内部的通讯机制.这篇文章中,我们将会探讨服务发现相关问题. 为什么要使用服务发现? 我们设想一下当正在写代码时,使用了提供REST API或者Thrift API的服务,为了完成一次服务请求,代码需要知道服务实例的网络位置(IP地址和端口).传统应用都运行在物理硬件上,服务实例的网络位置都是相对固定的.例如,代码可以从一个经常变更的配置文件中读取网络位

微服务实践(五):微服务的事件驱动数据管理

[编者的话]本文是使用微服务创建应用系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第三篇描述了微服务架构模块间通讯的不同方面:第四篇研究了服务发现中的问题.本篇中,我们从另外一个角度研究一下微服务架构带来的分布式数据管理问题. 1.1 微服务和分布式数据管理问题 单体式应用一般都会有一个关系型数据库,由此带来的好处是应用可以使用 ACID transactions,可以带来一些重要的操作特性: 原子性 – 任何改变都是原子性的 一致性 – 数据库状态一直是

微服务实战系列--Nginx官网发布(转)

这是Nginx官网写的一个系列,共七篇文章,如下 Introduction to Microservices (this article) Building Microservices: Using an API Gateway Building Microservices: Inter-Process Communication in a Microservices Architecture Service Discovery in a Microservices Architecture E

微服务学习笔记(一)

什么是六边形架构 “六边形架构”是 Cockburn大牛在2005年 提出的.该架构提供了一种将业务逻辑和具体输入输出技术分离的模式. 为什么采用微服务 现在大多数开发一个应用,哪怕是类似Uber或者淘宝的应用.基本上都是已单体模式开发.虽然在应用自身架构上采用了模块化设计,但在本质上他还是一个单体应用. 例如:如下图 这样的单体应用不好吗? 上图,是比较经典优秀的单体六边形架构.在很多公司实际上因为各种原因单体应用架构还没有达到这个水平.所以会有以下几个方面问题 1. 整体扩展性差,当应用越来

Chris Richardson微服务翻译:微服务介绍

作者简介:Chris Richardson,世界著名的软件架构师,经典著作<POJOS IN ACTION>的作者,cloudfoundry.com 的创始人 微服务目前正受到大量的关注,成为文章.博客.会议讨论的热点.与此同时,也有人质疑微服务并非新事物,只是SOA(Service Oriented Architecure)的二度封装.无论是追捧还是质疑,微服务架构拥有巨大的优势,尤其是让敏捷开发和复杂的企业应用支付成为可能. 本系列包含7篇文章,介绍了微服务架构的各个因素,了解微服务模型的

微服务实践(总)-原文

本系列文章为 dockone.io 首发,转载请标明出处,以示尊重!! http://dockone.io/people/hokingyang   希望读者通过本系列文章对微服务优缺点有一个比较好的理解,以及何时使用这种架构.也许微服务架构比较适合你的应用.也许你正在开发一个大型.复杂单体式应用,日常开发和部署经验非常缓慢和痛苦,而微服务看起来是远方一个极乐世界.幸运的是,有可以参考的脱离苦海的策略,本篇文章中,我将描述如何逐步将单体式应用迁移到微服务架构. 本系列七篇文章列表如下: 微服务实战

5G 融合计费系统架构设计与实现(一)

5G 融合计费系统架构设计与实现(一) 随着5G商用临近,5G的各个子系统也在加紧研发调试,本人有兴全程参与5G中的融合计费系统(CCS)的设计.开发.联调工作.接下来将用几篇文章介绍我们在CCS实现过程遇到的挑战与架构设计的考量.相信这些宝贵的经验可以适用于更广的软件系统,免于重复地陷入软件开发的焦油坑. 5G系统由3Gpp定制统一的架构和协议规范,这也是电信行业一直以来通行的作法.不同的是,5G以前的规范3Gpp总是喜欢独树一帜,比如最出名的DCC(Diameter Credit Contr

微服务系列

Introduction to Microservices Building Microservices: Using an API Gateway Building Microservices: Inter-Process Communication in a Microservices Architecture Service Discovery in a Microservices Architecture Event-Driven Data Management for Microser

Securing Spring Cloud Microservices With OAuth2

From Zero to OAuth2 in Spring cloud Today I am presenting hours of research about a (apparently) simple question: “How can I maintain security in my microservices architecture?”. The task is to enable a simple but mighty possibility to secure spring