<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Distributed on elonnzhang</title><link>https://jiabin.dev/categories/distributed/</link><description>Recent content in Distributed on elonnzhang</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sat, 05 Jul 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://jiabin.dev/categories/distributed/index.xml" rel="self" type="application/rss+xml"/><item><title>tRPC-Go 与 RPC 基础</title><link>https://jiabin.dev/blog/trpc-go/</link><pubDate>Sat, 05 Jul 2025 00:00:00 +0800</pubDate><guid>https://jiabin.dev/blog/trpc-go/</guid><description>&lt;h1 id="trpc-go"&gt;&lt;strong&gt;tRPC-go&lt;/strong&gt;&lt;/h1&gt;&#10;&lt;p&gt;&lt;a href="https://trpc.group"&gt;https://trpc.group&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;先说一说RPC&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;remote procedure call protocol 远程调用协议&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;客户端在不知道调用细节的情况下，调用存在于远程计算机上的某个对象，就像调用本地应用程序中的对象一样。&lt;/p&gt;&#10;&lt;p&gt;C/S 架构&lt;/p&gt;&#10;&lt;p&gt;当客户端发送的请求消息到达服务器时，服务器上的操作系统就将他传递给服务器存根（server stub）， &lt;strong&gt;服务器存根是客户存根在服务器端的对应程序和真正实现，用来将通过网络输入的请求转化为本地过程调用&lt;/strong&gt; 服务器存根一直在等待客户端的调用，处于阻塞状态，等待消息输入。&lt;/p&gt;&#10;&lt;p&gt;RPC流程&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;客户端进程以正常方式调用客户存根&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;客户存根生成一个消息。然后调用本地操作系统的网络通信模块，存根进入阻塞状态。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;客户端操作系统将网络消息发送给远程操作系统。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;远程操作系统将网络消息交给服务器存根。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;服务器存根从网络消息将参数提取出来，而后调用服务器存根。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;服务器执行相应的程序，操作完成后将结果返回给服务器存根。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;服务器存根打包消息，调用本地操作系统。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;发送给客户端操作系统。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;客户端操作系统将消息交给客户端存根，存根从阻塞状态回复，进入运行状态。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;客户端存根从消息中提取结果，返回调用的客户端。&#10;&lt;img src="https://jiabin.dev/assets/img/%E5%88%86%E5%B1%82%E8%AE%BE%E8%AE%A1.png" alt=""&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;过程中需要考虑的问题：&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;参数传递&lt;/li&gt;&#10;&lt;li&gt;通信协议&lt;/li&gt;&#10;&lt;li&gt;出错&lt;/li&gt;&#10;&lt;li&gt;超时处理&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;一些说明&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;既然是协议就只是一套规范。那么就需要有人遵循这套规范来进行实现 典型的RPC协议 Dubbo Thrift gRPC Hetty&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;网络协议和网络io模型&lt;/strong&gt; 对其透明 既然RPC的客户端认为自己是在调用本地对象。那么传输层使用的是TCP/UDP还是HTTP协议，又或者是一些其他的网络协议它就不需要关心了。&lt;/li&gt;&#10;&lt;li&gt;信息格式对其透明.&lt;/li&gt;&#10;&lt;li&gt;应该有跨语言能力， 调用方也不清楚远程服务器的应用程序是使用的什么语言与你性的，对于调用方来说，无论服务器方使用的什么语言，本次调用都应该成功。并且放回置应该按照调用方程序语言所能理解的形式表达。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h1 id="idl-interface-definition-language"&gt;&lt;strong&gt;IDL interface definition language&lt;/strong&gt;&lt;/h1&gt;&#10;&lt;p&gt;protocol buffer language .proto version 3&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;proto3&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;nbsp&lt;span class="p"&gt;;&lt;/span&gt; // 必须&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;message SearchRequest&lt;span class="o"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; string &lt;span class="nv"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 1&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int32 &lt;span class="nv"&gt;page_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 2&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int32 &lt;span class="nv"&gt;result_per_page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 3&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="trpc-能做什么"&gt;&lt;strong&gt;tRPC 能做什么&lt;/strong&gt;&lt;/h1&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;搭建多个端口支持多个协议（一个端口对应一个协议）&lt;/li&gt;&#10;&lt;li&gt;搭建消息队列消费者服务 提供消息队列生产者客户端发送消息&lt;/li&gt;&#10;&lt;li&gt;搭建本地定时器 分布式定时器服务&lt;/li&gt;&#10;&lt;li&gt;搭建流式服务 实现push 文件上传 消息下发等流式模型&lt;/li&gt;&#10;&lt;li&gt;访问各种私有协议后端服务&lt;/li&gt;&#10;&lt;li&gt;通过trpc工具生成桩代码和服务模板&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="需要基础知识"&gt;&lt;strong&gt;需要基础知识&lt;/strong&gt;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Go语言基础&lt;/li&gt;&#10;&lt;li&gt;context原理&lt;/li&gt;&#10;&lt;li&gt;RPC概念&lt;/li&gt;&#10;&lt;li&gt;tRPC术语&lt;/li&gt;&#10;&lt;li&gt;proto3知识&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;安装 proto&lt;/p&gt;</description></item><item><title>Raft 共识算法笔记</title><link>https://jiabin.dev/blog/raft/</link><pubDate>Wed, 25 Dec 2024 00:00:00 +0800</pubDate><guid>https://jiabin.dev/blog/raft/</guid><description>&lt;h1 id="分布式系统下的一致性问题"&gt;分布式系统下的一致性问题&lt;/h1&gt;&#10;&lt;p&gt;分布式系统有多个服务节点，给定一系列操作，在约定协议的保障下，使得它们对处理结果达成某种程度的协同。&lt;/p&gt;&#10;&lt;p&gt;分布式系统中的节点通信存在两种模型：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;共享内存（Shared memory）&lt;/li&gt;&#10;&lt;li&gt;消息传递（Messages passing）。&#10;基于消息传递通信模型的分布式系统，不可避免的会发生以下错误：进程可能会响应慢、被杀死或者重启，消息可能会延迟、丢失、重复；发生上面任意一种异常都会对分布式系统中各个节点对某一个值达成一致性产生问题。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;一致性&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;强一致性&lt;/li&gt;&#10;&lt;li&gt;弱一致性&lt;/li&gt;&#10;&lt;li&gt;最终一致性&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;共识算法&#10;&lt;strong&gt;共识算法（Consensus Algorithm）是分布式系统中用于在多个节点之间就某个值达成一致&lt;/strong&gt;的算法，即使在存在节点故障、网络分区的情况下，也能确保系统状态的一致性。&lt;/p&gt;&#10;&lt;p&gt;共识算法解决的问题&lt;/p&gt;&#10;&lt;p&gt;共识算法解决的是分布式系统对某个提案（Proposal），&lt;strong&gt;大部分节点&lt;/strong&gt;达成一致意见的过程。提案泛指多个事件发生的顺序、某个键对应的值…对于分布式系而言，各个节点通常都是相同的确定性状态机模型（又称为状态机复制问题，State-Machine Replication），从相同初始状态开始接收相同顺序的指令，则可以保证相同的结果状态。&lt;/p&gt;&#10;&lt;p&gt;这里共识算法需要解决两个基本问题：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;如何提出一个待共识的提案（令牌传递、随机选取…）&lt;/li&gt;&#10;&lt;li&gt;如何让多个节点对提案达成共识（投票、规则验证…）&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;现实网络环境中存在各种各样的问题，在分布式环境下，共识算法还需要解决如通信问题（网络中断、分区）、节点故障、消息伪造…&lt;/p&gt;&#10;&lt;p&gt;CAP定理&#10;&lt;strong&gt;CAP定理&lt;/strong&gt;（CAP theorem），又被称作&lt;strong&gt;布鲁尔定理&lt;/strong&gt;（Brewer’s theorem），它指出对于一个分布式计算系统来说，不可能同时满足以下三点，只能满足三项中的两项：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;C（一致性）&lt;/strong&gt;：任何事务都应该是原子的，所有副本上的状态都是事务成功提交后的结果，并保持强一致性。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;A（可用性）&lt;/strong&gt;：系统正常节点能在有限时间内完成对操作请求的应答。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;P（分区容错性）&lt;/strong&gt;：系统中的网络可能发生分区故障（成为多个子网、节点上线和下线），节点之间的通信无法保障，而网络故障不应该影响到系统正常服务。&lt;/li&gt;&#10;&lt;li&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;：在分布式系统中 &lt;strong&gt;P 必须要保证&lt;/strong&gt;，只能在 &lt;strong&gt;C 和 A&lt;/strong&gt; 之间权衡：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;保 C（强一致性）→ 可能牺牲可用性（如 Zookeeper）&lt;/li&gt;&#10;&lt;li&gt;保 A（高可用）→ 只能是最终一致性（如 Dynamo、Cassandra）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;三类系统模型&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;CA（一致性+可用性）：包括完全严格的仲裁协议，例如&lt;strong&gt;2PC（两阶段提交）&lt;/strong&gt;。&lt;/li&gt;&#10;&lt;li&gt;CP（一致性+分区容错性）： 包括多数仲裁协议，其中少数分区不可用，&lt;strong&gt;例如Paxos&lt;/strong&gt;。&lt;/li&gt;&#10;&lt;li&gt;AP（可用性+分区容错性）： 包括执行最终一致性的协议，&lt;strong&gt;例如Gossip&lt;/strong&gt;。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;ACID&lt;/strong&gt;&#10;ACID 即 Atomicity（原子性）、Consistency（一致性）、Isolation（隔离性）、Durability（持久性）四种特性的缩写，一般出现在分布式数据库等基于事务过程的系统中；ACID 原则描述了分布式数据库需要满足的一致性需求，同时允许付出可用性的代价。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Atomicity&lt;/strong&gt;: 每次事务是原子的，事务包含的所有操作要么全部成功，要么全部不执行。一旦有操作失败，则需要回退状态到执行事务之前；&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Consistency&lt;/strong&gt;: 数据库的状态在事务执行前后的状态是一致的和完整的，无中间状态。即只能处于成功事务提交后的状态；&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Isolation&lt;/strong&gt;: 各种事务可以并发执行，但彼此之间互相不影响。按照标准 SQL 规范，从弱到强可以分为未授权读取、授权读取、可重复读取和串行化四种隔离等级；&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Durability&lt;/strong&gt;: 状态的改变是持久的，不会失效。一旦某个事务提交，则它造成的状态变更就是永久性的。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;BASE原则&lt;/strong&gt;&#10;BASE即 Basic Availability（基本可用），Soft-state（弱状态），Eventual Consistency（最终一致性），为 eBay 技术专家 Dan Pritchett 提出的与ACID相对的一个原则，主要面向大型高可用分布式系统，主张牺牲掉对强一致性的追求，而实现最终一致性，来换取一定的可用性。&lt;/p&gt;</description></item></channel></rss>