Microservices a definition of this new architectural term

2014年3月25日

The term “Microservice Architecture” has sprung up over the last few years to describe a particular way of designing software applications as suites of independently deployable services. While there is no precise definition of this architectural style, there are certain common characteristics around organization around business capability, automated deployment, intelligence in the endpoints, and decentralized control of languages and data.

微服务在最近几年频繁出现,它用来表示一种软件设计架构,该架构将应用拆分为一系列可以独立部署的服务。关于该架构没有明确的定义,但是有一些共同特征:围绕业务功能组织、自动化部署、智能端点和哑管道、以及去中心化的管理和数据存储。

“Microservices” - yet another new term on the crowded streets of software architecture. Although our natural inclination is to pass such things by with a contemptuous glance, this bit of terminology describes a style of software systems that we are finding more and more appealing. We've seen many projects use this style in the last few years, and results so far have been positive, so much so that for many of our colleagues this is becoming the default style for building enterprise applications. Sadly, however, there's not much information that outlines what the microservice style is and how to do it.

 “微服务”——软件架构领域中又一个新名词。尽管我们往往会对这类新概念不屑一顾,但这个术语描述的软件系统风格正变得越来越有吸引力。我们注意到最近几年有很多项目使用这种架构,而且其带来的影响都是正面的,我的很多同事开始将其当作默认的企业应用架构。很遗憾关于该架构是什么以及如何应用,没有太多的信息可以参考。

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

 简而言之,微服务架构是将应用作为一系列小的服务开发,每个服务有自己的进程,服务间使用轻量通信机制(主要是HTTP resource API)。这些服务是根据业务功能拆分出来的,可以使用自动化部署机制独立的部署。这些服务的集中管理会尽可能的最小化,而且这些服务可能会采用不同的语言编写,或者采用不同的数据库技术。

To start explaining the microservice style it's useful to compare it to the monolithic style: a monolithic application built as a single unit. Enterprise Applications are often built in three main parts: a client-side user interface (consisting of HTML pages and javascript running in a browser on the user's machine) a database (consisting of many tables inserted into a common, and usually relational, database management system), and a server-side application. The server-side application will handle HTTP requests, execute domain logic, retrieve and update data from the database, and select and populate HTML views to be sent to the browser. This server-side application is a monolith - a single logical executable Any changes to the system involve building and deploying a new version of the server-side application.

 为了理解什么是微服务,我们先看一下单体架构,单体应用作为一个单独的单元构建。企业应用往往分为三部分:客户端用户界面(html页面和js,在用户机器上运行)、数据库、服务端应用。服务端应用会处理HTTP请求、执行业务逻辑、获取或更新数据库、选择并填充html视图并发送给用户浏览器。这种服务端应用是单体应用,一个单独的逻辑执行体,系统任何微小的改变都需要重新构建并部署整个应用。

Such a monolithic server is a natural way to approach building such a system. All your logic for handling a request runs in a single process, allowing you to use the basic features of your language to divide up the application into classes, functions, and namespaces. With some care, you can run and test the application on a developer's laptop, and use a deployment pipeline to ensure that changes are properly tested and deployed into production. You can horizontally scale the monolith by running many instances behind a load-balancer.

 要构建企业应用系统,单体架构是自然的选择。所有的逻辑在一个进程中,可以根据语言的特性将应用划分为不同的类、方法、以及命名空间。开发者可以在自己的电脑上运行并测试,可以使用部署流水线保证代码的修改会经过测试然后部署到生产环境。你可以通过运行很多单体应用的实例,并通过负载均衡来调用他们。

Monolithic applications can be successful, but increasingly people are feeling frustrations with them - especially as more applications are being deployed to the cloud . Change cycles are tied together - a change made to a small part of the application, requires the entire monolith to be rebuilt and deployed. Over time it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module. Scaling requires scaling of the entire application rather than parts of it that require greater resource.

 单体应用很成功,但是有一些缺点。如:应用的极小的改动就需要整个应用的重构和部署。随着时间发展,很难保持模块化的结构,很难保证模块内的更改只会影响该模块。应用扩展也需要扩展整个应用而不是只扩展急需资源的那部分。

Figure 1: Monoliths and Microservices

These frustrations have led to the microservice architectural style: building applications as suites of services. As well as the fact that services are independently deployable and scalable, each service also provides a firm module boundary, even allowing for different services to be written in different programming languages. They can also be managed by different teams .

 为了解决这些缺点、微服务出现了,它将应用作为一系列服务来构建。每个服务可以独立的部署和扩展,都有自己明确的边界,可以用不同的语言编写,由不同的团队管理。

We do not claim that the microservice style is novel or innovative, its roots go back at least to the design principles of Unix. But we do think that not enough people consider a microservice architecture and that many software developments would be better off if they used it.

 microservice的概念并不新颖,它可以追溯到unix的设计原则。使用microservice,很多软件可能会开发的更好。

Characteristics of a Microservice Architecture

We cannot say there is a formal definition of the microservices architectural style, but we can attempt to describe what we see as common characteristics for architectures that fit the label. As with any definition that outlines common characteristics, not all microservice architectures have all the characteristics, but we do expect that most microservice architectures exhibit most characteristics. While we authors have been active members of this rather loose community, our intention is to attempt a description of what we see in our own work and in similar efforts by teams we know of. In particular we are not laying down some definition to conform to.

 microservices没有正式的定义,我们只是尝试描述这类应用的一些共同特征。不是所有的microservices都符合这些特征,但是我们认为大多数microservices架构符合这里的大部分特征。虽然我们作者一直是这个相当松散的社区的活跃成员,但我们的意图是尝试描述我们在自己的工作中看到的内容,以及我们知道的团队在类似工作中看到的内容。特别是,我们没有制定一些要遵守的定义。

Componentization via Services

通过服务实现组件化

For as long as we've been involved in the software industry, there's been a desire to build systems by plugging together components, much in the way we see things are made in the physical world. During the last couple of decades we've seen considerable progress with large compendiums of common libraries that are part of most language platforms.

像现实世界一样通过堆叠组件构建系统是一直以来的目标,过去几十年间各个语言的通用库有了很大的发展。

When talking about components we run into the difficult definition of what makes a component. Our definition is that a component is a unit of software that is independently replaceable and upgradeable.

很难定义什么是组件,我们认为组件是可以独立替换和更新,而不对系统其他地方产生影响。

Microservice architectures will use libraries, but their primary way of componentizing their own software is by breaking down into services. We define libraries as components that are linked into a program and called using in-memory function calls, while services are out-of-process components who communicate with a mechanism such as a web service request, or remote procedure call. (This is a different concept to that of a service object in many OO programs 3.)

微服务主要通过把应用拆分成服务来实现组件化,库是链接到程序中并通过内存中的方法调用的组件,而服务是进程外的组件,他通过通信协议交互。

One main reason for using services as components (rather than libraries) is that services are independently deployable. If you have an application that consists of a multiple libraries in a single process, a change to any single component results in having to redeploy the entire application. But if that application is decomposed into multiple services, you can expect many single service changes to only require that service to be redeployed. That's not an absolute, some changes will change service interfaces resulting in some coordination, but the aim of a good microservice architecture is to minimize these through cohesive service boundaries and evolution mechanisms in the service contracts.

服务做组件的一个原因是可以独立部署,如果你有一个包含多个库的进程,任何一个组件的更改都会导致整个程序的重新部署。相反,如果程序被拆分为多个服务,一个服务的更改一般只需要重新部署该服务,但是有些更改也会影响到其他组件,好的微服务架构会通过明确服务边界和服务契约演化机制来最小化这种影响。

Another consequence of using services as components is a more explicit component interface. Most languages do not have a good mechanism for defining an explicit Published Interface. Often it's only documentation and discipline that prevents clients breaking a component's encapsulation, leading to overly-tight coupling between components. Services make it easier to avoid this by using explicit remote call mechanisms.

服务做组件的另一个好处是有明确的组件接口。很多语言没有好的机制来定义显示的发布接口。开发中通常是通过文档和开发规范来防止客户端破坏组件的封装性,导致组件间的紧密耦合。但是服务会通过明确的远程调用机制来避免这种情况。

Using services like this does have downsides. Remote calls are more expensive than in-process calls, and thus remote APIs need to be coarser-grained, which is often more awkward to use. If you need to change the allocation of responsibilities between components, such movements of behavior are harder to do when you're crossing process boundaries.

服务也有缺点,远程调用比进程内调用更低效,于是远程调用相对粒度比较粗,很难使用。另外,如果你想要讲一个功能转移到另一个服务中会很麻烦。

At a first approximation, we can observe that services map to runtime processes, but that is only a first approximation. A service may consist of multiple processes that will always be developed and deployed together, such as an application process and a database that's only used by that service.

我们的第一印象是服务是一个单独的进程,其实服务可以包含很多进程,这些进程会一起开发和部署,比如一个服务包含一个应用进程和一个服务独有的数据库。

Organized around Business Capabilities

围绕业务能力组织

When looking to split a large application into parts, often management focuses on the technology layer, leading to UI teams, server-side logic teams, and database teams. When teams are separated along these lines, even simple changes can lead to a cross-team project taking time and budgetary approval. A smart team will optimise around this and plump for the lesser of two evils - just force the logic into whichever application they have access to. Logic everywhere in other words. This is an example of Conway's Law in action.

之前我们往往按照技术划分应用,UI团队、服务端团队、数据库团队。这样任何一个改动都需要所有团队合作处理,非常低效。各个团队通常把逻辑写在自己的那一层,这样业务逻辑会分布js、服务端,各个地方都有。

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.

-- Melvin Conway, 1968

Figure 2: Conway's Law in action

The microservice approach to division is different, splitting up into services organized around business capability. Such services take a broad-stack implementation of software for that business area, including user-interface, persistant storage, and any external collaborations. Consequently the teams are cross-functional, including the full range of skills required for the development: user-experience, database, and project management.

相反,微服务通过业务能力划分应用。每个服务都需要完整的实现自己对应的业务能力。包括页面、存储、外部协作。于是服务所对应的团队也要拥有开发业务能力所需的全部技能,包括用户体验、数据库、项目管理。

Figure 3: Service boundaries reinforced by team boundaries

How big is a microservice?

Although “microservice” has become a popular name for this architectural style, its name does lead to an unfortunate focus on the size of service, and arguments about what constitutes “micro”. In our conversations with microservice practitioners, we see a range of sizes of services. The largest sizes reported follow Amazon's notion of the Two Pizza Team (i.e. the whole team can be fed by two pizzas), meaning no more than a dozen people. On the smaller size scale we've seen setups where a team of half-a-dozen would support half-a-dozen services.

This leads to the question of whether there are sufficiently large differences within this size range that the service-per-dozen-people and service-per-person sizes shouldn't be lumped under one microservices label. At the moment we think it's better to group them together, but it's certainly possible that we'll change our mind as we explore this style further.

One company organised in this way is www.comparethemarket.com. Cross functional teams are responsible for building and operating each product and each product is split out into a number of individual services communicating via a message bus.

ctk公司就是按这种方式组织的。拥有多技能的团队负责开发和维护产品,产品被分成独立的服务,服务间通过消息总线通信。

Large monolithic applications can always be modularized around business capabilities too, although that's not the common case. Certainly we would urge a large team building a monolithic application to divide itself along business lines. The main issue we have seen here, is that they tend to be organised around too many contexts. If the monolith spans many of these modular boundaries it can be difficult for individual members of a team to fit them into their short-term memory. Additionally we see that the modular lines require a great deal of discipline to enforce. The necessarily more explicit separation required by service components makes it easier to keep the team boundaries clear.

大型的单体应用也可以按照业务能力模块化,虽然不常见。通常我们建议开发单体应用的大型团队按照业务线拆分自己。我们发现一个很大的问题是他们往往要处理太多的上下文,开发人员很难记住大量的模块边界。另外,我们还发现每个模块有大量的开发规范要遵守。相反,服务作为组件有明确的划分,这使得团队边界更加清晰。

Products not Projects

产品而不是项目

Most application development efforts that we see use a project model: where the aim is to deliver some piece of software which is then considered to be completed. On completion the software is handed over to a maintenance organization and the project team that built it is disbanded.

很多应用通过项目进行开发,项目的目标是交付一些软件,然后就认为项目完成了。随后软件由运维团队接管,开发团队就地解散。

Microservice proponents tend to avoid this model, preferring instead the notion that a team should own a product over its full lifetime. A common inspiration for this is Amazon's notion of “you build, you run it” where a development team takes full responsibility for the software in production. This brings developers into day-to-day contact with how their software behaves in production and increases contact with their users, as they have to take on at least some of the support burden.

微服务更倾向于开发团队持续的负责产品的相关部分。这样开发团队会日复一日的接触他们开发的产品和产品的用户并提供支持。

The product mentality, ties in with the linkage to business capabilities. Rather than looking at the software as a set of functionality to be completed, there is an on-going relationship where the question is how can software assist its users to enhance the business capability.

产品的思维方式与业务能力绑定在一起。不是将软件视为一系列功能来完成,而是持续保持关系,同时考虑软件如何帮助用户加强业务能力。

There's no reason why this same approach can't be taken with monolithic applications, but the smaller granularity of services can make it easier to create the personal relationships between service developers and their users.

单体应用应该也可以采用这种方式,但是服务的粒度相对更细,更容易让开发者与用户建立联系。

Smart endpoints and dumb pipes

智能端点和哑管道

When building communication structures between different processes, we've seen many products and approaches that stress putting significant smarts into the communication mechanism itself. A good example of this is the Enterprise Service Bus (ESB), where ESB products often include sophisticated facilities for message routing, choreography, transformation, and applying business rules.

在不同进程之间构建通信结构时,我们发现有很多产品和方式将精力放到通信机制上面。如esb,包含消息路由、协同编排、转换以及应用业务规则等复杂的功能。

Microservices and SOA

When we've talked about microservices a common question is whether this is just Service Oriented Architecture (SOA) that we saw a decade ago. There is merit to this point, because the microservice style is very similar to what some advocates of SOA have been in favor of. The problem, however, is that SOA means too many different things, and that most of the time that we come across something called “SOA” it's significantly different to the style we're describing here, usually due to a focus on ESBs used to integrate monolithic applications.

In particular we have seen so many botched implementations of service orientation - from the tendency to hide complexity away in ESB's 5, to failed multi-year initiatives that cost millions and deliver no value, to centralised governance models that actively inhibit change, that it is sometimes difficult to see past these problems.

Certainly, many of the techniques in use in the microservice community have grown from the experiences of developers integrating services in large organisations. The Tolerant Reader pattern is an example of this. Efforts to use the web have contributed, using simple protocols is another approach derived from these experiences - a reaction away from central standards that have reached a complexity that is, frankly, breathtaking. (Any time you need an ontology to manage your ontologies you know you are in deep trouble.)

This common manifestation of SOA has led some microservice advocates to reject the SOA label entirely, although others consider microservices to be one form of SOA 6, perhaps service orientation done right. Either way, the fact that SOA means such different things means it's valuable to have a term that more crisply defines this architectural style.

The microservice community favours an alternative approach: smart endpoints and dumb pipes. Applications built from microservices aim to be as decoupled and as cohesive as possible - they own their own domain logic and act more as filters in the classical Unix sense - receiving a request, applying logic as appropriate and producing a response. These are choreographed using simple RESTish protocols rather than complex protocols such as WS-Choreography or BPEL or orchestration by a central tool.

然而,微服务社区喜欢另一种方法,智能的终端和哑管道。通过微服务构建的应用应该尽可能的解耦合。服务有自己的业务逻辑,就像unix的filter一样,接收请求、执行相关逻辑、返回结果。他们通过简单的rest协议协同编排起来。

The two protocols used most commonly are HTTP request-response with resource API's and lightweight messaging The best expression of the first is

Be of the web, not behind the web

-- Ian Robinson

Microservice teams use the principles and protocols that the world wide web (and to a large extent, Unix) is built on. Often used resources can be cached with very little effort on the part of developers or operations folk.

微服务中最常用的两种协议是http请求-响应资源接口和轻量级消息传递。关于第一种的最好的描述是 融入web而不是藏在web后。即要尽可能的使用http的能力,如cache等,而不是隐藏其细节。

The second approach in common use is messaging over a lightweight message bus. The infrastructure chosen is typically dumb (dumb as in acts as a message router only) - simple implementations such as RabbitMQ or ZeroMQ don't do much more than provide a reliable asynchronous fabric - the smarts still live in the end points that are producing and consuming messages; in the services.

通过轻量级消息总线进行消息传递,消息传递中间件往往选择哑的,即只提供简单的消息路由功能。如rabbitmq,只是提供可靠的异步消息传递功能。终端,即服务,即消费者和生产者用来处理复杂的事情。

In a monolith, the components are executing in-process and communication between them is via either method invocation or function call. The biggest issue in changing a monolith into microservices lies in changing the communication pattern. A naive conversion from in-memory method calls to RPC leads to chatty communications which don't perform well. Instead you need to replace the fine-grained communication with a coarser -grained approach.

单体应用中组件在同一进程中,通过方法调用进行交互。将单体应用改为微服务最大的挑战是修改组件通信的模式。一个简单的想法是直接将方法调用改成远程调用,但是这样会产生太多的远程调用,拉低性能,因此,必须将细粒度的方法调用替换成更粗粒度的远程调用。

Decentralized Governance

去中心化治理

One of the consequences of centralised governance is the tendency to standardise on single technology platforms. Experience shows that this approach is constricting - not every problem is a nail and not every solution a hammer. We prefer using the right tool for the job and while monolithic applications can take advantage of different languages to a certain extent, it isn't that common.

集中治理会趋向于产生单一技术平台的标准化。经验表明这种方式有一定局限性。标准并不能解决所有问题。我们更喜欢使用合适的工具来处理相应的问题,单体应用通常不具备这种能力。

Splitting the monolith's components out into services we have a choice when building each of them. You want to use Node.js to standup a simple reports page? Go for it. C++ for a particularly gnarly near-real-time component? Fine. You want to swap in a different flavour of database that better suits the read behaviour of one component? We have the technology to rebuild him.

当构建服务时,我们至少可以选择使用那种技术开发。如使用nodejs开发报告页面,使用c++开发实时组件,选择合适的数据库。

Of course, just because you can do something, doesn't mean you should - but partitioning your system in this way means you have the option.

Teams building microservices prefer a different approach to standards too. Rather than use a set of defined standards written down somewhere on paper they prefer the idea of producing useful tools that other developers can use to solve similar problems to the ones they are facing. These tools are usually harvested from implementations and shared with a wider group, sometimes, but not exclusively using an internal open source model. Now that git and github have become the de facto version control system of choice, open source practices are becoming more and more common in-house .

微服务不喜欢标准化,更喜欢开发一套工具,其他人遇到相似问题时可以使用。这些工具通常从实现中取得,并进行广泛的分享,有时会使用内部的开源模型。通过git和github,内部开源更容易实现。

Netflix is a good example of an organisation that follows this philosophy. Sharing useful and, above all, battle-tested code as libraries encourages other developers to solve similar problems in similar ways yet leaves the door open to picking a different approach if required. Shared libraries tend to be focused on common problems of data storage, inter-process communication and as we discuss further below, infrastructure automation.

网飞很好的应用了这一原则。将有用的且经过充分测试的代码封装成库来共享,鼓励开发者采用相识的方法处理相似的问题。共享库专注于数据存储,进程通信和自动部署等方面的问题。

Many languages, many options

The growth of JVM as a platform is just the latest example of mixing languages within a common platform. It's been common practice to shell-out to a higher level language to take advantage of higher level abstractions for decades. As is dropping down to the metal and writing performance sensitive code in a lower level one. However, many monoliths don't need this level of performance optimisation nor are DSL's and higher level abstractions that common (to our dismay). Instead monoliths are usually single language and the tendency is to limit the number of technologies in use 8.

For the microservice community, overheads are particularly unattractive. That isn't to say that the community doesn't value service contracts. Quite the opposite, since there tend to be many more of them. It's just that they are looking at different ways of managing those contracts. Patterns like Tolerant Reader and Consumer-Driven Contracts are often applied to microservices. These aid service contracts in evolving independently. Executing consumer driven contracts as part of your build increases confidence and provides fast feedback on whether your services are functioning. Indeed we know of a team in Australia who drive the build of new services with consumer driven contracts. They use simple tools that allow them to define the contract for a service. This becomes part of the automated build before code for the new service is even written. The service is then built out only to the point where it satisfies the contract - an elegant approach to avoid the 'YAGNI' dilemma when building new software. These techniques and the tooling growing up around them, limit the need for central contract management by decreasing the temporal coupling between services.

在微服务社区中,管理开销非常不受欢迎。不是不采用服务契约。而是有太多的服务契约需要管理。需要采用另一种方式进行管理。Tolerant Reader 和 Consumer-Driven Contracts 是常用的方法。这些方法有利于服务契约独立的演化。使用cdc可以提供信心和快速反馈。我们知道澳洲有个团队采用cdc,他们使用简单的工具定义契约。在服务编写前就可以编写客户端。服务根据契约编写,避免了 你不需要他 这种困境。这些技术和工具的使用避免了契约的集中化管理,降低了服务间的时间耦合。

Perhaps the apogee of decentralised governance is the build it / run it ethos popularised by Amazon. Teams are responsible for all aspects of the software they build including operating the software 24/7. Devolution of this level of responsibility is definitely not the norm but we do see more and more companies pushing responsibility to the development teams. Netflix is another organisation that has adopted this ethos. Being woken up at 3am every night by your pager is certainly a powerful incentive to focus on quality when writing your code. These ideas are about as far away from the traditional centralized governance model as it is possible to be.

或许去中心化的极致是亚马逊提出的构建它/运行它 。团队负责他们所构建的软件的所有方面,包括7x24小时的运维。责任下放到这种程度肯定不正常,但是越来越多的公司开始把更多的责任分配给开发团队。网飞采用了这种方式。每天凌晨3点被叫醒绝对是开发高质量代码

Decentralized Data Management

去中心化数据管理

Decentralization of data management presents in a number of different ways. At the most abstract level, it means that the conceptual model of the world will differ between systems. This is a common issue when integrating across a large enterprise, the sales view of a customer will differ from the support view. Some things that are called customers in the sales view may not appear at all in the support view. Those that do may have different attributes and (worse) common attributes with subtly different semantics.

数据管理去中心化有很多实现方式。在最抽象的层面, 映射现实世界的概念模型在不同系统中有很大差异。举一个例子,大企业集成常见的问题是 客户 这一概念在销售的视角 与售后支持的视角中是不同的。客户在这两种视角中有不同的属性,或者相同名称的属性但是语义不同。

Battle-tested standards and enforced standards

It's a bit of a dichotomy that microservice teams tend to eschew the kind of rigid enforced standards laid down by enterprise architecture groups but will happily use and even evangelise the use of open standards such as HTTP, ATOM and other microformats.

The key difference is how the standards are developed and how they are enforced. Standards managed by groups such as the IETF only become standards when there are several live implementations of them in the wider world and which often grow from successful open-source projects.

These standards are a world apart from many in a corporate world, which are often developed by groups that have little recent programming experience or overly influenced by vendors.

This issue is common between applications, but can also occur within applications, particular when that application is divided into separate components. A useful way of thinking about this is the Domain-Driven Design notion of Bounded Context. DDD divides a complex domain up into multiple bounded contexts and maps out the relationships between them. This process is useful for both monolithic and microservice architectures, but there is a natural correlation between service and context boundaries that helps clarify, and as we describe in the section on business capabilities, reinforce the separations.

这类问题在多个应用之间中很常见, 也会出现在单一应用中,尤其是当应用拆分为多个模块时。一个有效的解决方案是ddd。ddd将一个复杂的领域拆分成多个有边界的上下文,并且描绘出他们之间的关系。这种方法对单体应用和microservice都有用。但是service与context边界之间有着天然的联系。

As well as decentralizing decisions about conceptual models, microservices also decentralize data storage decisions. While monolithic applications prefer a single logical database for persistant data, enterprises often prefer a single database across a range of applications - many of these decisions driven through vendor's commercial models around licensing. Microservices prefer letting each service manage its own database, either different instances of the same database technology, or entirely different database systems - an approach called Polyglot Persistence. You can use polyglot persistence in a monolith, but it appears more frequently with microservices.

就像概念模型的去中心化一样,microservices也对数据存储技术去中心化。单体应用喜欢一个单独的数据库来存储数据,企业中的多个应用经常使用同一个数据库。microservices更喜欢让services管理各自的数据库,不论是相同数据库技术的不同实例,还是entirely不同的数据库系统,也叫 多语言持久化。

Decentralizing responsibility for data across microservices has implications for managing updates. The common approach to dealing with updates has been to use transactions to guarantee consistency when updating multiple resources. This approach is often used within monoliths.

 数据管理的去中心化会影响数据的更新操作。常见的的处理更新的方式是当一次更新多个资源时使用事务来保证一致性。单体应用中经常使用transactions

Using transactions like this helps with consistency, but imposes significant temporal coupling, which is problematic across multiple services. Distributed transactions are notoriously difficult to implement and as a consequence microservice architectures emphasize transactionless coordination between services, with explicit recognition that consistency may only be eventual consistency and problems are dealt with by compensating operations.

 使用transactions对一致性很有帮助,但是会带来显著的时间耦合,在跨多个services时尤其严重。分布式transactions出了名的难以实现,于是microservice强调services间transactionless的协作,只要求到达最终一致性,problems由补偿性操作处理。

Choosing to manage inconsistencies in this way is a new challenge for many development teams, but it is one that often matches business practice. Often businesses handle a degree of inconsistency in order to respond quickly to demand, while having some kind of reversal process to deal with mistakes. The trade-off is worth it as long as the cost of fixing mistakes is less than the cost of lost business under greater consistency.

 这样管理不一致problem对很多研发团队都是一个挑战,但是这常常符合business实践。businesses经常处理一定程度的不一致性来快速的响应需求,有一些回滚程序来处理mistakes。让步是值得的,只要修复mistakes的开销小于由于保证强一致而损失business的开销。

Infrastructure Automation

自动化工具

Infrastructure automation techniques have evolved enormously over the last few years - the evolution of the cloud and AWS in particular has reduced the operational complexity of building, deploying and operating microservices.

 自动化技术最近几年有了巨大的发展。云技术和AWS的发展降低了构建、部署和operating的复杂性。

Many of the products or systems being build with microservices are being built by teams with extensive experience of Continuous Delivery and it's precursor, Continuous Integration. Teams building software this way make extensive use of infrastructure automation techniques. This is illustrated in the build pipeline shown below.

构建 microservices系统的很多团队都有持续交付和持续集成的背景。这使得自动化工具得到广泛运用。下图展示构建流水线。

Figure 5: basic build pipeline

Since this isn't an article on Continuous Delivery we will call attention to just a couple of key features here. We want as much confidence as possible that our software is working, so we run lots of automated tests. Promotion of working software 'up' the pipeline means we automate deployment to each new environment.

 这里只介绍一些持续交付的关键特性。We want 对软件正常工作这一目标有足够的信心,于是we运行大量的自动化测试。推动软件在流水线上前进,means将软件自动化部署到新的环境中。

Make it easy to do the right thing

One side effect we have found of increased automation as a consequence of continuous delivery and deployment is the creation of useful tools to help developers and operations folk. Tooling for creating artefacts, managing codebases, standing up simple services or for adding standard monitoring and logging are pretty common now. The best example on the web is probably Netflix's set of open source tools, but there are others including Dropwizard which we have used extensively.

A monolithic application will be built, tested and pushed through these environments quite happlily. It turns out that once you have invested in automating the path to production for a monolith, then deploying more applications doesn't seem so scary any more. Remember, one of the aims of CD is to make deployment boring, so whether its one or three applications, as long as its still boring it doesn't matter.

 单体应用可以很轻松的在这些环境中构建、测试、部署。一旦你投入一段时间来实现自动化部署,后面的部署将会变得很简单。cd的目的之一是使得部署boring。

Another area where we see teams using extensive infrastructure automation is when managing microservices in production. In contrast to our assertion above that as long as deployment is boring there isn't that much difference between monoliths and microservices, the operational landscape for each can be strikingly different.

 在生产环境中管理microservices也经常使用自动化工具。与上面提到的结论不同,microservices和单体应用的operational环境存在显著的差异。

Figure 6: Module deployment often differs

Design for failure

关于错误的设计

A consequence of using services as components, is that applications need to be designed so that they can tolerate the failure of services. Any service call could fail due to unavailability of the supplier, the client has to respond to this as gracefully as possible. This is a disadvantage compared to a monolithic design as it introduces additional complexity to handle it. The consequence is that microservice teams constantly reflect on how service failures affect the user experience. Netflix's Simian Army induces failures of services and even datacenters during the working day to test both the application's resilience and monitoring.

 services做组件的一个结果是必须将应用设计的能够容忍services的的失败。任何services调用可能由于提供者的不可用而失败,客户端必须要优雅的响应这种情况。这与单体应用比是一个很大的缺点。because这引入了additional复杂性(for处理这种情况)。于是microservice团队不断的反思服务故障是如何影响用户体验的。Netflix's Simian Army 在工作日主动引发故障来测试系统的弹性和监控情况。

The circuit breaker and production ready code

Circuit Breaker appears in Release It! alongside other patterns such as Bulkhead and Timeout. Implemented together, these patterns are crucially important when building communicating applications. This Netflix blog entry does a great job of explaining their application of them.

This kind of automated testing in production would be enough to give most operation groups the kind of shivers usually preceding a week off work. This isn't to say that monolithic architectural styles aren't capable of sophisticated monitoring setups - it's just less common in our experience.

这种程度的生产环境测试足以使 operation团队战栗。

Since services can fail at any time, it's important to be able to detect the failures quickly and, if possible, automatically restore service. Microservice applications put a lot of emphasis on real-time monitoring of the application, checking both architectural elements (how many requests per second is the database getting) and business relevant metrics (such as how many orders per minute are received). Semantic monitoring can provide an early warning system of something going wrong that triggers development teams to follow up and investigate.

 由于services可能在任何时间故障,所以尽快发现故障很重要,必要时可以自动重启services。Microservice应用强调实时监控,同时检查架构相关指标(数据库每秒收到多少请求)和business相关指标(每分钟收到多少订单)。语义监控可以提供一个提前预警系统,在事情发送异常之前提醒开发团队跟进调查。

This is particularly important to a microservices architecture because the microservice preference towards choreography and event collaboration leads to emergent behavior. While many pundits praise the value of serendipitous emergence, the truth is that emergent behavior can sometimes be a bad thing. Monitoring is vital to spot bad emergent behavior quickly so it can be fixed.

 这种语言监控在microservices架构中很重要,because microservices通常使用协同编排(非中心化编排)和事件协同,从而导致behavior的不可预见性。这种方式虽然有一定的好处(如负载均衡、减少时间耦合),但它确实会导致一些problem。监控是处理这种problem的关键。

Synchronous calls considered harmful

Any time you have a number of synchronous calls between services you will encounter the multiplicative effect of downtime. Simply, this is when the downtime of your system becomes the product of the downtimes of the individual components. You face a choice, making your calls asynchronous or managing the downtime. At www.guardian.co.uk they have implemented a simple rule on the new platform - one synchronous call per user request while at Netflix, their platform API redesign has built asynchronicity into the API fabric.

Monoliths can be built to be as transparent as a microservice - in fact, they should be. The difference is that you absolutely need to know when services running in different processes are disconnected. With libraries within the same process this kind of transparency is less likely to be useful.

单体应用也可以很透明(监控各个方面) 。与microservice的不同之处是你当运行在不同进程中的service断开连接时你必须要及时知道。单体应用不需要这种程度的透明度。

Microservice teams would expect to see sophisticated monitoring and logging setups for each individual service such as dashboards showing up/down status and a variety of operational and business relevant metrics. Details on circuit breaker status, current throughput and latency are other examples we often encounter in the wild.

 Microservice团队需要看到每个service精密的监控和日志,如dashboards展示service存活状态以及各种operational和business相关的指标。详细的断路器状态、当前吞吐量、延迟也需要关注。

Evolutionary Design

进化型设计

Microservice practitioners, usually have come from an evolutionary design background and see service decomposition as a further tool to enable application developers to control changes in their application without slowing down change. Change control doesn't necessarily mean change reduction - with the right attitudes and tools you can make frequent, fast, and well-controlled changes to software.

 Microservice参与者通常会有进化设计的背景,将service划分看作控制但不减缓变化的工具。使用好的方法可以进行频繁、快速,同时能精确控制的变化。

Whenever you try to break a software system into components, you're faced with the decision of how to divide up the pieces - what are the principles on which we decide to slice up our application? The key property of a component is the notion of independent replacement and upgradeability - which implies we look for points where we can imagine rewriting a component without affecting its collaborators. Indeed many microservice groups take this further by explicitly expecting many services to be scrapped rather than evolved in the longer term.

 Whenever你尝试组件化你的应用,你会面对如何划分,有什么划分标准?组件的关键特征是可以独立替换和升级。we可以构想一下重新这个模块会不会影响系统的其他部分。有些团队甚至要求services在将来可以被丢弃而不影响其他部分。

The Guardian website is a good example of an application that was designed and built as a monolith, but has been evolving in a microservice direction. The monolith still is the core of the website, but they prefer to add new features by building microservices that use the monolith's API. This approach is particularly handy for features that are inherently temporary, such as specialized pages to handle a sporting event. Such a part of the website can quickly be put together using rapid development languages, and removed once the event is over. We've seen similar approaches at a financial institution where new services are added for a market opportunity and discarded after a few months or even weeks.

《卫报》 website是个很好的例子,他的主体是一个单体应用,但是正在向microservice演化。当添加新功能的时候采用microservice的形式,新功能会调用单体应用的接口。这对于一些临时的功能很有用,如报道体育事件的特殊页面。这部分website的内容可以通过迅捷的开发语言快速开发出来,然后当事件结束后移除掉这部分内容。金融机构也有类似的approaches,市场机会来临时新增一个相应的service,结束时在移除掉。

This emphasis on replaceability is a special case of a more general principle of modular design, which is to drive modularity through the pattern of change. You want to keep things that change at the same time in the same module. Parts of a system that change rarely should be in different services to those that are currently undergoing lots of churn. If you find yourself repeatedly changing two services together, that's a sign that they should be merged.

 对可替换性的强调是很多模块化设计原则中比较特殊的一种情况,即通过模式的变化来驱动模块的划分。你want将需要同时修改的东西放到一个模块中。系统中很少变化的部分需要与频繁变化的那部分分开放到不同的service中。如果你经常同时修改两个servcie,那么你应该将这两个service合并起来。

Putting components into services adds an opportunity for more granular release planning. With a monolith any changes require a full build and deployment of the entire application. With microservices, however, you only need to redeploy the service(s) you modified. This can simplify and speed up the release process. The downside is that you have to worry about changes to one service breaking its consumers. The traditional integration approach is to try to deal with this problem using versioning, but the preference in the microservice world is to only use versioning as a last resort. We can avoid a lot of versioning by designing services to be as tolerant as possible to changes in their suppliers.

 service做组件可以带来更细粒度的发布计划。单体应用中很小的修改就需要重新部署和构建整个应用。使用microservices,你只需要重新部署修改的service。这可以简化和加速发布进程。缺点是你需要考虑service的修改会不会影响到他的客户端。传统的解决方案是将接口版本化,但microservice中将其当作最后的手段。通过将service设计的能够尽可能的容忍提供者,可以避免大量的版本。

Are Microservices the Future?

Our main aim in writing this article is to explain the major ideas and principles of microservices. By taking the time to do this we clearly think that the microservices architectural style is an important idea - one worth serious consideration for enterprise applications. We have recently built several systems using the style and know of others who have used and favor this approach.

本文的主要目的是解释微服务的主要思想和一些原则。

Microservice Trade-Offs

Many development teams have found the microservices architectural style to be a superior approach to a monolithic architecture. But other teams have found them to be a productivity-sapping burden. Like any architectural style, microservices bring costs and benefits. To make a sensible choice you have to understand these and apply them to your specific context.

Those we know about who are in some way pioneering the architectural style include Amazon, Netflix, The Guardian, the UK Government Digital Servicerealestate.com.au, Forward and comparethemarket.com. The conference circuit in 2013 was full of examples of companies that are moving to something that would class as microservices - including Travis CI. In addition there are plenty of organizations that have long been doing what we would class as microservices, but without ever using the name. (Often this is labelled as SOA - although, as we've said, SOA comes in many contradictory forms. 14)

Despite these positive experiences, however, we aren't arguing that we are certain that microservices are the future direction for software architectures. While our experiences so far are positive compared to monolithic applications, we're conscious of the fact that not enough time has passed for us to make a full judgement.

Often the true consequences of your architectural decisions are only evident several years after you made them. We have seen projects where a good team, with a strong desire for modularity, has built a monolithic architecture that has decayed over the years. Many people believe that such decay is less likely with microservices, since the service boundaries are explicit and hard to patch around. Yet until we see enough systems with enough age, we can't truly assess how microservice architectures mature.

There are certainly reasons why one might expect microservices to mature poorly. In any effort at componentization, success depends on how well the software fits into components. It's hard to figure out exactly where the component boundaries should lie. Evolutionary design recognizes the difficulties of getting boundaries right and thus the importance of it being easy to refactor them. But when your components are services with remote communications, then refactoring is much harder than with in-process libraries. Moving code is difficult across service boundaries, any interface changes need to be coordinated between participants, layers of backwards compatibility need to be added, and testing is made more complicated.

Our colleague Sam Newman spent most of 2014 working on a book that captures our experiences with building microservices. This should be your next step if you want a deeper dive into the topic.

Another issue is If the components do not compose cleanly, then all you are doing is shifting complexity from inside a component to the connections between components. Not just does this just move complexity around, it moves it to a place that's less explicit and harder to control. It's easy to think things are better when you are looking at the inside of a small, simple component, while missing messy connections between services.

Finally, there is the factor of team skill. New techniques tend to be adopted by more skillful teams. But a technique that is more effective for a more skillful team isn't necessarily going to work for less skillful teams. We've seen plenty of cases of less skillful teams building messy monolithic architectures, but it takes time to see what happens when this kind of mess occurs with microservices. A poor team will always create a poor system - it's very hard to tell if microservices reduce the mess in this case or make it worse.

One reasonable argument we've heard is that you shouldn't start with a microservices architecture. Instead begin with a monolith, keep it modular, and split it into microservices once the monolith becomes a problem. (Although this advice isn't ideal, since a good in-process interface is usually not a good service interface.)

So we write this with cautious optimism. So far, we've seen enough about the microservice style to feel that it can be a worthwhile road to tread. We can't say for sure where we'll end up, but one of the challenges of software development is that you can only make decisions based on the imperfect information that you currently have to hand.


Footnotes

1: The term “microservice” was discussed at a workshop of software architects near Venice in May, 2011 to describe what the participants saw as a common architectural style that many of them had been recently exploring. In May 2012, the same group decided on “microservices” as the most appropriate name. James presented some of these ideas as a case study in March 2012 at 33rd Degree in Krakow in Microservices - Java, the Unix Way as did Fred George about the same time. Adrian Cockcroft at Netflix, describing this approach as “fine grained SOA” was pioneering the style at web scale as were many of the others mentioned in this article - Joe Walnes, Daniel Terhorst-North, Evan Botcher and Graham Tackley.

2: The term monolith has been in use by the Unix community for some time. It appears in The Art of Unix Programming to describe systems that get too big.

3: Many object-oriented designers, including ourselves, use the term service object in the Domain-Driven Design sense for an object that carries out a significant process that isn't tied to an entity. This is a different concept to how we're using “service” in this article. Sadly the term service has both meanings and we have to live with the polyseme.

4: We consider an application to be a social construction that binds together a code base, group of functionality, and body of funding.

5: We can't resist mentioning Jim Webber's statement that ESB stands for “Erroneous Spaghetti Box”.

6: Netflix makes the link explicit - until recently referring to their architectural style as fine-grained SOA.

7: At extremes of scale, organisations often move to binary protocols - protobufs for example. Systems using these still exhibit the characteristic of smart endpoints, dumb pipes - and trade off transparency for scale. Most web properties and certainly the vast majority of enterprises don't need to make this tradeoff - transparency can be a big win.

8: It's a little disengenuous of us to claim that monoliths are single language - in order to build systems on todays web, you probably need to know JavaScript and XHTML, CSS, your server side language of choice, SQL and an ORM dialect. Hardly single language, but you know what we mean.

9: “YAGNI” or “You Aren't Going To Need It” is an XP principle and exhortation to not add features until you know you need them.

10: Adrian Cockcroft specifically mentions “developer self-service” and “Developers run what they wrote”(sic) in this excellent presentation delivered at Flowcon in November, 2013.

11: We are being a little disengenuous here. Obviously deploying more services, in more complex topologies is more difficult than deploying a single monolith. Fortunately, patterns reduce this complexity - investment in tooling is still a must though.

12: In fact, Daniel Terhorst-North refers to this style as Replaceable Component Architecture rather than microservices. Since this seems to talk to a subset of the characteristics we prefer the latter.

13: Kent Beck highlights this as one his design principles in Implementation Patterns.

14: And SOA is hardly the root of this history. I remember people saying “we've been doing this for years” when the SOA term appeared at the beginning of the century. One argument was that this style sees its roots as the way COBOL programs communicated via data files in the earliest days of enterprise computing. In another direction, one could argue that microservices are the same thing as the Erlang programming model, but applied to an enterprise application context.

References

While this is not an exhaustive list, there are a number of sources that practitioners have drawn inspiration from or which espouse a similar philosophy to that described in this article.

Blogs and online articles

Books

Presentations

Papers

  • L. Lamport, “The Implementation of Reliable Distributed Multiprocess Systems”, 1978 http:// research.microsoft.com/en-us/um/people/lamport/pubs/implementation.pdf
  • L. Lamport, R. Shostak, M. Pease, “The Byzantine Generals Problem”, 1982 (available at) http:// www.cs.cornell.edu/courses/cs614/2004sp/papers/lsp82.pdf
  • R.T. Fielding, “Architectural Styles and the Design of Network-based Software Architectures”, 2000 http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
  • E. A. Brewer, “Towards Robust Distributed Systems”, 2000 http://www.cs.berkeley.edu/ ~brewer/cs262b-2004/PODC-keynote.pdf
  • E. Brewer, “CAP Twelve Years Later: How the 'Rules' Have Changed”, 2012, http:// www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed

Further Reading

The above list captures the references we used when we originally wrote this article in early 2014. For an up to date list of sources for more information, take a look at the Microservice Resource Guide.

Significant Revisions

"设计和平铺四边形的建筑自由曲面"是指将自由曲面的设计和面板化通过平铺四边形的方法实现。 传统的建筑设计通常是基于直线和平面的几何图形,但自由曲面具有复杂的形状和曲线,不能简单地用直线和平面几何来描述。因此,设计和面板化自由曲面是一项具有挑战性的任务。 在这种方法中,首先需要将自由曲面划分为多个小块,这些小块要具有四边形的形状。然后,通过将这些小块沿着曲面的方向平铺,并进行适当的旋转和缩放,使它们能够拼接成一个平面。 这种方法的优势在于,可以简化自由曲面的制作和安装过程。首先,面板可以在工厂中预制,减少现场加工的需求。其次,平铺四边形的形状使得面板之间的连接更加紧密,可以减少曲面上的缝隙和不匹配。最后,面板化的自由曲面可以更容易地完成细节和装饰的设计,并且可以更容易地进行维护和修复。 然而,这种方法也存在一些挑战和限制。首先,将自由曲面平铺的过程需要耗费较多的时间和精力。其次,面板化可能会限制设计师在自由曲面上实现复杂的形状和曲线。此外,平铺四边形的面板必须在曲面上进行适当的旋转和缩放,以确保其完全覆盖曲面,并与相邻面板相吻合。 总之,设计和面板化自由曲面是一项复杂而具有挑战性的任务,通过平铺四边形的方法可以简化制作和安装过程,但也需要在设计和制作过程中克服一些限制和难题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值