后台架构总结

前言

疫情三年,全国各地的健康码成为了每个人的重要生活组成部分。虽然过去一年,但是回想起来任然历历在目。

今天我就通过当时基于小程序的健康码架构,来给大家讲一下如何基于java,springboot等技术来快速搭建一个后台业务系统

本次“腾讯防疫健康码”小程序项目本身因为时间特别仓促,从1月28号启动,到2月1号开始部署其他地市,业务迭代非常快速,已经达到了和阿里的健康码直面竞争的态势,全国各个省市抢地盘。从健康上报,到抢口罩,到健康码,经历的几次主业务方向的调整,外加各种ISV的开发团队加入进来,面临更加严峻的问题就是微应急->健康码,用户量大增,并且加入了各省市互通的业务需求。

从最开始简单的“微应用” 式的后台开发模式,一直没有进行架构上的调整与设计,导致中后期开始出现在研发技术,以及合作研发方面的各种问题,所以本次项目在架构上并不是很理想,于是我想是否能够根据以往经验,梳理总结一套能够更大众的框架。

声明:因为我们团队在docker方面,以及云原生,小程序云开发方面没有丰富的积累,所以本次项目依然使用的java的springboot框架进行服务开发,部署在腾讯云的虚拟机上。

先说一句:好的架构不是设计出来的,而是演进出来的

一、健康码架构简述

本次开发服务全部都是基于腾讯云开发,其中使用waf,clb,cdn,redis,mysql,es,cos等中间件已经作为成熟的解决方案。在这里就不再赘述。

下图为 部署架构:

1.1、本框架设计优点:

1、小程序服务链路与管理后台服务,口罩服务通过使用clb进行链路分离,根据服务属性区分开,思路清晰

2、使用rio智能网关,其中api网关有效的进行了限流,并能统计接口以及接口安全防护,保护了后台的服务,API网关用来注册接口,实现了可扩展与第三方接入等,但是api网关是在很后期加入了。

3、数据库和redis使用了分库设计,根据不同业务进行了分库,减缓部分压力。

1.2、本项目暴露的问题:

通过以上图的架构,我们也会发现:

1、没有加服务发现的能力,导致后期服务的扩展性很差, 同事带来以下几个问题

2、因为没有服务发现,那么应用层是按照模块的一个个单体服务,没有进行分层设计,出现的问题就是不同的服务可能同样的代码在多个服务上出现,明明是加一个接口的问题就可以解决的问题。

2.1 比如调用API网关是需要配置paasid和token的,如果没有加一个代理proxy层,那么所有调用网关的服务一旦修改token就要全部修改服务重启

2.2 比如同一张表,多个服务同时操作,就会出现字段乱修改,而互相没有告知对方,就会出现各种服务上的莫名其妙的bug

3、没有面向服务的开发模式,一些能力参差不齐的开发商,随意操作公共部分能力,尤其是处于性能瓶颈的数据库,第三方外部接口等。

4、应用或者服务过多,就会带来在管理应用,以及配置发布变更带来了巨大的挑战。

二、健康码登录以及基本请求流程

下图主要是描述用户登录小程序以及登录后请求到我们的业务服务模块。

其中流程中已经省略准入网关一层,因为目前我们的网关主要是用来限流,并没有校验登录态或者说拦截登录的能力。接下来主要讲整个登录以及如何做第第一笔业务。

  • account服务,主要是用来通过微信小程序的jscode ,去微信服务器换取用户的openi,以及sessionkey,同时会生成用户的唯一会话ID,以及用户我们系统的useid,进行关联,接下来通过session_key信息等来解析用户的电话号码,我们微应急通过是否有电话来确认用户登录完成。

  • 业务请求,当header存在登录态的时候,请求业务接口api,http的header会存有一个sessionid,业务层通过拦截器的功能,获取sessionid,通过协商好的get sessionid 获取临时登录信息,存在表示在有效期,不存在直接返回用户未登录的的状态码。

通过以上表述,我们可以看到,用户登录态校验也是在每个业务应用进行校验,也就是说每次请求都必须经过一次redis的get处理。我们通过一个公共的第三方jar包的形式加入到各个应用中。

这就带来两个问题:

1、每次请求都会get一次redis,这回对redis带来一定的压力,虽然目前这个瓶颈还没遇到

2、通过业务层的拦截器方式,一旦common包修改,就要对所有应用进行重新编译处理。

通过分析,我们可以发现,在这种“微应用模式”下的架构,尤其是在有各种ISV,第三方开发服务商,个人能力不是很强的情况下,加入进来的时候,并不是一种优秀的开发模式,尤其中间还没有进行及时的架构调整,因此通过我个人的过往项目开发经历,来简述一下架构经验。

三、腾讯短信后台架构

我在16年-18年参与的短信后台架构,针对当时已有老的短信架构进行深度的重构,基于taf的c++框架进行开发,充分利用了taf的综合解决方案,服务发现以及dcache等,还有使用公司的cmq消息队列对服务充分的解耦等技术。请看下图:

这个是重构后的一个目前使用的新架构,绿色箭头所指服务为下发短信的主服务调用链条。逻辑层与接入层和内部之间的服务均为taf调用。按照功能与逻辑进行了解耦和拆分。

2.1、产品接入层:

提供了tcp协议,http/https的标准协议,以及基于taf的jce协议。并提供了c++版本,java,php等多语言服务 频率限制服务:用来控制每个业务的每秒的发送速率。默认100.

2.2、逻辑层

这个层是主要对短信处理的业务逻辑层。

1、短信下行服务:短信下行收到接入层的短信后,进行编解码,长短信拆分,脏词过滤,短信签名,分配端口等等逻辑处理。

2、流量控制服务:而流量控制服务主要是用来针对某条短信是用来选择一个最优的通道号,如果端口挂了也会通过它控制。接下来会着重讲述这块服务是如何进行选择最优的一个接入号的

3、短信数据服务:主要功能有,对短信的存储,匹配,采集数据,统计等一系列工作。为流量控制提供数据支持依据。而数据服务的数据源就是从网关处取得

4、异常服务 :主要用来在下发错误短信后,如没有下发成功后,通知到业务方 上行服务:有一些业务需要用户发送一些业务代码,我们这里需要进行转发工作。

5、分发路由服务:因为短信是按照通道号进行下发,运营商网关负责连接到对应的特定的运营商。因此该服务就是负责对应通道号的短信派发到指定的网关接入层。

2.3、运营商接入层

1、接入服务,负责维持和所有供应商的网络连接服务。 调度模块:就是用来管理多个网关服务的之间的故障处理,负载均衡,容错等一系列操作。

2、预处理服务:通过cmq和接入层解耦,将所有短信都丢在预处理层进行记录,预处理保存所有短信记录,使用TDSQL进行分库分表

3、管理层:提供的是一个可视化的管理信息系统,比如查询短信下发后记录的客服查询系统。给营销短信提供操作的营销平台。等等

以上新架构,在未来各种多样的业务需求下,通过服务扩展等方式来加以轻松的支持

2.4 、TAF的框架介绍

目前taf在内网已经非常成熟了,而且各个部门都有在使用,集成开发,运维,部署等一体的解决方案,也同时支持了docker等能力

目前外网开源的版本叫tars,基本的功能都已经具备了。

四、电子签章架构

电子签章项目是我18年-19年的在数字广东的一个子项目,历时五个月,作为技术负责人,带领几个外包和实习生等人员开发,也是做了对整个业务分析,技术架构等进行了详细分解和架构。该项目主要是基于golang开发,并且我们当时搭建了一个完整的基于golang的框架。

曾经也简单的总结过,文章连接:http://km.woa.com/group/38350/articles/show/369458 ,项目过程以及内容不再过多描述

服务应用结构:

我在这里主要是简述和应用层内容:

1、使用了基于etcd的服务发现以及统一配置管理,做到服务统一管理以及配置发布。

2、接入层api网关,可以理解为nginx以及api路由,用来实现和外部接口暴露的安全接入。

3、使用数据库代理层,保证数据库层压力以及使用事物等

4、第三方服务,比如我们会用到小信科技与国脉的接口,封装在同一层,保证了只修改协议适配层即可,业务逻辑层不用大动干戈。

五、“数据ai中台”项目架构

当前,我正在负责研发 基于多种大数据套件 平台的机器学习训练平台以及人工智能方面的平台性质的项目,比如腾讯的TBDS,华为的fusioninsght,以及CDH等平台,几乎都要深度的使用他们的开放的api接口能力。该项目团队最多时候20多人,我作为技术负责人,负责整个项目技术方面的工作。

项目也是考虑了方方面面的设计,因为是属于tob项目,会根据部署以及不同环境要求,都会有个性化的系统配置等,因此使用了通知数据库代理配置,第三方接口适配层。

因此我们有了如下的功能架构:

我这边进行了清晰的对架构分层设计,业务服务模块必须调用组件层的api接口来完成业务逻辑。保证了可以适配不通的大数据平台,依然能够使用。

  • 1、API-GATEWAY

    作为ng的下一层,挂着所有服务的入口,同时所有的请求的登录态都在改层完成校验完成,可以适配不同套件的用户接入,当一个请求进入的时候,会根据session换取user_id,放到头部,传递到下一层业务逻辑。同时也完成基本的流量控制,鉴权等能力

  • 2、微服务层-业务逻辑

    微服务层会暴露所有的api接口在 gateway上,包括模型训练,模型部署,模型编排,应用管理,系统参数配置,作业管理,发布服务等所有接口操作

  • 微服务层-公共组件与代理

    服务对数据库的操作以及对大数据的暴露的API接口的调用,全部都是通过用代理层

六、优化我们的“健康码”项目架构

通过以上架构的总结,其实我想通过以往的架构设计经验,来如何优化我们本次”防疫健康码“架构,以及在一些技术点上的优化,下面我来主要介绍我的想法。

6.1、必须要引入网关能力

在我最近三年经历的的服务总结,我们发现,目前所有项目几乎都是微服务形式,因此必须要有网关,以及服务发现的能力,所以,我们简单总结:

服务网关 = 路由转发 + 过滤器+...

引入网关的基本简图如下:

  • 1、服务网关、open-service和service启动时注册到注册中心上去;

  • 2、用户请求时直接请求网关,网关做智能路由转发(包括服务发现,负载均衡)到open-service,这其中包含权限校验、监控、限流等操作

  • 3、open-service聚合内部service响应,返回给网关,网关再返回给用户

    其中

    • 智能路由:接收外部一切请求,并转发到后端的对外服务open-service上去;

      • 注意:我们只转发外部请求,服务之间的请求不走网关,这就表示全链路追踪、内部服务API监控、内部服务之间调用的容错、智能路由不能在网关完成;当然,也可以将所有的服务调用都走网关,那么几乎所有的功能都可以集成到网关中,但是这样的话,网关的压力会很大,不堪重负。

    • 权限校验:只校验用户向open-service服务的请求,不校验服务内部的请求。服务内部的请求有必要校验吗?

    • API监控:只监控经过网关的请求,以及网关本身的一些性能指标(例如,gc等);

    • 限流:与监控配合,进行限流操作;

    • API日志统一收集:类似于一个aspect切面,记录接口的进入和出去时的相关日志

综上:在做任何大型项目,使用网关+注册中心是必要的。

6.2 、能用缓存必须要用

在本次项目中,因为在对ISV的开发同学的技术能力不甚了解,因此在review代码中,出现了大量的,几乎都是直接连接mysql数据库进行业务逻辑操作,甚至出现了多表联合查询的情况发生。让人痛心不已,果然在将服务上线后,尤其以省级项目的时候,政府大力宣传,出现了服务各种不可用,数据库最终成为最大瓶颈。

因此,在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用机器内存或者redis做一个缓冲操作,让请求先访问到redis,而不是直接访问Mysql等数据库。这样可以大大缓解数据库的压力。

按缓存类型可以分为:

1、本地缓存:不需要序列化,速度快,缓存的数量与大小受限于本机内存,很多语言提供一些框架来支持内存缓存,例如 guava cache,spring默认集成的 Ehcache。

2、分布式缓存:需要序列化,速度相较于本地缓存较慢,但是理论上缓存的数量与容量无限制(因为分布式缓存机器可以不断扩展),常见的分布式缓存包括 Redis 和 Memcache,本次使用了腾讯云的集群redis。

但是在使用缓存也要注意很多方面,比如缓存击穿,缓存以及mysql的一致性问题,避免方案有很多,比如双删,根据场景设置过期时间等等手段,在这里不一一详述。

6.3、索引必须优化

本次项目,我们也发现大量的sql语句没有命中索引:一方面java的很多同学喜欢使用多表联合查询,一方面没有那种在高并发大流量的情况下优化索引的意识,这两点在类toc项目中导致非常致命的性能问题。

每次评审,我都会要开发同学对sql进行explain的优化。

因此,我对mysql的索引原理以及优化,进行过一次讲座:

ppt链接:http://km.woa.com/group/27940/attachments/attachment_view/161143

6.4、解耦一定要用队列

伴随着业务的复杂,我们往往会遇到这个场景,一个数据操作后,需要触发下游若干个子操作。本次我们的项目使用rabbitmq,我在短信项目使用了公司内部的cmq的队列服务,效果是非常好的。

我们可以把消息队列(MQ)比作是一个存放消息的容器,Producer 负责生产消息,将消息发送到MQ,Consumer取出消息供自己使用。

我在这里是强烈推荐腾讯云的ckafka,稳定高效,金融级别的队列服务,如下图

腾讯云上也有同样的服务能力。

6.5 、如何优雅的拆分服务

在拆分我们微服务的的时候,我个人认为并不是完全的微服务化,将服务拆的很细,所以,经过我各种总结:

总结一下我的思路与原则:

1、分离服务中占用系统资源(cpu,内存,IO等)较多的功能,独立成服务器,屏蔽性能瓶颈,比如实现实现数据库代理层因为涉及到磁盘+网络的io,实现接口代理层,因为涉及到网络,

2、在同一服务器架构下的不同模块,应尽可能的复用某些服务器(进程服务级别的复用)。比如读取配置,统一出口。

3、以多线程并发的编程方式适应多核处理器。

4、宁可在服务器之间多复制数据,也要保持清晰的数据流向。

5、主要按照场景划分进程,若需按功能划分,必须保持整个逻辑足够的简单,并满足以上1,2点。

6.6、“防疫健康码“理想架构

经过以上总结与整理,我想本次的后台架构应该都是这个样子。

 

以上,是基于sprigcloud技术栈实现的技术架构图,包含了服务发现节点,统一配置节点,以及认证等基础设施。在服务集群模块,往往是比实际更加复杂。

七、总结

说了以上那么多,总结两点就是

1、如何能够搭建好一个好的后台项目架构

2、如何能够写出优雅的代码

在架构层次,一般分为:业务架构、技术架构、应用架构、部署架构,不同的架构关注面不一样。

业务架构:业务提供的能力,业务能做什么;

技术架构:技术领域解决问题,如存储、计算等;

应用架构:应用之间的关系;

部署架构:应用实际是怎样部署的,不同机房等。

所谓的软件架构,是对业务进行理解并设计,不同业务使用不同的软件架构,要画出一个概貌图出来表示这个系统有哪些关键部分,通过这些关键部分组成的骨架可以看到整个系统的扭转流程。

健壮的代码方面就需要多多看一些优秀的开源代码,多多总结实践。

综上述:架够是一种全局,代表了整体的方向,如果大方向出错了,即使再多的努力也是没有用的。

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

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

相关文章

CMUS狮身人面像(四)-构建语言模型

构建语言模型 语言模型是配置的重要组成部分,它告诉解码器可以识别哪些单词序列。 模型有多种类型:关键词列表、语法和统计语言模型以及语音语言模型。它们具有不同的功能和性能特性。您可以根据需要选择任何解码模式,甚至可以在运行时在模…

Python基础知识—函数(五)

🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 一:函数基础1.1函数的定义和调用1.2函数的定义格式1.3函数的调用格式1.4第一个函数 二:函数的文档注释三:函数的参数3.1参数的定义和…

Pixelmator Pro for Mac:简洁而强大的图像编辑软件

Pixelmator Pro for Mac是一款专为Mac用户设计的图像编辑软件,它集简洁的操作界面与强大的功能于一身,为用户提供了卓越的图像编辑体验。 Pixelmator Pro for Mac v3.5.9中文激活版下载 该软件支持多种文件格式,包括常见的JPEG、PNG、TIFF等&…

系统触发器

目录 数据库触发器 常见触发器,记录登录和退出数据库事件 模式触发器 创建一个模式触发器,记录各种 DDL 操作的日志 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 前面已经介绍过,…

WEB攻防-PHP特性-函数缺陷对比

目录 和 MD5函数 intval ​strpos in_array preg_match str_replace 和 使用 时,如果两个比较的操作数类型不同,PHP 会尝试将它们转换为相同的类型,然后再进行比较。 使用 进行比较时,不仅比较值,还比较变量…

MATLAB非均匀网格梯度计算

在matlab中,gradient函数可以很方便的对均匀网格进行梯度计算,但是对于非均匀网格,但是gradient却无法求解非均匀网格的梯度,这一点我之前犯过错误。我之前以为在gradient函数中指定x,y等坐标,其求解的就是…

秋招后端开发面试题 - Java集合

目录 Java集合前言面试题Java 集合?说说 List、Set、Queue、Map 四者的区别?集合框架底层数据结构总结?ArrayList 和 Vector 的区别?ArrayList 与 LinkedList 区别?ArrayList 核心扩容机制?ArrayList 怎么序列化的知道吗&#x…

Metasploit 溢出 samba 提权漏洞

一、信息收集 1.1 右键单击桌面,选择 Open Terminal Here ,打开终端。 1.2 输入命令 nmap -sS -p 139,445 -A 192.168.1.254 ,对目标主机进行扫描,发现 139、445 端口开放。 1.3 输入命令“msfconsole”,启动 MSF 终端。 1.4 输入命令“searc…

电脑录制视频快捷键,一键开启录屏新时代(干货)

“最近尝试录制一些电脑上的操作视频,用来制作教学教程。不过,每次录制都要通过菜单或搜索来打开录屏软件,实在是有些繁琐。有没有人知道哪些电脑录制视频的快捷键呀?或者有没有通用的快捷键设置方法?” 在当今数字时…

Elasticsearch索引状态管理实战指南

在维护Elasticsearch集群的过程中,有效地管理索引状态对于确保系统性能、节省资源以及优化数据处理流程至关重要。本文将深入介绍Elasticsearch提供的关键索引管理操作,包括清空缓存、刷新索引、冲洗索引、强制合并、关闭索引及冻结索引等,帮…

免费语音转文字:自建Whisper,贝锐花生壳3步远程访问

Whisper是OpenAI开发的自动语音识别系统(语音转文字)。 OpenAI称其英文语音辨识能力已达到人类水准,且支持其它98中语言的自动语音辨识,Whisper神经网络模型被训练来运行语音辨识与翻译任务。 此外,与其他需要联网运行…

MySQL中脏读与幻读

一般对于我们的业务系统去访问数据库而言,它往往是多个线程并发执行多个事务的,对于数据库而言,它会有多个事务同时执行,可能这多个事务还会同时更新和查询同一条数据,所以这里会有一些问题需要数据库来解决 我们来看…

centos 7使用源码编译安装Python 3.12.2(最新版本)

(一)、说明 在centos 7上,默认安装出来的python是:2.7.5版本 1.查看python版本: python --version 2.通过yum安装出来的,适合当前操作系统的,最新的python版本是:3.6.8 python3…

python代码实现KNN对鸢尾花的分类

一、KNN模型-KNeighborsClassifier() 1.1 导入sklearn第三方库 from sklearn import datasets #sklearn的数据集 from sklearn.neighbors import KNeighborsClassifier #sklearn模块的KNN类我们使用一个叫作鸢尾花数据集的数据,这个数据集里面有 150 条数据&#…

身份证实名认证接口守护账号安全、实名认证接口Java开发示例

身份证实名认证接口就是网民账号的贴身保镖,只需简单几步操作,即可实现高效、精准的身份验证,从此告别信息泄露的恐慌!无论是线上交易、社交互动还是各类服务注册,都能确保你是独一无二的你! 翔云身份证实…

IP Transit作为一种网络服务

IP Transit作为一种网络服务,通过BGP(边界网关协议)对接,将用户的IP地址段与全球互联网进行连接,实现用户自有IP地址段在全球互联网的穿透。这种服务在中国境外,特别是在AS4837/AS10099网络平台上得到了广泛…

云手机对出海企业有什么帮助?

近些年,越来越多的企业开始向海外拓展,意图发掘更广阔的市场。在这过程中,云手机作为一个新型工具为很多企业提供了助力,尤其在解决海外市场拓展过程中的诸多挑战方面发挥着作用。 首先,云手机的出现解决了企业在海外拓…

【Linux系统化学习】死锁 | 线程同步

目录 死锁 死锁的必要条件 避免死锁 线程同步 条件变量 同步概念和竞态条件 条件变量接口 创建和初始化条件变量 等待条件满足 唤醒等待 毁条件变量 为什么 pthread_cond_wait 需要互斥量? 条件变量使用规范 等待条件代码 给条件发送信号代码 死锁 死锁是指在一…

扭蛋机小程序带来了什么优势?扭蛋机收益攻略

在当下的潮流消费时代,人们对潮玩也日益个性化,扭蛋机作为一种新型的娱乐消费模式,深受大众喜爱。扭蛋机的价格低,各个年龄层的玩家都可以进行购买,潜在玩家量非常大。扭蛋机商品主打热门IP周边等,种类繁多…

SQL注入攻击:原理与防御策略

SQL注入攻击:原理与防御策略 目录 SQL注入攻击:原理与防御策略 一、SQL注入简介 二、攻击语句原型 三、技术分析与深度挖掘 四、防御策略与最佳实践 五、案例研究与实际应用 一、SQL注入简介 定义与原理 SQL注入是一种攻击技术,通过在…