“乐高式松耦合”架构实战

news/2023/12/9 1:37:20

作者:王康

白山联合创始人兼产品副总裁。
王康先生主要负责产品的完善与升级、产品开发流程把控及进度协调、产品设计改进及定期优化、产品全生命周期管理等工作。他带领团队实现白山首款产品CDN-X的多项创新,降低CDN使用门槛,极大拓展了CDN客户资源,提升了白山品牌价值,促进整体CDN市场的扩大与发展。
王康先生曾就职于网宿科技,任该公司产品及售前高级总监,负责技术团队的运营工作;拥有10年CDN行业经验,专注于提高产品输出的高质量和高可靠性。
王康先生拥有三项发明专利。

现在很多公司都在做松耦合,因为随着业务发展、需求增加,紧耦合系统的问题会慢慢凸显,并日益加剧。
以云分发行业为例,其属性在逐渐发生变化。过去,极少人产生内容,绝大多数人消费内容,云分发主要以下行流量为主,而随着全民直播的兴起,云分发变成了云交互;物联网的发展使物与物的数据交流成为主要方式,例如智能家居每天会产生上千条数据,但其中只有几条会被消费;VR爆发,用户产生的数据逐渐会从图片、视频转变为VR内容;基于此我们可以预料到上行流量将逐步增加,并逐渐超过下行流量,成为基础网络架构的巨大挑战。
用户需求与网络基础环境的快速变化,使得我们需要越来越快的实现需求,然而紧耦合系统却为研发带来诸多困难,使功能实现越来越耗费精力与时间,所以在白山创立之初就决定做“乐高式松耦合”架构,来构建整个产品体系,像搭积木一般灵活自如。

一、 传统难点
(1)需求堆积,收敛周期长
很多创业公司在成立之初采用野蛮生长的模式,原则是越快越好。紧耦合架构可以很好的满足这些要求,他们可以快速的建立CMDB与资源管理平台,并配置自动化、portal、监控等功能。但随着功能增多与需求开发的增加,这个系统逐渐变为一盘散沙。当有新需求发生时,他们需要为其做很多硬编码动作,收敛周期越来越长。
(2)“老中医”资源的浪费
在紧耦合系统中,看似一个没有什么关系的小改动,极有可能会引起一个重大bug;为防止错误发生,只能将系统设计的越来越复杂。例如为防止客户端挂掉,研发通常会为其添加一个守护进程;当守护进程不稳定时,新入职的研发常用的解决方案是再添加一个守护进程,这就导致了系统越来越臃肿。
这时候,公司往往就需要经验丰富、了解系统整体情况的“老中医”才能对平台进行改造。而作为核心资产的“老中医”在忙于救火、进行技术攻坚,很难抽出时间来进行系统重构。

二、 “乐高式松耦合”架构落地
快速实现需求与需求实现越来越慢的矛盾如何解决?最终白山的产品架构聚焦在解耦上,方便平台快速迭代,减少系统间依赖程度,打通无关联项目,为运营互动提供高效支持,确保服务质量。
(1) 第一层松耦合架构
以白山云分发CDN-X系统为例,其根本核心是运营。为使运营支撑系统通过解耦让公司的研发、运营灵活运转,需要进行第一层抽象。将运营支撑系统抽象为5个组件,包括:客户管理类、账单信息类、资源管理、运营监控和配置管理。并对这5个组件进行画像,确定边界、输入输出,按照运营场景描述用户场景。
几个组件之间通过消息总线交互指令,通过标准的reset接口交互数据;同时将5个组件投入到实际开发中,按照不同类型做实例化。
图片描述

(第一层松耦合架构)

(2)第二层松耦合架构
做完第一层解耦之后,我们发现第二层还可以继续做抽象。以配置管理系统为例,又可抽象出4部分。

  1. 生成配置:主要负责配置的生成以及配置到git仓库;

  2. 分发控制:管理灰度发布过程;

  3. 执行分发:分发收到的指令,并通过一些工具(如:salt、ansible、http get)汇报给上面的组件;

  4. 执行测试:调用已经写好的测试用例仓库测试这一次配置分发过程的最后效果。

图片描述
(第二层松耦合架构)

运营支撑系统中的各个组件都可以一直抽象下去,抽象概念贯穿整个设计平台的始末。
核心组件设计时再经过进一步抽象成工厂模式或单例模式,形成针对不同特性服务及场景,只需编写极小的落地代码即可获得整个运营支撑服务的可插拔架构。

(3)建设原则

  1. 组件即服务
    研发中人人都是架构师,收到研发需求后不是研究输入输出与边界,而是了解业务。根据情况输出需求文档,并与业务方进行确认,按照需求设计架构。每一个组件,不再是功能,而是服务,有自己的服务对象;研发人员从最初的对代码质量、输入输出负责,发展为对服务质量负责。

  2. 事件组件化
    在最初设计过程中,我们发现,很多运营中的动作称不上是平台上的动作,而是由事件组成。如果这些事件通过自动化来完成,就需要投入大量的精力。以节点上架自动化为例:包括自动化扫描端口、监控、安装、配置下发管理,甚至可以将自动化加入当前系统平台为用户提供服务。组件自动后,如果包装成事件,将浪费不必要的人力成本。如果将事件组件化,运维管理人员则可以在平台上方便的拖拽、引用、规范组件,通过拖拽、配置工作实现整体自动化。

  3. 数据聚合管理系统
    数据往往是运营中的判断标志,通过数据与数据间的关系来组建成组件。由于数据源之间的API不同,会导致花费过长的时间来对接API。我们将机房质量、监控负载、慢速比、卡顿率等数据进行整理,部分进行二次转化,通过统一的接口调用,做成一个数据聚合管理系统。

实例分享-节点自动上线
图片描述
(运维完成过程)

这个过程中运维人员完成了很多组件,如:配置管理、内部测试以及外部测试、入覆盖地区等;随后引入多种数据源进行追踪。事件模版完成后只需运维人员选择需上架的节点及其覆盖方案与地区,其余过程均有系统自动化完成。
此模版还可以根据需要不断修改,例如:丢包率组件等可以随时加入,不会影响业务的进行。
很多公司也在做同样的事件管理系统,不同的是其管理的是动作;而我们发现往往动作完成后还需要进行人工跟踪。鉴于此我们将事件做成一个完整的生命周期,同时引入数据源来跟踪异常服务状态码。
这个事件的完成过程中运维人员所需的操作已经从写脚本、人肉分析,简化为在模版上拖拽、引用组件,根据经验设置阀值,甚至使用其他的事件模版来完成事件。

三、 松耦合需要坚持的细节
(1)保持简单
随着时间的推移与功能的不断增加,系统必然会出现复杂性,而这种复杂性很多是由我们自身操作导致的,如上文提到的“守护进程”的例子,当使用复杂方案解决问题时往往会导致系统的臃肿。如果保证系统具备容错能力,组件运营不正常时系统可以自动修复,这个问题就会简化。
以消息管理机制为例,强消息管理机制要求确认消息确实可以被每台设备收到并执行。我们对此进行了改善,使消息病毒式传播,每台设备可以向周围5-6台设备发出消息,即便中间有一次失败,还会有其他设备再次向这台设备传输。这样的容错能力保证了系统可以简单地自动实现强研发、强跟踪等功能。
(2)在平台的基础上构建应用程序
例如在大数据平台上构建应用,研发人员在开发组件时无需考虑数据库的设计以及瓶颈优化问题,只需要对接数据聚合平台,大幅提高研发效率。
(3)不断迭代
以Facebook为例,目前每秒可以处理12亿张图片;而其第一版系统只能允许用户上传图片,并将其保存在数据库中,该系统只存续3个月;随着活跃用户的增加, 其后端压力不断增加,于是将存储改为二进制存储方式;Facebook的每一次迭代都不是为了某一特定目标,而是为了解决业务上的痛苦。
所以最开始做开发时,我们只需要考虑需求与业务,设计足够简单的方案,再进行不断迭代以满足新增需求。

四、 带来的变化
(1) 快捷引入新特性
我们使用P2P消息管理机制结合收敛算法,将文件删除由5分钟改进至0.7秒,我们对系统没有进行大范围改变,只是替换了其中的消息机制,利用当前基础的通讯机制和基础数据,过去所做的优化与UI仍可以继续使用。引用这些新特性时保持轻量级,对其他组件几乎没有影响。
(2) 开发效率高
例如游戏交互过程中的数字包交互,业内公认很难做到。目前我们正在进行尝试,我们引入开源的TCP代理软件,并规划新的应用服务类型,软件按指定好的打包方式放在指定位置,就可以实现软件的自动发布,同时调用其他组件接口对新业务进行监控,编写配置生成逻辑实现业务配置自动化。只需要编写非常轻量级的落地代码,整个组件落地之后就可以服务运营。
(3)运维自动化提高
在问题定位时,如果人工跟踪一般是“是与否选择”的串行计算,而在事件管理系统中,则进行并行计算,即:调用监控系统,判断节点是否正常;调用第三方数据进行及时测试,判断节点当前服务是否正常;调用客户App数据验证服务质量;使用ELK系统分析日志,精准、快速的定位问题,分析时间由10分钟大幅度缩减为3分钟。


http://www.niftyadmin.cn/n/1176689.html

相关文章

Field 'id' doesn't have a default value 错误处理

2019独角兽企业重金招聘Python工程师标准>>> Field id doesnt have a default value昨晚做项目的时候遇到一个问题,在测试数据存储的时候老是报Field id doesnt have a default value异常,从网上找了好久,根据各位大虾的说法也测试…

小高考计算机专业,只要专业选的好,年年都是小高考,这些大学专业堪称“难于上天”...

文/教育一角在高中阶段,同学们都在紧张的学习状态当中,其中也会有不少人会因此抱怨自己太难了。这个时候,不管是老师还是家长总会说出那句——现在压力大没事,到了大学就好了!这句话可以说是被很多高三考生“奉为圭臬”…

php 双向链表

<?php class student{ public $name; //姓名 public $id; public $gender; // 性别 public $chinese; public $math; …

常见的英文面试问题

常见的英文面试问题常见的英语面试问题个人介绍类&#xff1a; 1&#xff0e;Could you introduce yourself in English&#xff1f; 2&#xff0e;What are your greastest strengths&#xff1f; 3&#xff0e;What are your greastest weaknesses&#xff1f; 4&#xff0e;…

计算机公式筛选,Excel数据汇总计算的套路:5种筛选后的数据处理技巧

1、筛选后填充序号表格中的序号我们一般利用拖动或双击鼠标来填充&#xff0c;但在使用筛选功能后&#xff0c;筛选出的部分数据&#xff0c;序号是不连续的&#xff0c;如何让序号在筛选后也是从1开始递增显示呢&#xff1f;在A2单元格输入公式&#xff1a;SUBTOTAL(3,B$1:B2)…

Word 之 清除页眉下划线

在应用 Word 的时候&#xff0c;有时我们需要为文件添加页眉&#xff0c;但是首页却不需要。这时一般都会勾选“ 首页不同 ”并关闭页眉页脚。一种情况页眉不显示任何信息及下划线&#xff0c;另一种情况页眉留有下划线。以下针对第二种情况去除页眉下划线&#xff0c;由于我本…

fast服务器响应,FastApi教程|响应状态码

您可以使用指定响应模型的相同方法&#xff0c;也可以status_code在任何路径操作中使用参数声明用于响应的HTTP状态代码&#xff1a;app.get()app.post()app.put()app.delete()等等from fastapi import FastAPIapp FastAPI()app.post("/items/", status_code201)asy…

9. python 条件判断

1. if age 20if age > 10:print yes2. if else age 20if age > 20:print old else:print young3. if elif else score 85if score > 90:print excellent elif score > 80:print good elif score > 60:print passed else:print failed转载于:https://www.cn…

大数相加(c语言实现)

用字符串模拟大数&#xff0c;只需注意进位&#xff0c;使用了栈。 代码&#xff1a; 1 #include<stdio.h>2 #include<string.h>3 char A[99999];4 char B[99999];5 char sum[99999]"0";6 void add()7 {8 int top10,top20,len1,len2,len,top0,i,j,te…

菜鸟PHP九九口决 有好的代码一定要分享哦

<?php //九九口决$x1; //变量值为1while ($x<9) { //循环&#xff0c;当变量x的值小于等于9时开始循环执行下面语句块&#xff0c;大于9跳出循环$y1;//赋值变量y1while ($y<$x) { //内循环y的值小于等于X的值&#xff0c;执行内循环内语句$z$x*$y;//运算X乘y的积赋值…

css 嵌套列表下拉,使用CSS的水平嵌套列表

我正在尝试从嵌套列表标记创建水平列表,例如,我拥有当前标记&#xff1a;List Item 1List Item 2List Item 3List Item 4List Item 4aList Item 4bList Item 4cList Item 4dList Item 5我想要实现类似于以下内容&#xff1a;div { display: inline-block; }.alone { background…

while 循环 实例

/*int i0; while(i<100){// 循环条件 while先执行后循环 printf("while第%d遍循环体\n",i);//循环体 i; } *///计算0~100奇数和 while /*int i1; int sum0; while(i<100){ if(i%2!0){ sumi; } i; } printf("所有得奇数和&#xff1a;%d",sum);…

字符串问题 【微软面试100题 第八十五题】

题目要求 已知一个字符串&#xff0c;比如adserwsde&#xff0c;寻找其中的一个子字符串比如sde的个数&#xff0c;如果没有就返回0&#xff0c;有的话返回子字符串的个数。 题目分析 对KMP算法稍加修改一下就行&#xff1a;在应该返回字符串的地方进行计数。 代码实现 #includ…

android中利用HttpURLConnection进行Get、Post和Session读取页面。

直接上代码&#xff0c;调用的时候要放在线程中。 package slj.getsms;import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.io.IOException;public class …

登录 ajax密码明文,若依框架渗透测试用户名密码明文传输问题

解决思路&#xff0c;前端js加密&#xff0c;controller层解密1、前端加密引入js(jsencrypt.min.js) 个人备份jsfunction login() {$.modal.loading($("#btnSubmit").data("loading"));var username $("input[nameusername]").val().trim();var…

Nginx安装部署与测试

场景&#xff1a;项目需要部署在生产环境中&#xff0c;这些新的工具都需要在生产环境中去实践练习。有时间再部署一套ELK的日志分析系统&#xff0c;这样的系统才算具有一定的应用价值。 1 Nginx安装 用root用户安装&#xff0c;采用源代码编译的方式来进行安装&#xff0c;正…
最新文章