从公共业务提取来看架构演进——帐号权限篇

news2024/11/27 18:26:57

1. 引言

在产品业务多元化的过程中,往往会遇到一些与业务发展不匹配的架构问题,这些问题可能会在业务迭代中以性能差、重复开发等形式表现出来,进而给系统的扩展和维护带来一些挑战。

本文准备以一个帐号权限的业务为例,来讨论下:当遇到架构问题时,如何识别并及时调整,以适应业务的发展。

在问题开始之前,先对帐号的权限作下说明,以便更好的理解。

在本文中,权限是指帐号在一个产品系统中能允许使用的功能列表。以视频会议产品举例大概如下图所示:

一个帐号在多个产品中可能会有多套权限,就权限的理解达成一致后,下面我们进入正文。

2. 问题

企业有一个合同计费系统叫作Boss, 负责合同和帐号权限的开通, 它和业务系统之间的交互形式最初可能是这样:

  • 一个帐号在系统中有两套组件权限:网络会议组件权限和云会议组件权限
  • 开通帐号时,boss将两组权限分别下发到网络会议平台和云会议系统,由每个系统分别管理自己职责范围内的帐号权限数据。

如下图所示:
在这里插入图片描述

看起来也挺清晰,boss和业务之间耦合少,不用关心产品的业务迭代,只通过回调机制来同步帐号数据。

但这可能只是第一个版本,随着公司产品和业务的发展,又上线了一些系统,如:

  • 电话业务
  • 直播业务
  • 课堂业务

并且一个帐号有可能同时开通这些业务,Boss就要向多个产品系统都同步数据,系统模型演变成下图所示:
在这里插入图片描述

上图中红色的气泡里也有指明,随着产品业务线的扩张,带出了不少问题,例如:

  1. 开通慢:开通帐号要回调的业务系统越来越多,由于Boss要等每个业务系统都回复处理成功后帐号才算开通完成,所以帐号开通速度就变得越来越慢;
  2. 重复做:各个产品都要自己维护一份帐号权限数据,并且业务逻辑相似,代码也类同;
  3. 扩展差:各个团队对帐号权限这块儿业务数据的理解层次不齐,直接表现是代码扩展性不足,导致的结果是:每当产品要增加功能权限时,对应系统的代码和DB结构就要不停的跟着调整。

尤其是第1个问题,当面向C端的个人注册上线后,这个帐号开通慢的问题就如同被拿到放大镜下,在用户侧直接表现一种很差的体验,例如:

  • 用户提交注册表单成功了,但打开产品的客户端却无法登录,原因在于向业务系统的帐号同步工作是后台异步进行的,还未同步完。

这种问题在目前的系统模型下几乎没什么有效的根治办法,只能让用户等待。但等待也就意味着体验差、用户流失。

而且随着业务的多元化继续发展,帐号开通速度还会变得更慢。如果帐号开不出来,就等于是把用户挡在了门外面,产品都没有展示给用户的机会,所以问题还是相当棘手的。

那如何解决呢?

3. 方案思路

对于此问题的解决思路,我们从架构调整、存储优化、可扩展性三个方面来描述具体的优化方案。

3.1 架构调整

上面提到,各个产品对帐号权限的维护工作几乎是相同的。因此,我们可以尝试把帐号权限从各个产品中提取出来,成为公共服务,我们暂且称为统一权限。引入此服务后,系统需要做一定的调整:

  1. 各个产品都改从统一权限服务查询帐号数据,自己不需要再额外存储;
  2. Boss开帐号时只需要等待统一权限的结果回执,帐号开通模型大大简化;

系统模型演化如下:
在这里插入图片描述

这样调整后,带来几个明显的好处:

  1. 减少重复工作:不论有多少产品,帐号权限的回调、保存、查询等操作都只需要维护一份;
  2. 提升开通速度:Boss只需要把数据下发到统一权限即可认为帐号开通成功,回调链路大大缩短,帐号开通慢的问题也就得到解决。
  3. 带动登录业务的优化:依赖帐号校验的登录也可以提取为公共服务,进一步减少了各产品中的重复业务工作量。

3.2 存储优化

看到这里,不知道你心中是否有疑问:为何要额外增加一个统一权限服务,而不直接让Boss来提供帐号查询服务呢?

  • 原因1: 前面已经提到的,Boss不愿意与业务系统耦合,阻力大;
  • 原因2:Boss的DB存储不是为了高并发场景服务的,它有很大的历史包袱(具体下面会说明),即使它提供了查询服务,也很有可能达不到优化的目标。

帐号权限的数据内容本身是比较复杂的,它涉及到多块信息:

  • 帐号信息
  • 产品状态
  • 资源信息
  • 开通的产品组件
  • 开通的权限属性
  • ……

传统的关系数据库基本就是把每块信息建一张表,使用时再多表联查出来合并数据。导致的结果就是IO多,查询慢,并且还不好扩展字段。
<多张表的示意>

Boss基本就是类似上面这种拆分存储模式,甚至表比上面更多。估计也正是因为如此,Boss才把帐号下发给各个产品,以免自己成为性能瓶颈点。

这个问题放在10多年前的Boss上可能确实是个问题,但放在如今,却不一定难解。

仔细梳理会发现,上面这些信息不论如何分块,其实本质上都是帐号的一部分,如果把帐号的这些组成部分视作一个整体,其实就是一个带嵌套结构的文档对象。而这类数据的存储最适合面向文档的数据库,例如mongoDB。

它的特点是一个文档就能存下整个对象,特别适合存储结构化的对象。帐号权限用mongoDB存储后的结构示例:

{
  "_id": {
    "$oid": "5ef0a57570b03d622f967848"
  },
  "userId": 81299529, 
  "userStatus": 82,
  "status": 62,
  "contractId": 73522,
  "productId": 60000,
  "billingCode": "88130601",
  "resource": {      # 帐号资源信息
    "siteId": 95729,
    "siteURL": "20180518test8.quanshi.com/meetnow",
    "hostPassword": "2020194396",
    "guestPassword": "2020194397",
    "password": ""
  },
  "accountId": 154772,
  "siteId": 95729,
  "components": [    # 产品组件列表
    {                # 产品组件1
      "id": 1,
      ……
    },
    {                # 产品组件2
      "id": 2,
      "name": "summit",
      "activationUrl": "",
      "property": {  # 帐号在产品下的权限信息
        "AllowGuestMuteOverride": "0",
        "MuteOverride": "2",
        "AllowHostMuteOverride": "0"
      },
      "status": 1
    },
    {                 # 产品组件3
      "id": 22,
        ……
    }
  ],
  "expiryDate": 0,
  "gender": 0,
  "vip": "",
  "conferenceName": "88130601",
  "isFee": 1,
  "buyMonths": 0,
  "buyParties": 0
}

这样,带来两个好处:

  1. 易扩展:不论是帐号信息、权限属性和还是组件都很容易扩展,DB结构不用调整;
  2. 查询快:帐号所有信息都在一个文档中,一次IO就能将它查出来。

3.3 扩展性优化

此处扩展性主要是指业务逻辑的可扩展性。在新设计的统一权限服务上,如果帐号权限需要扩展业务逻辑,例如:

  • 支持给免费帐号特殊定义权限
  • 支持按产品强制关闭某个功能权限
  • 支持按会员等级来定义权限
  • 支持按商业模式来定义权限
  • 支持付费功能的免费试用权限

先不论这些业务的实现细节,单就工作量和影响范围来说,在新架构下实现就会比老架构下小很多。因为不论需求怎么做都只是在统一权限内部调整,各个产品系统一般都不用关心。

不仅仅是业务扩展,像一些性能调优,也只需要在统一权限服务内部考虑和实施优化方案,影响范围很容易评估和控制,这都得益于帐号权限从各个系统中提取为独立服务。

小结

本文以帐号权限为主要业务视角,介绍了一个局部架构演进的案例:通过将公共业务提取为独立服务并针对性设计,化解了帐号开通速度慢和相似业务重复开发的实际难题,同时让系统架构能与业务发展相匹配。

介绍已经完成的案例是容易的,但实际工作中要想将架构优化真正的落地却并不容易,我觉得至少需要具备以下几个条件:

  1. 有能发现问题的全局视角,如果只盯着局部,是很难看到整个系统结构层面的问题的;
  2. 有能协调资源的领导者,如果要优化的范围跨了部门,想推动下去是很难的,除非掌握资源的上级愿意帮你协调,或者自己有协调这些资源的能力和权力;
  3. 有能将思路真正落地的干将,提出优化方向需要的是前瞻思维,而将思路转化为能够落地的设计、代码和方案,则需要的是胆大心细 + 脚踏实地。

正因为如此,架构问题才是系统中最难解决的问题之一,有的时候缺方案、有的时候缺人、有的时候缺支持,甚至花了几个月时间最终夭折的也不乏例子。

所以有一个互相支持的研发团队和上下级很重要,最后祝愿看文章的你也能在自己的工作中获得支持,做出更大的成绩。

参考阅读:

  • 从功能设置提取来看架构如何演进:https://blog.csdn.net/xiaojia1001/article/details/134214400
  • 一个功能试用模块的抽取案例:https://blog.csdn.net/xiaojia1001/article/details/132959395

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1175301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL FULL OUTER JOIN 关键字(完整外部连接)||SQL自连接 Self JOIN

SQL FULL OUTER JOIN 关键字 当左&#xff08;表1&#xff09;或右&#xff08;表2&#xff09;表记录匹配时&#xff0c;FULL OUTER JOIN关键字将返回所有记录。 注意&#xff1a; FULL OUTER JOIN可能会返回非常大的结果集&#xff01; SQL FULL OUTER JOIN 语法 SELECT …

[100天算法】-搜索旋转排序数组(day 60)

题目描述 升序排列的整数数组 nums 在预先未知的某个点上进行了旋转&#xff08;例如&#xff0c; [0,1,2,4,5,6,7] 经旋转后可能变为 [4,5,6,7,0,1,2] &#xff09;。请你在数组中搜索 target &#xff0c;如果数组中存在这个目标值&#xff0c;则返回它的索引&#xff0c;否…

计算机毕设 基于大数据的服务器数据分析与可视化系统 -python 可视化 大数据

文章目录 0 前言1 课题背景2 实现效果3 数据收集分析过程**总体框架图****kafka 创建日志主题****flume 收集日志写到 kafka****python 读取 kafka 实时处理****数据分析可视化** 4 Flask框架5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&a…

MATLAB和西门子SMART PLC UDP通信

MATLAB和SMART PLC的OPC通信请参考下面文章链接,这里不再赘述: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读661次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的o…

Spring Security入门教程,springboot整合Spring Security

Spring Security是Spring官方推荐的认证、授权框架&#xff0c;功能相比Apache Shiro功能更丰富也更强大&#xff0c;但是使用起来更麻烦。 如果使用过Apache Shiro&#xff0c;学习Spring Security会比较简单一点&#xff0c;两种框架有很多相似的地方。 目录 一、准备工作 …

“Java与Redis的默契舞曲:优雅地连接与存储数据“

文章目录 引言1. Java连接上Redis2. Java对Redis进行存储数据2.1 存储set类型数据2.2 存储hash类型数据2.3 存储list类型数据 总结 引言 在现代软件开发中&#xff0c;数据存储和处理是至关重要的一环。Java作为一门强大的编程语言&#xff0c;与Redis这个高性能的内存数据库相…

【PWN · heap | unlink】hitcon2014_stkof

初学&#xff0c;通过一道题初步掌握unlink。不教学unlink的具体过程&#xff0c;仅是一篇wp记录笔记 前言 教学和具体过程可以看这个大佬的博客&#xff1a; buuctf pwn hitcon2014_stkof 初识unlink_buuctf hitcon2014_stkof-CSDN博客 一、题目 fill函数可读大量字符&#…

正点原子嵌入式linux驱动开发——Linux WIFI驱动

WIFI的使用已经很常见了&#xff0c;手机、平板、汽车等等&#xff0c;虽然可以使用有线网络&#xff0c;但是有时候很多设备存在布线困难的情况&#xff0c;此时WIFI就是一个不错的选择。正点原子STM32MP1开发板支持USB和SDIO这两种接口的WIFI&#xff0c;本章就来学习一下如何…

springboot前后端时间类型传输

springboot前后端时间类型传输 前言1.java使用时间类型java.util.Date2.java使用localDateTime 前言 springboot前后端分离项目总是需要进行时间数据类型的接受和转换,针对打代码过程中不同的类型转化做个总结 1.java使用时间类型java.util.Date springboot的项目中使用了new …

基于前馈神经网络完成鸢尾花分类

目录 1 小批量梯度下降法 1.0 展开聊一聊~ 1.1 数据分组 1.2 用DataLoader进行封装 1.3 模型构建 1.4 完善Runner类 1.5 模型训练 1.6 模型评价 1.7 模型预测 思考 总结 参考文献 首先基础知识铺垫~ 继续使用第三章中的鸢尾花分类任务&#xff0c;将Softm…

OCS2工具箱

实时系统优化控制工具箱 参考视频&#xff1a;ETH 最优控制/MPC 实时求解器 OCS2 使用入门 参考文档&#xff1a;OCS2 求解器入门 选择OCS2 OCS2 是一个 MPC 实时求解器 (SLQ/iLQR)&#xff0c;依赖 Pinocchio 构建机器人动力学模型&#xff0c;采用 RViz 或者 RaiSim 验证 (…

Ansible 自动化运维工具 --- playbook 剧本

文章目录 1. Host inventory ---- 主机清单1.1 简介1.2 inventory文件1.3 Inventory 文件的构成1.3.1 主机与组1.3.2 变量 1.4 inventory 中的常用变量 2. Ansible-playbook剧本2.1 简介2.2 Playbook的结构组成2.3 编写playbook的基本格式与写法2.3.1 基本格式2.3.2 语句的横向…

C语言打印出九九乘法表

#include<stdio.h> int main() {int i,j;for(i1;i<9;i){for(j1;j<9;j){printf("%d*%d%d\t",i,j,i*j); //\t制表符}printf("\n"); //\n输出个回车} }

Redis03-过期策略和淘汰策略

目录 Redis数据过期策略 Redis数据淘汰策略 Redis数据过期策略 Redis使用一种基于过期策略来处理键的过期和自动失效。这种策略可以确保不再需要的数据被自动删除&#xff0c;以释放内存并避免数据过期后仍然在缓存中存留。 Redis的过期删除策略主要有两种&#xff1a; 惰性…

【MySQL数据库】 四

本文主要介绍了mysql数据库的几种常见的约束. 一.数据库约束 我们希望存储的数据是靠谱的,mysql提供一些机制来辅助我们自动的依赖程序对数据进行检查 . 这类查数据的机制,就是约束 一旦约束好了,后续在进行增 删 改的时候,mysql就会自动的对修改的数据做出检查,如果不符合…

并发编程: 2. 线程管控

给定一个线程&#xff0c;只要令std::thread对象与之关联&#xff0c;就能管控该线程的几乎每个细节。 2.1 线程的基本管控 2.1.1 发起线程 线程通过构建std::thread对象而启动&#xff0c;该对象指明线程要运行的任务&#xff08;函数&#xff09;。简单的任务&#xff0c;…

【大数据】NiFi 中的重要术语

NiFi 中的重要术语 1.Flow Controller2.Processor3.Connection4.Controller Service5.Process Group6.FlowFile 那些一个个黑匣子称为 Processor&#xff0c;它们通过称为 Connection 的队列交换名为 FlowFile 的信息块。最后&#xff0c;FlowFile Controller 负责管理这些组件…

隐私安全|隐私安全已从国家法律法规转向商业企业应用,如何理解以及落地建设,相信大家正在经历隐私安全的困扰

网络空间的隐私安全主要是指网络隐私权不受侵犯&#xff0c;网络隐私权是指自然人在网上享有的&#xff0c;与公共利益无关的个人活动领域与个人信息秘密依法受到保护&#xff0c;不被他人非法侵扰&#xff0c;知悉收集&#xff0c;利用和公开的一种人格权&#xff0c;也包括第…

基于鹰栖息算法的无人机航迹规划-附代码

基于鹰栖息算法的无人机航迹规划 文章目录 基于鹰栖息算法的无人机航迹规划1.鹰栖息搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用鹰栖息算法来优化无人机航迹规划。 1.鹰栖息…

ActiveMq学习⑧__ActiveMQ的消息持久化机制

ActiveMQ的消息存储和持久化 MQ的高可用 事务持久签收可持久化 &#xff08;类似于与mq消息的同步机制&#xff09; 为了避免意外宕机以后丢失信息&#xff0c;需要做到重启后可以恢复消息队列&#xff0c;消息系统一半都会采用持久化机制。 ActiveMQ的消息持久化机制 Act…