中国人自己的框架——蚂蚁金服RPC框架结构分析
在数据库实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《中国人自己的框架——蚂蚁金服RPC框架结构分析》,聊聊MySQL、Java、nginx、spring、tomcat,希望可以帮助到正在努力赚钱的你。
蚂蚁金服近期开源了研发多年的SOFA一篮子框架,其中就有一个非常核心的RPC框架,它叫SOFA-BOLT。小编今天花了近一天的时间仔细阅读研究它的源码,阅读过程中遇到了不少问题,蚂蚁金服的相关技术人员都非常耐心的及时解答了我的疑难。这里将我从中学到的知识点一并分享给大家。
SOFA-BOLT基于开源的Netty框架,同时提供了服务器和客户端的实现。它的源码非常值得一读,结构简单,考虑周全,绝不是一个普通的玩具。它没有滥用设计模式,源码阅读起来比较直接,没有太多绕来绕去的复杂结构。

一个节点既可以同时既是RPC服务器又是客户端,作为客户端该节点需要其它节点提供服务,作为服务器它可以为其它节点提供服务。不过上面这张图并不是合理的结构,因为两个服务相互耦合了,我需要你,你也需要我,就成了鸡蛋问题。比较合理的结构一般如下图所示,它们之间不构成环。

通讯协议
通讯协议是客户端和服务器之间交流的语言,SOFA定义了自己的一套通讯协议,它的编码解码分为二层,第一层是消息体对象的二进制序列化,这部分默认由开源的Hession协议库序列化完成,第二层是负责给序列化的消息体增加一系列包装字段,形成一个完整的消息。包括请求ID、消息体的长度、协议版本号和CRC32校验位等等
如果希望进一步优化网络性能,SOFA还提供了Snappy压缩协议,可以在现有的两层协议基础上增加第三层,能显著降低网络传输负担。压缩是时间换空间,提升网络性能的同时,它也会加重CPU计算,所以在使用时需要适当进行权衡。

连接池
客户端和服务器之间一般需要建立多个连接,但是也不能每个请求都建立一个连接。一般是通过维护一个连接池,限定最大连接数。客户端通过有限的连接来和服务器进行通信。
我们在使用Jedis客户端和Redis服务器进行通信时,也是通过连接池来获取连接的。Jedis的连接必须是线程独占的,因为它不是线程安全的。从连接池中获取连接时,其它线程就暂时拿不到这个连接了,待当前线程处理完毕后,要将连接归还给线程池,这样其它线程才可以继续使用这个连接。

Redis的客户端请求和应答是顺序性的,一问一答,所以请求和应答不需要唯一ID就可以建立起关联。
Bolt不一样,它的问答是乱序的,问和答之间是必须通过请求的唯一ID来建立起关联。Bolt的客户端是线程安全的,它可以同时传递多个请求,连接对象会维护一个正在处理的RPC请求对象字典。当客户端想要发起RPC请求时,它不是从连接池中摘出一个独占连接,而是随意选择一个连接来传递自己的请求,这个连接也可以被其它线程同时使用。
负载均衡
客户端提供了多种复杂均衡的实现,阿里默认使用带权重的随机算法(RandomLoadBalancer),此外还有
- ConsistentHashLoaderBalancer 一致性hash,客户端和服务器之间的连接关系(谁跟谁连)比较稳定
- LocalPreferenceLoadBalancer 本地环回地址优先,提升本机调用性能
- RoundRobinLoadBalancer 循环依次来
- WeightedRoundRobinLoadBalancer 带权重的循环依次来
- RandomLoadBalancer 这个是带权重的随机,阿里的默认使用
服务器线程模型
服务器采用传统netty多线程模型,一个acceptor线程专门用来接收连接,然后扔给io线程处理读消息并解码成请求

对象,最后扔给业务线程池进行处理。
心跳
客户端和服务器之间会有定时心跳检测连接的存活,默认30s来一次。tcp的关闭是通过FIN包来通知对方的,如果因为网络问题,对方连FIN包都收不到,那么即使一边关闭了套接字,另一边可能还以为连接正常。所以心跳检测存活机制在长连接应用里非常普遍。如果客户端连续发了三次心跳都没有收到服务器的回复,那么就认为连接已经关闭。服务器也会有连接存活检测,如果一个客户端连接90s内没有任何消息进来,那么也认为该连接已经断开。服务器不会主动发送心跳消息。
双工通信
RPC一般是由客户端向服务器发起一个请求,然后收到服务器的应答。Bolt的RPC是双工通信,服务器也可以向客户端主动发起请求,它们共享一个TCP连接。TCP连接本身就是双工的,所以这也不算什么奇迹。只是服务器在什么业务场景需要向客户端主动发起请求,这个蚂蚁并没有进行详细说明。

客户端作为主动连接方,它要负责重连和发起心跳消息。服务器作为被动方,它不需要处理重连,如果连接断开,它就直接将连接从集合中移除就行,不需要做特殊的处理,但是它会检测心跳消息,如果在一定时间内连接通道没有任何消息到来,它就会主动关闭。
重连
客户端的重连策略是一个单独的模块,有两个地方会成为重连的入口。一个是正常连接断开触发channelInActive回调,另一个就是重连连接不能建立成功时需要进行重试。Bolt有一个单独的重连线程,所有需要重连的连接会被包装成一个任务塞进这个线程的任务队列,该线程不断地从队列里拿任务进行重连处理,如果重连失败会尝试再将任务重新包装进队列延后继续处理。默认是1s钟处理一个重连任务。

RPC连接是延迟建立的,它在第一次客户端发送RPC请求时尝试进行连接,如果连接失败,它会立即继续重连最多默认两次。如果三次尝试连接后还是没有建立成功,就向上层爆出异常。它不需要包装一个重连任务塞进ReconnectManager,因为后续客户端请求会继续触发连接。
单向消息
RPC通常是一应一答,客户端可以同步等待响应,也可以提供回调接口等待结果通知。Bolt除了提供应答模式之外,还提供了oneway单向消息,这种消息服务器收到后不用回复,客户端发送请求之后就立即返回了也不需要等待结果。
oneway消息一般用于不那么重要的日志类消息,它不能保证服务器一定能收到,所以此种业务消息应该是那种允许丢失的消息,形式上类似于UDP,它在牺牲可靠性的前提下能大幅提升消息的吞吐量。
在此我向大家推荐一个架构学习交流群。交流学习群号:575745314 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
消息追踪
Bolt提供了回调接口,方便监控系统可以对请求的调用状况进行分析。监控的客户端可以通过实现该接口,注册进RPC的客户端和服务器进行打点收集日志,然后发送到日志分析系统。

总结
Bolt是一个成熟的比较复杂的RPC系统,这篇小文章只讲解了其中一部分,内部还有大量的实现细节有待去挖掘。
注:关注微信公众号:《JAVA烂猪皮》解锁更多精彩内容
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于数据库的相关知识,也可关注golang学习网公众号。

- 上一篇
- Spring 框架分为哪七个模块

- 下一篇
- 面试是人生走向成功的第一步, 你是怎样面对面试的呢?
-
- 悲凉的人生
- 这篇技术贴太及时了,很详细,感谢大佬分享,收藏了,关注up主了!希望up主能多写数据库相关的文章。
- 2023-03-03 10:43:48
-
- 数据库 · MySQL | 14小时前 | 索引 数据类型 字符集 存储引擎 CREATETABLE
- MySQL新建表操作指南与建表技巧
- 462浏览 收藏
-
- 数据库 · MySQL | 1个月前 | 条件判断
- CASEWHEN条件判断的嵌套使用详解与实战场景分析
- 469浏览 收藏
-
- 数据库 · MySQL | 1个月前 | java php
- CSV文件批量导入MySQL的性能优化秘籍大揭秘
- 289浏览 收藏
-
- 数据库 · MySQL | 1个月前 |
- GaleraCluster多主集群配置与冲突解决攻略
- 239浏览 收藏
-
- 数据库 · MySQL | 1个月前 | 窗口函数实战
- MySQL窗口函数实战案例深度剖析
- 315浏览 收藏
-
- 数据库 · MySQL | 1个月前 | 自定义函数
- MySQL插件开发入门:自定义函数(UDF)编写指南
- 184浏览 收藏
-
- 数据库 · MySQL | 1个月前 |
- Windows系统MySQL8.0免安装版配置攻略
- 227浏览 收藏
-
- 数据库 · MySQL | 1个月前 | MySQL错误 数据库诊断
- 深度解析错误代码1045/1217/1205的根本原因及解决方案
- 202浏览 收藏
-
- 数据库 · MySQL | 1个月前 | sql注入 编码规范
- 防范SQL注入必备:编码规范与工具推荐指南
- 140浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 笔灵AI生成答辩PPT
- 探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
- 14次使用
-
- 知网AIGC检测服务系统
- 知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
- 23次使用
-
- AIGC检测-Aibiye
- AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
- 30次使用
-
- 易笔AI论文
- 易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
- 40次使用
-
- 笔启AI论文写作平台
- 笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
- 35次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览