当前位置: 首页 > news >正文

单体架构的 IM 系统设计

先直接抛出业务背景!

有一款游戏,日活跃量(DAU)在两千左右,虽然 DAU 不高,但这两千用户的忠诚度非常高,而且会持续为游戏充值;为了进一步提高用户体验,继续增强用户的忠诚度,老板想要在该款游戏中引入聊天功能,同时探索和验证游戏用户对 IM 的需求和依赖度。IM 需要在两周后上线,如果你是这个 IM 项目的架构师,带着两名经验尚欠的程序员,你如何设计并落地该 IM 系统?

业务背景并不复杂,简单总结一下:

  1. 用户规模小:DAU 在两千左右,同时在线人数高峰期不到200;

  2. 开发人员少:一名架构师加两名程序员;

  3. 开发时间短:一周开发加一周测试,只有两周时间。

这种情况下,研发策略通常是:怎么简单就怎么做,怎么快就怎么来!

所以对该 IM 系统采用【单体架构】的方式进行设计,见下图。

前端是运行安卓系统和 IOS 系统的移动设备,游戏 APP 内嵌 IM 的客户端,由前端同学负责开发。

后端是 Server 节点,通过多进程多机器部署的方式,避免 “单点”; 这个地方需要注意:【单体架构】并非 “单点架构” ,单体架构仍然是分布式架构的一种,通过集群的方式提供高可用和高吞吐的服务;对多个 Server 节点的访问通过 Nginx 来做反向代理;Server节点由后端同学负责开发。

存储部分包括数据库和缓存,数据库中分别创建 “消息表”、“离线消息表”、“联系人表” 和 “用户表”; 缓存用来记录用户的在线信息;数据库和缓存由 DBA 同学负责维护。

单体架构的系统,最大的优势就是在项目前期开发简单、部署简单、测试简单、运维简单,开发同学几乎可以将所有的注意力全部放在业务逻辑上,实现真正的【快速落地】。

下面分别讨论一下关键的技术选型:前端与后端的通讯协议、后端的编程语言、数据库选型。

一、通讯协议

前端与后端之间的通讯协议,有四种选择,见下表。

IM 系统通常会选择 “长连接” 类型的协议;但是 WebSocket 协议因为刚推出不久,成熟度不高;TCP 协议属于传输层协议,较为复杂,如果没有丰富的 TCP 网络编程经验的话,在研发时间非常紧张的情况下,建议不要选择 TCP。

所以,这里我们选择最简单和最容易落地的协议—Http;对于编程经验尚欠的应届生来讲,Http编程也不会有太大难度。

分析到这里,相信大家肯定有这样的疑惑:Http 是短连接的无状态协议,如何进行消息的即时通讯呢?难道是通过客户端周期性的轮询访问吗? 是的,同时在线人数只有几百的情况下,客户端周期性轮询是完全没有问题的,况且Server是多节点部署,完全可以 Cover 客户端周期轮询的压力。

二、编程语言

Server 端编程语言,也有四种选择(公司内部正在使用的技术栈),见下表。

C++、Java、PHP、Go 四门编程语言都有非常成熟的并发编程模型,这里我们选择公司和团队最熟悉的语言—Go,使用最熟悉的语言才会带来更高的编程效率和更快的问题解决速度。

三、数据库

数据库选型有三种选择,分别是关系型 SQL 数据库—MySQL、非关系型 NoSQL 数据库—MongoDB、已经新兴的NewSQL 数据库—TiDB,见下表。

在该单体架构的 IM 系统中,数据库需要提供强事务能力,来保证业务的完整逻辑;同时,数据库需要做到更低成本的运维;这里我们选择满足需求和容易运维的数据库—MySQL。

最后,总结文中关键:

1、业务背景:用户规模小、开发人员少、开发时间短;

2、研发策略:怎么简单怎么做,怎么快怎么来;

3、 IM单体架构: 前端(APP)+ Server + 数据库

单体架构最大的优势就是在项目前期开发简单、部署简单、测试简单、运维简单。

4、技术选型:

选择最简单和最容易落地的协议—Http,

选择公司和团队最熟悉的语言—Go,

选择满足需求和容易运维的数据库—MySQL。

提出一个思考问题,我们会在下篇技术短文中进行分析:

基于该IM单体架构,如何实现用户的登录和收发消息呢?Server 节点是无状态化的吗?

相关文章:

单体架构的 IM 系统设计

先直接抛出业务背景! 有一款游戏,日活跃量(DAU)在两千左右,虽然 DAU 不高,但这两千用户的忠诚度非常高,而且会持续为游戏充值;为了进一步提高用户体验,继续增强用户的忠…...

kafka消费端常见故障及处理方法

文章目录 前言一、消费端某个进程已经crash1. 主要心跳相关配置2. 完整的消费者配置示例3. 调整参数的建议 二、客户端没有crash,但是消费阻塞1. 工作机制2. 示例配置3.运用在代码里3. 配置建议 前言 kafka消费端经常会出现一些故障,一起来分析一下故障…...

【linux 多进程并发】0302 Linux下多进程模型的网络服务器架构设计,实时响应多客户端请求

0302 多进程网络服务器架构 ​专栏内容: postgresql使用入门基础手写数据库toadb并发编程 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 一、概…...

LTE及EPC技术原理(笔记)

无线网络发展历史 20世纪80年代:模拟技术和FDMA 20世纪90年代:数字技术和TDMA 21世纪初:数字技术和CDMA LTE进步 下行100Mbps,上行50Mbps 用户面时延10-20ms,控制面时延小于100ms 带宽从1.4MHz~20MHz&#xff0…...

穿越数据迷宫

第一章 在未来的世界里,人类的生活已经被高度数字化。互联网不再是简单的信息交换平台,而是成为了一个庞大的虚拟世界——“数据迷宫”。在这个世界里,每个人都有一个独特的数字身份,他们的生活、工作、娱乐都离不开这个虚拟空间…...

FBX福币交易所国际油价突然大涨!美伊针锋相对

11月4日早上,国际原油大幅高开。WTI原油一度涨超2%。 消息面上,主要产油国宣布延长自愿减产措施至12月底 FBX福币凭借用户友好的界面和对透明度的承诺,迅速在加密货币市场中崭露头角,成为广大用户信赖的平台。 石油输出国组织(欧佩克)发表声明说,8个欧佩克和非欧佩克产油国决…...

Java项目管理与SSM框架介绍

Maven简介 Maven是一个项目管理工具。它可以帮助程序员构建工程,管理jar包,编译代码,完成测试,项目打包等等。Maven工具是基于POM(Project Object Model,项目对象模型)实现的。在Maven的管理下每…...

WorkFlow源码剖析——Communicator之TCPServer(中)

WorkFlow源码剖析——Communicator之TCPServer(中) 前言 上节博客已经详细介绍了workflow的poller的实现,这节我们来看看Communicator是如何利用poller的,对连接对象生命周期的管理。(PS:与其说Communica…...

在做题中学习(73):删除字符串中所有相邻重复项

解法&#xff1a;用栈来模拟 思路&#xff1a;不用真的定义一个栈,用字符串string来模拟栈的行为 入栈&#xff1a;push_back(s[i]) 出栈:s[i] s.back()的时候&#xff0c;并且s.size() > 0&#xff0c;循环结束得到结果 注意&#xff1a;如果真的用stack<char>来…...

springboot 单元测试-各个模块举例

controller单测 import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Moc…...

MS01SF1 精准测距UWB模组助力露天采矿中的人车定位安全和作业效率提升

在当今矿业行业&#xff0c;随着全球对资源需求的不断增加和开采难度的逐步提升&#xff0c;传统的作业方式面临着越来越多的挑战。露天矿山开采&#xff0c;因其大规模的作业环境和复杂的地形特点&#xff0c;面临着作业人员的安全风险、设备调度的高难度以及资源利用率低下等…...

Android亮屏Job的功耗优化方案

摘要: Job运行时会带来持锁的现象,目前灭屏放电Job的锁托管已经有doze和绿盟标准监管,但是亮屏时仍旧存在过长的持锁现象,故为了优化功耗和不影响用户体验下,新增亮屏放电下如果满足冻结和已运行过一次Job,则进行job限制,当非冻结时恢复的策略 1.现象: (gms_schedu…...

React05 样式控制 classnames工具优化类名控制

样式控制 & classnames工具优化类名控制 样式控制1. 行内样式控制2. 外部样式控制 classnames工具优化类名控制 样式控制 1. 行内样式控制 //定义样式 const style {color: red,fontSize: 30px }function App() {return (<div className"App">{/* 行内样…...

OJ-5G网络建设

示例1 输入&#xff1a; 3 3 1 2 3 0 1 3 1 0 2 3 5 0 输出&#xff1a; 4示例2 输入&#xff1a; 3 1 1 2 5 0 输出&#xff1a; -1 示例3 输入&#xff1a; 3 3 1 2 3 0 1 3 1 0 2 3 5 1 输出&#xff1a; 1 分析&#xff1a;压缩路径 顺序&#xff1a;1 2&#xff1b;…...

Linux简介

1.Linux定义 Linux 是免费使用和自由传播的类 Unix 操作系统&#xff0c;是基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议。它支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思…...

android——渐变色

1、xml的方式实现渐变色 效果图&#xff1a; xml的代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools…...

MySQL约束管理

介绍 MySQL约束管理是指在MySQL数据库中定义和管理数据约束的过程。数据约束用于维护数据的完整性和一致性&#xff0c;确保数据在表中的存储符合特定的规则。通过约束&#xff0c;可以防止不符合要求的数据被插入或更新&#xff0c;从而保护数据库的质量。 约束管理的主要内…...

拯救者y7000p 打开XMP

拯救者y7000p 打开XMP 拯救者bios隐藏功能 第一步、开机按F2进入bios 第二步、点击more settings 第三步、依次按Fnrn再按F12保存重启 第四步、再进bios&#xff0c;点击more settings则显示更多可调制选项&#xff0c;可找到内存超频功能&#xff0c;进行xmp超频 如果第三步失…...

2024 Rust现代实用教程Iterator迭代器

文章目录 一、迭代与循环1.循环2.迭代iteration3.区别 二、Intoiterator、Iterator和Iter之间的关系1.Intolterator2.Iterator Trait3. 源码中经常出现的iter 三、获取迭代器的三种方法iter(),iter_mut()和into_iter()1.iter()方法2.iter_mut()方法3.into_iter()方法---尽量写 …...

基于SpringBoot司机信用评价的货运管理系统【附源码】

基于SpringBoot司机信用评价的货运管理系统 效果如下&#xff1a; 系统主页面 系统注册页面 司机注册页面 管理员主页面 订单评价页面 货物信息页面 个人信息页面 研究背景 随着我国物流行业的迅猛发展&#xff0c;货运管理系统的效率与安全性日益受到重视。在货运过程中&am…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...