【Java面试场景题】如何优化系统架构设计来缓解流量压力提升并发性能?

news2024/11/16 10:47:05

一、问题解析

我会以直播互动为例,带你看看读多写多的情况下如何应对流量压力。- 一般来说,这种服务多数属于实时互动服务,因为时效性要求很高,导致很多场景下,我们无法用读缓存的方式来降低核心数据的压力。所以,为了降低这类互动服务器的压力,我们可以从架构入手,做一些灵活拆分的设计改造。

事实上这些设计是混合实现对外提供服务的,为了让你更好地理解,我会针对直播互动里的特定的场景进行讲解。一般来说,直播场景可以分为可预估用户量和不可预估用户量的场景,两者的设计有很大的不同,我们分别来看看。

29.1 可预估用户量的服务:游戏创建房间

相信很多玩对战游戏的伙伴都有类似经历,就是联网玩游戏要先创建房间。这种设计主要是通过设置一台服务器可以开启的房间数量上限,来限制一台服务器能同时服务多少用户。

我们从服务器端的资源分配角度分析一下,创建房间这个设计是如何做资源调配的。创建房间后,用户通过房间号就可以邀请其他伙伴加入游戏进行对战,房主和加入的伙伴,都会通过房间的标识由调度服务统一分配到同一服务集群上进行互动。

这里我提示一下,开房间这个动作不一定需要游戏用户主动完成,可以设置成用户开启游戏就自动分配房间,这样做不但能提前预估用户量,还能很好地规划和掌控我们的服务资源。

如何评估一个服务器支持多少人同时在线呢?

我们可以通过压测测出单台服务器的服务在线人数,以此精确地预估带宽和服务器资源,算出一个集群(集群里包括若干服务器)需要多少资源、可以承担多少人在线进行互动,再通过调度服务分配资源,将新来的房主分配到空闲的服务集群。

最后的实现效果如下所示:

如上图所示,在创建房间阶段,我们的客户端在进入区域服务器集群之前,都是通过请求调度服务来进行调度的。调度服务器会定期接收各组服务器的服务用户在线情况,以此来评估需要调配多少用户进入到不同区域集群;同时客户端收到调度后,会拿着调度服务给的token去不同区域申请创建房间。

房间创建后,调度服务会在本地集群内维护这个房间的列表和信息,提供给其他要加入游戏的玩家展示。而加入的玩家同样会接入对应房间的区域服务器,与房主及同房间玩家进行实时互动。

这种通过配额房间个数来做服务器资源调度的设计,不光是对战游戏里,很多场景都用了类似设计,比如在线小课堂这类教学互动的。我们可以预见,通过这个设计能够对资源做到精准把控,用户不会超过我们服务器的设计容量。

29.2 不可预估用户量的服务

但是,有很多场景是随机的,我们无法把控有多少用户会进入这个服务器进行互动。

全国直播就无法确认会有多少用户访问,为此,很多直播服务首先按主播过往预测用户量。通过预估量,提前将他们的直播安排到相对空闲的服务器群组里,同时提前准备一些调度工具,比如通过控制曝光度来延缓用户进入直播,通过这些为服务器调度争取更多时间来动态扩容。

由于这一类的服务无法预估会有多少用户,所以之前的服务器小组模式并不适用于这种方式,需要更高一个级别的调度。

我们分析一下场景,对于直播来说,用户常见的交互形式包括聊天、答题、点赞、打赏和购物,考虑到这些形式的特点不同,我们针对不同的关键点依次做分析。

29.2.1 聊天:信息合并

聊天的内容普遍比较短,为了提高吞吐能力,通常会把用户的聊天内容放入分布式队列做传输,这样能延缓写入压力。

另外,在点赞或大量用户输入同样内容的刷屏情境下,我们可以通过大数据实时计算分析用户的输入,并压缩整理大量重复的内容,过滤掉一些无用信息。

压缩整理后的聊天内容会被分发到多个聊天内容分发服务器上,直播间内用户的聊天长连接会收到消息更新的推送通知,接着客户端会到指定的内容分发服务器群组批量拉取数据,拿到数据后会根据时间顺序来回放。请注意,这个方式只适合用在疯狂刷屏的情况,如果用户量很少可以通过长链接进行实时互动。

29.2.2 答题:瞬时信息拉取高峰

除了交互流量极大的聊天互动信息之外,还有一些特殊的互动,如做题互动。直播间老师发送一个题目,题目消息会广播给所有用户,客户端收到消息后会从服务端拉取题目的数据。

如果有10w用户在线,很有可能导致瞬间有10w人在线同时请求服务端拉取题目。这样的数据请求量,需要我们投入大量的服务器和带宽才能承受,不过这么做这个性价比并不高。

理论上我们可以将数据静态化,并通过CDN阻挡这个流量,但是为了避免出现瞬时的高峰,推荐客户端拉取时加入随机延迟几秒,再发送请求,这样可以大大延缓服务器压力,获得更好的用户体验。

切记对于客户端来说,这种服务如果失败了,就不要频繁地请求重试,不然会将服务端打沉。如果必须这样做,那么建议你对重试的时间做退火算法,以此保证服务端不会因为一时故障收到大量的请求,导致服务器崩溃。

如果是教学场景的直播,有两个缓解服务器压力的技巧。第一个技巧是在上课当天,把抢答题目提前交给客户端做预加载下载,这样可以减少实时拉取的压力。

第二个方式是题目抢答的情况,老师发布题目的时候,提前设定发送动作生效后5秒再弹出题目,这样能让所有直播用户的接收端“准时”地收到题目信息,而不至于出现用户题目接收时间不一致的情况。

至于非抢答类型的题目,用户回答完题目后,我们可以先在客户端本地先做预判卷,把正确答案和解析展示给用户,然后在直播期间异步缓慢地提交用户答题结果到服务端,以此保证服务器不会因用户瞬时的流量被冲垮。

29.2.3 点赞:客户端互动合并

对于点赞的场景,我会分成客户端和服务端两个角度带你了解。

先看客户端,很多时候,客户端无需实时提交用户的所有交互,因为有很多机械的重复动作对实时性要求没那么高。

举个例子,用户在本地狂点了100下赞,客户端就可以合并这些操作为一条消息(例如用户3秒内点赞10次)。相信聪明如你,可以把互动动作合并这一招用在更多情景,比如用户连续打赏100个礼物。

通过这个方式可以大幅度降低服务器压力,既可以保证直播间的火爆依旧,还节省了大量的流量资源,何乐而不为。

29.2.4 点赞:服务端树形多层汇总架构

我们回头再看看点赞的场景下,如何设计服务端才能缓解请求压力。

如果我们的集群QPS超过十万,服务端数据层已经无法承受这样的压力时,如何应对高并发写、高并发读呢?微博做过一个类似的案例,用途是缓解用户的点赞请求流量,这种方式适合一致性要求不高的计数器,如下图所示:

这个方式可以将用户点赞流量随机压到不同的写缓存服务上,通过第一层写缓存本地的实时汇总来缓解大量用户的请求,将更新数据周期性地汇总后,提交到二级写缓存。

之后,二级汇总所在分片的所有上层服务数值后,最终汇总同步给核心缓存服务。接着,通过核心缓存把最终结果汇总累加起来。最后通过主从复制到多个子查询节点服务,供用户查询汇总结果。

另外,说个题外话,微博是Redis重度用户,后来因为点赞数据量太大,在Redis中缓存点赞数内存浪费严重,改为自行实现点赞服务来节省内存。

29.2.5 打赏&购物:服务端分片及分片实时扩容

前面的互动只要保证最终一致性就可以,但打赏和购物的场景下,库存和金额需要提供事务一致性的服务。

因为事务一致性的要求,这种服务我们不能做成多层缓冲方式提供服务,而且这种服务的数据特征是读多写多,所以我们可以通过数据分片方式实现这一类服务,如下图:

看了图是不是很好理解?我们可以按用户id做了 hash拆分,通过网关将不同用户uid取模后,根据范围分配到不同分片服务上,然后分片内的服务对类似的请求进行内存实时计算更新。

通过这个方式,可以快速方便地实现负载切分,但缺点是hash分配容易出现个别热点,当我们流量扛不住的时候需要扩容。

但是hash这个方式如果出现个别服务器故障的话,会导致hash映射错误,从而请求到错误的分片。类似的解决方案有很多,如一致性hash算法,这种算法可以对局部的区域扩容,不会影响整个集群的分片,但是这个方法很多时候因为算法不通用,无法人为控制,使用起来很麻烦,需要开发配套工具。

除此之外,我给你推荐另外一个方式——树形热迁移切片法,这是一种类似虚拟桶的方式。

比如我们将全量数据拆分成256份,一份代表一个桶,16个服务器每个分16个桶,当我们个别服务器压力过大的时候,可以给这个服务器增加两个订阅服务器去做主从同步,迁移这个服务器的16个桶的数据。

待同步迁移成功后,将这个服务器的请求流量拆分转发到两个8桶服务器,分别请求这两个订阅服务器继续对外服务,原服务器摘除回收即可。

服务切换成功后,由于是全量迁移,这两个服务同时同步了不属于自己的8个桶数据,这时新服务器遍历自己存储的数据,删除掉不属于自己的数据即可。当然也可以在同步16桶服务的数据时,过滤掉这些数据,这个方法适用于Redis、MySQL等所有有状态分片数据服务

这个服务的难点在于请求的客户端不直接请求分片,而是通过代理服务去请求数据服务,只有通过代理服务才能够动态更新调度流量,实现平滑无损地转发流量。

最后,如何让客户端知道请求哪个分片才能找到数据呢?我给你分享两个常见的方式:

第一种方式是,客户端通过算法找到分片,比如:用户 hash(uid) % 100 = 桶id,在配置中通过桶id找到对应分片。

第二种方式是,数据服务端收到请求后,将请求转发到有数据的分片。比如客户端请求A分片,再根据数据算法对应的分片配置找到数据在B分片,这时A分片会转发这个请求到B,待B处理后返回给客户端数据(A返回或B返回,取决于客户端跳转还是服务端转发)。

29.3 服务降级:分布式队列汇总缓冲

即使通过这么多技术来优化架构,我们的服务仍旧无法完全承受过高的瞬发流量。

对于这种情况,我们可以做一些服务降级的操作,通过队列将修改合并或做网关限流。虽然这会牺牲一些实时性,但是实际上,很多数字可能没有我们想象中那么重要。像微博的点赞统计数据,如果客户端点赞无法请求到服务器,那么这些数据会在客户端暂存一段时间,在用户看数据时看到的只是短期历史数字,不是实时数字。

十万零五的点赞数跟十万零三千的点赞数,差异并不大,等之后服务器有空闲了,结果追上来最终是一致的。但作为降级方案,这么做能节省大量的服务器资源,也算是个好方法。

二、粉丝福利

我根据我从小白到架构师多年的学习经验整理出来了一份50W字面试解析文档、简历模板、学习路线图、java必看学习书籍 、 需要的小伙伴斯我“159”,或者评论区扣“求分享

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

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

相关文章

B端系统:配置页面如何设计,这可是用户体验的关键的关键。

提升配置页面体验的十大原则 设计B端系统的配置页面时,用户体验确实是非常关键的。以下是一些设计原则和建议,可以帮助提高配置页面的用户体验: 简洁明了:配置页面应该尽量简洁明了,避免过多的复杂选项和信息。使用清…

基于先验知识引导的三域Transformer-GAN,直接从低计数正电子发射断层扫描图像重建| 文献速递-先进深度学习疾病诊断

Title 题目 Prior Knowledge-guided Triple-Domain Transformer-GAN for Direct PET Reconstruction from Low-Count Sinograms 基于先验知识引导的三域Transformer-GAN,用于直接从低计数正电子发射断层扫描图像重建 01 文献速递介绍 正电子发射断层扫描&…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-38实战Kaggle比赛:图像分类 (CIFAR-10)

38实战Kaggle比赛:图像分类 (CIFAR-10) 比赛链接:CIFAR-10 - Object Recognition in Images | Kaggle 导入包 import os import glob import pandas as pd import numpy as np import torch import torchvision from torch.utils.data import Dataset…

【应届应知应会】Linux常用指令

SueWakeup 个人主页:SueWakeup 系列专栏:学习技术栈 个性签名:保留赤子之心也许是种幸运吧 本文封面由 凯楠📸友情提供 目录 文件与目录管理 目录操作命令: ls [选项] [目录或文件] mkdir 文件操作命令&#xf…

MacOS java多版本安装与管理

安装sdkman curl -s "https://get.sdkman.io" | bashsource "$HOME/.sdkman/bin/sdkman-init.sh"sdk version正常出现sdkman版本号就安装成功了 # 安装java # 安装java8 sdk install java 8.0.412.fx-zulu建议和上述一样安装 fx-zulu 的jdk&#xff0c…

谷歌SEO在外贸推广中的应用效果如何?

谷歌SEO在外贸推广中非常有效。通过优化网站,可以提高在搜索结果中的排名,这意味着更多的潜在客户会看到你的产品和服务。 一个高排名的网站能带来更多自然流量,不需要花费广告费用。这种流量通常质量较高,因为用户是主动搜索相关…

【仿真建模-anylogic】Scale解析

Author:赵志乾 Date:2024-06-27 Declaration:All Right Reserved!!! 1. 应用场景 Scale是比例尺,用于长度单位和像素之间的换算,anylogic默认为每个agent生成一个scale,…

1.iptables

iptables 防火墙iptables工作流程iptables表与链filter表nat表 防火墙 防火墙开源iptables、firewalld管理控制网络流量、封端口、封IP、nat、(snat、dnat)映射 共享上网硬件防火墙思科、华三等、深信服、路由器内置防火墙保护内部网络、检测和阻挡恶意…

ISO 50001能源管理体系:激活绿色动能和共塑可持续发展

在当今全球化加速和工业化水平不断提高的背景下,能源消费呈现出前所未有的增长趋势。然而,能源资源的有限性、能源价格的波动以及能源消费对环境造成的影响,尤其是温室气体排放导致的全球气候变化问题,已经成为全球关注的焦点。为…

C++之STL(十二)

1、容器适配器 #include <iostream> #include <stack> #include <list> #include <queue> #include <functional> #include <iterator>using namespace std;int main() {// 栈&#xff08;先进后出filo&#xff09;stack<int, list<…

Linux-笔记 嵌入式gdb远程调试

目录 前言 实现 1、内核配置 2、GDB移植 3、准备调试程序 4、开始调试 前言 gdb调试器是基于命令行的GNU项目调试器&#xff0c;通过gdb工具我们可以实现许多调试手段&#xff0c;同时gdb支持多种语言&#xff0c;兼容性很强。 在桌面 Linux 系统&#xff08;如 Ubuntu、Cent…

基于SpringBoot校园一卡通系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; Java精品实战案例《600套》 2023-2025年最值得选择的Java毕业设计选题大全&#xff1…

Zabbix对接Elasticsearch(ES)数据库(未成功)

0.需求分析 不管zabbix的后端数据库是oracle还是mysql&#xff0c;当zabbix监控的量级达到了一定程度后&#xff0c;那么对数据库的性能是一个非常严峻的挑战。特别是对历史数据的查询&#xff0c;将会变得非常非常的慢&#xff0c;别告诉我可以建索引优化&#xff0c;当量级达…

信创数据库沙龙(上海站 | 报名中)

信创数据库沙龙: 是一个致力于推动数据库技术创新和发展的高端交流平台&#xff0c;旨在增强国内数据库产业的自主可控性和高质量发展。这个平台汇集了学术界和产业界的顶尖专家、学者以及技术爱好者&#xff0c;通过专题演讲、案例分享和技术研讨等丰富多样的活动形式&#x…

常见Web认证方式对比

认证是一个在用户或者设备在访问一个受限的系统时&#xff0c;鉴定用户凭据的过程&#xff0c;即确认“你是谁”的问题。最常见的认证用户的方式是通过用户名和密码的形式进行校验&#xff0c;目前存在多种校验方式&#xff0c;本文将对其进行一个简单的对比&#xff0c;使得大…

“数字政协”平台如何提高政协工作效率?正宇软件助力建设!

随着信息技术的飞速发展&#xff0c;数字化已成为推动各行各业转型升级的重要力量。在政协工作中&#xff0c;数字政协平台的建设与运用&#xff0c;正成为提高政协工作效率、促进民主协商的重要手段。本文将从数字政协平台的功能特点、优势分析以及实践应用等方面&#xff0c;…

6.26.7 两阶段卷积神经网络在乳腺癌组织学图像分类中的应用

本文探讨了乳腺组织显微图像的分类问题。根据主要的癌症类型&#xff0c;目标是将图像分为四类:正常、良性、原位癌和浸润性癌。给定合适的训练数据集&#xff0c;利用深度学习技术来解决分类问题。由于训练数据集中每个图像的大小很大&#xff0c;提出了一种基于patch的技术&a…

美团校招机试 - 小美的平衡矩阵(20240309-T1)

题目来源 美团校招笔试真题_小美的平衡矩阵 题目描述 小美拿到了一个 n * n 的矩阵&#xff0c;其中每个元素是 0 或者 1。 小美认为一个矩形区域是完美的&#xff0c;当且仅当该区域内 0 的数量恰好等于 1 的数量。 现在&#xff0c;小美希望你回答有多少个 i * i 的完美…

软件测试面试题:Web View如何测试?

Web View介绍 Web View&#xff08;网页视图&#xff09;是一种用于在应用程序中显示网页内容的组件或控件。提供了一种将网页内容嵌入到应用程序中的方式&#xff0c;使用户能够在应用程序中浏览和交互网页。 Web View通常用于开发移动应用程序&#xff0c;特别是混合应用程…

SOBEL图像边缘检测器的设计

本项目使用FPGA设计出SOBEL图像边缘检测器&#xff0c;通过分析项目在使用过程中的工作原理和相关软硬件设计进行分析详细介绍SOBEL图像边缘检测器的设计。 资料获取可联系wechat 号&#xff1a;comprehensivable 边缘可定义为图像中灰度发生急剧变化的区域边界,它是图像最基本…