RPC几大特性

RPC的几大特点 这几个特点都是为了在高并发的情况下,RPC能够平稳正常的实现!!! 服务发现 为了高可用,在生产环境中服务提供方都是以集群的方式对外提供服务,集群里面的这些 IP 随时可能变化,我们也需要用一本“通信录”及时获取到对应的服务节点,这个获取的过程一般叫作“服务发现”。 对于服务调用方和服务提供方来说,其契约就是接口,相当于“通信录”中的姓名,服务节点就是提供该契约的一个具体实例。服务 IP 集合作为“通信录”中的地址,从而可以通过接口获取服务 IP 的集合来完成服务的发现。 服务发现 网络IO 首先我们知道RPC 是解决进程间通信的一种方式。一次 RPC 调用,本质就是服务消费者与服务提供者间的一次网络信息交换的过程。服务调用者通过网络 IO 发送一条请求消息,服务提供者接收并解析,处理完相关的业务逻辑之后,再发送一条响应消息给服务调用者,服务调用者接收并解析响应消息,处理完相关的响应逻辑,一次 RPC 调用便结束了。可以说,网络通信是整个 RPC 调用流程的基础。 常见的网络 IO 模型 那说到网络通信,就不得不提一下网络 IO 模型。为什么要讲网络 IO 模型呢?因为所谓的两台 PC 机之间的网络通信,实际上就是两台 PC 机对网络 IO 的操作。 常见的网络 IO 模型分为四种:同步阻塞 IO(BIO)、同步非阻塞 IO(NIO)、IO 多路复用和异步非阻塞 IO(AIO)。在这四种 IO 模型中,只有 AIO 为异步 IO,其他都是同步IO。 其中,最常用的就是同步阻塞 IO 和 IO 多路复用,这一点通过了解它们的机制,你会 get到。至于其他两种 IO 模型,因为不常用,则不作阐述。 阻塞 IO(blocking IO) 同步阻塞 IO 是最简单、最常见的 IO 模型,在 Linux 中,默认情况下所有的 socket 都是blocking 的,先看下操作流程。...

2022-05-24 · qinzhuzhu

RPC具体的细节

RPC项目具体细节 在实现RPC框架的整体步骤中,需要弄清楚caller与callee的通信过程,那么就需要针对protobuf进行具体的了解。 protobuf 三大方面:在整体框架上,需要对这三部分进行继承与重写 Service 当在 protobuf 定义了 service UserServiceRpc 后,经过 protoc 编译后,会生成两个类 class UserServiceRpc 和 class UserServiceRpc_stub,UserServiceRpc 是继承于 service 基类,UserServiceRpc_stub 是继承于 UserServiceRpc 。UserServiceRpc 是供给 rpc 服务发布者(生产者)使用,UserServiceRpc_stub 是供给 rpc 服务的调用方使用。 在 service UserServiceRpc 里定义的函数方法,都会在UserServiceRpc_stub 中提供,底层源码的所有方法都是调用 RpcChannel 的 CallMethod 方法 对 CallMethod 函数进行追踪,发现 RpcChannel 是一个抽象类,CallMethod 是一个纯虚函数,而调用的方法在底层上都调用了 CallMethod 函数,那么这个 CallMethod 就必须重写。 当客户端stub调用远程函数或者方法时,底层调用 CallMethod 是同步调用,也就是说,会一直阻塞等待调用的结果。 那么如果调用失败,该如何得知当前RPC的调用状态呢?因此就需要使用 RpcController 来记录RPC方法调用过程中的错误信息 RpcController 在 RpcController 主要有3个纯虚函数,因此也需要重写这三个函数。三个函数包括 Reset() Failed() ErrorText() 这三个函数记录了错误信息 RpcChannel 由上面的介绍可知,RpcChannel内部只有一个函数,就是调用函数 全部过程 文字版 具体函数 致谢 感谢大佬...

2022-05-22 · qinzhuzhu

RPC项目介绍

项目整体介绍 项目的流程图 1.1 Zookeeper 注册中心会把这个服务提供者的地址信息以及提供的服务对象名以及函数方法名保存下来 Zookeeper有两种库用于注册,分别为zookeeper_st(单线程库)和zookeeper_mt(多线程库),一般使用zookeeper_mt的API。 在客户端,如果使用zookeeper_mt库,需要使用三个线程: 主线程:用户调用API线程 IO线程:负责网络通信的线程 completion线程:对于异步请求(Zookeeper中提供的异步API)以及watcher的响应回调,IO线程会发送给completion线程完成处理 Watcher机制 zookeeper中最重要的就是实现watcher机制。 该机制具体过程: ZooKeeper客户端(Callee)首先将Watcher注册到服务端,同时把Watcher对象保存到客户端的Watcher管理器中。当ZooKeeper服务端监听到ZooKeeper中的数据状态发生变化时,服务端主动通知客户端(告知客户端事件类型和状态类型),接着客户端的Watch管理器会触发相关Watcher来回调相应处理逻辑(GlobalWatcher),从而完成整体的数据发布/订阅流程。 Zookeeper C API 博客 (https://cloud.tencent.com/developer/article/1142948) 1.2 protobuf protobuf能够提供对数据的序列化和反序列化,可用于结构化的数据的串行序列化,使用Key-Value格式存储数据,因为采用二进制格式,所以序列化的数据比较小。 其中消息体进行了嵌套,关键字message为方法,而service为服务名,而编译的代码: protoc user.proto -I ./ -cpp_out=./user 基本过程是:Caller远端调用Login函数,Callee执行Login函数并返回结果,Caller获取返回结果 protobuf相关介绍 (https://cloud.tencent.com/developer/article/1176660) 1.3 网络库 在网络库部分,目前muduo库,也有自造的web服务器轮子。 未完待续… 致谢 感谢大佬 (https://blog.csdn.net/T_Solotov/article/details/124170856) (https://blog.csdn.net/qq_45132647?type=blog)

2022-05-20 · qinzhuzhu

初识RPC

个人对RPC的理解 在如今微服务盛行的时代,RPC最主要的用处是,解决分布式系统通信问题。个人理解是,之前我们在本地写代码,调用本地的函数等,现在由于微服务,将函数等放到了远程的服务器上,需要远程调用。因此就需要开发出一套框架,使得我们能够在调用服务器上的函数时跟调用本地函数一样,不出错,能够实现函数的功能!当然这只是粗浅的认识,对于RPC,包含很多东西,比如负载均衡、异步调用等等,目前还在进一步的学习。👊👊👊 RPC整体的流程 RPC具体的几大模块 客户端 在客户端,跟之前调用本地函数有所不同,除了必要的函数方法名,函数参数等,还需要传入请求的服务对象名。同时使用TCP传输,需要处理拆粘包问题,保证数据正确传输,因此这部分跟Http协议的请求头、响应头相似,需要自己确定一套数据消息传输格式。而在调用时,分为同步调用和异步调用。所谓异步调用,就是在进行RPC远端调用之后,不等待结果,直接运行其它不需要RPC调用结果的代码,等远端调用得到结果之后,再处理需要结果的部分。这样可以提高客户端的吞吐量。 序列化和反序列化 序列化和反序列化,有几种适合序列化的协议,如Json、protobuf、Hessian等。 这部分就涉及到序列化协议的选型问题。在选择时,需要考虑以下几点: 序列化和反序列化的性能效率以及空间消耗,这一点直接影响整体RPC框架的性能和效率。 协议的通用性与兼容性 这部分目前对于我来说可能是最重要的,因为目前作为初学者,更重要的是,先跑通整体代码,等日后有了更深入的学习,再来完善其他几点。基于此选择目前的Protobuf(用的人挺多的好像👽👽👽) 协议的安全性 Protobuf 目前项目中使用的是就是Protubuf,网上也有很多关于Protobuf的教程,这里就不赘述了。主要就是把我们要发送的消息数据序列化成二进制数据。 针对这个消息数据,我们需要自己手动定义格式,为 .proto 文件 在发送的时候,需要按照 .proto 文件定义的参数进行发送,同时也需要发送函数的参数,这时间就需要明确头信息与函数参数的分界点。 传输协议 在使用序列化获得需要发送的数据之后,需要进行传输,而传输所使用的协议,可以用HTTP2、TCP、自定义的传输协议等等,从这里可以看出RPC和HTTP的关系,它们彼此独立,又可以使用。而对于RPC,相比于HTTP协议,会有更多的特性,比如:负载均衡、服务发现等等。 服务端 在服务端,需要接受经过序列化之后的数据包,进行拆包、消息解码、反序列化等,再根据解码出来函数名调用业务逻辑处理函数。 这部分仿照web服务器的思路,类似于Reactor模式,使用IO线程处理数据包的拆解,解码和反序列化等等工作,而业务逻辑使用线程池中的工作线程。 注册中心 最后一个问题,就是通信双方怎么知道对方是谁。对于客户端来说,自己想要调用的服务方法在哪台服务器上,如何通信? 针对这个问题,我们需要对服务器上服务对象方法以及对应服务器的IP进行记录,也就是注册中心集群,而获得服务对象方法提供者地址信息的过程叫服务发现。 两个功能: 服务注册:服务提供方在正式提供服务之前需要把自己的服务对象方法注册到注册中心上,注册中心会把这个服务提供者的地址信息以及提供的服务对象名以及函数方法名保存下来。 服务订阅:在服务调用方启动时,会去注册中心找自己需要的服务对象对应的服务提供者的地址信息,然后缓存到本地。 Zookeeper 而使用的注册中心,使用的是Zookeeper。这部分就涉及到分布式系统的一些概念,比如:CAP理论和BASE理论等等,目前还在进一步的学习。Zookeeper具有强一致性,只要有一个节点更新了,就会要求其他节点一起更新,保证每一个节点的数据都是完全实时同步的,所有节点上的数据在没有完全同步之前,不处理程序。由此可知,当分布式环境提供的服务和访问的机器越多,变化越多,Zookeeper就不理想了。 Zookeeper是一个开源的分布式协调服务,设计的目标是将复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。 目前先学习Zookeeper的使用,理论部分后续加强。 存储数据 服务端的示意图(还有客户端的数据,没有展示) 注册中心的管理者会在Zookeeper下创建一个服务根路径,可以根据接口来命名(对应最左边,最上边的“/”路径),根据这个路径再创建服务提供方的目录与服务这个方法的服务器的IP:Port 服务提供方注册的时候,在发起注册时,会在服务提供方目录中创建一个临时节点node,这个节点存储服务提供方的注册信息,比如UserServiceRpc/Login节点中存的就是提供这个方法的服务器的IP端口号。 服务调用方发起订阅时,服务调用方目录会创建一个临时节点,临时节点中存储调用方信息 当服务提供方的目录中节点发起了任何变化(新增节点、移除节点、节点上数据变动等等),Zookeeper就会通知发起订阅的服务调用方 翻译过来: ZooKeeper相当于是一个特殊的文件系统,不过和普通文件系统不同的是,这些节点都可以设置关联的数据,而文件系统中只有文件节点可以存放数据,目录节点不行。ZooKeeper内部为了保持高吞吐和低延迟,再内存中维护了一个树状的目录结构,这种特性使ZooKeeper不能存放大量数据,每个节点存放数据的上线为1M。 服务对象名在ZooKeeper中以永久性节点的形式存在,当RpcServer与ZooKeeper断开连接后,整个节点还是会存在。方法对象名则以临时性节点存在,RpcServer与ZooKeeper断开后临时节点被删除。临时节点上带着节点数据,在本项目中,节点数据就是提供该服务方法的RpcServer的通信地址(IP+Port)。 Watcher机制 对于上面的第四点,这个是Zookeeper最重要的内容。就是在服务提供方目录中节点变化之后,Zookeeper该如何通知订阅的服务调用方。–Watcher机制 对于客户端来说,保存了若干服务对象方法的服务提供者的地址信息,如果有一个服务提供者出现问题,在Zookeeper中表现为服务提供方的某一个节点消失了。此时就需要告知客户端,该节点消失,无法继续提供服务,在本地也就需要将该节点删除。 Watcher机制是在客户端进行实现的,具体作用是,在运行之前,客户端告知服务端,如果服务端某一个节点或者这些子节点发生变化,都必须通知客户端。而对于服务端来说,该如何告知客户端呢?这就要求客户端必须在Zookeeper服务端上注册对某个节点的watch事件。服务端发给客户端watch通知,不过发送的watch通知里面不会包含某一个节点数据,只是高索节点发生了设么watch事件。同时watch的触发是一次性触发,假如某一个客户端收到这个watch通知之后,如果后续还想收到相同节点的watch通知,就必须再注册一次对这个节点的watch事件(Zookeeper3....

2022-05-20 · qinzhuzhu

heli上网

解决代理服务器一直使用自动设置代理中的设置脚本选项 问题 按照这个网页,修改

2022-05-16 · qinzhuzhu

介绍刷题时的常用小技巧_02

2022-05-16 · qinzhuzhu

介绍刷题时的常用小技巧_01

Leetcode常用的小技巧(刷题必备) 由于之前刷题时,使用notion作为日常笔记,一些技巧也都记在了notion上,现在对笔记进行整理 这部分在写的时候,可能会比较乱,因为刷题的时候,没有按照链表、树,这种分类强的,整理的时候尽量处理到一起。

2022-05-16 · qinzhuzhu

秋招安排

秋招安排 时间飞逝,转眼自己也要进入社会的大熔炉之中,今年的形式又是格外的难顶,加油把,前进的人!!! 首先,几个方面,作为跳槽进入互联网的小白,唯有笨鸟先飞 求职方向:C++ 职业必备: C++基础知识:包括《C++ primer》、《Effective C++》、《STL源码剖析》等 八股文:计算机网络、操作系统、数据库、设计模式 算法:数据结构、Leetcode 项目: 底层、分布式等等吧 感觉最重要的应该是,对新技术有一颗想接触的心,不论什么困难,自己都会想办法克服,实现自己的想法。 对于秋招,心态肯定是第一位的,回顾高考的情况,自己应该能从中学到点东西,放开手,干就完事了!!! 接下来,一天一篇算法 + 一篇八股文,充实生活,充实自己,加油

2022-05-16 · qinzhuzhu

建站之路

使用hugo + nginx,在阿里云服务器上部署自己的博客 配置hugo的主题 主题 人麻了,hugo使用的是go语言编写的,以其轻便、快捷、方便出名,但是我配这个,配到吐,一开始想用hugo + github.io 这个组合的,但是由于你懂的原因,github上不去,而且机场也不是很好用,所以尝试了很多次,最后放弃。 由于之前曾经白嫖过阿里云的服务器,自己也购买了域名,并作了备案。所以又变成了hugo + nginx 😭😭,hugo的安装就不介绍了,最重要的是主题的选择,本人选了PaperMod,当时赶脚挺简洁的,就入坑了。 hugo的主题设置,我主要参考的是 大神的配置方案(感谢大神,ღ( ´・ᴗ・` )比心),只不过需要强调的是,一开始的时候,出现了在使用 hugo -F --cleanDestinationDir 的命令之后,打开网站之后,发现没有将部署的博客展示出来,最后经过排查发现,对于baseURL:这个配置项,不能写成www.xxx.com这种形式,必须加上http://,这是第一个注意点 而对于展示的评论区,标签等等,都需要在layouts文件下再加入其他的文件,如下示例 这部分参考的是另几个大神,感谢 感谢 多次尝试就变成了现在的网页(可能这里面有些坑,但自己不走过怎么能叫坑呢???😅😅😅) 文章头部的配置信息 对于文章头部的配置信息,参考第一个链接,然后根据自己的需要进行相应的调整,即可 nginx 服务器是阿里云的,在安装anginx时,尝试了很多教程的方法之后,最终选择 安装aginx第二种方式,使用安装包的方法,这种最稳定,同时需要注意执行./configure时,需要装上ssl_mode等,不然就会在http->https时出现问题。 http -> https 在阿里云服务器,使用 Certbot 申请 LetsEncrypt 泛域名免费证书,并实现自动续订, 亲测有用的链接 ,其中需要为RAM用户创建AccessKey,参考 阿里云官方 在运行的时候,发现Nginx未开启SSL模块,配置Https时提示错误,参考 感谢,最终处理了问题。🌹🌹🌹 省去www + http自动跳转https 为了访问的便捷,肯定希望直接输入xxx.com就能访问,如果想实现这个,以本人为例,从阿里云上购买的域名,因此需要在阿里云的域名解析上,定义好相应的规则@.xxx.com和www.xxx.com两种,再在nginx.conf的几个位置配置rewrite ^(.*)$ https://www.$server_name$1 permanent;以及rewrite ^(.*)$ https://$host$1 permanent;等代码,这部分由于网上有很多的教程,就不赘述,只是有很多教程可能只适合他(她)自己的服务器😅😅😅 nginx命令 cd /usr/local/nginx/sbin ./nginx -t ./nginx ./nginx -s reload ./nginx -s stop hugo -F --cleanDestinationDir

2022-05-15 · qinzhuzhu

第一篇博客

一切为了生活,一切为了更好地生活 未完待续… 加油

2022-05-14 · qinzhuzhu