仿`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的功能,像正常编写代码一样调用服务端的程序。
创造价值,分享学习,一起成长,相伴前行,欢迎大家提出意见,共同交流。
相关文章:
仿`gRPC`功能实现像调用本地方法一样调用其他服务器方法
文章目录 仿gRPC功能实现像调用本地方法一样调用其他服务器方法 简介单体架构微服务架构RPCgPRC gRPC交互逻辑服务端逻辑客户端逻辑示例图 原生实现仿gRPC框架编写客户端方法编写服务端方法综合演示 仿 gRPC功能实现像调用本地方法一样调用其他服务器方法 简介 在介绍gRPC简介…...
分布式环境下的数据同步
一般而言elasticsearch负责搜索(查询),而sql数据负责记录(增删改),elasticsearch中的数据来自于sql数据库,因此sql数据发生改变时,elasticsearch也必须跟着改变,这个就是…...
无涯教程-Flutter - 数据库
SQLite" class"css-1occaib">SQLite数据库是基于事实和标准SQL的嵌入式数据库引擎,它是小型且经过时间考验的数据库引擎,sqflite软件包提供了许多函数,可以有效地与SQLite数据库一起使用,它提供了操作SQLite数据…...
算法笔记:平衡二叉树
1 介绍 平衡二叉树(AVL树)是一种特殊的二叉搜索树(BST),它自动确保树保持低高度,以便实现各种基本操作(如添加、删除和查找)的高效性能。 ——>时间都维持在了O(logN)它是一棵空…...
redis 通用命令
目录 通用命令是什么 SET & GET keys EXISTS DEL EXPIRE TTL redis 的过期策略 定时器策略 基于优先级队列定时器 基于时间轮的定时器 TYPE 通过 redis 客户端和 redis 服务器交互。 所以需要使用 redis 的命令,但是 redis 的命令非常多。 通用命令…...
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到本地&…...
CSS transition 过渡
1 前言 水平居中、垂直居中是前端面试百问不厌的问题。 其实现方案也是多种多样,常叫人头昏眼花。 水平方向可以认为是内联方向,垂直方向认为是块级方向。 下面介绍一些常见的方法。 2 内联元素的水平垂直居中 首先,常见内联元素有&…...
Unity中Shader的UV扭曲效果的实现
文章目录 前言一、实现的思路1、在属性面板暴露一个 扭曲贴图的属性2、在片元结构体中,新增一个float2类型的变量,用于独立存储将用于扭曲的纹理的信息3、在顶点着色器中,根据需要使用TRANSFORM_TEX对Tilling 和 Offset 插值;以及…...
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…...
自定义TimeLine
自定义TimeLine 什么是TimeLineData(数据)Clip(片段)Track(轨道)Mixer(混合) 什么是TimeLine 在 Unity 中,TimeLine(时间轴)是一种用于创建和管理…...
如何使用SQL系列 之 如何在SQL中使用WHERE条件语句
引言 在结构化查询语言 (SQL)语句中,WHERE子句限制了给定操作会影响哪些行。它们通过定义特定的条件(称为搜索条件)来实现这一点,每一行都必须满足这些条件才能受到操作的影响。 本指南将介绍WHERE子句中使用的通用语法。它还将概述如何在单个WHERE子句…...
leetcode:1941. 检查是否所有字符出现次数相同(python3解法)
难度:简单 给你一个字符串 s ,如果 s 是一个 好 字符串,请你返回 true ,否则请返回 false 。 如果 s 中出现过的 所有 字符的出现次数 相同 ,那么我们称字符串 s 是 好 字符串。 示例 1: 输入:s…...
Echarts 各种点击事件监听
目录 一、鼠标事件1.1、左击1.2、双击1.3、右击1.4、右键双击1.5、中轴滚动二、时间轴2.1、时间轴监听三、拖动3.1、拖动事件一、鼠标事件 1.1、左击 chart.on(click, function(params)...
《智能网联汽车自动驾驶功能测试规程》
一、 编制背景 2018 年4 月12 日,工业和信息化部、公安部、交通运输部联合发布《智能网联汽车道路测试管理规范(试行)》(以下简称《管理规范》),对智能网联汽车道路测试申请、审核、管理以及测试主体、测试驾驶人和测试车辆要求等…...
NVIDIA CUDA Win10安装步骤
前言 windows10 版本安装 CUDA ,首先需要下载两个安装包 CUDA toolkit(toolkit就是指工具包)cuDNN 1. 安装前准备 在安装CUDA之前,需要完成以下准备工作: 确认你的显卡已经正确安装,在设备管理器中可以看…...
Elasticsearch、Kibana以及Java操作ES 的快速使用
docker 安装elastic search 、 kibana(可视化管理elastic search) docker pull elasticsearch:7.12.1 docker pull kibana:7.12.1创建docker自定义网络 docker自定义网络可以使得容器之间使用容器名网络互连,默认的网络不会有这功能。 一定…...
逐鹿人形机器人,百度、腾讯、小米卷起来
长期不温不火的人形机器人产业迎来新风口,技术显著提升、新品层出不穷、资本投资态度也逐渐好转。 8月18日,2023世界机器人大会博览会正式开放,全面展示了机器人行业的新技术、新产品和新应用。据悉,此次展会展览总面积达4.5万平…...
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.…...
mysql异常占用资源排查
通过执行日志与连接信息排查 查看是否开启日志记录 mysql> show global variables like %general%; --------------------------------- | Variable_name | Value | --------------------------------- | general_log | OFF | | general_log_file…...
requests 库:发送 form-data 格式的 http 请求 (python)
安装 requests-toolbelt !pip install requests-toolbeltdemo from requests_toolbelt import MultipartEncoder import requestsm MultipartEncoder(fields{query: """第一,向量化匹配是有能力上限的。搜索引擎实现语义搜索已经是好几年的事情了…...
Excel数据导入实战:为缺失ID列批量生成标准UUID
1. 为什么需要为Excel数据批量生成UUID? 最近在处理一个数据迁移项目时,遇到了一个典型问题:从Navicat导出的Excel表格缺少主键列,导致后续数据导入时频频报错。这种情况在数据迁移、系统对接时特别常见。UUID(通用唯…...
51单片机电子秤的语音播报怎么选?JQ8400模块 vs OTP芯片,实测成本与易用性对比
51单片机电子秤语音方案实战选型:JQ8400模块与OTP芯片的深度拆解 在智能硬件开发中,语音交互功能正从锦上添花的附加项逐渐变为核心用户体验的关键组成部分。以51单片机电子秤为例,语音播报功能不仅能提升产品的无障碍使用体验,还…...
如何用ComfyUI-Impact-Pack实现专业级AI图像增强:解决细节缺失的终极方案
如何用ComfyUI-Impact-Pack实现专业级AI图像增强:解决细节缺失的终极方案 【免费下载链接】ComfyUI-Impact-Pack Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more. …...
终极指南:Visual C++运行库合集AIO - 一站式解决Windows软件依赖问题
终极指南:Visual C运行库合集AIO - 一站式解决Windows软件依赖问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 还在为运行软件时遇到"找不到…...
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
前言:直面 SLAM 的“先有鸡还是先有蛋” 在机器人领域,SLAM(Simultaneous Localization and Mapping,同时定位与地图构建) 毫无疑问是最耀眼的明珠之一。简单来说,它的核心任务就是让一个机器人在未知环境中…...
保姆级教程:在Windows上用CMake搞定Qt 6.5与WebRTC M114的集成(附完整代码)
Windows平台Qt 6.5与WebRTC M114深度集成实战指南 环境准备与工具链配置 在Windows平台上进行Qt与WebRTC的集成开发,首先需要搭建完整的工具链环境。不同于简单的库引用,这种深度集成对工具版本和系统配置有着严格要求。 必备组件清单: Visua…...
Excel MCP Server 完全指南:无需安装Excel的自动化处理方案
Excel MCP Server 完全指南:无需安装Excel的自动化处理方案 【免费下载链接】excel-mcp-server A Model Context Protocol server for Excel file manipulation 项目地址: https://gitcode.com/gh_mirrors/ex/excel-mcp-server Excel MCP Server 是一个基于模…...
XUnity Auto Translator:Unity游戏玩家的终极翻译解决方案
XUnity Auto Translator:Unity游戏玩家的终极翻译解决方案 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为外语游戏中的生涩文本而烦恼吗?XUnity Auto Translator为你提供了…...
TI SimpleLink平台实战:MSP432+CC3120构建统一嵌入式开发方案
1. 项目概述:为什么我们需要一个统一的嵌入式开发平台?如果你和我一样,在嵌入式行业摸爬滚打了几年,一定会对下面这个场景深有感触:老板今天说要做个带Wi-Fi的智能插座,你吭哧吭哧用ESP32调通了;…...
2026年婚礼背景音乐素材下载网站TOP5:从版权、曲库到实用场景全面评测
引言:为什么婚礼背景音乐素材越来越需要“可商用、可溯源、可快速下载” 2026年,婚礼内容已经不再只是一支婚礼纪录片,而是拆分成婚礼预告片、接亲快剪、仪式短片、First Look、婚礼跟拍花絮、短视频平台竖版成片、婚庆公司案例展示等多个内…...
