分享一个简单的前端灰度系统

本篇文章给大家带来了关于前端的相关知识,其中主要跟大家分享一个简单的前端灰度系统,并且介绍这个系统怎么写的?感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。

写在前面的话

灰度这个概念,来自数字图像领域,最初是描述黑白数字图像的灰度值,范围从 02550 表示黑色,255 表示白色,中间的数值表示不同程度的灰色。

灰度系统的诞生源于交叉学科的建设,在互联网上也不例外。对于一个软件产品,在开发和发布的时候肯定希望用户能够顺利的看到想让其看到的内容。但是,发布没有一帆风顺的,如果在发布的某个环节出了问题,比如打错了镜像或者由于部署环境不同触发了隐藏的bug,导致用户看到了错误的页面或者旧的页面,这就出现了生产事故。为了避免这种情况出现,借鉴数字图像处理的理念,设计师们设计出了一种介于 01 之间的过渡系统的概念:让系统可以预先发布,并设置可见范围,就像朋友圈一样,等到风险可控后,再对公众可见。这就是灰度系统。

灰度系统版本的发布动作称作 灰度发布,又名金丝雀发布,或者灰度测试,他是指在黑与白之间能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。(概念来自知乎)

立即学习“前端免费学习笔记(深入)”;

对于前端领域,演进到现在,灰度系统主要有如下几点功能:

增量灰度:小的patch可以增量的添加在发布版本上,也可以通过开关一键关闭用户灰度:增量和全量版本都可对不同群体或者某几个特定的用户进行灰度可见版本回退:每一个版本都在灰度系统里可见,可以一键回退

前端灰度系统工作流程图如下:

sequenceDiagram前端项目-->灰度系统: 部署阶段前端项目->>灰度系统: 1.CI 写入打包资源前端项目->>灰度系统: 2.CI 打包完成后更新资源状态前端项目-->灰度系统: 访问阶段前端项目->>灰度系统: 1.页面访问,请求当前登录用户对应的资源版本灰度系统-->>前端项目: 2.从对应版本的资源目录返回前端资源

灰度规则

关于灰度资源优先级的说明如下:

灰度策略 优先级

未生效低生效高全量一般

如此就起到了灰度的作用:全量表示所有人都可以看;生效表示只有在规则中的用户才可以看到这部分增量更新,优先级最高;未生效表示不灰度,优先级最低。

灰度系统数据库设计

为什么灰度系统有后端:前端项目 CI 部署后,会产生一个 commit 号和一个镜像记录,并且打包后的文件存放在服务器中某一个深层的文件夹目录中,灰度系统需要存入该部署的目录地址,便于在切换灰度时查找不同版本的文件。

先介绍一个要部署的前端项目(你可以根据自己的前端项目动态调整)。

本项目针对的前端项目是一个基于微服务架构的项目,

下面是设计ER图:

image.png

我们依此来分析:

子项目表

该表用于存放所有子项目的信息,新建一个微服务子项目时,会在这个表里新建一个条目,数据示意如下:

image.png

灰度用户表

用于灰度系统登录的用户,拥有灰度权限的人才可以加入。

资源表

资源表存放项目在 CI 中写入的 commit 信息和 build 完以后在服务器的存放位置,数据示意如下:

image.png

其中 branch 是跑CI的分支,data 存放打包资源目录信息,一般结构如下:

image.png

gitProjectId 存放该产品在 gitlab 中的项目号, status 表示构建状态:0:构建完成 1:部署完成 2:构建失败,3:部署失败。

这里简单提一下 CI 是如何写入灰度系统数据库的,过多详情不做解释,写入数据库方式很多,这只是其中一种实现方式。

首先在 CI build 环节往服务器写入打包信息的 JSON:

image.png

其中 build.sh 负责把传入的参数写到一个 json 中。

在 CI 部署环节,通过调用脚本创建资源:

image.png

其中 run_gray.js:

const { ENV, file, branch, projectId, gitProjectId, user, commitMsg } = require('yargs').argv;axios({    url: URL,    method: "POST",    headers: {        remoteUser: user    },    data: {        Action: "CreateResource",        projectId,        branch,        commitMsg,        gitProjectId,        channel: Channel,        data: fs.readFileSync(file, 'utf8'),        status: "0"    }}).then(...)

其中 status 的变化,在 CI 部署服务器完成后,追加一个 UpdateResource 动作即可:

简单听记 简单听记

百度网盘推出的一款AI语音转文字工具

简单听记 269 查看详情 简单听记

if [[ $RetCode != 0 ]]; then curl "$STARK_URL" -X 'POST' -H 'remoteUser: '"$GITLAB_USER_NAME"'' -H 'Content-Type: application/json' -d '{"Action": "UpdateResource", "id": "'"$ResourceId"'", "status": "2"}' > test.log && echo `cat test.log`; fi

灰度策略表

灰度策略是对灰度资源的调动配置。其设计如下:

image.png

其中,prijectId 表示灰度的项目,resourceId 表示使用的资源,rules 配置了对应的用户或用户组(看你怎么配置了,我这里只配置了单独的 userId),status 是灰度的状态,我设置了三种:

default: 未生效failure: 生效success: 全量

状态生效表示是增量发布的意思。

到这里,数据库设计就完毕了。

灰度系统接口API开发

有了数据库,还需要提供能够操作数据库的服务,上边创建资源的接口就是调用的灰度自己的API实现的。主要的API列表如下:

名称 描述

getResourcesByProjectId获取单个产品下所有资源getResourcesById通过主键获取资源createResource创建一个资源updateResource更新一个资源getIngressesByProjectId获取单个产品下灰度策略任务列表getIngressById通过主键获取单个灰度策略任务详情createIngress创建一个策略updateIngress更新一个策略

剩余的接口有用户处理的,有子项目管理的,这里不做详述。除了上边的必须的接口外,还有一个最重要的接口,那就是获取当前登录用户需要的资源版本的接口。在用户访问时,需要首先调用灰度系统的这个接口来获取资源地址,然后才能重定向到给该用户看的页面中去:

名称 描述 接收参数 输出

getConsoleVersion获取当前用的产品版本userId,productsresource键值对列表

getConsoleVersion 接受两个参数,一个是当前登录的用户 ID, 一个是当前用户访问的微服务系统中所包含的产品列表。该接口做了如下几步操作:

遍历 products,获取每一个产品的 projectId对于每一个 projectId,联查资源表,分别获取对应的 resourceId对于每一个resourceId,结合 userId,并联查灰度策略表,筛选出起作用的灰度策略中可用的资源返回每一个资源的 data 信息。

其中第三步处理相对繁琐一些,比如说,一个资源有两个起作用的灰度资源,一个是增量的,一个是全量的,这里应该拿增量的版本,因为他优先级更高。

获取用户版本的流程图如下:

graph TD用户登录页面 --> 获取所有产品下的资源列表获取所有产品下的资源列表 --> 根据灰度策略筛选资源中该用户可用的部分 --> 返回产品维度的资源对象

最后返回的资源大概长这个样子:

interface VersionResponse {    [productId: number]: ResourceVersion;}interface ResourceVersion {    files: string[];    config: ResourceConfig;    dependencies: string[];}

其中 files 就是 JSON 解析后的上述 data 信息的文件列表,因为打包后的文件往往有 css和多个js。

至于这个后端使用什么语言,什么框架来写,并不重要,重要的是一定要稳定,他要挂掉了,用户就进不去系统了,容灾和容错要做好;如果是个客户比较多的网站,并发分流也要考虑进去。

前端页面展示

前端页面就随便使用了一个前端框架搭了一下,选型不是重点,组件库能够满足要求就行:

登录

image.png

查看资源

image.png

配置策略

image.png

image.png

部署以后,实际运行项目看看效果:

image.png

可以看到,在调用业务接口之前,优先调用了 getConsoleVersion来获取版本,其返回值是以产品为 key 的键值对:

image.png

访问转发

这里拿到部署信息后,服务器要进行下一步处理的。我这里是把它封装到一个对象中,带着参数传给了微服务的 hook 去了,可以期待一下后续的手写一个前端微服务的系列文章;如果你是单页应用,可能需要把工作重心放在 Nginx 的转发上,通过灰度系统告知转发策略后,Nginx负责来切换路由转发,可能只是改变一个路由变量。 (你也可以参照我 nginx 相关文章),下面我简单的给个示意图:

graph TD灰度系统配置灰度策略 --> 告知Nginx资源地址 告知Nginx资源地址 --> Nginx服务器配置资源转发

总结

前端灰度系统,其实就是一个后台管理系统。他配置和管理了不同版本的前端部署资源和对应的用户策略,在需要的时候进行配置。

接下来的文章我会配套性的讲一下 NginxDocker 的前端入门使用,敬请期待!

推荐学习:《web前端开发》

以上就是分享一个简单的前端灰度系统的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/542618.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何将豆包 AI 大模型与 AI 简历优化工具结合,打造吸睛简历?详细教程​
上一篇 2025年11月9日 16:00:32
光遇3.21免费魔法是什么 光遇3月21日免费魔法收集攻略
下一篇 2025年11月9日 16:00:35

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    000
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    100
  • JavaScript 高效判断页面所有复选框状态的技巧与实践

    本文旨在提供一套高效且专业的javascript方法,用于判断网页中所有复选框的选中状态。我们将探讨如何利用`array.some()`快速确定是否有未选中的复选框(进而判断是否全部选中),以及如何使用`array.filter()`统计选中和未选中的复选框数量。通过优化dom元素选择和数组操作,提…

    2026年5月10日
    000
  • 从 JavaScript 获取 URL 并在 PHP DataGrid 中使用

    本文档旨在指导开发者如何从 JavaScript 函数中获取 URL,并将其动态应用于 PHP DataGrid。通过前端 JavaScript 动态生成 API 地址,并将其传递给后端的 PHP DataGrid,实现数据根据用户会话动态加载。 动态配置 DataGrid 的 URL 在构建动态 …

    2026年5月10日
    000
  • 控制HTML Canvas颜色空间输出24位深度TIFF图像

    本教程详细介绍了如何在web前端环境中,特别是结合`html2canvas`和`canvas-to-tiff`库时,通过明确设置html canvas的颜色空间为`srgb`,从而确保输出24位深度的tiff图像。文章将提供具体的javascript代码示例,并解释其原理,帮助开发者解决canvas…

    2026年5月10日
    100
  • HTML中如何实现MathML

    答案是利用HTML5原生支持MathML,只需将MathML代码嵌入标签即可,现代浏览器能直接渲染,无需插件;通过CSS可美化公式样式,如字体、颜色、间距等,提升显示效果;对于老旧浏览器,推荐使用MathJax作为兼容方案,支持LaTeX输入并渲染为高质量公式,兼顾可访问性与跨浏览器兼容性。 在HT…

    2026年5月10日
    000
  • JavaScript Electron桌面应用

    答案:使用JavaScript开发%ignore_a_1%桌面应用需结合Web技术与Node.js,通过主进程管理窗口、渲染进程展示界面,并利用IPC通信,调用系统功能如文件对话框,最后用electron-builder打包发布,注意安全与进程职责分离。 用JavaScript开发Electron桌…

    2026年5月10日
    000
  • 如何通过浏览器扩展实现快速HTML代码编辑的处理方法

    答案:通过浏览器扩展可实现快速HTML编辑,提升开发效率。首先选择如EditThisPage、Live HTML Editor、Web Developer或Scratchpad for Chrome等工具,安装后启用扩展的页面内编辑功能,直接修改DOM并实时预览;修改仅限当前会话,刷新即失效,适合临…

    2026年5月10日
    000
  • PHP代码注入检测日志分析_PHP代码注入日志检测方法详解

    答案:日志分析是发现PHP代码注入的关键手段,主要通过Web服务器访问日志、PHP错误日志、PHP-FPM日志及应用自定义日志等多源数据,结合grep、ELK、WAF等工具识别含eval()、system()、Base64编码、目录遍历等特征的异常请求,并建立基线、设置检测规则与自动化告警,配合事件…

    2026年5月10日
    000
  • JavaScript中为动态列表元素创建唯一悬停描述的教程

    本教程旨在解决如何为动态生成的列表或数组元素分配唯一悬停描述(tooltip)的问题。文章将深入探讨使用javascript对象和map数据结构来高效地管理名称与描述的映射关系,并提供具体的代码示例,以实现每个列表项在鼠标悬停时显示不同的自定义信息,同时兼顾性能与数据顺序的需求。 在网页开发中,我们…

    2026年5月10日
    000
  • Go语言与Microsoft SharePoint集成指南

    Go语言可以有效集成Microsoft SharePoint,主要通过两种途径:一是利用SharePoint提供的RESTful API进行数据交互,Go的标准HTTP客户端库即可轻松实现;二是通过SharePoint应用模型开发自托管应用,这种模型支持使用包括Go在内的任何语言编写后端逻辑。 1.…

    2026年5月10日
    000
  • javascript生命周期钩子是什么_组件有哪些关键阶段?

    JavaScript原生无生命周期钩子,这是Vue、React等框架为组件设计的机制;Vue按创建、挂载、更新、卸载四阶段提供对应钩子,React类组件有明确生命周期方法,函数组件则通过useEffect模拟,其核心价值在于精准控制执行时机以避免DOM操作错误和内存泄漏。 JavaScript 本身…

    2026年5月10日
    000
  • 如何安全有效地从外部网页获取HTML元素数据并应用于自身页面

    本教程旨在解决如何在不同域名下,通过javascript获取并使用另一个网页的html元素数据。文章将深入探讨同源策略的限制,并提供两种主要解决方案:使用` 在现代Web开发中,有时我们需要从外部网站获取特定的HTML内容或属性值,并将其整合到我们自己的网页中。例如,从XYZ.COM/B.html页…

    2026年5月10日
    000
  • 怎么安装html5_HTML5开发环境安装与配置详细步骤

    答案是配置HTML5开发环境需三步:1. 安装VS Code等编辑器并配置插件;2. 使用Chrome或Firefox测试页面;3. 可选搭建本地服务器,如Live Server或http-server;最后创建index.html文件验证环境。 安装HTML5开发环境其实并不复杂,因为HTML5本…

    2026年5月10日
    000
  • JavaScript动态下拉菜单:实现日期选项与价格计算关联

    在现代web应用中,动态生成表单元素并使其具备交互逻辑是常见的需求。特别是在需要根据用户选择调整价格或服务参数的场景下,下拉菜单()常被用来展示一系列选项。本教程将指导您如何利用javascript动态生成一个包含日期选项的下拉菜单,并为每个选项关联一个具体的数值(如剩余天数),进而实现一个基于用户…

    2026年5月10日
    000
  • 从视频链接中提取视频时长的前端实现教程

    从视频链接中提取视频时长的前端实现教程从视频链接中提取视频时长的前端实现教程从视频链接中提取视频时长的前端实现教程从视频链接中提取视频时长的前端实现教程

    本文详细介绍了如何在%ignore_a_1%通过javascript从html “ 元素中提取视频时长。核心方法是利用视频元素的 `loadeddata` 事件,确保视频元数据加载完成后,再访问其 `duration` 属性。教程将提供完整的html和javascript代码示例,并讨论相关注意事…

    2026年5月10日 用户投稿
    100
  • 使用SMTP.js发送邮件:客户端集成、常见问题与最佳实践指南

    本文深入探讨了使用SMTP.js库在前端发送邮件时可能遇到的问题,特别是与Elastic Email集成时的挑战。我们将分析代码中常见的异步处理错误、条件函数定义陷阱,并提供修正后的代码示例和最佳实践。重点强调了正确处理Promise链、确保函数可访问性以及客户端邮件发送的安全考量,帮助开发者构建更…

    2026年5月10日
    000
  • 前端性能监控如何量化JavaScript的加载时间?

    通过Performance API可精确量化JavaScript加载时间,首先调用performance.getEntriesByType(‘resource’)获取资源加载记录,筛选出mimeType为application/javascript或URL含.js的条目,提取…

    2026年5月10日
    000
  • 使用CSS Grid实现不规则列布局:告别传统表格的限制

    本教程详细阐述如何利用css grid实现复杂的、不规则的列布局,尤其适用于那些传统html表格难以实现的块状结构。文章将通过具体的css属性和html结构示例,指导读者如何定义网格、控制子项的跨度与位置,以及优化自动布局流程,从而高效构建灵活且响应式的页面布局。 1. 传统表格的局限与CSS Gr…

    2026年5月10日
    000
  • 如何在仅表单ID唯一时精确选择表单内部元素进行CSS样式定制

    当网页中存在多个结构相似的表单,且其内部元素(如输入框、按钮)的类名或标签名不唯一时,通过css为特定表单进行独立样式定制会面临挑战。本文将详细介绍如何利用表单的唯一id作为父选择器,结合后代选择器,精确地定位并样式化目标表单内的任意元素,从而避免样式冲突,实现精细化控制。 精准定位表单元素的CSS…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信