一个go http和grpc客户端库

news2024/10/6 10:31:22

大家好,我是peachesTao,今天是五一假期的第4天,首先祝大家劳动节快乐。今天给大家推荐一个统一http和grpc客户端调用的库,名为prpc,github地址:prpc,该库是我公司根据最佳实践总结开发出来的,它可以提升开发效率,让开发者聚焦于业务层代码。

下面我从三个方面来介绍

自动生成http客户端代码

1、编写http客户端代码痛点

首选我们来看一段调用http接口获取用户列表的代码

type GetUserListReq struct {
 Age  int32  `json:"age"`
}

type GetUserListReply struct {
 Code int32       `json:"code"`
 Msg  string      `json:"msg"`
 List []*UserInfo `json:"list"`
}

type UserInfo struct {
 Name string `json:"name"`
 Age  int32  `json:"age"`
}

func GetUserList(req *protocol.GetUserListReq) (*GetUserListReply, error) {
  user := config.GetServerConfig().User
  request, err := httplib.Post(user.URL+user.GetUserList).Debug(true).JSONBody(req)
  if err != nil {
    return nil, err
  }
  resp := new(protocol.GetUserListReply)
  err = request.ToJSON(resp)
  if err != nil {
    return nil, err
  }
  return resp, nil
}

分别定义了请求和响应数据结构体,从配置文件中获取http服务的url和用户列表接口的path,将请求结构体编码,然后通过http client库发起http请求,将返回的数据解码为响应结构体。

我们发现这样的代码有下面三个痛点

  1. 每次调用都要对req对象编码、res对象进行解码

  2. 需要在代码中硬编码读取配置服务端的url

  3. 如果服务端将Post改成Get方式,要改客户端的代码

这非常影响开发效率且容易出错,这些代码能不能自动生成?答案是可以的,凡是有规律的代码都可以自动生成。我们的实现方案是基于protobuf实现的。

2、基于protobuf的http客户端代码生成

我们使用protobuf定义服务调用方法、请求和响应结构体,再借助http Method Option自定义服务url和http method,最后用prpc内置的插件protoc-gen-go-prpc生成跟grpc相似的函数签名的客户端代码。

GetUserList protobuf文件定义:

syntax = "proto3";

option go_package = "/api/";
import "google/api/annotations.proto";

service User {
  //获取用户列表
  rpc GetUserList(GetUserListReq) returns (GetUserListReply) {
    option (google.api.http) = {
      get: "/user/list"
      body: "*"
      additional_bindings:[
        {custom:{kind:"Content-Type", path:"application/json"}}]
    };
  }
}

message GetUserListReq {
  int32 age = 1;
}

message GetUserListReply {
  int32 code = 1;
  string msg = 2 ;
  repeated UserInfo list = 3;
}

message UserInfo {
  string name = 1;
  int32 age = 2;
}

自动生成的调用入口函数如下(此处省略了其他部分代码,想看完整的代码可以前往prpc-examples):

func (c *userClient) GetUserList(ctx context.Context, in *GetUserListReq, opts ...http.CallOption) (*GetUserListReply, error) {
 out := new(GetUserListReply)
 header := map[string]string{
  "Content-Type": "application/json",
 }
 opts = http.CallOptions(opts).CombineHeader(header)
 err := c.cc.HttpInvoke(ctx, "GET", "/user/list", in, out, opts...)
 if err != nil {
  return nil, err
 }
 return out, nil
}

开发者侧代码:

 conn := prpc.NewClientConn()
 err := conn.NewHttpClientConn(context.Background(), "127.0.0.1:8000")
 if err != nil {
  log.Error(err)
  return
 }
 userClient := api.NewUserClient(conn)
 listReply, err := userClient.GetUserList(context.Background(), &api.GetUserListReq{Age: 18})
 if err != nil {
  log.Error(err)
  return
 }
 log.Info(listReply)

可以看出,开发者就像调用grpc方法一样简单的调用http接口,实现了对协议的无感,开发者只需要在protobuf中定义相关信息,其他的交给插件就行。

http和grpc调用随意切换

因为http和grpc客户端调用代码都是根据protobuf生成的,生成的是http还是grpc取决于rpc方法是否定义了http method option,如果定义了则生成http代码,否则生成grpc调用代码。

所以http切换成grpc protobuf只需要删除http method option 部分即可,同理,grpc切换成http则加上它就行。

上面GetUserList改成grpc调用的话protobuf rpc方法定义如下:

service User {
  //获取用户列表
  rpc GetUserList(GetUserListReq) returns (GetUserListReply) {}
}

服务发现和负载均衡

prpc还包含集群模式下的服务发现和负载均衡功能,一套服务发现和负载均衡机制同时兼容http和grpc,且都支持扩展。

开发者只需要实现resolver和balancer接口就可以自定义服务发现和负载均衡,目前prpc内置了基于consul的服务发现和轮训的负载均衡功能。

后续我们将增加基于zookeeper,etcd的服务发现和实现权重的负载均衡方式,也欢迎小伙伴积极参与进来,给我们贡献代码,共同完善prpc。

更多的细节请前往github prpc了解

相关链接

[prpc] https://github.com/classtorch/prpc
[prpc-examples] https://github.com/classtorch/prpc-examples

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/483461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++进阶之路】类和对象(上)

文章目录 一.面向对象和面向过程二.类的引入——结构体三.类的定义1.类定义的两种方式在类里面定义函数在类外定义函数——类域 2.访问限定符3.封装——面向对象的三大特性4.类的实例化 四.类对象模型求一个类的大小 五.this指针基本认识代码解读 一.面向对象和面向过程 面向对…

【移动端网页布局】流式布局案例 ③ ( 实现搜索栏功能 | 伪元素选择器 | 子绝父相 | 外边距塌陷处理 | 二倍精灵图处理方案 )

文章目录 一、搜索栏样式及核心要点1、实现效果2、自动伸缩搜索栏实现3、搜索栏父容器设置4、搜索栏左右两侧的按钮盒子5、搜索栏盒子6、二倍精灵图处理方案 二、完整代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、搜索栏样式及核心要点 1、实现效果 上一篇博客中 , 完成…

2022年职业教育技能大赛网络安全 linux系统渗透提权

B-10:Linux 系统渗透提权 任务环境说明: ✓ 服务器场景:Server2202(关闭链接) ✓ 用户名:hacker 密码:123456 使用渗透机对服务器信息收集,并将服务器中 SSH 服务端口号作为 flag…

API 接口自动化测试的基本原理及实战教程

目录 常用API接口协议介绍 Http协议接口请求的介绍 HTTPS协议 SMTP协议 SNMP协议 FTP协议 API 接口自动化测试的基本原理 常用API接口协议介绍 HTTP协议 超文本传输协议 它是用来在Internet上传送超文本的传送协议,运行在TCP/IP协议族之上,它可…

Docker file镜像

目录 一、Docker镜像的创建 1、基于现有镜像创建 2、基于本地模版创建 3、基于Dockerfile创建 1、联合文件系统(UnionFS) ​编辑2、镜像加载原理 3、Dockerfile 4、Docker 镜像结构的分层 二、Dockerfile 操作常用的指令 (1&#xf…

把树莓派改造成NAT软路由器

本文目录 1、查看网卡情况2、配置静态ip3、配置IP转发和SNAT功能3.1、开启Linux的报文转发功能 3.2、开启SNAT功能4、进阶配置4.1、如果WAN口(上行接口)eth0是动态分配的IP地址4.2、在LAN口上,给下游主机开启自动分配IP地址功能4.3、永久保存iptables, SNAT配置&…

Redis学习笔记02(主从同步,哨兵,哨兵集群)

数据同步:主从数据库如何保障数据一致性 redis具有高可靠性:1.数据尽量减少丢失(AOF和RDB来保障) 2.服务尽量减少中断.第二点通过增加冗余副本来保障。 读写分离: 减少保障数据一致性的开销。修改操作只会在主库上进…

《花雕学AI》解锁ChatGPT潜力!183个最佳提示语,助您充分利用人工智能技术

随着机器学习和自然语言处理技术的不断进步,人工智能在各个领域的应用越来越广泛。ChatGPT(Generative Pre-trained Transformer)是一个强大的自然语言生成模型,它可以帮助我们生成高质量的文本内容。本文为你列举了 183 种可能的…

【51单片机】DS1302时钟模块

🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Waiting For Love】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🍔效果 🍔代码 main.…

Stable Diffusion 本地部署教程不完全指南

ChatGPT免费体验入口网址 http://chat.xutongbao.top 参考链接: ERROR: Could not find a version that satisfies the requirement torch1.7.0 ERROR: No matching……_congcongiii的博客-CSDN博客 下载链接: https://download.pytorch.org/whl/cu11…

VMware下centos7开机登陆页面死循环问题解决

文章目录 VMware下centos7开机登陆页面死循环问题详细解决解决 VMware下centos7开机登陆页面死循环问题详细解决 脚本中有reboot重启命令 并且给该脚本加上了开机自启动 因为在脚本中没有给重启做判断,运行脚本后就会一直重启 解决 在VMware下centos7开机页面按e键…

【Linux】如何实现单机版QQ,来看进程间通信之管道

学会了管道,就可以实现简单的qq哦~ 文章目录 前言一、匿名管道总结 前言 为什么要进行进程间通信呢?因为需要以下这些事: 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源。 …

【五一创作】Linux---I2C应用编程

目录简述 前言: 一、I2C协议 (1)概述 (2)I2C硬件框架: (3)I2C软件框架 (4)I2C数据格式 二、SMBus协议 三、I2C系统重要的结构体 四、访问I2C设备&am…

欧姆龙NX/NJ系列PLC对接Oracle数据库,实现PLC与数据库双向数据通讯

智能网关IGT-DSER方便实现PLC与数据库之间的数据通讯,既可以读取PLC的数据上报到数据库,也可以从数据库查询数据后写入到PLC的寄存器。 网关安装在设备侧,与设备同时起停,不担心数据丢失;在断网、服务器维护上报数据有…

ID3算法报告理解笔记

专有名词解释: 决策树:决策树是根据已知若干条件,来对事件做出判断。从根节点到叶子结点。自上而下生成,每个决策或事件都可能引发两个或多个事件。将这些事件根据不同的特征进行划分,最后将类别分出,得到…

【Java校招面试】基础知识(四)——JVM

目录 前言一、基础概念二、反射三、类加载器ClassLoader四、JVM内存模型后记 前言 本篇主要介绍Java虚拟机——JVM的相关内容。 “基础知识”是本专栏的第一个部分,本篇博文是第四篇博文,如有需要,可: 点击这里,返回…

java 泛型知识整理

Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所…

【网络协议详解】——GNS3的使用(学习笔记)

📖 前言:在IT领域,网络协议的理解和掌握是至关重要的。GNS3和Wireshark是非常实用的工具,它们可以帮助你深入了解TCP/IP协议和网络的运作情况。 目录 🕒 1. 网络协议分析工具——GNS3🕘 1.1 快速上手&#…

磁盘和固态磁盘

磁盘和固态磁盘 磁盘的物理结构 ​ 磁盘的表面由一些磁性的物质组成,可以用这些磁性物质来记录二进制数据。磁盘的盘面被划分成一个个磁道,这样一个“圈”就是一个磁道。同一磁盘上不同磁道上记录的信息量相同,因此内侧磁道上的数据密度较大…

嵌入式C语言自我修养笔记1-ARM体系结构与编译运行

目录 ARM 体系结构ARM 体系结构ARM 汇编指令ARM 寻址方式ARM 伪指令C 与汇编混合编程 程序编译链接与安装运行预处理过程编译过程链接过程程序安装apt-get链接静态库动态链接共享库插件工作原理Linux 内核模块运行机制Linux 内核编译与启动分析 ARM 体系结构 ARM 体系结构 AR…