仿`gRPC`功能实现像调用本地方法一样调用其他服务器方法
文章目录
仿 gRPC
功能实现像调用本地方法一样调用其他服务器方法
gRPC
功能实现像调用本地方法一样调用其他服务器方法 简介
在介绍gRPC
简介之前我们先了解一写概念:
单体架构
单体架构简单理解就是所有的业务代码都在一台服务器上,一旦某个服务宕机,会引起整个应用不可用,隔离性差。只能整体应用进行伸缩,例如整体打包部署一台或多台服务器,浪费资源,可伸缩性差。代码耦合在一起,可维护性差。
微服务架构
解决了单体架构的弊端。可按需拆成多个服务,例如针对用户的请求非常多,针对支付的请求少,可以将用户业务功能拆为多个服务器,支付业务功能拆为单个服务器。
也有一些弊端,例如代码冗余,同样的代码在多个服务器上都要写,例如接口等。服务与服务之间存在调用关系,服务拆分之后,就是服务和服务之间发生是进程与进程之间的调用,服务器与服务器之间的调用。
这时候就需要发起网络调用, 网络调用一般使用HTTP
,但是在微服务架构中,HTTP
虽然方便,但性能较低,这时候就需要引入RPC
(远程过程调用),通过自定义协议发起TCP
调用,来加快传输效率。
RPC
RPC
的全称是Remote Procedure Call
,远程过程调用。这是一种协议,是用来屏蔽分布式计算中的各种调用细节,使得你可以像是本地调用一样直接调用一个远程的函数。
gPRC
gRPC
是一个高性能、开源和通用的RPC
框架,面向移动和 HTTP/2
设计。目前提供 C
、Java
和 Go
语言版本,分别是:grpc
, grpc-java
, grpc-go.
其中 C
版本支持 C
, C++
, Node.js
, Python
, Ruby
, Objective-C
, PHP
和 C#
支持。
中文文档:http://doc.oschina.net/grpc
在gRPC
中,我们称调用方为client
,被调用方为server
。跟其他的RPC
框架一样,gRPC
也是基于服务定义的思想。简单的来讲,就是我们通过某种方式来描述一个服务,这种描述方式是语言无关的。在这个服务定义的过程中,我们描述了我们提供的服务服务名是什么,有哪些方法可以被调用,这些方法有什么样的入参,有什么样的回参。
也就是说,在定义好了这些服务、这些方法之后,gRPC
会屏蔽底层的细节,client
只需要直接调用定义好的方法,就能拿到预期的返回结果。对于server
端来说,还需要实现我们定义的方法。同样的,gRPC
也会帮我们屏蔽底层的细节,我们只需要实现所定义的方法的具体逻辑即可。
可以发现,在上面的描述过程中,所谓的服务定义,就跟定义接口的语义是很接近的。我更愿意理解为这是一种"约定”,双方约定好接口,然后server
实现这个接口,client
调用这个接口的代理对象。到于其他的细节,交给gRPC
。
gRPC
交互逻辑
服务端逻辑
- 创建
gRPC Server
对象,可以理解为它是Server
端的抽象对象。 - 将
server
(其包含需要被调用的服务端接口)注册到gRPC Server
的内部注册中心。- 这样可以在接受到请求时,通过内部的服务发现。发现该服务端接口并转接进行逻辑处理。
- 创建
Listen
,监听TCP
端口。 gRPC Server
开始lis.Accept
,直到Stop
。
客户端逻辑
- 创建与给定目标服务端的连接交互。
- 创建
server
的客户端对象。 - 发送
RPC
请求,等待同步响应,得到回调后返回响应结果。 - 输出响应结里。
示例图
如下图:业务服务器调用登录业务服务器,支付服务器,库存服务器。
原生实现仿gRPC
框架
因为gRPC
框架目前不支持IRIS/Caché
,所以这里我们了解gRPC
原理后,仿造gRPC
框架实现类似的功能。通过正常编写代码无感知的情况下调用其他服务器上的代码方法。
注:为了显示这里使用Caché
作为客户端,IRIS
作为服务端。
编写客户端方法
- 首先在客户端也就是调用端创建客户端类
Util.RPC.Client
,代码如下:%DispatchClassMethod
- 动态派发方法是实现无感知的关键。SERVERIP
- 目标服务端的IP
地址。PORT
- 目标服务端的端口号。
Class Util.RPC.Client Extends %RegisteredObject
{Parameter SERVERIP = "127.0.0.1";Parameter PORT = 7788;ClassMethod %DispatchClassMethod(class As %String, method As %String, args...) [ ServerOnly = 1 ]
{#; 客户端通信、客户端需要设置服务器IP与端口号#dim clientSocket As %IO.Socket = ##class(%IO.Socket).%New()s host = ..#SERVERIPs port = ..#PORTs clientSocket.TranslationTable = "UTF8"d clientSocket.Open(host, port, .sc)s obj = {} //注释1s obj.class = classs obj.method = methods params = []s i = ""for {s i = $o(args(i))q:(i = "")d params.%Push(args(i))}s obj.params = paramsd clientSocket.WriteLine(obj.%ToJSON()) //注释2while (1) {s data = clientSocket.ReadLine() if (data '= "" ){ //注释3ret data}}q $$$OK
}}
- 创建空类
M.Login
,M.Pay
,M.Stock
分别继承Util.RPC.Client
。- 目的是模拟交互接口,因为要调用其他服务器方法,首先要确定要调用的服务器接口名称。
-
按照常规调用方法的模式,来编写方法。
-
这里实际上是没有
Login
,Pay
,Stock
方法的,因为上一步创建的类为空类。 -
如果按照常规直接调用方法肯定会提示方法不存在的错误,这里实际上我们调用的是服务端的方法。
-
可以观察到,这里是按照正常调用类方法的方式编写的代码,并没有其他额外的操作。
-
Class M.RPC Extends %RegisteredObject
{/// d ##class(M.RPC).Biz()
ClassMethod Biz()
{w ##class(M.Login).Login("yx","123456"),!w ##class(M.Pay).Pay(100),!w ##class(M.Stock).Stock(3),!
}}
编写服务端方法
- 创建服务端监听
Util.RPC.Server
类,这里模拟的是gRPC
创建Server
对象,创建Listen
,监听TCP
端口。代码如下:- 参数
PORT
为服务端监听和开启的接口。
- 参数
Class Util.RPC.Server Extends %RegisteredObject
{Parameter PORT = 7788;/// d ##class(Util.RPC.Server).ServerRPC()
ClassMethod ServerRPC()
{#; 服务端通信、服务端需要打开端口,等待客户端通信#dim severSocket As %IO.ServerSocket = ##class(%IO.ServerSocket).%New()s port = ..#PORTs severSocket.TranslationTable="UTF8"s severSocket.ConnectionQueueSize = 2d severSocket.Open(port, 10, .sc)q:($$$ISERR(sc)) "Open:" _ $System.Status.GetOneErrorText(sc)d severSocket.Listen(10, .sc)q:($$$ISERR(sc)) "Listen:" _ $System.Status.GetOneErrorText(sc)while (1) {s data = severSocket.ReadLine()if (data '= "") {s obj = {}.%FromJSON(data) //注释1s arg = obj.params.%Size()for i = 1 : 1 : arg{s arg(i) = obj.params.%Get(i - 1)}s ret = $classmethod(obj.class, obj.method, arg...) //注释2d severSocket.WriteLine(ret) //注释3}}q $$$OK
}}
-
编写服务端
M.Login
的Login
方法,M.Pay
的Pay
方法,M.Stock
的Stock
方法。-
这里使用
IRIS
当服务端,实现的方法都在服务端,客户端是没有该方法的。 -
客户端调用的方法实际上是服务端的上的方法。
-
综合演示
-
IRIS
服务端开启监听方法。 -
客户端
Caché
调用无感知业务逻辑业务员Biz()
方法。-
可观察到客户端直接调用到了服务端的方法,并且编码方式跟正常编写代码并无差别。
-
客户端不需要了解底层的细节,
client
只需要直接调用定义好的方法。
-
通过这种方式我们就实现了类似gRPC
的功能,像正常编写代码一样调用服务端的程序。
创造价值,分享学习,一起成长,相伴前行,欢迎大家提出意见,共同交流。
相关文章:
![](https://img-blog.csdnimg.cn/493d7a73f7d34efca745ebceb981e32a.gif#pic_center)
仿`gRPC`功能实现像调用本地方法一样调用其他服务器方法
文章目录 仿gRPC功能实现像调用本地方法一样调用其他服务器方法 简介单体架构微服务架构RPCgPRC gRPC交互逻辑服务端逻辑客户端逻辑示例图 原生实现仿gRPC框架编写客户端方法编写服务端方法综合演示 仿 gRPC功能实现像调用本地方法一样调用其他服务器方法 简介 在介绍gRPC简介…...
![](https://img-blog.csdnimg.cn/bde7ae6359c44370bb3cb152dcfb4240.png)
分布式环境下的数据同步
一般而言elasticsearch负责搜索(查询),而sql数据负责记录(增删改),elasticsearch中的数据来自于sql数据库,因此sql数据发生改变时,elasticsearch也必须跟着改变,这个就是…...
![](https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=https://www.learnfk.com/guide/images/wuya.png)
无涯教程-Flutter - 数据库
SQLite" class"css-1occaib">SQLite数据库是基于事实和标准SQL的嵌入式数据库引擎,它是小型且经过时间考验的数据库引擎,sqflite软件包提供了许多函数,可以有效地与SQLite数据库一起使用,它提供了操作SQLite数据…...
![](https://img-blog.csdnimg.cn/344a998571554d87a362b157a43de47b.jpeg)
算法笔记:平衡二叉树
1 介绍 平衡二叉树(AVL树)是一种特殊的二叉搜索树(BST),它自动确保树保持低高度,以便实现各种基本操作(如添加、删除和查找)的高效性能。 ——>时间都维持在了O(logN)它是一棵空…...
![](https://www.ngui.cc/images/no-images.jpg)
redis 通用命令
目录 通用命令是什么 SET & GET keys EXISTS DEL EXPIRE TTL redis 的过期策略 定时器策略 基于优先级队列定时器 基于时间轮的定时器 TYPE 通过 redis 客户端和 redis 服务器交互。 所以需要使用 redis 的命令,但是 redis 的命令非常多。 通用命令…...
![](https://img-blog.csdnimg.cn/d838c8f45c61424daea1afa32781cf06.jpeg)
Pycharm配置及使用Git教程
文章目录 1. 安装PyCharm2. 安装Git3. 在PyCharm中配置Git插件4. 连接远程Gtilab仓库5. Clone项目代码6. 将本地文件提交到远程仓库6.1 git add6.2 git commit6.3 git push6.4 git pull 平时习惯在windows下开发,但是我们又需要实时将远方仓库的代码clone到本地&…...
![](https://www.ngui.cc/images/no-images.jpg)
CSS transition 过渡
1 前言 水平居中、垂直居中是前端面试百问不厌的问题。 其实现方案也是多种多样,常叫人头昏眼花。 水平方向可以认为是内联方向,垂直方向认为是块级方向。 下面介绍一些常见的方法。 2 内联元素的水平垂直居中 首先,常见内联元素有&…...
![](https://img-blog.csdnimg.cn/3324bcb653b84d5abd3e95981b68059f.gif)
Unity中Shader的UV扭曲效果的实现
文章目录 前言一、实现的思路1、在属性面板暴露一个 扭曲贴图的属性2、在片元结构体中,新增一个float2类型的变量,用于独立存储将用于扭曲的纹理的信息3、在顶点着色器中,根据需要使用TRANSFORM_TEX对Tilling 和 Offset 插值;以及…...
![](https://img-blog.csdnimg.cn/bb111097ddd642259b21fe2e01fcb84f.png)
Automotive 添加一个特权APP
Automotive 添加一个特权APP platform: android-13.0.0_r32 一. 添加一个自定义空调的app为例 路径:packages/apps/Car/MyHvac app内容可以自己定义,目录结构如下: 1.1 Android.bp package {default_applicable_licenses: ["Andr…...
![](https://www.ngui.cc/images/no-images.jpg)
自定义TimeLine
自定义TimeLine 什么是TimeLineData(数据)Clip(片段)Track(轨道)Mixer(混合) 什么是TimeLine 在 Unity 中,TimeLine(时间轴)是一种用于创建和管理…...
![](https://www.ngui.cc/images/no-images.jpg)
如何使用SQL系列 之 如何在SQL中使用WHERE条件语句
引言 在结构化查询语言 (SQL)语句中,WHERE子句限制了给定操作会影响哪些行。它们通过定义特定的条件(称为搜索条件)来实现这一点,每一行都必须满足这些条件才能受到操作的影响。 本指南将介绍WHERE子句中使用的通用语法。它还将概述如何在单个WHERE子句…...
![](https://img-blog.csdnimg.cn/44b68787936d4b98b53480e3a8d9295b.png)
leetcode:1941. 检查是否所有字符出现次数相同(python3解法)
难度:简单 给你一个字符串 s ,如果 s 是一个 好 字符串,请你返回 true ,否则请返回 false 。 如果 s 中出现过的 所有 字符的出现次数 相同 ,那么我们称字符串 s 是 好 字符串。 示例 1: 输入:s…...
![](https://www.ngui.cc/images/no-images.jpg)
Echarts 各种点击事件监听
目录 一、鼠标事件1.1、左击1.2、双击1.3、右击1.4、右键双击1.5、中轴滚动二、时间轴2.1、时间轴监听三、拖动3.1、拖动事件一、鼠标事件 1.1、左击 chart.on(click, function(params)...
![](https://img-blog.csdnimg.cn/bdd4f87824db4c649b5bdfdeea33ffda.png)
《智能网联汽车自动驾驶功能测试规程》
一、 编制背景 2018 年4 月12 日,工业和信息化部、公安部、交通运输部联合发布《智能网联汽车道路测试管理规范(试行)》(以下简称《管理规范》),对智能网联汽车道路测试申请、审核、管理以及测试主体、测试驾驶人和测试车辆要求等…...
![](https://img-blog.csdnimg.cn/f6e4e4d43d504585a39b3e8918e3ca64.png)
NVIDIA CUDA Win10安装步骤
前言 windows10 版本安装 CUDA ,首先需要下载两个安装包 CUDA toolkit(toolkit就是指工具包)cuDNN 1. 安装前准备 在安装CUDA之前,需要完成以下准备工作: 确认你的显卡已经正确安装,在设备管理器中可以看…...
![](https://img-blog.csdnimg.cn/cfe9410b8dd6416fb39eff19d8287e28.png)
Elasticsearch、Kibana以及Java操作ES 的快速使用
docker 安装elastic search 、 kibana(可视化管理elastic search) docker pull elasticsearch:7.12.1 docker pull kibana:7.12.1创建docker自定义网络 docker自定义网络可以使得容器之间使用容器名网络互连,默认的网络不会有这功能。 一定…...
![](https://www.ngui.cc/images/no-images.jpg)
逐鹿人形机器人,百度、腾讯、小米卷起来
长期不温不火的人形机器人产业迎来新风口,技术显著提升、新品层出不穷、资本投资态度也逐渐好转。 8月18日,2023世界机器人大会博览会正式开放,全面展示了机器人行业的新技术、新产品和新应用。据悉,此次展会展览总面积达4.5万平…...
![](https://www.ngui.cc/images/no-images.jpg)
AndroidStudio推荐下载和配置
1、推荐下载链接 Download Android Studio & App Tools - Android Developers 2、gradle配置案例 // Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories {maven { url https://maven.aliyun.…...
![](https://www.ngui.cc/images/no-images.jpg)
mysql异常占用资源排查
通过执行日志与连接信息排查 查看是否开启日志记录 mysql> show global variables like %general%; --------------------------------- | Variable_name | Value | --------------------------------- | general_log | OFF | | general_log_file…...
![](https://www.ngui.cc/images/no-images.jpg)
requests 库:发送 form-data 格式的 http 请求 (python)
安装 requests-toolbelt !pip install requests-toolbeltdemo from requests_toolbelt import MultipartEncoder import requestsm MultipartEncoder(fields{query: """第一,向量化匹配是有能力上限的。搜索引擎实现语义搜索已经是好几年的事情了…...
![](https://img-blog.csdnimg.cn/40520506b62e4f64a8e758fc448d8b68.png)
行测图形推理规律(一)元素组成
题库:粉笔网题库 (fenbi.com) 不知道和测评的行测题库是不是一样的,但是总结的规律应该是一样的。 规律并不唯一,题库的答案也只是参考答案,切勿当杠精,你觉得你的规律更合适就别管。本人所归纳的规律仅代表本人想法…...
![](https://img-blog.csdnimg.cn/af21faeae6ac4725b373bc2b4bebb59f.png)
【python爬虫】13.吃什么不会胖(爬虫实操练习)
文章目录 前言项目实操明确目标分析过程代码实现 前言 吃什么不会胖——这是我前段时间在健身时比较关注的话题。 相信很多人,哪怕不健身,也会和我一样注重饮食的健康,在乎自己每天摄入的食物热量。 不过,生活中应该很少有人会…...
![](https://www.ngui.cc/images/no-images.jpg)
深入理解联邦学习——联邦学习与现有理论的区别与联系
分类目录:《深入理解联邦学习》总目录 作为一种全新的技术,联邦学习在借鉴一些成熟技术的同时也具备了一定的独创性。下面我们就从多个角度来阐释联邦学习和其他相关概念之间的关系。 联邦学习与差分隐私理论的区别 联邦学习的特点使其可以被用来保护用…...
![](https://img-blog.csdnimg.cn/img_convert/46a2618df85d860719dc0b38766308d7.jpeg)
基于Python+DenseNet121算法模型实现一个图像分类识别系统案例
目录 介绍在TensorFlow中的应用实战案例最后 一、介绍 DenseNet(Densely Connected Convolutional Networks)是一种卷积神经网络(CNN)架构,2017年由Gao Huang等人提出。该网络的核心思想是密集连接,即每…...
![](https://www.ngui.cc/images/no-images.jpg)
旋转图片两种方法
这两种方法在旋转图像时,可能会产生一些不同的效果: rotate_image_new()旋转后的图像完全包含旋转前的内容,并且填充边界尽可能小 rotate_image() 保持原始图像的大小,并根据填充选项决定是否填充边界为白色。如果 if_fill_whit…...
![](https://img-blog.csdnimg.cn/b7cf359e7de44899bd4e6fbbd2f85ea9.png)
10 mysql tiny/small/medium/big int 的数据存储
前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 int 类类型的相关数据的存储 …...
![](https://img-blog.csdnimg.cn/8b1d1b46e047429cba0f4a2a115d53d7.png)
UI自动化测试之Jenkins配置
团队下半年的目标之一是实现自动化测试,这里要吐槽一下,之前开发的测试平台了,最初的目的是用来做接口自动化测试和性能测试,但由于各种原因,接口自动化测试那部分功能整个废弃掉了,其中和易用性有很大关系…...
![](https://img-blog.csdnimg.cn/4f2d87dc6de24aeab1eccc132e6b4efd.png)
电视盒子什么品牌好?数码博主盘点目前性能最好的电视盒子
电视盒子是非常重要的,老人小孩基本每天都会看电视,而电视盒子作为电视盒子的最佳拍档销量十分火爆,我自己每个月都会测评几次电视盒子,今天给大家详细解读一下电视盒子什么品牌好,看看目前性能最好的电视盒子是哪些&a…...
![](https://www.ngui.cc/images/no-images.jpg)
对于枚举类型的输出
对于枚举类型的输出 对于枚举类型的输出,您可以使用以下方法:1. 将枚举值转换为整数进行输出:cppODU_TYPE type ODU_TYPE_331;int value static_cast<int>(type);std::cout << "ODU_TYPE: " << value <<…...
![](https://img-blog.csdnimg.cn/e074ae3af8ae432da5f7bacd597ecd1d.png)
solidity开发环境配置,vscode搭配remix
#学习笔记 初学solidity,使用remix非常方便,因为需要的环境都配置好了,打开网站就可以使用。 不过在编写代码方面,使用vscode更方便,而vscode本身并不能像remix那样部署合约,它还需要安装插件。 点击红色箭…...
![](https://img-blog.csdnimg.cn/img_convert/ccf60b5f64612f9dbf968577874fb175.gif)
如何快速推广一个网站/seo优化服务是什么意思
电工之家:www.dgzj.com QQ群:2179090关注电工之家官方微信公众号“电工之家”,收获更多经验知识灯带电压不足是因为导线的压降过大,因为导线的材料、线径一定时,导线的长度越长,导线的电阻就越大…...
![](https://img-blog.csdnimg.cn/a23c48ab170e4c2eb10d9a401ed6f48d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5rW36IulW01BVFJJWF0=,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
一个空间放几个网站/网络推广客服好做吗
set hive.cli.print.headertrue 1.设置前 2.设置后 3.进阶设置(点击下方链接查看) Hive sql查询结果显示表头(header)如何配置:只显示列名,不显示表名...
![](/images/no-images.jpg)
建网站怎么备案/semester什么意思
在学习递归方法之前,我们首先得知道什么是递归? 什么是递归方法呢?通俗易懂的说就是方法本身调用自身。 可以设计模型为 a( ){ a( ); } 方法递归的调用代码 public class digui{public static void main(String[] args){System.out.pr…...
![](/images/no-images.jpg)
深圳p2p网站建设/做销售有什么技巧和方法
一、忘记除SYS、SYSTEM用户之外的用户的登录密码。用SYS (或SYSTEM)用户登录: CONN SYS/PASS_WORD AS SYSDBA;使用如下语句修改用户的密码: ALTER USER user_name IDENTIFIED BY "newpass";注意:密码不能全是数字。并且不能是数字开头。否则会出现&#x…...
![](https://img-blog.csdnimg.cn/img_convert/67d0865f17d9be527254bf8a8ff6c5b4.gif)
新开传奇网站单职业/推广平台排行榜app
一、NDK中获取android设备ID的方式Java代码如下(获取设备ANDROID_ID):final String androidId Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);对应的c代码(相当蛋疼),注意如果是C,需要把所有的(*env)->替换成env-&…...
![](http://static.oschina.net/uploads/space/2016/0429/150902_xhuX_2613440.png)
具有价值的做网站/如何制定会员营销方案
2019独角兽企业重金招聘Python工程师标准>>> // MARK: 需要用 convenience 声明 遍历构造函数 convenience init(normalImage: UIImage,highlightedImage: UIImage?) { // 必须先 调用本类的指定构造函数 实例化自己 self.init(); …...