gRPC实战 | 实现Python 和 Go 之间的 gRPC 交互

news2024/11/24 6:50:07

前言

📢博客主页:程序源⠀-CSDN博客
📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!

一、gRPC 简介

gRPC是一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。

gRPC具有以下重要特征:

  • 强大的IDL特性
    RPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议,性能出众,得到了广泛的应用。
  • 支持多种语言
    支持 C++、Java、Go、Python、Ruby、C#、Node.js、Android Java、Objective-C、PHP等编程语言。
  • 基于 HTTP/2 标准设计

使用 gRPC 服务之间的交互流程:

gRPC使用流程

  • 定义标准的proto文件
  • 生成标准代码
  • 服务端使用生成的代码提供服务
  • 客户端使用生成的代码调用服务

二、Python gRPC

python 环境

使用 virtualenv 来初始化一个干净的 Python 环境

pip3 install virtualenv
# 使用 python3.7 创建虚拟环境
virtualenv --python=python3.7 venv
source venv/bin/activate

gRPC 依赖

# grpcio 是启动 gRPC 服务的项目依赖
pip install grpcio
# gPRC tools 包含 protocol buffer 编译器和用于从 .proto 文件生成服务端和客户端代码的插件
pip install grpcio-tools

定义 proto 文件api.proto

//声明proto的版本 只有 proto3 才支持 gRPC
syntax = "proto3";
// 将编译后文件输出在 github.com/lixd/grpc-go-example/helloworld/helloworld 目录
option go_package = "./";
// 指定当前proto文件属于helloworld包


import "google/protobuf/empty.proto";


// service 关键字定义提供的服务
service MyService {
// 定义一个探活方法
rpc Health (.google.protobuf.Empty) returns (.google.protobuf.Empty){
}
// 定义一个批量查询 user 的方法
rpc User (UserReq) returns (UserReply){
}

}

// message 关键字定义交互的数据结构
message UserReq {
repeated int32 userIDs= 1;
}

message UserReply {
string message = 1;
// repeated 定义一个数组
repeated User data = 2;
}

message User {
string name = 1;
int32 age = 2;
string email = 3;
}

生成代码

# 使用 protoc 和相应的插件可以编译生成对应语言的代码
# -I 指定 import 路径,可以指定多个 -I 参数,编译时按顺序查找,不指定默认当前目录
python -m grpc_tools.protoc -I ./ --python_out=. --grpc_python_out=. ./api.proto

经过上述步骤,生成了这样两个文件
api_pb2.py 此文件包含每个 message 生成一个含有静态描述符的模块,,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类
api_pb2_grpc.py 此文件包含生成的 客户端(MyServiceStub)和服务端 (MyServiceServicer)的类。

实现服务端service.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
from concurrent import futures

import grpc
import api_pb2_grpc, api_pb2
from api_pb2_grpc import MyServiceServicer


def get_users(user_ids):
    users = []
    for user_id in user_ids:
        # Here you would implement your logic to retrieve the user data based on the user_id
        # For this example, we'll just return some dummy data
        users.append({'name': f'User {user_id}', 'age': 30, 'email': f'user{user_id}@example.com'})
    return users


class Service(MyServiceServicer):
    def Health(self, request, context):
        return

    def User(self, request, context):
        print('start to process request...')
        res = get_users(request.userIDs)
        users = []
        for u in res:
            users.append(api_pb2.User(name=u['name'], age=u['age'], email=u['email']))
        return api_pb2.UserReply(message='success', data=users)


def serve():
    print('start grpc server====>')
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    api_pb2_grpc.add_MyServiceServicer_to_server(Service(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    server.wait_for_termination()


if __name__ == '__main__':
    logging.basicConfig()
    serve()

文件最终目录

三、Go gRPC

新建一个目录gRPC_study,用GoLand打开,最终目录如下

初始化一下: go mod init gRPC_study

go gRPC 依赖

go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28

go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

生成 Go pb 代码

先下载protoc:Releases · protocolbuffers/protobuf · GitHub

我是Windows,找到对应的文件

下载好之后解压,配置环境变量

 

客户端调用main.go

package main  
  
import (  
    "context"  
    "fmt"  
    "log"  
    "time"  
  
    "google.golang.org/grpc"  
    api "leetcode_test/api"  
)  
  
const (  
    address = "localhost:50051"  
    defaultName = "world"  
)  
  
func main() {  
    conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())  
    if err != nil {  
        log.Fatalf("did not connect: %v", err)  
    }  
    defer conn.Close()  
    c := api.NewMyServiceClient(conn)  
  
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)  
    defer cancel()  
    r, err := c.User(ctx, &api.UserReq{UserIDs: []int32{1, 2}})  
    if err != nil {  
        log.Fatalf("could not greet: %v", err)  
    }  
    fmt.Printf("gprc result: %+v", r.Data)  
}

运行结果、输出示例

运行service服务

再运行go客户端获取信息

四、总结

实现了一个 gRPC 服务,用于处理健康检查(Health)和用户信息请求(User)的 gRPC 调用。

main.go

这个文件是用 Go 实现的 gRPC 客户端。它的主要功能是:

  1. 连接到运行在本地的 gRPC 服务器。
  2. 调用服务器的 Health 方法进行健康检查,确保服务器正常运行。
  3. 调用服务器的 User 方法,发送用户 ID 列表并接收用户信息的响应。

service.py

这个文件是用 Python 实现的 gRPC 服务器。其主要功能是:

  1. 实现 Health 方法,用于健康检查。这个方法应返回服务器的健康状态。
  2. 实现 User 方法,接收客户端发送的用户 ID 列表,返回对应的用户信息。
  3. 启动 gRPC 服务器并监听端口,以便处理客户端请求。

参考文章链接:https://juejin.cn/post/7244487194174259255

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

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

相关文章

eNSP学习——RIP路由协议的汇总

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、配置RIPv1协议 3、配置RIPv2自动汇总 4、配置RIPv2手动汇总 需要eNSP各种配置命令的点击链接自取:华为eNSP各种设备配置命令大全PDF版_ensp配置命令大全…

Acwing 786.第K个数

Acwing 786.第K个数 题目描述 786. 第k个数 - AcWing题库 运行代码 #include <iostream> #include <algorithm> using namespace std; const int N 100010; int q[N];int main() {int n, k;scanf("%d%d", &n, &k);for (int i 0; i < n; …

网络通讯协议UDP转发TCP工具_UdpToTcpRelay

网络通讯协议UDP转发TCP工具_UdpToTcpRelay 本程序旨在提供一个灵活的、可配置的服务&#xff0c;它处理特定的UDP端口以接收命令&#xff0c;然后将这些命令转换为TCP命令并通过网络发送到指定的TCP服务器【TCP支持十六进制和ASCII】。 此设计特别适用于需要远程控制或自动化…

百度/迅雷/夸克,网盘免费加速,已破!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 之前给大家安利了百度网盘及迅雷的加速方法&#xff0c;详细方法及获取参考之前文章&#xff1a; 刚刚&#xff01;度盘、某雷已破&#xff01;速度50M/s&#xff01; 本次主要介绍夸…

Day23 自定义对话框服务

​本章节实现了,自定义对话框服务的功能 当现有的对话框服务无法满足特定需求时,我们可以采用自定义对话框的解决方案,以更好地满足一些特殊需求。 一.自定义对话框主机服务步骤 在Models 文件夹中,再建立一个 IDialogHostService 接口类,继承自 IDialogService 对话框服…

[个人总结]-java常用方法

1.获取项目根路径 user.dir是一个系统属性&#xff0c;表示用户当前的工作目录&#xff0c;大多数情况下&#xff0c;用户的当前工作目录就是java项目的根目录&#xff08;src文件的同级路径&#xff09; System.getProperty("user.dir") 结果&#xff1a;D:\code…

什么是IDE?– 集成开发环境

IDE &#xff08;集成开发环境&#xff09;是将常用的开发人员工具组合到紧凑的 GUI&#xff08;图形用户界面&#xff09;应用程序中的软件。它是代码编辑器、代码编译器和代码调试器等工具与集成终端的组合。 为什么 IDE 很重要&#xff1f; 人们当然不需要 IDE来编码或开发…

【动手学深度学习】softmax回归从零开始实现的研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 softmax回归的从零开始实现 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 理解softmax回归的原理和基本实现方式&#xff1b;学习…

Python SQLAlchemy库详解

大家好&#xff0c;在Python生态系统中&#xff0c;SQLAlchemy库是一个强大的工具&#xff0c;为开发人员提供了便捷的方式来处理与数据库的交互。无论是开发一个小型的Web应用程序&#xff0c;还是构建一个大型的企业级系统&#xff0c;SQLAlchemy都能满足你的需求&#xff0c…

hid.dll丢失怎么办?hid.dll丢失多种解决方法详解

hid.dll&#xff0c;即Human Interface Device (HID) Dynamic Link Library&#xff0c;是Windows操作系统中用于管理人机交互设备&#xff08;如键盘、鼠标、游戏控制器等&#xff09;的动态链接库文件。它负责处理这些设备的输入和输出&#xff0c;确保设备与系统之间的通信顺…

SpringBoot+Vue在线考试答题系统【附:资料➕文档】

前言&#xff1a;我是源码分享交流Coding&#xff0c;专注JavaVue领域&#xff0c;专业提供程序设计开发、源码分享、 技术指导讲解、各类项目免费分享&#xff0c;定制和毕业设计服务&#xff01; 免费获取方式--->>文章末尾处&#xff01; 项目介绍016&#xff1a; 本…

windows10子系统wsl ubuntu22.04下GN/ninja环境搭建

打开windows10子系统 ubuntu22.04 ubuntu22.04: 首先需要 安装ninja $sudo apt install ninja-build $ ninja --version 1.10.0 安装clang $sudo apt install clang $clang --version Ubuntu clang version 14.0.0-1ubuntu1.1安装gn Github: https://github.com/timniederh…

如何在npm上发布自己的包

如何在npm上发布自己的包 npm创建自己的包 一、一个简单的创建 1、创建npm账号 官网&#xff1a;https://www.npmjs.com/创建账号入口&#xff1a;https://www.npmjs.com/signup 注意&#xff1a;需要进入邮箱验证 2、创建目录及初始化 $ mkdir ufrontend-test $ cd ufron…

LLM主流开源代表模型

LLM主流开源大模型介绍 1 LLM主流大模型类别 随着ChatGPT迅速火爆&#xff0c;引发了大模型的时代变革&#xff0c;国内外各大公司也快速跟进生成式AI市场&#xff0c;近百款大模型发布及应用。 目前&#xff0c;市面上已经开源了各种类型的大语言模型&#xff0c;本章节我们…

用idea将java文件打成jar包

一、用idea将java文件打成jar包 1、在idea上选择file—Project Structure 2、Artifacts —点–JAR—From modules with dependencies 3、选择要打包的java文件 4、Build — Build Artifacts 5、找到刚才添加的Artifacts直接Build 6、生成jar包文件

tomcat服务器之maxHttpHeaderSize

背景&#xff1a;在OA流程表单中&#xff0c;填写了200条数据&#xff0c;一提交&#xff0c;秒报400错误&#xff0c;且请求没有打到后端中&#xff08;无报错日志&#xff09;&#xff0c;一开始以为是谷歌浏览器的问题&#xff0c;可百度上关于这个错误的解决方案都是清除缓…

Renesas MCU之FreeRTOS的应用

目录 概述 1 FSP配置FreeRTOS 1.1 软件版本信息 1.2 配置FreeRTOS 2 FreeRTOS的Task 2.1 FSP下的项目结构 2.2 Task代码 2.2.1 Task测试案例配置 2.2.2 测试代码实现 3 自定义Task 3.1 编写代码 3.2 测试函数 4 测试 4.1 Task断点测试 4.2 板卡运行测试 概述 …

Spring boot 集成mybatis-plus

Spring boot 集成mybatis-plus 背景 Spring boot集成mybatis后&#xff0c;我们可以使用mybatis来操作数据。然后&#xff0c;我们还是需要写许多重复的代码和sql语句&#xff0c;比如增删改查。这时候&#xff0c;我们就可以使用 mybatis-plus了&#xff0c;它可以极大解放我…

CC++内存管理【new和delete操作符的详细分析】【常见面试题】

C/C内存管理 1.C/C内存分布 我们先来看一段代码&#xff0c;来了解一下C/C中的数据内存分布。 # include <stdlib.h>int globalVar 1; static int staticGlobalVar 1; // 比globalVar还要先销毁,同一个文件下后定义的先析构 // 全局变量存在 数据段&#xff08;静态…

opencv进阶 ——(十三)基于三角剖分实现换脸

换脸的关键在于人脸对齐&#xff0c;人脸对齐主要包括以下几点&#xff1a; 1、人脸可能存在一定的角度&#xff0c;因此需要先将倾斜方向进行对齐 2、大小对齐&#xff0c;将模板人脸的大小缩放到同一大小 3、要想有好的效果&#xff0c;关键点选取很重要 4、人脸对齐后&a…