基于Tars高并发IM系统的设计与实现-实战篇1

news2025/2/21 23:21:29

基于Tars高并发IM系统的设计与实现-实战篇1

通过前文基础篇,进阶篇的介绍,相信大家已经对IM的基础能力实现,难点及其如何解决有了一个全面的了解与认识。
相信大家都迫不及待想看看一个高性能的IM系统到底怎么设计与实现,从本篇开始主要讲述如何实现一个完整的IM系统。

消息流转整体方案我们采用服务器中转方案:A通过服务器S将信息发给B
在这里插入图片描述

在目前互联网时代,已经有一些大公司提供了不错的开源基础平台供大家使用,站在巨人肩上可以省不少力。

Tars平台作为腾讯近几年推出的一款基础框架,在腾讯内部也适用广泛,以是C++方面开源少有且稳定的技术平台。

笔者通过几年在IM领域对Tars的使用,对该框架也比较熟悉,是目前市场上C++语言IM领域比较适合的开发平台,其本身就是来源于QQ服务平台,对IM领域可以说是有天然的适应性,完全能够满足高可靠,高并发,低延时的基本性能需求。

采用Tars平台总体设计方案,前文已经描述,具体见下图;
在这里插入图片描述

基于Tars框架实现的IM系统设计与实现,我们从下面三章内容着手介绍:

  • Tars框架
  • IM服务端实现
  • IM客户端实现

Tars框架

本章节内容主要来自Tars在线文档:https://doc.tarsyun.com/

基础介绍

Tars是基于名字服务使用Tars协议的高性能RPC开发框架,同时配套一体化的服务治理平台,帮助个人或者企业快速的以微服务的方式构建自己稳定可靠的分布式应用。
Tars是将腾讯内部使用的微服务架构TAF(Total Application Framework)多年的实践成果总结而成的开源项目。Tars这个名字来自《星际穿越》电影中机器人Tars, 电影中Tars有着非常友好的交互方式,任何初次接触它的人都可以轻松的和它进行交流,同时能在外太空、外星等复杂地形上,超预期的高效率的完成托付的所有任务。 拥有着类似设计理念的Tars也是一个兼顾易用性、高性能、服务治理的框架,目的是让开发更简单,聚焦业务逻辑,让运营更高效,一切尽在掌握。
目前该框架在腾讯内部,有100多个业务、10多万台服务器上运行使用。

设计思想

Tars的设计思路是采用微服务的思想对服务进行治理,同时对整个系统的各个模块进行抽象分层,将各个层次之间相互解耦或者松耦合,如下图:
在这里插入图片描述

最底的协议层,设计思路是将业务网络通信的协议进行统一,以IDL(接口定义语言)的方式,开发支持多平台、可扩展、协议代码自动生成的统一协议。在开发过程中,开发人员只需要关注通讯的协议字段的内容,不需要关注其实现的细节,大大减轻了开发服务时需要考虑的协议是否能跨平台使用、是否可能需要兼容、扩展等问题。
中间的公共库、通讯框架、平台层,设计思路是让业务开发更加聚焦业务逻辑的本身。因此,从使用者的角度出发,封装了大量日常开发过程中经常使用的公共库代码和远程过程调用,让开发使用更简单方便;从框架本身的角度出发,做到高稳定性、高可用性、高性能,这样才能让业务服务运营更加放心;从分布式平台的角度出发,解决服务运营过程中,遇到的容错、负载均衡、容量管理、就近接入、灰度发布等问题,让平台更加强大。
最上面的运营层,设计思路是让运维只需要关注日常的服务部署、发布、配置、监控、调度管理等操作。

整体架构

  • 架构拓扑
    在这里插入图片描述

整体架构的拓扑图主要分为2个部分:

  • 服务节点
  • 公共框架节点。

服务节点

服务节点可以认为是服务所实际运行的一个具体的操作系统实例,可以是物理主机或者虚拟主机、云主机。随着服务的种类扩展和规模扩大,服务节点可能成千上万甚至数以十万计。 每台服务节点上均有一个Node服务节点和N(N>=0)个业务服务节点,Node服务节点会对业务服务节点进行统一管理,提供启停、发布、监控等功能,同时接收业务服务节点上报过来的心跳。

公共框架节点

除了服务节点以外的服务,其他服务节点均归为一类。
公共框架节点,数量不定,为了自身的容错容灾,一般也要求在在多个机房的多个服务器上进行部署,具体的节点数量,与服务节点的规模有关,比如,如果某些服务需要打较多的日志,就需要部署更多的日志服务节点。

又可细分为如下几个部分:

  • Web管理系统:在Web上可以看到服务运行的各种实时数据情况,以及对服务进行发布、启停、部署等操作;
  • Registry(路由+管理服务):提供服务节点的地址查询、发布、启停、管理等操作,以及对服务上报心跳的管理,通过它实现服务的注册与发现;
  • Patch(发布管理):提供服务的发布功能;
  • Config(配置中心):提供服务配置文件的统一管理功能;
  • Log(远程日志):提供服务打日志到远程的功能;
  • Stat(调用统计):统计业务服务上报的各种调用信息,比如总流量、平均耗时、超时率等,以便对服务出现异常时进行告警;
  • Property(业务属性):统计业务自定义上报的属性信息,比如内存使用大小、队列大小、cache命中率等,以便对服务出现异常时进行告警;
  • Notify(异常信息):统计业务上报的各种异常信息,比如服务状态变更信息、访问db失败信息等,以便对服务出现异常时进行告警;

原则上要求全部的节点之间网络互通,至少每台机器的node能够与公共框架节点之间都是可以连通的。

  • 服务交互流程
    在这里插入图片描述

框架服务在整个系统中运行时,服务之间的交互分:业务服务之间的交互、业务服务与框架基础服务之间的交互。

  • 服务发布流程:在Web系统上传server的发布包到patch,上传成功后,在web上提交发布server请求,由registry服务传达到node,然后node拉取server的发布包到本地,拉起server服务。
  • 管理命令流程:Web系统上的可以提交管理server服务命令请求,由registry服务传达到node服务,然后由node向server发送管理命令。
  • 心跳上报流程:server服务运行后,会定期上报心跳到node,node然后把服务心跳信息上报到registry服务,由registry进行统一管理。
  • 信息上报流程:server服务运行后,会定期上报统计信息到stat,打印远程日志到log,定期上报属性信息到property、上报异常信息到notify、从config拉取服务配置信息。
  • Client访问Server流程:client可以通过server的对象名Obj间接访问server,Client会从registry上拉取server的路由信息(如ip、port信息),然后根据具体的业务特性(同步或者异步,tcp或者udp方式)访问server(当然client也可以通过ip/port直接访问server)。

web管理系统

在这里插入图片描述

web管理系统主要包含以下功能:

  • 业务管理:包括已部署的服务,以及服务管理、发布管理、服务配置、服务监控、特性监控等;
  • 运维管理:包括服务部署、扩容、模版管理等;

服务结构

框架核心的服务端与客户端实现结构图如下:
在这里插入图片描述

  • 服务端:

    • NetThread: 收发包,连接管理,多线程(可配置),采用epoll ET触发实现,支持tcp/udp;
    • BindAdapter: 绑定端口类,用于管理Servant对应的绑定端口的信息操作;
    • ServantHandle:业务线程类,根据对象名分派Servant的对象和接口调用;
    • AdminServant: 管理端口的对象;
    • ServantImp: 继承Servant的业务处理基类(Servant:服务端接口对象的基类);
  • 客户端:

    • NetThread: 收发包,连接管理,多线程(可配置),采用epoll ET触发实现,支持tcp/udp;
    • AdapterProxy: 具体服务器某个节点的本地代理,管理到服务器的连接,以及请求超时处理;
    • ObjectProxy: 远程对象代理,负责路由分发、负载均衡、容错,支持轮询/hash/权重;
    • ServantProxy: 远程对象调用的本地代理,支持同步/异步/单向,Tars协议和非Tars协议;
    • AsyncThread: 异步请求的回应包处理线程;
    • Callback: 具体业务Callback的处理基类对象。

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

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

相关文章

grpc学习笔记

目录 gRPC原理网络传输效率问题基本概念概览ClientServer 异步相关概念异步 Client异步 Server gRPC原理 RPC 即远程过程调用协议(Remote Procedure Call Protocol),可以让我们像调用本地对象一样发起 远程调用。 网络传输效率问题 HTTP…

Mysql---explain详解

explain命令是用来分析查询语句的执行计划的工具。它可以显示查询语句的执行计划,包括查询的顺序、使用的索引、扫描的行数等信息,帮助开发人员优化查询语句的性能。通过分析执行计划,可以找到查询语句的瓶颈,进而优化查询语句的性…

机器学习笔记 - 探索PaddlePaddle框架的对象检测、分割和关键点检测

一、PaddlePaddle简述 PaddlePaddle(PArallel Distributed Deep LEarning)是百度于2016年发布的开源深度学习框架。它为各种机器学习任务提供了统一的平台。 但是最近的基准测试显示 PaddlePaddle 是潜在的领跑者,其基准速度超过了其更知名的竞争对手。 PaddlePaddle 与 PyT…

2.SpringBoot集成Swagger

1.添加依赖 <!--添加Swagger依赖 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version></dependency><!--添加Swagger-UI依赖 --><dependenc…

Python实现操作MySQL【增删改查-示例】

闲话少叙,直接上操作! 一、准备工作 1.本地安装MySQL、Python(以3.6为例) 2.MySQL新建数据库【test】,新建表【user】,新建字段【name】【age】 3.建表方式:navicat工具 字段 二、Python操作—插入数据 #!/usr/bin/env # coding=utf-8import pymysql # Python 连…

Leetcode-每日一题【430.扁平化多级双向链表】

题目 你会得到一个双链表&#xff0c;其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表&#xff0c;也包含这些特殊的节点。这些子列表可以有一个或多个自己的子列表&#xff0c;以此类推&#xff0c;以生成如下面…

Java语言程序设计试卷6套

目录 Java语言程序设计试卷1 一、单项选择题 二、多项选择题 三、判断题 Java语言程序设计试卷2 一、单项选择题 二、多项选择题 三、判断题 Java语言程序设计试卷3 一、单项选择题 二、多项选择题 三、判断题 Java语言程序设计试卷4 一、单项选择题 二、多项选…

【7月比赛合集】119场可报名的数据挖掘大奖赛,任君挑选!

CompHub[1] 主页增加了“近两周上新的奖金赛”&#xff0c;更加方便查找最新比赛&#xff0c;欢迎访问和反馈&#xff01; 最新更新的比赛会第一时间在群里通知&#xff0c;欢迎加群交流&#xff01;&#xff08;公众号回复“加群”即可&#xff09; 以下信息仅供参考&#xff…

一种简单的数据库性能测试方法

这两天接到一个任务&#xff0c;要测试一个服务器的性能&#xff0c;客户要求向数据库内 1000/s&#xff08;每插入一千条数据&#xff09; 的处理能力&#xff0c;当时脑子赌赛了&#xff0c;想的是用LR来进行&#xff0c;由于LR接触不深&#xff0c;只知道LR实现参数化的时候…

Java基础---异常

目录 典型回答 什么是Throwable Error和Exception的区别和联系 Java异常处理相关的几个关键字&#xff0c;以及简单用法 什么是自定义异常&#xff0c;如何使用自定义异常 Java异常体系结构 以下关于异常处理的代码有哪些问题 典型回答 Java中的异常&#xff0c;主要可以…

力扣 62. 不同路径

文章目录 题目描述思路代码 题目描述 思路 动态规划 代码 private int UniquePaths(int m, int n) {int[][] dp new int[m][];for (int i 0; i < m; i) {dp[i] new int[n];}for (int i 0; i < m; i) {for (int j 0; j < n; j) {if (i 0 || j 0) dp[i][j] …

LLM - Baichuan7B Tokenizer 生成训练数据

目录 一.引言 二.Tokenizer 原始数据 1.原始数据样例 2.加载并 Token 原始数据 2.1 参数准备 2.2 单条样本处理逻辑 2.3 批量处理逻辑 2.4 主函数与完整代码 三.shell 执行 四.总结 一.引言 前面提到了自己在微调 Baichuan7B Lora 的过程中遇到了一些问题&#xff0c…

Cesium Token申请

一、什么是Cesium ion&#xff1f; Cesium ion是一个提供瓦片图和3D地理空间数据的平台&#xff0c;支持把数据添加到用户自己的应用程序中。 二、为什么需要access token&#xff1f; 使用Cesium ion需要申请access token,当用户将数据添加到自己的账户后&#xff0c;便可以…

Android-jar包方式连接本地sqlite并操作返回数据

背景: 数据库的创建及字段都是后端人员维护,Android端只是映射相关数据库到本地来操作。为了统一管理操作方式方法,所以提出,后端打jar包的方式封装对Android端数据库sqllite的连接、操作。 说明: 因为之前是后端打jar包,JDBC连接的驱动及方法有差异,导致连接Android…

PHP在线拨打电话的代码

这段代码包括一个HTML表单,用于收集用户的姓名,电子邮件和消息。当用户提交表单时,邮件将发送到指定的电子邮件地址,并显示一条消息,指示我们将在不久的将来拨打电话回复。请注意,在上面的代码中,电话号码硬编码为 $phone_number 变量,您需要将其更改为您想要的电话号码…

jmeter使用正则表达式匹配多个中的响应结果

目录 一、背景&#xff1a; 二、例如&#xff1a; 三、接口响应的所有结果&#xff1a; 四、正则表达式的写法&#xff1a; 五、调试的时候添加一个Debug PostProcessor 调试器 六、在Debug PostProcessor中可以查看到获取的参数结果 七、引用方式&#xff1a;${testValue…

【js前端去空格】

javascript字符串去空格 js去除字符串空格的方法 说到去除空格&#xff0c;首先都会想到的就是trim()方法&#xff0c;但是trim()只能去除字符串前后的空格&#xff0c;无法去除字符串中间的空格。 下面总结一下js去除字符串空格的几种方法&#xff1a; 1、trim() trim()是…

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)

我们知道包含string.h头文件后&#xff0c;就可以使用strncpy,strncmp,strncat,strstr,strtok这些库函数&#xff0c;接下来让我们了解他们。 目录 #strncpy #strncmp #strncat #strstr #strtok #下期预告 #strncpy 该库函数作用和strcpy很相似&#xff0c;不同点在于 发现了吗…

《面试1v1》Redis分片集群

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Redis Brpop 命令

目录 一、作用二、demo演示 一、作用 Redis Brpop 命令拥有移出并获取list右边的最后一个元素&#xff0c; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 二、demo演示 向 list1 中插入三个元素 a、b、c lpush list1 a b c查看list1中的元素 lrange lis…