mvc 到微服务
What is the Microservice Architecture?
什么是微服务架构?
We have probably all heard of microservices before, but what does that really mean? Microservice architecture is a type of distributed system. This means we have our components decoupled or detached from each other, instead of having them all in the same place like with the Model-View-Controller (MVC) architecture pattern.
我们以前可能都听说过微服务,但这真的意味着什么? 微服务架构是一种分布式系统。 这意味着我们使组件彼此分离或分离,而不是像Model-View-Controller(MVC)架构模式那样将它们全部放在同一位置。
This allows us to break up our application, similar to how on a low-level we break up our classes and interfaces into different files. The general idea with this, is that most of our services are backend, which means they are simply dealing with business logic. Most of these services will take in data, do some operation, then return data back. These backend services send the data back to other services, including the frontend (FE) or user interface (UI). They talk to one another using various protocols such as HTTP and some kind of data-interchange format, which is just a fancy way of saying a way to easily send and receive data, a popular example of this being JSON.
这使我们可以分解应用程序,类似于在低层将类和接口分解为不同文件的方式。 这样的总体思路是,我们的大多数服务都是后端的,这意味着它们只是在处理业务逻辑。 这些服务大多数将接收数据,执行一些操作,然后将数据返回。 这些后端服务将数据发送回其他服务,包括前端(FE)或用户界面(UI)。 他们使用各种协议(例如HTTP和某种数据交换格式)相互交谈,这只是一种表达方式,可以轻松地发送和接收数据,这是JSON的一个流行示例。
The FE of our application is a service as well. It is the entry point into the rest of our code for the user. The FE, which might be a Javascript framework like Vue or React, will generally have a UI backend ‘attached’. This UI backend will act as a dummy or glue API between what the user interacts with on the website or app, and all the backend services. This means that the backend attached to the website or app has a single job, which is to format outgoing and incoming requests so that the actual UI doesn’t need to manipulate any data.
我们的应用程序的FE也是一项服务。 这是用户其余代码的入口点。 FE,可能是像Vue或React这样的Javascript框架,通常会将UI后端“附加”。 此UI后端将充当用户在网站或应用上与之交互的内容与所有后端服务之间的虚拟API或粘合API。 这意味着附加到网站或应用程序的后端只有一项工作,即格式化传出和传入的请求,以便实际的UI不需要处理任何数据。
Every service is entirely self-contained. This means that they each have their own database if needed, and they only talk to other services through API calls. There are various reasons for using microservice architecture — which will be discussed later in the article — but there are limitations and downsides to consider as well.
每个服务都是完全独立的。 这意味着,如果需要,它们各自都有自己的数据库,并且它们仅通过API调用与其他服务通信。 使用微服务架构的原因多种多样(将在本文的后面进行讨论),但也有一些局限性和不足之处。
Figure 1. MVC architecture diagram 图1. MVC架构图 Figure 2. Microservice architecture diagram 图2.微服务架构图Mapping an MVC system to a microservice system
将MVC系统映射到微服务系统
The key to understanding microservices is understanding how they came to exist in the first place. Like most things, they evolved out of necessity. Other architectures were not scaling effectively, so a new type of system had to be designed. More importantly, the design of microservice architecture is just an iteration on past architectures, not a complete redesign, so we can see how pieces of other architectures were used to create the standard microservice architecture.
理解微服务的关键是首先了解它们是如何存在的。 像大多数事物一样,它们是出于必要而进化的。 其他架构无法有效扩展,因此必须设计一种新型的系统。 更重要的是,微服务架构的设计只是过去架构的迭代,而不是完整的重新设计,因此我们可以看到如何使用其他架构的片段来创建标准微服务架构。
The main idea is that we are taking each controller and model pair — such asCheckoutController and CheckoutModel — from our MVC project and converting it into an entirely new service, most likely named CheckoutService. The CheckoutService is now its own entire web server with its own database, all of which is completely independent and decoupled from any other services.
主要思想是,我们将从MVC项目中获取每个控制器和模型对(例如CheckoutController和CheckoutModel),并将其转换为全新的服务,最有可能名为CheckoutService。 CheckoutService现在是拥有自己的数据库的自己的整个Web服务器,所有这些服务器都是完全独立的,并且与任何其他服务都没有关联。
The views then get migrated into their own service. This is generally a single monolithic service, but it could also be a micro frontend, although this is out of the scope of this article. The frontend code, for example, a Javascript FE framework, will still need some backend code in order to communicate with all the other services. For this, we will have a UI backend, which will act as a backend for the front-end (BFF). Its sole purpose is to bridge the FE and the other microservices. This is mainly done by normalizing the data of incoming and outgoing requests, allowing for slight variations between how different frontends handle and work with the microservices, so the FE only has to display the UI and nothing more.
然后将视图迁移到其自己的服务中。 尽管这不在本文的讨论范围之内,但这通常是一个单一的整体服务,但它也可能是一个微型前端。 前端代码(例如Javascript FE框架)仍将需要一些后端代码才能与所有其他服务进行通信。 为此,我们将有一个UI后端,它将用作前端(BFF)的后端。 其唯一目的是桥接FE和其他微服务。 这主要是通过标准化传入和传出请求的数据来完成的,从而允许不同的前端处理和使用微服务的方式之间略有差异,因此FE仅需显示UI,而无须其他任何操作。
The beauty of this type of FE system is that we aren’t solely reliant on a browser or a mobile app like MVC is. We can add as many frontends as we want, from a website on a browser, as shown in the MVC diagram above, to an app on an Apple TV, and still use the same backend services.
这种有限元系统的优点在于,我们不仅仅依赖于浏览器或像MVC这样的移动应用程序。 我们可以从浏览器上的网站(如上面的MVC图所示)向Apple TV上的应用程序添加任意数量的前端,而仍然使用相同的后端服务。
Differences between microservices and MVC / other architectures
微服务与MVC /其他架构之间的差异
The first thing most of us are probably taught in our first enterprise web applications course is the MVC architecture. On smaller applications, like what is worked on in school, MVC is great. It is fast to develop, has very little boilerplate code compared to microservices, and is easily manageable since all the files are close together. We have everything from our UI to our database interactions all in a singular src folder.
MVC体系结构是我们大多数人在第一门企业Web应用程序课程中所教的第一件事。 在较小的应用程序上,例如在学校进行的工作,MVC很棒。 与所有微服务相比,它开发速度快,具有很少的样板代码,并且易于管理,因为所有文件都在一起。 我们从UI到数据库交互的所有内容都在单个src文件夹中。
The first problem we will encounter is when we need to scale up our app. This could mean logistically, by adding more software engineers to the project, vertically scaling our application by increasing the resource allocation of the hardware it is running on, or by making our app bigger with more features. Growing an MVC app from 2,000 lines of code to 10,000 lines of code would most likely cause the software engineers to spend half their days fixing merge conflicts and resolving issues when they inevitably break other services. This is primarily a byproduct of tightly coupled services.
我们将遇到的第一个问题是何时需要扩展应用程序。 从逻辑上讲,这可能意味着通过向项目中添加更多的软件工程师,通过增加正在运行的硬件的资源分配来垂直扩展我们的应用程序,或者通过增加具有更多功能的应用程序来扩大我们的应用程序。 将MVC应用程序从2,000行代码扩展到10,000行代码,很可能会导致软件工程师花一半的时间来解决合并冲突并解决不可避免地破坏其他服务的问题。 这主要是紧密耦合的服务的副产品。
With microservices, the software engineers might encounter this problem in the form of two services. For example, a checkout service and a cart service might currently be a single microservice tightly coupled together. As the project expands, we might find that we want to decouple the two, that is, split them into two distinct microservices and have no overlap between them besides API communication. This might be needed for various reasons, but let’s say it is because we want to be able to checkout and complete a transaction, without the use of a cart. Creating a new microservice is quite similar to how many Object-Oriented Programming (OOP) languages overcome the same issue between classes, which is by using encapsulation and data hiding. We can make parts of our checkout service ‘private’ and inaccessible to other services (i.e. our new cart service). This means anything in our cart service that isn’t accessible through an API call, would be ‘private’, and inversely any function or data accessible through an API call would be ‘public’. Similar to how getters and setters would be used as a strict public way to access and set private data. This means we can enforce data hiding and service level encapsulation of our classes, interfaces, functions, and even database access.
使用微服务时,软件工程师可能会以两种服务的形式遇到此问题。 例如,结帐服务和购物车服务当前可能是紧密耦合在一起的单个微服务。 随着项目的扩展,我们可能会发现我们想将两者解耦,即将它们拆分为两个不同的微服务,并且除了API通信外,它们之间没有任何重叠。 出于各种原因可能需要这样做,但是可以说这是因为我们希望能够在不使用购物车的情况下结帐并完成交易。 创建新的微服务与使用面向对象编程(OOP)语言克服了类之间的相同问题(通过使用封装和数据隐藏)非常相似。 我们可以将结帐服务的一部分设为“私有”,而其他服务(即我们的新购物车服务)则无法使用。 这意味着我们购物车服务中任何无法通过API调用访问的东西都是“私有”的,相反,通过API调用可以访问的任何函数或数据都是“公开的”。 类似于将getter和setter用作访问和设置私有数据的严格公共方式。 这意味着我们可以对类,接口,函数甚至数据库访问执行数据隐藏和服务级别封装。
In MVC, we would be hard-pressed to do this. There are ways with proper folder structure and organization, but, in the real world, this is rarely the case. Most projects grow to be much larger than initially expected, and having a strict folder setup in order to force inaccessible code is in itself not scalable or maintainable. There is also the logistic aspect of having software engineers not use parts of the code without strict enforcement.
在MVC中,我们很难做到这一点。 某些方法具有正确的文件夹结构和组织,但是在现实世界中,这种情况很少发生。 大多数项目都变得比最初预期的要大得多,并且具有严格的文件夹设置以强制无法访问的代码本身不能扩展或维护。 还有一个后勤方面,即如果没有严格的执行,则软件工程师不要使用部分代码。
In an MVC application, your controller will be sending the rendered view or FE to the client. This means that the application will dictate what views the client receives, this might not seem important but it has many implications. In other words, the server is deciding for the user what to display. This might be worded a little oddly, but think about it like this: if the user wants to use the checkout service on a mobile app instead of a web app, this translates to the user wanting to decide which views/UI they want to use to interact with the checkout service.
在MVC应用程序中,您的控制器将把渲染的视图或FE发送给客户端。 这意味着应用程序将决定客户端接收的视图,这似乎并不重要,但有很多含义。 换句话说,服务器正在为用户决定要显示什么。 这可能有点奇怪,但可以这样想:如果用户想在移动应用而非网络应用上使用结帐服务,则意味着用户想要确定他们要使用的视图/ UI与结帐服务进行交互。
MVC applications don’t allow the user to make that decision. They already have a set of predetermined views or a UI that the user must use in order to interact with the service. This means that if we want to add a mobile app, we need to rewrite or copy and paste most, if not all, of our backend code. This will yield the same results, in addition to serving the user a different UI. So, as our app gets bigger, the general way they scale up is as depicted in Figure 3.
MVC应用程序不允许用户做出该决定。 它们已经具有一组预定视图或用户必须使用的UI才能与服务进行交互。 这意味着,如果要添加移动应用程序,则需要重写或复制并粘贴大部分(如果不是全部)后端代码。 除了为用户提供不同的UI外,这还将产生相同的结果。 因此,随着我们的应用程序变得更大,它们扩展的一般方式如图3所示。
Figure 3. MVC to microservice transition 图3.从MVC到微服务的过渡Another difference we see with microservice architecture versus an MVC or monolithic application, is that the code of most services is inherently abstracted, which could cause a lack of visibility between teams. Some teams might have never seen the code behind APIs they call every day. They receive documentation on the endpoints they need to communicate with and the contracts on how the data should look like. While on the MVC side it might be as simple as just peeking into the method body in the same IDE window. This is not necessarily a pro or a con, just a difference. One could make the argument that it is better for software engineers of a particular team to know their code extremely well. Others might argue that while that is true, they only know their own code very well and lack any meaningful understanding of the code from other teams.
我们发现微服务架构与MVC或单片应用程序之间的另一个区别是,大多数服务的代码是固有抽象的,这可能导致团队之间缺乏可见性。 有些团队可能从未见过每天调用的API背后的代码。 他们收到需要与之通信的端点的文档以及有关数据外观的合同。 在MVC方面,可能只是在同一个IDE窗口中浏览方法主体一样简单。 这不一定是利弊,只是区别。 有人可能会说,最好让特定团队的软件工程师非常了解他们的代码。 其他人可能会争辩说,尽管这是事实,但他们只非常了解自己的代码,而对其他团队的代码缺乏任何有意义的理解。
How and why we use microservices
我们如何以及为什么使用微服务
The purpose of microservices is best explained using an example. Imagine we have an ecommerce site with the following features:
使用示例可以最好地说明微服务的目的。 想象一下,我们有一个具有以下功能的电子商务网站:
Accounts 帐目 Login 登录 Cart 大车 Checkout 退房 Products 产品展示 Inventory 库存These are all small sections of the site that work together to give the user the full experience, but they should be completely independent of each other. After all, why does the cart need to know how to login the user?
这些都是站点的各个小部分,可以共同为用户提供完整的体验,但是它们应该彼此完全独立。 毕竟,为什么购物车需要知道如何登录用户?
This gives us the first use case of microservices: to be able to easily decouple different services. It provides us with a lot of benefits such as easily re-usable services. If our ecommerce business grows and we want to build a mobile app, by using a microservice architecture we can re-use the same services to supply the needed data to our app’s UI. With decoupled services, we can now more easily implement unit and functional tests for our app. This, in turn, means more and better testing, which is likely to improve the quality of the final product. We can smoothly deploy certain components of the app and revert back to older versions if needed without impacting any other flow.
这为我们提供了微服务的第一个用例:能够轻松分离不同的服务。 它为我们提供了很多好处,例如易于重用的服务。 如果我们的电子商务业务发展壮大,并且我们想构建一个移动应用程序,那么通过使用微服务架构,我们可以重复使用相同的服务来向应用程序的UI提供所需的数据。 借助分离的服务,我们现在可以更轻松地为我们的应用程序实施单元和功能测试。 反过来,这意味着要进行更多更好的测试,这可能会改善最终产品的质量。 我们可以顺利部署应用程序的某些组件,并在需要时恢复到较早版本,而不会影响任何其他流程。
Another really nice thing about microservices is that they provide us with the ability to abstract away other services. As a distributed system grows, it can have infinitely many microservices. Let’s say our site has 200 microservices, with some bigger and some more important than others. When hiring a new software engineer for a specific team, we can abstract all the work of the other teams away and reduce it all to a simple API call, which is hopefully well-documented. This allows for faster onboarding and an easier understanding of the codebase.
微服务的另一个真正的好处是它们为我们提供了抽象其他服务的能力。 随着分布式系统的发展,它可以具有无限多个微服务。 假设我们的站点有200个微服务,其中一些更大,一些比其他更重要。 在为特定团队雇用新的软件工程师时,我们可以将其他团队的所有工作抽象化,并将其简化为一个简单的API调用,希望该文档已被很好地记录在案。 这样可以加快入门速度并更容易理解代码库。
Overall limitations and cons of microservices
微服务的总体局限性和弊端
The biggest or most apparent downside of the microservice architecture is the fact that it is so verbose. Everything you want to add that isn’t already encapsulated by another service must be abstracted into its own service. This means a lot of boilerplate code and configuration, as opposed to another architecture where you might just create a new service file and start working. This results in an increase in time for developing new features and a decrease in developer productivity.
微服务架构最大或最明显的缺点是它是如此冗长。 您想要添加的所有其他服务尚未封装的内容都必须抽象到其自己的服务中。 这意味着很多样板代码和配置,而不是另一种体系结构,在该体系结构中,您可能只是创建一个新的服务文件并开始工作。 这导致开发新功能的时间增加,并降低了开发人员的生产率。
Something that isn’t often addressed, is the paradox of choice. In this instance, this refers to software engineers making their application so extensible that a software engineer might have two or three equally good ways of implementing a new feature. They might choose option A. Another software engineer might go with option B. Both are equally valid, but now we have different ways of doing the same thing within the same code base.
选择的悖论通常不被解决。 在这种情况下,这是指软件工程师将其应用程序扩展得如此之大,以至于软件工程师可能有两种或三种同样好的实现新功能的方式。 他们可能选择选项A。另一个软件工程师可能会选择选项B。两者都同样有效,但是现在我们在同一代码库中执行相同操作的方式不同。
Oftentimes, we see a much worse situation unfold where the feature gets gridlocked by decision making. In this scenario, every minor detail goes through extensive architecture review because no one is quite sure what the best way to design or implement the feature. As engineers, we must always strive to produce the best work possible, which is great, except when it starts to hurt productivity.
通常,我们会看到情况更加糟糕的情况,即该功能由于决策而陷入僵局。 在这种情况下,每个次要细节都要经过广泛的体系结构审查,因为没有人完全确定设计或实现功能的最佳方法。 作为工程师,我们必须始终努力产生最好的工作,这是很棒的,除非它开始损害生产力。
Conclusion
结论
Overall, there are many pros and cons to implementing a distributed system. While microservice architecture is just one of many ways, it is the most popular and has become the industry-standard amongst large companies right now for good reasons. This type of architecture allows for enough extensibility and options that it can be made to adapt to most of the needs of a given system.
总体而言,实现分布式系统有很多利弊。 尽管微服务架构只是众多方式中的一种,但它却是最受欢迎的方式,并且由于充分的理由,目前已经成为大公司中的行业标准。 这种类型的体系结构可提供足够的可扩展性和选项,以适应给定系统的大多数需求。
Hopefully, this article has provided a clear explanation of the transition from another architecture, such as MVC, to the microservice architecture. If you wish to explore microservices further, you can take a deeper look at some of these advanced topics:
希望本文为从其他架构(例如MVC)到微服务架构的过渡提供了清晰的解释。 如果您希望进一步探索微服务,则可以更深入地了解以下一些高级主题:
How microservices can communicate with each other asynchronously with event busses, queues, event sourcing vs event driven, and publisher-subscriber pattern 微服务如何通过事件总线,队列,事件源与事件驱动以及发布者-订阅者模式进行异步通信 The different types of frontends we can implement with microservices, such as micro frontends vs monoliths 我们可以通过微服务实现的不同类型的前端,例如微前端与整体式 The different types of architectural patterns we can use to implement a microservice at scale, such as domain-driven-design 我们可以用来实现大规模微服务的不同类型的架构模式,例如域驱动设计 As your project/application scales to microservice architectures, your databases will need to scale as well. Examine how to scale databases and optimize them with table sharding, functional partitioning, and master/replica patterns 随着您的项目/应用程序扩展到微服务架构,您的数据库也将需要扩展。 检查如何扩展数据库并使用表分片,功能分区和主/副本模式对其进行优化 How we can deploy, manage dependencies, and vertically/horizontally scale our microservices with tools such as Docker, Docker Compose, Docker Swarm, and Kubernetes 我们如何使用Docker,Docker Compose,Docker Swarm和Kubernetes等工具来部署,管理依赖关系以及垂直/水平扩展我们的微服务Editorial reviews by Deanna Chow, Liela Touré, & Pablo Martinez.
Deanna Chow , LielaTouré和Pablo Martinez的社论评论。
Want to work with us? Click here to see all open positions at SSENSE!
想与我们合作? 单击此处查看SSENSE的所有空缺职位!
翻译自: https://medium.com/ssense-tech/mvc-to-microservices-from-a-students-perspective-c29f9cf799d5
mvc 到微服务
相关资源:从MVC到微服务,技术演变的必经之路 - 北京简网CTO - 郭理靖