
Li Guangqiao
一个正在转rust的ExtJs前端工程师。迷信rust的整体发展,十分相信rust在各个领域都能发光发热,至少目前rust在很多领域上验证了其安全性、易维护性。但说实话对于我这种菜鸡也是真的难上手哈哈哈~~。 思路总结:
- 万物诞生都会有一个需求来源,每一个改变都是为了解决某个问题,最后应该考虑如何去做
- 学会掌握一些宏观的知识和理论:系统论、还原论
- 工程化思想,如何描述整体,从整体架构到模块关联等 故学习东西应该像看地图一样,先看整体了解整体的结构,然后再聚焦每一个模块,对于模块的学习,思考三个问题,“是什么?”、“为什么?”、“怎么做?”;那么设计一个东西时也应该去考虑整体性和关联性。
有关于未来的发展,以下是鄙人的粗浅的观点:
- 编程语言未来应该是每个人必备的工具
- 未来的交互方式应该会以语言交互为主流
- 下一个去中心化的技术方案出来之前,区块链依然是web3建立价值体系的基础技术方案,如何将现实价值和虚拟价值联通是进入数字世界的一个大难题。
- 未来注定是AI的世界。AI的进化会伴随绝大部分人的退化,届时除了尖端人才,人们学习的重心会放在何处?

dcoker与docker-compose区别
Li Guangqiao - 07/03/2024
dcoker与docker-compose区别 Docker 和 Docker Compose 在容器化技术中扮演着互补的角色。二者共同目的是简化容器的管理和部署过程,但它们在功能和使用场景上有所不同。 Docker Docker 是一种容器化平台,提供了一个环境,让您可以在轻量级的容器中构建、发布和运行应用程序。容器允许您将应用程序及其依赖项打包到一个可移植的单元中,从而在任何支持 Docker 的环境中以一致的方式运行。Docker 的核心组件包括: Docker Daemon:运行在宿主机上的服务,负责构建、运行和分发 Docker 容器。 Docker Client:用户通过命令行工具与 Docker Daemon 交互。 Docker Images:只读模板,用于创建容器。镜像包含运行应用程序所需的代码、运行时、库等。 Docker Containers:镜像的运行实例。容器在被启动时,在镜像的顶层添加一个可写层。 Docker Compose Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过编写一个 YAML 文件(docker-compose.yml),您可以配置应用服务的所有方面,然后使用一个命令来启动和管理所有服务。Docker Compose 的关键特性包括: 服务定义:在 docker-compose.yml 文件中定义您的应用程序的服务,这样您可以在一个命令中启动整个应用程序。 网络配置:自动设置容器间的网络,使得不同的服务可以轻松地相互通信。 卷管理:在服务之间共享数据或持久化数据时,可以配置和管理卷。 依赖管理:可以明确服务启动的顺序,确保依赖的服务先启动。 区别总结 用途:Docker 专注于单个容器的生命周期管理,而 Docker Compose 用于在单个主机上编排多容器应用程序。 作用范围:Docker 通常用于容器化单个应用或服务,Docker Compose 则允许您同时管理多个容器,定义它们如何相互作用。 配置方法:Docker 使用 Dockerfile 来构建镜像,而 Docker Compose 使用 docker-compose.yml 文件来定义多服务应用程序的配置。 在实际应用中,Docker Compose 大大简化了在开发、测试和生产环境中部署和管理多容器应用程序的复杂性。而 Docker 提供了底层技术和命令行工具来管理单个容器的生命周期。二者结合使用,能够高效地开发、部署和扩展容器化应用程序。 ...

离线部署dcoker与docker-compose
Li Guangqiao - 07/03/2024
离线部署docker与docker-compose 离线部署docker参考文档 (tencent.com) docker-20.10.7.tgz 解压安装包docker-20.10.7.tgz 移动所有文件到/usr/bin/目录下cp docker/* /usr/bin/ 将docker注册为service,在/etc/systemd/system目录下创建docker.service文件,并配置如下内容保存。 [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID # Having non-zero Limit*s causes performance problems due to...

加密算法
Li Guangqiao - 25/01/2024
密码学技术
摘要算法
摘要算法是指把任意长度的输入消息数据转化为固定长度的输出数据的一种密码算法,又称为散列函数 、 哈希函数 、 杂凑函数 、单向函数等。
摘要算法所产生的固定长度的输出数据称为 摘要值、散列值和哈希值。
摘要算法通常用来做数据完整性的判定,即对数据进行哈希计算然后比较摘要值是否一致。
MD5算法
目标
通过MD5为数据建立一个唯一数字标识
特点
压缩性:输出长度固定
抗修改:对原数据进行任何改动,都会影响输出结果
强抗碰撞:已知原数据和其MD5值,想找到MD5值相同的另一个数据极其困难
作用
让大容量信息在用数字签名软件签署私人密钥前被压缩成一种保密的格式(就是把一个任意长度的字节串变换成一定长的16进制数字串)
过程
MD5算法的基本过程为:填充、分块、缓冲区初始化、循环压缩、计算结果。
填充
MD5算法对于待处理信息的位长有以下要求:假设信息长度为Kbit,填充位长为Pbit,且1<P<512,要求

分布式系统核心理论
Li Guangqiao - 19/01/2024
分布式系统核心理论
概念
分布式系统是指分散在多个物理机/虚拟机节点的资源,节点在网络中相互通信,并对外暴露统一服务的系统。
注意:外部访问节点A的接口时,内部路由到对应的节点服务。核心是搞一个哈希表,方便做路由转发。
其他概念
分布式容错,是指在分布式环境下,能够容忍一部分节点宕机,还能向外提供稳定的服务。
分布式共识算法,是指在分布式环境下,各个节点能就某个值达成共识,即所有节点都认同某个值。
设计目标
为什么要设计分布式系统?
设计分布式系统的目标是解决单节点资源限制问题。在业务量增长速度比较快的场景下,单节点的资源难适应(计算资源和存储资源需要不断扩)。
分布式系统如何解决单节点的资源限制问题?
关键词:多节点、节点通信、服务分散、容易拓展、高容错。通过将系统的服务分散到多个节点,有效提高了单节点的资源利用率,并且后续的拓展容易,只需要增加节点即可。
引入分布式设计带来什么问题?
节点与节点之间的关联数据容易出现不一致的情况。
网络通信情况对系统性能存在比较大的影响。比如延迟。
系统结构
分布式系统的结构式由节点组成的一个P2P网络。
P2P网络
点对点技术,本质上也是基于C/S模式,简单来说每个网络节点既是客户端也是服务端,不存在中心的服务器。
内网穿透技术
(1) UDP打洞技术
最为常见的实现P2P的方式是采用UDP打洞技术,UDP打洞技术是通过中间服务器的协助在各自的NAT网关上建立相关的表项,使P2P连接的双方发送的报文能够直接穿透对方的NAT网关,从而实现P2P客户端互连。如果两台位于NAT设备后面的P2P客户端希望在自己的NAT网关上打个洞,那么他们需要一个协助者——集中服务器,并且还需要一种用于打洞的Session建立机制。
Session建立机制:
假定客户端A要发起对客户端B的直接连接,具体的“打洞”过程如下:
(1)A最初不知道如何向客户端B发起连接,于是A向集中服务器(本质上是一台被设置在公网上的服务器,建立P2P的双方都可以直接访问到这台服务器。位于NAT网关后面的客户端A和B都可以与一台已知的集中服务器建立连接,并通过这台集中服务器了解对方的信息并中转各自的信息)发送消息,请求集中服务器帮助建立与客户端B的UDP连接。
(2)集中服务器将含有B的外网和内网的地址二元组发给A,同时,集中服务器将包含有A的外网和内网的地址二元组信息的消息也发给B。这样一来, A与B就都知道对方外网和内网的地址二元组信息了。
(3)当A收到由集中服务器发来的包含B的外网和内网的地址二元组信息后, A开始向B的地址二元组发送UDP数据包,并且A会自动锁定第一个给出响应的B的地址二元组。同理,当B收到由集中服务器发来的A的外网和内网地址二元组信息后,也会开始向A的外网和内网的地址二元组发送UDP数据包,并且自动锁定第一个得到A回应的地址二元组。一旦A与B都向对方的NAT设备在外网上的地址二元组发送了数据包,就打开了A与B之间的“洞”,A与B向对方的外网地址发送数据,等效为向对方的客户端直接发送UDP数据包了。一旦应用程序确认已经可以通过往对方的外网地址发送数据包的方式让数据包到达NAT后面的目的应用程序,程序会自动停止继续发送用于“打洞”的数据包,转而开始真正的P2P数据传输。
当然,UDP转换协议提供的“洞”不是绝对可靠的,多数NAT设备内部都有一个UDP转换的空闲状态计时器,如果在一段时间内没有UDP数据通信,NAT设备会关掉由“打洞”过程打出来的“洞”。如果P2P应用程序希望“洞”的存活时间不受NAT网关的限制,就最好在穿越NAT以后设定一个穿越的有效期。
(2) TCP打洞技术
从现在的主流应用的角度上来看,基于TCP的P2P应用显然不如基于UDP的应用那么广泛,但是也存在打洞的需求。
TCP相对于UDP而言要复杂的多,TCP连接的建立要依赖于三次握手的交互,所以NAT网关在处理TCP连接的时候,需要更多的开销。但是,由于TCP协议完备的状态机机制,TCP反而比UDP更能精确的获取某个Session的生命期。
一种新的代理类型 XTCP 能解决这个问题,实现方式可以是采用搭建FRP服务器的方式,在传输数据的两端都部署上 FRP 客户端上用于建立直接的连接。实现方法点击此处
Gossip协议
Gossip协议是一种在分布式系统中用于节点间通信和数据同步的算法。这种协议通过“流言”(Gossip)方式传播信息,类似于人们通过口耳相传的方式传播小道消息。Gossip协议特别适用于大规模、无中心的网络环境,因为它不依赖于单一的通信路径或节点。
Gossip协议的工作原理大致如下:
随机性:每个节点定期与其他节点(通常是随机选择的)交换信息。这种随机选择的机制使得信息能够在网络中迅速扩散。
信息交换:当两个节点交互时,它们会交换彼此还没有的信息,或者更新对方的过时信息。这个过程可以比作两个人互相交换彼此还没有听说过的最新八卦。
冗余传播:由于每个节点都与多个其他节点交换信息,相同的信息会在网络中多次传播。这种冗余确保了信息即使在网络中存在故障的情况下也能可靠地传播。
收敛性:随着时间的推移,所有节点最终会获取到网络中的全部信息,达到一致的状态(收敛)。这个过程的速度取决于节点交换信息的频率和网络的结构。
Gossip协议有几个显著的优点:
可扩展性:它能够很好地扩展到大规模网络,因为每个节点只需要与少数几个其他节点通信。
容错性:由于信息通过多条路径传播,即使一些节点或连接失败,信息也可以通过其他路径传播。
去中心化:它不依赖于任何中心节点或结构,增强了网络的鲁棒性。
Gossip协议在多种场景中有应用,包括但不限于分布式数据库的数据同步、P2P网络、容错系统和一些基于微服务的架构中的服务发现机制。
Gossip协议类型
传播协议/谣言协议(Dissemination Protocols / Rumor-Mongering Protocols):
通过网络中的泛洪代理来工作,节点收到广播的数据后直接转发给所有的邻居节点;此方式可以提高网络的健壮性,但是容易造成广播风暴。
反熵协议(Anti-Entropy Protocols):用于修复复制数据,通过比较复制和协调差异进行操作;Hyperledger Fabric中的数据同步就是使用此方式实现。
计算聚合的协议(Protocols that Compute Aggregates):通过对网络中节点的信息进行采样,并将这些值组合起来得到系统范围内的值,从而计算出网络范围内的集合 ;之后将建立一种全面的信息流模式。
Gossip数据传输
Gossip 协议最终的目的是将数据分发到网络中的每一个节点,那么在不同的具体应用场景中如何保证网络中的每一个节点都能够接收到对应的数据且在不稳定的网络环境中保持数据的实时同步。
Gossip数据分发协议实现了两种数据传输方式:
推送方式(Push-based):
网络中的某个节点随机选择N个节点作为数据接收对象
该节点向其选中的N个节点传输相应的信息
接收到信息的节点处理它接收到的数据
接收到数据的节点再从第一步开始重复执行
拉取方式
某个节点周期性地选择随机N个节点询问有没有最新的信息
收到请求的节点回复请求节点其最近未收到的信息
CAP设计原则
一致性Consistency
所有节点在同一时间看到相同的数据。这意味着一旦数据更新,所有的读取操作都应该返回最新的值。
可用性Availability
每个请求都能得到响应,无论响应成功或失败。系统应该保证每个请求不会因为系统故障而失败。(即时响应性)
分区容错性Partition tolerance
系统应该能够在网络分区(即某些节点之间的通信断裂)的情况下继续运行。
三性权衡
CAP定理指出,在任何分布式系统中,最多只能同时满足上述三个特性中的两个。具体来说:
如果系统优先保证一致性和可用性(C和A),那么它可能无法处理网络分区。
简单理解,前提条件就是节点数据保持实时一致,节点面对请求始终有响应。如果出现节点通信不可靠时,节点实时响应请求,除非节点在同一个分区,否则数据就无法保持一致,故保证C、A无法处理网络分区。
如果系统优先保证一致性和分区容错性(C和P),那么在网络分区发生时,可能无法保持高可用性。
简单理解,网络分区发生时,如果要保证数据一致且系统正常运行,相关的服务就需要停止,等待恢复节点通信,直到数据达到一致才可对外提供服务。此时可用性就无法保证了。
如果系统优先保证可用性和分区容错性(A和P),那么在网络分区发生时,可能无法保持强一致性。
简单理解,网络分区时时,服务需要及时响应,若此时不同分区的节点之间仍未恢复通信,则数据无法保持一致。
Base设计理论
核心思想:牺牲强一致性来获取高可用性,只强调最终的结果一致性。即区块链的共识机制。
其实就是采用弱一致性模型来设计分布式系统。
一致性问题
分布式系统的一致性问题主要强调数据的一致性问题。
导致分布式系统数据不一致的原因
网络延迟: 导致节点数据同步出现延迟。
举个例子,x 值为1,客户端1要求节点A的更新x值为2,节点A需要同步给节点B,但由于延迟问题还没有完成同步,此时客户端2通过节点B读取x值得到的值仍为1,即当前情景下节点A、B数据不一致。
节点故障:某些节点可能因故障而未能接受或处理最新数据。
举个例子,节点B宕机,未处理到节点A的数据更新请求。
数据副本:在多个节点间维护数据副本时,同步更新可能导致不一致。
举个例子,多节点维护同一份账本,同步更新过程可能存在数据不一致的情况。主要考虑延迟、处理顺序、节点硬件配置、并发冲突等因素。
并发更新:多个节点同时对同一数据进行更新时可能导致冲突和不一致。
时钟偏差:分布式系统中的不同节点可能有时钟偏差,影响时间顺序的数据处理。
不同操作系统的中断逻辑可能不一样。
消息丢失或重复:网络问题可能导致数据包的丢失或重复发送。
重放攻击和丢包问题,存在一些简单的解决方式:时间戳和完整性验证(hash对比),验证不同通知重新发送数据。
一致性策略:如使用最终一致性而非严格一致性策略,会有过程不一致的情况出现。
一致性模型类型
目标:解决分布式系统的数据一致性问题.,保证节点之间关联的数据逻辑上完整且正确。
强一致性模型,即严格一致性模型。
弱一致性模型,即非严格一致性模型。
简单来说,两者的区别是,是否能保证数据的过程一致性,能就是强一致性,不能就是弱一致性。但需要进一步理解的是,paxos的达到提案一致的过程存在数据不一致的情况,但paxos也归属强一致性模型,目前的理解可以为“提案提出——接受——一致”的过程中数据处于一种不可用的状态,所以不属于过程不一致。
注:过程一致性的“过程”主要是指数据外部可用的过程。
一致性协议
两段提交(强一致性模型)
核心思想:是在分布式事务中保证原子性。当一个事务跨多个节点时,要么所有节点上的参与进程都提交事务,要么都取消事务,强调事务一致性。
优点:
强一致性
简单易实现
场景广泛支持
故障恢复
适用于分布式系统
存在的问题:(也就是在节点数量较少、网络比较稳定的前提下,可以考虑使用两段提交)
性能开销大,需要等待所有节点表决完。
若存在网络故障,进入一种无限等待的情况,即锁定状态。
协调者节点崩坏,业务崩溃。
Quorum(弱一致性模型)
鸽巢原理:假设有m个苹果,需要全部分配给n个人,当m=n+1时,至少存在一个人拥有2个苹果。
Quorum的主要作用的削弱一致性,增加可用性。
场景推导:当前有N个节点,节点数据X需要保持一致。
现有节点提出更新数据X,已知了M个节点更新数据X,当前已经读取R个节点的数据X,当R+M>N时(即R+M>=N+1),R中至少存在一个数据X为最新提交的版本。
进一步推导,若希望读取M个节点的X时,M中至少存在一个数据X为最新提交的版本,可以得到大于半数的不等式推导:

走读Writing an OS in Rust实验(四)
Li Guangqiao - 07/12/2023
VGA文本模式 参考原作者phil的官方博客 目标:VGA文本模式将字符打印到屏幕上,要实现此目标需要将字符写入到VGA硬件的文本缓冲区。VGA文本缓冲区是一个二维数组,通常有25行和80列,直接呈现到屏幕上。每个数组条目通过以下格式描述单个屏幕字符: 位值 0-7ASCII码 8-11前景色 12-14背景色 15闪烁位 第一个字节表示应以 ASCII 编码打印的字符。更具体地说,它并不完全是 ASCII,而是一个名为代码页 437 的字符集,其中包含一些附加字符和轻微修改。为简单起见,我们将在这篇文章中继续称其为 ASCII 字符。第二个字节定义字符的显示方式。前四位定义前景色,后三位定义背景色,最后一位定义字符是否应该闪烁。 数值位颜色数值位+明亮位亮色 0x0Black0x8Dark Gray 0x1Blue0x9Light Blue 0x2Green0xaLight Green 0x3Cyan0xbLight Cyan 0x4Red0xcLight Red 0x5Magenta0xdPink 0x6Brown0xeYellow 0x7Light Gray0xfWhite 明亮位是高4位,对于前景色是色调变亮;对于背景色则是用作闪烁位 VGA 文本缓冲区可通过内存映射的 I/O 访问地址。这意味着对该地址的读取和写入不会访问 RAM,而是直接访问 VGA 硬件上的文本缓冲区。这意味着我们可以通过正常的内存操作读取和写入该地址0xb8000 请注意,内存映射硬件可能不支持所有正常的 RAM 操作。例如,设备只能支持按字节读取,并在读取 a 时返回垃圾。幸运的是,文本缓冲区支持正常的读取和写入,因此我们不必以特殊方式处理它u64 Rust 模块 该模块用来处理字符打印逻辑 // in src/main.rs mod vga_buffer; 打印逻辑主要分为以下几步: 定义颜色 定义屏幕字符和文本缓冲区 实现打印方法 避免打印操作被编译器优化 实现格式化宏 实现下一行函数 暴露一个全局的接口 实现恐慌的错误提示 定义颜色 枚举颜色 #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] pub enum Color { Black = 0, //00000000 Blue = 1, //00000001 ...