重构国内游戏账号登录系统的思考和实践

news2024/11/22 21:25:38

本期作者

背景

账号登录系统,作为游戏发行平台最重要的应用之一,在当前的发行平台的应用架构中,主要承载的是用户的账号注册、登录、实名、防沉迷、隐私合规、风控等职责。合规作为企业经营的生命线,同时,账号登录作为在线链路转化的第一站,因此账号登录系统的稳定性,一直面临极高的要求。

出于稳定性需要,游戏发行平台在很早期就实践了两地三中心的多活架构。目前以公司公司机房为中心,同时在华东公有云和华南公有云,实现了两地三中心部署方案。依托公有云的主要考量因素在于,早期公有云提供的快速弹性和按量付费的能力,能够高效的承接游戏业务方的发展诉求;其次,对于华南地区的选择,也是优先考虑重要合作方所处的地理位置。

基于稳定性、效率、成本的多方考量,最终实现了公司机房、华东公有云A、华南公有云B的混合云架构。混合云架构带来便利的同时,也存在普遍的挑战,其中最显著在于两个方面:

其一、数据架构,数据在云端存储的存在的泄露风险。在具体实施层面,数据架构的差异化,将会导致底层的领域服务所能交付的API必定存在差异,主要差异体现在API的能力范围。比如,bilibili授权登录等能力,云上机房是无法做到实际支持的,服务端只能将相关请求转发至公司机房处理。

其二、PaaS平台的差异。公司基础架构在数据库管理平台、KV数据管理平台、消息队列等产品支撑已相当成熟,但早期在公有云的应用部署只能依托云原生的能力。这导致在底层的依赖上,原本需要建立一个标准防腐层,屏蔽具体的实现差异,但因为业务进度的需要,导致有所折中欠缺。

由于存在以上两个显著的挑战,项目进展等因素的考虑,最终演变的应用架构如下,也因此账号登录系统,在公司机房和公有云机房演变出了两套代码仓库(login-idc-api / login-cloud-api)。

图片

游戏账号登录应用的两套代码,迭代至今已近7年。当前应用,虽然在主观上理解已经迭代趋于稳定,但是基于最近一年完成的迭代版本统计,全年迭代版本超过10次,版本平均耗时接近4周,包括设计、开发、测试、上线。双代码仓库导致的设计、开发、测试,部署平均耗时增加了30%~40%。其次,在双代码仓库,且依赖Spring等核心组件版本较低的情况下,对齐公司基础架构的各项产品,可预见工作量的前提之下,该系统的重构工作,已经到了不得不行的地步。

挑战

为稳定性诉求极高、迭代长久的系统发起重构,需要巨大勇气,得失于转瞬之间。

  1. 重要性:承载千万MAU,L0不可降级链路;支撑113个SDK版本(采样周期:2024/02/15 - 2024/03/15)

  2. 稳定性:重构过程中SLO 4个9的约定,必须在执行之前规划完成执行细节和过程,全面又不失细致;

  3. 复杂度:业务本身内在的复杂度,7年来的高速发展,积累的大量技术债。

价值

1.效率:开发效率提升50%,迭代效率提升30%-40%

2.成本:节省人力(预期当前系统的生命周期至少5年)

3.质量:

  • 代码圈复杂度:降低40%;

  • 内网调用去SLB依赖,核心链路接口RT 99.9Line 提升31.5%

4.文化:践行“极致执行”的价值观。

实践:如何实现重构?

战略方向

方案一、放弃现有的两地三中心,账号登录全部统一到公司标准,不依赖云厂商。该方案作为未来的长期方向,完全回公司部署符合公司长期战略规划,难点在于发行平台的应用架构,目前绝大多数服务还是重点依赖公有云,短期内不具备独立完成的可行性。

方案二、推动主站账号团队,打通公司和公有云的数据架构,实现领域能力的对等,但存在数据安全风险,考虑到项目收益和跨团队的工作成本,并非当前最高ROI的选择。

方案三、将双代码仓库中,有关于数据架构和PaaS的差异,以重构的办法实现兼容,达到最终的代码仓库统一。

思考过程

重构的前提

回顾Martin Flower有关重构的著作《重构 改善既有代码的设计》一文中,将”重构“以名词、动词两种方式定义如下:

重构(名词):对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

重构(动词):使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。

这本关于重构的经典,在两种定义方式中,提到了3个关键概念,”调整“、”结构“、”不改变软件可观察行为“。这3个关键词组合起来,约等于行动指南。”不改变软件的可观察行为“作为前提,如何理解可观察行为,Martin并未在技术和业务上做过明确的定义,因此在这个概念的理解上,不免要多一些执行者的个人理解和思考。

如果把应用架构视为当前的结构,对于“可观察行为”的理解,从以下几个角度尝试去思考:

1.系统职责,前后端分离的应用架构之下,交付这些职责的API是一类可观察的行为;

2.系统依赖项,是一类可观察的行为,包括两个大部分:

  • bilibili账号的领域服务、游戏发行的领域服务、第三方服务(比如:极验服务提供商)

  • PaaS基础架构(公司的数据库、KV数据系统、消息队列等等;公有云的云MySQL、Redis、Kafka等等)

3.系统的横向服务。从分层架构的层次上来说,当前定位是应用服务层BFF,本不应该出现较大的横向影响,但是过往高速演进的过程中,承载了部分领域服务的职责(比如:查询游戏信息、查询活跃游戏、查询用户信息等),因此姑且对于这一类概括为横向的影响。

形形色色的差异

当前应用架构下,双仓库在逻辑模块、应用内分层(J2EE的3层模型)的特点,展示如图:

图片

在不可变的前提之下,试图通过对齐双仓库代码差异,以求得统一的思路,单从Service这一层来说(其依赖的bilibili账号服务API超过80个),理解起来已足够让人头大,其变更风险也是极其巨大,更何况还有JDBC ORM、Redis在技术选型和使用约束上的差异。如此风险再加上即将投入较大的工作量,势必提案困难重重。基于静态的模块和应用内代码分层来看,这巨大的差异看似是无法“暴力”抹平。

消失的复杂度

柳暗花明时刻,来源于应用运行时的一个事实:“生产环境多次高可用切流”。这个事实不仅实现了对SDK上游异地多活的承诺,而且经过了生产环境的多次验证。简而言之,双仓库在Controller、Service这两个最业务逻辑最复杂,技术债积累最多的分层,虽各有千秋,但殊途同归。

由此推理,重构过程中的最大的认知注意力负担,可以直接从这两层忽视。这两层注意力的移除,同时也利好DB和Redis的兼容工作量,作为基础架构中最重要的两个组件,完全无需再关注各类RedisTemplate/Jedis,Key命名、JdbcTemplate/Mybatis 、SQL的之间的逻辑差异,因为他们只是Controller和Service最终呈现出来的一部分。

在混沌中聚焦

SDK API链路:由于Controller、Service复杂度的消失,那么剩余的不可变的可观察行为,就只集中在DAO。DAO差异的本质来源于混合云部署架构的挑战(数据架构、PaaS差异),那么实现策略也就清晰了,在DAO层基于运行时ZONE来标识依赖的bilibili账号API调用即可。参考六边形架构,对于外部依赖和业务逻辑的隔离方式,实现核心业务逻辑对于外部API和PaaS解耦,以此降低变更侵入的影响面。

图片

PaaS的差异在业务逻辑层Service(或者少量的Controller)已经被消化,因此无需再考虑逻辑上的差异,只需关注框架和数据库的版本兼容性。

领域类和通知类API链路:这条链路虽然不是核心,但这是混合云数据架构差异的体现。生产环境的调用集中在公司机房,能力”较小“的公有云应用,向公司应用融合靠拢,也正因如此,统一之后的代码仓库是以公司机房代码仓为基准。

转发类API链路:这条链路差异化的本质也是来源于混合云部署的数据架构差异,在当前的融合方案中无法解决,因此只能沿用现有的转发策略,但转发后续可向上移交至API GW实现,这个已在计划当中。

具体实现

图片

公司机房原仓库为基准,在公有云A/B可用区部署,可用区选择与当前两地三中心保持一致。依赖的DB Schema在三机房原本就相同,因此可直接复用已有的DB实例。Redis,因其均有读写操作,避免灰度过程对于线上应用的数据污染,因此部署单独的Redis集群用于数据隔离,待完成灰度之后,一并下线原应用和原Redis集群。

数据验证

产品视角

  1. 基于用户维度,验证比对新老集群的数据写入和查询;

  2. 基于游戏维度,验证比对新老集群的数据写入和查询;

  3. 生产环境SDK,基于测试域名,实现核心SDK产品回归验证,覆盖全量用例;

  4. 其他非SDK API,实现全量的单测覆盖,基于接口实现验收。

数据视角

  1. 数据库:基于Job任务,实现源与目标数据源内容比对;

  2. 缓存:纯缓存场景,灰度期间隔离部署,回滚后不影响业务逻辑。缓存未命中直接远程调用;

  3. 埋点/报表:基于灰度过程观察游戏维度的报表趋势,并与过往数据进行比对。

发布方案

发布计划设计,严格遵守公司安全生产要求:可灰度、可观测、可恢复。

可灰度

灰度过程一共分为两个大步:

Step1

在公司机房执行灰度部署,分批部署导入生产流量,发现异常立即回滚。

Step2

在公有云A执行全量发布,但未接流;通过SLB规则配置,基于域名、规则的重要性、API的量级(调用量/周)制定规则级的SLB发布计划。公有云B部署同样重复此步骤。

可观测

观测的主要维度:业务和SLO、日志、性能

观测1:原公有云A应用流量切流后分布和成功率

图片

观测2:新公有云A应用流量切流后分布和成功率

图片

观测3:新公有云A应用错误码分布

图片

观测4:新公有云A应用API性能

图片

观测5:新公有云A应用JVM性能

图片

可恢复

1.公司机房应用执行灰度部署,如遇异常立即回滚,且不产生脏数据

2.新的公有云A/B应用,通过SLB基于规则分批发布,如遇异常立即回滚,回滚后流量指向原有对应机房服务集群,Redis写产生的脏数据不影响回滚后业务逻辑

3.新的公有云可用区,申请单独的Redis实例,用于隔离不同代码仓库,不同Key命名风格的数据,避免回滚过程中脏数据,对于原可用区服务的影响。

参考资料

  • 《B站安全生产专项建设实践》 https://mp.weixin.qq.com/s/tj1PEUWAyRZ1QzeW_oCWfg

  • 《重构 改善既有代码的设计》Martin Flower

  • 《Complexity Has to Live Somewhere》https://ferd.ca/complexity-has-to-live-somewhere.html

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

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

相关文章

解决跨域和https不能访问的问题。

本地安装了项目,是一键安装的,安装之后还是apache的web服务器,有个视频服务用的是https的服务,要对这个项目进行二次开发,本地调用没问题,可是别人已调用就跨域。只能本地访问。 现在有两个问题:1.解决跨域问题 2.还要解决https访问的问题。 解决思路,用nginx 的ssl证…

语雀如何显示 Markdown 语法

正常的文章链接 https://www.yuque.com/TesterRoad/t554s28/eds3pfeffefw12x94wu8rwer8o 访问后是文章,无法复制 markdown 的内容 在链接后增加参数 /markdown?plaintrue&linebreakfalse&anchorfalse 直接显示代码

力扣经典150题第三十题:长度最小的子数组

目录 力扣经典150题解析之三十:长度最小的子数组1. 介绍2. 问题描述3. 示例4. 解题思路方法一:滑动窗口 5. 算法实现6. 复杂度分析7. 测试与验证测试用例设计测试结果分析 8. 进阶9. 总结10. 参考文献感谢阅读 力扣经典150题解析之三十:长度最…

2024面试软件测试,常见的面试题(上)

一、综合素质 1、自我介绍 面试官您好,我叫XXX,一直从事车载软件测试,负责最多的是中控方面。 以下是我的一些优势: 车载的测试流程我是熟练掌握的,且能够独立编写测试用例。 平时BUG提交会使用到Jira,类似…

计算机组成原理【CO】Ch5 中央处理器

目录 大纲 一条指令的执行 取指令 执行指令 数据传送类(mov、load、store) 运算类指令(加、减、乘、除、移位、与、或) 转移类指令(jmp、jxxx) 如何看懂注释 袁版注释⻛格(16年以后的真题&…

草稿 | word格式的网址索引

参考文献引用 参考文献上标设置:(改为上标的快捷键为ctrlshift“”) https://jingyan.baidu.com/article/cbcede07d786c743f50b4d47.html 多个参考文献一起引用: https://blog.csdn.net/neptune4751/article/details/119921187 交…

记录一下因为没等配置文件上传完就跑lg.sh导致f2.sh没起作用的原因

【背景说明】 我正在学习sgg的数仓采集项目,采集内容分为用户行为日志采集和MySQL的业务数据采集。 用户行为日志采集分为2个阶段: 阶段1:将日志文件的数据通过flume采集到kafka。我的这一步正常,kafka上有数据,即f…

Springboot配置文件(application.yml)的加载顺序

spring boot 启动会扫描一下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件 file…/config/ file…/ classpath:/config classpath:/ 以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会…

Linux内核与基础命令学习总结

Linux操作系统 Linux操作系统博大精深,其中对线程,IO,文件系统等概念的实现都很有借鉴意义。 ​ 文件系统和VFS 文件系统的inode上面讲过了。VFS主要用于屏蔽底层的不同文件系统,比如接入网络中的nfs文件系统,亦或是w…

Pytest精通指南(20)日志收集器配置

文章目录 前言配置日志收集验证日志收集拓展-收集断言错误信息拓展-动态生成日志文件拓展-自定义封装日志收集类 前言 在pytest框架中,日志记录(logging)是一个强大的功能,它允许我们在测试期间记录信息、警告、错误等&#xff0c…

MongoDB扩大与谷歌云的合作,助推各行业客户部署和扩展新型应用

亮点前瞻 ● MongoDB Atlas Search Nodes现已在谷歌云(Google Cloud)上全面推出,让客户能够更轻松、更经济高效地隔离和扩展生成式AI工作负载 ●适用于MongoDB Atlas的Google Cloud Vertex AI扩展以及BigQuery与Spark的全新集成&#xff0c…

计算机软考流程介绍

笔者来介绍一下软考流程 1、考试简介 计算机技术与软件专业技术资格(水平)考试:简称 计算机软考 认证: 国家人力资源和社会保障部 国家工业和信息化部 目的: 科学、公正地对全国计算机与软件专业技术人员进行职业资格…

PolarDB MySQL 版 Serverless评测|一文带你体验什么是极致弹性|后续

PolarDB MySQL 版 Serverless评测|一文带你体验什么是极致弹性|后续 弹性压测三后续自动缩容全局一致性测试测评体验 在上一篇PolarDB MySQL 版 Serverless测评博文中:https://developer.aliyun.com/article/1385834 关于弹性压测三通过增加只读节点压测来观测到Ser…

流程图的新语法-mermaid的快速使用--推荐

chatgpt或者现在的大数据采用的流程图给出的代码如下: graph TD;A[接收客户请求] --> B[问题分类];B --> C[技术支持];B --> D[维修服务];C --> E[远程解决];C --> F[现场支持];D --> G[维修完成];G --> H[服务反馈];style A fill:#f9f,strok…

为什么学习C++之前学习C语言?

源地址:https://www.ctvol.com/c-cdevelopment/4074.html C 读作“C加加”,是“C Plus Plus”的简称。顾名思义,C 是在C语言的基础上增加新特性,玩出了新规则,所以叫“C Plus Plus”,还有C#,当然C#一般是针…

刻度清晰耐酸碱腐蚀PFA材质实验室用塑料量具特氟龙量筒量杯

PFA量筒为上下等粗的直筒状,特氟龙量杯是上大下小的圆台形,底座均有宽台设计,保证稳定性,两者均可在实验室中作为定量量取液体的量具,上沿一侧有弧嘴设计,便于流畅地倾倒液体。 规格参考:5ml、…

机器人路径规划:基于Q-learning算法的移动机器人路径规划,可以自定义地图,修改起始点,提供MATLAB代码

一、Q-learning算法 Q-learning算法是强化学习算法中的一种,该算法主要包含:Agent、状态、动作、环境、回报和惩罚。Q-learning算法通过机器人与环境不断地交换信息,来实现自我学习。Q-learning算法中的Q表是机器人与环境交互后的结果&#…

(十八)C++自制植物大战僵尸游戏的游戏暂停实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/uzrnw 游戏暂停 当玩家遇到突发事件,可以通过暂停功能暂停游戏,以便及时处理问题。在激烈的游戏中,玩家可能需要暂停游戏来进行策略调整。此外,长时间的游戏对战可能会让玩…

开源相机管理库Aravis例程学习(二)——连续采集multiple-acquisition-main-thread

开源相机管理库Aravis例程学习(二)——连续采集multiple-acquisition-main-thread 简介例程代码函数说明arv_camera_set_acquisition_modearv_camera_create_streamarv_camera_get_payloadarv_buffer_newarv_stream_push_bufferarv_camera_start_acquisi…