巨石加密_缓解巨石

巨石加密

by Ian Belcher

伊恩·贝尔彻(Ian Belcher)

我们如何将技术堆栈转向基于服务,以开发人员体验为中心的设计 (How we pivoted our tech stack to a service-based, developer experience-focused design)

This article documents the problems we experienced with monolithic architecture, our transition to a new service-based system, and the results we have seen from its implementation so far.

本文介绍了整体架构所遇到的问题,向新的基于服务的系统的过渡以及迄今为止从其实现中看到的结果。

问题 (The problem)

In 2015 we launched a minimum viable product — a monolith, built on top of a CMS running within a LAMP stack. The CMS in question is respected but has reached a point of decline in its lifecycle, arguably from poor management.

2015年,我们推出了最低可行的产品- 整体式产品,该产品基于在LAMP堆栈中运行的CMS构建。 有争议的CMS得到了尊重,但其生命周期已达到下降点,这可能是由于管理不善所致。

The costs relating to the development and delivery of our project had begun to exponentially increase:

与我们的项目的开发和交付有关的成本已开始成倍增加:

  • Our only feasible option was to scale vertically and it was a lot harder to implement high availability or redundant systems. Continual upgrades to our main host server were met with increases to our resource unit costs.

    我们唯一可行的选择是垂直扩展,而实现高可用性或冗余系统要困难得多。 不断升级我们的主主机服务器可以增加资源单位成本。
  • We were exclusively locked into a language and its performance. PHP is great for certain tasks, but not every task. In fact, it fails considerably for certain things where other languages shine.

    我们被专门锁定一种语言及其性能。 PHP对于某些任务非常有用,但对于每个任务却不是。 实际上,对于某些使用其他语言的语言来说,它会严重失败。

  • The internal design of the CMS performed terribly by today’s standards. Some core hacks improved this by orders of magnitude, but the site still performed poorly due to a number of suboptimal, upstream design decisions.

    CMS的内部设计按当今的标准执行得非常糟糕。 一些核心技巧将其改进了几个数量级,但是由于许多次优的上游设计决策,该站点的性能仍然很差。
  • As we continued to grow the project from its roots as a minimum viable product, we reached a complexity point where more additions or changes to functionality were met with a constantly increasing cost factor.

    随着我们从最小的可行产品的根源继续发展该项目,我们到达了一个复杂点,在不断增加的成本因素下,功能性得到了更多的增加或改变。
  • Due to increasing complexity, the developer experience sucked. Many developers will attest that once a project grows beyond a certain level of complexity, good, quality development drops off due to changes in one area having unforeseen consequences in other seemingly unrelated areas.

    由于复杂性的增加,开发人员的经验糟透了。 许多开发人员将证明,一旦项目增长到一定程度的复杂性之后,由于一个领域的变化会在其他看似无关的领域产生不可预见的后果,因此良好,高质量的开发就会下降。
  • Using a CMS meant that our product was almost fully dependent on the quality of a team of upstream developers from a small, privately owned company. The decisions they made impacted us. In effect, we were outsourcing many important tasks to this company, such as our security.

    使用CMS意味着我们的产品几乎完全依赖于一家小型私有公司的上游开发人员团队的质量。 他们做出的决定影响了我们。 实际上,我们将许多重要任务外包给了该公司,例如我们的安全部门。

  • The tight coupling within the core CMS system prevented us from trying out new technology. For example, direct interaction with the database could be found in nearly every part of the code-base, removing our ability to change or update the database technology.

    核心CMS系统内部的紧密耦合使我们无法尝试新技术。 例如,几乎可以在代码库的每个部分中找到与数据库的直接交互,从而消除了我们更改或更新数据库技术的能力。

We reached two important conclusions: Our monolith tech stack would continue to impede us from achieving our short-term goals, and our long-term goals would quickly become impossible from a product perspective and a human capital perspective.

我们得出两个重要结论:我们的整体技术堆栈将继续阻碍我们实现短期目标,而从产品和人力资本的角度来看,我们的长期目标将很快变得不可能。

Like any good, learning organization, we weren’t going to make these mistakes again. After many hours of further consideration we arrived at this hypothesis:

像任何一个好的学习型组织一样,我们不会再犯这些错误。 经过数小时的进一步考虑,我们得出了以下假设:

Monolith design facilitates, imposes and in some regards is itself, an anti-pattern.
整体设计促进,强加,并且在某些方面本身就是一种反模式。

Good development is about clear separation of concerns. Good development is about high classification and well-designed encapsulation of data and functionality.

良好的发展关系到明确的关注点分离。 良好的开发涉及数据和功能的高度分类和精心设计的封装。

The God class anti-pattern and the Law of Demeter tell us that we should limit knowledge in any specific area to only that which is required. So why are these principles often only implemented at a language level?

上帝的反模式和得墨of耳定律告诉我们,我们应该将任何特定领域的知识限制为仅需要的知识。 那么,为什么这些原则通常仅在语言级别实施?

In an abstract way, monolith systems are a ‘God class’. They function as a single, heavy controller — a global object that is injected upon instantiation with all of your system’s dependencies. They impose constraints such as operating system or language choices, where certain tasks are much better suited to other configurations.

抽象的角度讲 ,整体系统是“神类”。 它们充当单个重型控制器 - 一个 实例化时注入的全局对象,其中包含系统的所有依赖项。 它们强加了诸如操作系统或语言选择之类的约束,其中某些任务更适合于其他配置。

By definition, a monolith has full knowledge of the entire system. Therefore, in most cases, a developer working on a monolith also requires full knowledge to work on that project efficiently and effectively.

根据定义,整体具有对整个系统的全面了解。 因此,在大多数情况下,从事整体工作的开发人员还需要充分的知识才能有效地对该项目进行工作。

The developer needs this knowledge to make correct decisions that relate to the clear-cut separation of responsibilities between different areas of the code-base. When all of your classes are running ‘alongside each other,’ it is easy to make the wrong decision as to what should be done and where.

开发人员需要这些知识来做出与在代码库的不同区域之间明确划分职责相关的正确决策。 当您所有的类都“并排运行”时,很容易对应该做什么和在哪里做出错误的决定。

我们的解决方案 (Our solution)

Based on our hypothesis, we concluded that the current system was unsalvageable, and that a full rebuild under a service design pattern would produce a system that avoided the various issues we identified.

根据我们的假设,我们得出结论,当前系统是无法挽救的,并且在服务设计模式下进行全面重建将产生一个避免我们发现的各种问题的系统。

We created a matrix outlining what we wanted to achieve with the new system:

我们创建了一个矩阵,概述了我们希望通过新系统实现的目标:

Developer Experience (DX) defines the first half of our matrix. The desired calibre of developers we want are those looking for an opportunity to work on things they enjoy and are challenged by. To create a great DX, our code base needed to provide an ecosystem that talented developers would find engaging, while avoiding the pitfalls we had experienced in monolith design.

开发人员经验(DX)定义了矩阵的前半部分。 我们想要的开发人员的理想素质是那些寻找机会从事他们喜欢和受到挑战的事物的开发人员。 为了创建出色的DX,我们的代码库需要提供一个才华横溢的开发人员可以参与的生态系统,同时避免我们在整体设计中遇到的陷阱。

Product Delivery shapes the second half of our matrix. The phrase ‘content is king’ still holds true, but the performance of a website has also become a major factor from both a user perspective and search engine perspective. Fostering great DX was important, but it was imperative that the new website performed better for our users.

产品交付塑造了矩阵的后半部分。 “内容为王”一词仍然适用,但从用户角度和搜索引擎角度来看,网站的性能也已成为主要因素。 培养出色的DX很重要,但是必须让新网站对我们的用户有更好的表现。

Here is a breakdown of the four main components of the matrix and what we aimed to achieve.

这是矩阵的四个主要组成部分的细分以及我们要实现的目标。

敏捷 (Agility)

Complexity kills. Complexity sucks the life out of users, developers and IT. Complexity makes products difficult to plan, build, test and use. Complexity introduces security challenges. Complexity causes administrator frustration. And as time goes on and as software products mature — even with the best of intent — complexity is inescapable. Ray Ozzie

复杂性杀死。 复杂性使用户,开发人员和IT失去生命。 复杂性使产品难以计划,构建,测试和使用。 复杂性带来了安全挑战。 复杂性会使管理员感到沮丧。 随着时间的流逝以及软件产品的成熟(即使有最好的意图),复杂性也是不可避免的。 雷·奥兹 ( Ray Ozzie)

Solution: Reduce Complexity = lower financial cost, greater DX, lower learning curves.
解决方案:降低复杂性=降低财务成本,增加DX,降低学习曲线。

Complexity within a system behaves like a virus. The more complexity that is present, the more it grows. Reducing and segregating complex parts of the system stops more complexity from growing in other areas.

系统内的复杂性就像病毒一样。 存在的复杂性越高,增长的速度就越大。 减少和隔离系统的复杂部分可以防止其他方面的复杂性增加。

Service-based design can quarantine the virus. A monolith facilitates the spreading of complexity. (During the initial development of the new system, Conway’s Game of Life served as a good reminder of this fact).

基于服务的设计可以隔离病毒。 整体结构有助于分散复杂性。 (在新系统的最初开发过程中, Conway的“生命游戏”很好地提醒了这一事实)。

When the code is simple, it is easier to make it efficient and effective at what it does and more enjoyable to work on. The ‘art’ of the developing becomes the output, not the code itself.

当代码很简单时,使代码更高效,更有效,并且工作起来更有趣。 开发的“艺术”成为输出,而不是代码本身。

Separating out areas of concern into system level boundaries (which services do) means developers no longer need full knowledge of the entire system to work on it effectively. They are given a defined interface (for example, a HTTP API, socket or AMQP message) at a system level, not a language level, and can be assigned actual responsibility for that service.

将关注的区域划分为系统级别的边界(服务可以做到)意味着开发人员不再需要完整的系统知识就可以有效地进行工作。 在系统级别 (而不是语言级别)为它们提供了定义的接口(例如,HTTP API,套接字或AMQP消息),并且可以为他们分配对该服务的实际责任。

This separation means a developer who is given responsibility for a service can effectively change the underlying technology (such as what language, OS or persistence technology is used) without other team members knowing. This allows for performance trials and deep dives and prevents the need to up-skill the whole team to account for changes.

这种分离意味着负责服务的开发人员可以在其他团队成员不知情的情况下有效地更改基础技术(例如,使用哪种语言,操作系统或持久性技术)。 这样可以进行性能测试和深入研究,并避免需要提高整个团队的技能来应对变化。

The reduction of complexity and segregation that results from service design creates a code-base with a high agility factor. New developers can be committing on their first day, because reading and understanding the entire code base at a service level typically involves a few hundred lines of code.

服务设计导致的复杂性和隔离性的降低创建了具有高敏捷度因子的代码库。 新开发人员可以在第一天就下定决心,因为在服务级别阅读和理解整个代码库通常涉及几百行代码。

稳定性 (Stability)

Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. Alan Kay

如今,大多数软件非常像埃及的金字塔,成千上万的砖块彼此叠放,没有结构上的完整性,只是由蛮力和成千上万的奴隶完成的。 艾伦·凯

Solution: Minimize and mitigate dependencies = lower exposure to industry volatility and breakages, increased management ability and greater DX
解决方案:最小化和减轻依赖关系=降低行业波动和破损的风险,增强的管理能力和更大的DX

The volatility and rate of change in the software industry surpasses most other industries, yet most people in the software industry choose to accept these risks rather than mitigate them.

软件行业的波动性和变化率超过了大多数其他行业,但是大多数软件行业的人选择接受这些风险而不是减轻它们。

A number of wide scale breakages resulting from a lack of mitigation of upstream changes have already occurred this year (see here and here).

由于缺乏缓解上游变化的影响,今年已经发生了许多大规模破损(请参见此处此处 )。

Service design fosters greater separation, specificity, and the appropriate use of dependencies. This allows planned integration of upstream changes — not just when your CI breaks.

服务设计可促进更大的分离性,特异性和对依赖关系的适当使用。 这允许按计划整合上游变更 -不只是您的CI中断。

Using third party code (especially with standard package workflows such as npm et. al.) is the same as giving developers outside of your team write access to your code-base without the normal vesting such as PR’s or reviews. The inclusion of third party code needs to be given good cause, carefully chosen and then committed to. Better managing dependencies means that your team can focus more on building, not retrofitting.

使用第三方代码(尤其是在标准的软件包工作流程(例如npm等)中使用)与为团队外部的开发人员提供对代码库的写访问权限相同,而没有常规的权限(例如PR或评论)。 包含第三方代码需要有充分的理由,要仔细选择然后再承诺。 更好地管理依赖关系意味着您的团队可以将更多的精力放在构建而不是改造上。

可扩展性 (Scalability)

At a sysops level, it is well known that service design enables more manageable scalability compared with monoliths. It is common for teams to migrate from monolith design for this reason.

在系统操作级别,众所周知,与整体设计相比,服务设计可实现更可管理的可伸缩性。 因此,团队通常会从整体设计中迁移。

What isn’t so apparent before this transition is the resource unit cost reduction that occurs with service design, even on systems that don’t need to scale with demand.

在进行这种过渡之前,还不那么明显的是服务设计会降低资源单位成本,即使在不需要根据需求扩展的系统上也是如此。

Many hosts have greater resource unit costs for larger machines (i.e. $80 will buy 8GB 4 cores 80GB if buying one instance, or 8GB 8 cores 240GB if buying eight $10 instances).

许多主机在较大的机器上具有更高的资源单位成本(例如,如果购买一个实例,则80美元将购买8GB 4核80GB;如果购买八个实例,则将购买8GB 8核240GB)。

This cost reduction comes with the benefit of higher reliability, because service design offers better scope for state management. For example, if a service crashes, your entire system doesn’t go offline — everything continues and that service is restarted and re-added to your cluster.

成本的降低带来了更高的可靠性,因为服务设计为状态管理提供了更好的范围。 例如,如果服务崩溃,则整个系统不会离线 -一切继续进行,该服务重新启动并重新添加到您的集群中。

网站速度 (Site Speed)

A very common mistake was made on our previous monolith site. Our view layer was split across two different technologies : Server-side PHP templates and front end JavaScript. Under these circumstances there were multiple rendering processes that had to take place on both the client side and server side for every page view.

在我们以前的整体网站上犯了一个非常常见的错误。 我们的视图层分为两种不同的技术:服务器端PHP模板和前端JavaScript。 在这些情况下,每个页面视图的客户端和服务器端都必须执行多个渲染过程。

This added a ton of complexity for developers and also slowed the site considerably.

这给开发人员增加了很多复杂性,也大大降低了网站速度。

Solution: Implement classical client-server software design, make the client self sufficient and use the server only for persistence.
解决方案:实施经典的客户端-服务器软件设计,使客户端自给自足,并且仅将服务器用于持久性。

From a model-view-controller perspective, implementing classical client-server software design means your view layer is very well defined and encapsulated into a single area of concern.

从模型-视图-控制器的角度来看,实现经典的客户端-服务器软件设计意味着您的视图层已得到很好的定义,并被封装到单个关注区域中。

Great front end frameworks have become available in recent years which enable this to be done simply and easily.

近年来,强大的前端框架已经可用,这使此操作变得简单而轻松。

On most websites, almost everything required to display a page is delivered repeatedly (HTML structure, CSS, JavaScript) and the server typically acts as the part that populates the data within the HTML structure. It is more logical to deliver the static requirements once, then let the client populate the HTML with the data.

在大多数网站上,显示页面所需的几乎所有内容都是重复交付的(HTML结构,CSS,JavaScript),并且服务器通常充当填充HTML结构内数据的部分。 一次交付静态需求,然后让客户端用数据填充HTML,这更合乎逻辑。

到目前为止我们学到了什么 (What we’ve learnt so far)

Internally we believe we have delivered exceptionally well on the four components of our matrix. In future posts I will be exploring each one separately in more detail and sharing some metrics. In the meantime, here are a few key points we’ve taken away from the process:

在内部,我们认为我们在矩阵的四个组成部分上表现出色。 在以后的文章中,我将分别详细探讨每个方面,并分享一些指标 。 同时,以下是我们从流程中删除的一些关键点:

建立马戏团,而不是管弦乐队 (Build a circus, not an orchestra)

A monolith requires your entire team to be working in the same code space at the same time in a coordinated fashion. Picture an orchestra: A mistake by any member will affect the performance of the entire team.

整体需要您的整个团队以协调的方式在相同的代码空间中同时工作。 想像一个乐团:任何成员的失误都会影响整个团队的表现。

Instead, make your tech production about giving your developers the space they need to do what they do best. Service design allows you to create a set of well performed, isolated ‘acts’.

相反,进行技术生产时要给开发人员足够的空间,使他们可以做自己最擅长的事情。 服务设计使您可以创建一组性能良好的隔离“行为”。

像银行经纪人一样思考,而不是无家可归的人 (Think like a bank broker, not a bower bird)

Upstream dependencies, third party code and tooling can have quick returns but always come with a multitude of implied risks while writing your own ‘fit for purpose’ code will give you more efficiency and lower levels of risk. Continually picking up and collecting dependencies like a bower bird increases your exposure to these risks.

上游依存关系,第三方代码和工具可以快速获得回报,但始终伴随着许多隐含的风险,同时编写自己的“适合目的”代码将为您带来更高的效率和更低的风险。 像领鸟一样不断捡拾和收集依赖物会增加您面临的这些风险。

Instead, think like a bank broker and only choose the safest ‘stocks’ with good ‘returns’ to limit and mitigate your exposure wherever possible.

相反,请像银行经纪人那样思考,并仅选择具有良好“回报”的最安全“股票”,以尽可能限制和减轻您的风险敞口。

服务的行为与定义良好的类相同 (Services act the same as well defined classes)

The behaviour of a service is synonymous with a class within a monolith code-base. They have a public interface, they are constructed with their required dependencies and encapsulate their own data and control its access.

服务的行为与整体代码库中的类同义。 它们具有公共接口,它们以所需的依赖项进行构造,并封装自己的数据并控制其访问。

However unlike classes that run along side each other, it is more difficult for a developer to simply change the design of an interface to suit their needs in a given context. This constraint fosters stronger, interface-centric design which in turn leads to more predictable, higher quality code.

但是,与并排运行的类不同,对于开发人员而言,仅更改接口的设计以适应给定上下文中的需求更加困难。 这种约束促进了更强大的,以界面为中心的设计,进而导致了更可预测的,更高质量的代码。

服务器端渲染与典型软件开发实践相反 (Server-side rendering is the inverse of typical software development practice)

Like applications that run on your computer, gaming console or devices, servers act as a central persistence layer, not the renderer. Rendering the view on the server-side is a throw back to the earlier days of the internet where servers delivered static files. This practice has propagated to today’s web due to the server-only language preferences of web developers.

就像在计算机,游戏机或设备上运行的应用程序一样,服务器充当中央持久层,而不是渲染器。 在服务器端渲染视图可以追溯到Internet早期的服务器交付静态文件的时代。 由于Web开发人员仅使用服务器的语言偏爱,这种做法已传播到当今的Web。

The web browser is a smart, powerful, perfectly scalable and free-to-use resource. Make use of its full potential by producing ‘native’ web pages that run in the browser, not on your server.

Web浏览器是一种智能,功能强大,可完美扩展且免费使用的资源。 通过生成在浏览器而非服务器上运行的“本机”网页来发挥其全部潜力。

后记 (Postscript)

If you enjoyed this article, please hit the heart button below to promote further conversation.

如果您喜欢这篇文章,请点击下面的心脏按钮以促进进一步的对话。

I am CTO at Deckee — we help the boating community find, share and discuss the things they love.

我是Deckee的CTO-我们帮助划船社区 查找,分享和讨论他们喜欢的事物。

Deckee is an affirmative action employer and we are always on the lookout for likeminded, audacious developers. Please ‘inspect’ our site for more details.

Deckee是积极行动的雇主,我们一直在寻找志趣相投,大胆的开发人员。 请“ 检查 ”我们的网站以获取更多详细信息。

翻译自: https://www.freecodecamp.org/news/https-medium-com-deckee-tech-mitigating-monoliths-2a8dcb8603a9/

巨石加密

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值