grpc-通关速成

一、前言

1、什么是grpc, 设计该通信协议的背景、目的、可以用来做什么?

grpc全称:"Google Remote Procedure Call", 谷歌远程过程调用;

背景:原来在开发架构中很多采用"单体架构",将所有的功能模块集成到一个exe程序,但是当针对某个模块功能进行升级时,需要将整个程序进行升级;且当程序中某个模块宕机了,会导致整个软件的宕机;且当某个功能需要增加资源开支时,是对整个软件资源的开支增加,整体按照功能模块的伸缩性差;代码直接的耦合性高;

目的:为了解决模块间解耦,加强功能模块的伸缩性,这里引入了"微服务"架构;

微服务架构,采用grpc通信的方式进行,功能服务之间的解耦,服务之间是进程之间的关系

grpc远程调用屏蔽计算机底层调用细节以及编程语言之间的差异。跟本地调用一个函数一样,底层的通信实现交给了grpc处理

2、grpc协议的特点?以及优缺点?

grpc,数据是二进制字节流,采用了约定的编码,这里使用的是protobuff,因此安全性高

跨平台,跨语言,接口即代码

grpc支持多种通信模式,支持一对一,多对一,一对多,或多对多,支持断点续传;

缺点:

(1)、可读性差;

(2)、数据结构更改需要重新编译;

(3)、学习成本高;

二、编译安装(C++)

本文中提供编译好的库文件,编译好的环境是基于(msvc 2019 + 64位

1、编译源码

1.1、下载源码以及第三方库依赖

这里下载1.34版本的grpc, 这里使用国内镜像源仓库下载:(如果网络条件好,可以从github上下载)也可以从下面网盘地址获取

通过网盘分享的文件:grpc.zip

链接: https://pan.baidu.com/s/1__auslBbTnmbL99EEI16_w 提取码: 8888

cpp 复制代码
 git clone -b v1.34.0 https://gitee.com/mirrors/grpc-framework.git grpc_1.34

查看下载后的仓库所在文件夹:

cpp 复制代码
[submodule "third_party/zlib"]
	path = third_party/zlib
	url = https://gitee.com/mirrors/zlib.git
	# When using CMake to build, the zlib submodule ends up with a
	# generated file that makes Git consider the submodule dirty. This
	# state can be ignored for day-to-day development on gRPC.
	ignore = dirty
[submodule "third_party/protobuf"]
	path = third_party/protobuf
	url = https://gitee.com/local-grpc/protobuf.git
[submodule "third_party/googletest"]
	path = third_party/googletest
	url = https://gitee.com/local-grpc/googletest.git
[submodule "third_party/benchmark"]
	path = third_party/benchmark
	url = https://gitee.com/mirrors/google-benchmark.git
[submodule "third_party/boringssl-with-bazel"]
	path = third_party/boringssl-with-bazel
	url = https://gitee.com/mirrors/boringssl.git
[submodule "third_party/re2"]
	path = third_party/re2
	url = https://gitee.com/local-grpc/re2.git
[submodule "third_party/cares/cares"]
	path = third_party/cares/cares
	url = https://gitee.com/mirrors/c-ares.git
	branch = cares-1_12_0
[submodule "third_party/bloaty"]
	path = third_party/bloaty
	url = https://gitee.com/local-grpc/bloaty.git
[submodule "third_party/abseil-cpp"]
	path = third_party/abseil-cpp
	url = https://gitee.com/mirrors/abseil-cpp.git
	branch = lts_2020_02_25
[submodule "third_party/envoy-api"]
	path = third_party/envoy-api
	url = https://gitee.com/local-grpc/data-plane-api.git
[submodule "third_party/googleapis"]
	path = third_party/googleapis
	url = https://gitee.com/mirrors/googleapis.git
[submodule "third_party/protoc-gen-validate"]
	path = third_party/protoc-gen-validate
	url = https://gitee.com/local-grpc/protoc-gen-validate.git

拉取第三方依赖:

bash 复制代码
git submodule update --init

1.2 grpc这边需要汇编编译器,这里从下面链接下载:

bash 复制代码
https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/win64/ 

下载解压完,将路径放到环境变量中:

1.3、下载安装好cmake

创建编译目录,跟安装文件夹如下:

1.4、构建项目

cmake构建时,必须保证自己已经安装了相关的编译工具链,我已经安装了Vs Msvc2017的工具链;

构建选择有如下修改:

所有与测试相关的属性都不要勾选

我这里只使用C++跟Python版本的插件,所以下面选择这两个:

grpc依赖protobuf,所以这里需要选择protobuf的依赖跟生成器:

构建过程中的警告可以忽略,但是ERROR一定要解决!

1.5、编译

2、部署导出

用管理员方式打开CMD

进入到编译目录下grpc_build\

bash 复制代码
cmake --install .  --config Debug    # 导出debug版本
cmake --install .  --config Release    # 导出Release版本

三、使用教程

进行grpc通信之前先定义好通信服务的接口,例如下文举例:

msg.proto

bash 复制代码
syntax = "proto3";

// 消息包名,类似于C++中的名字空间
package demo;

// 求和请求
message addRequest{
    int32 paramA = 1;   // 1 表示第一个参数
    int32 paramB = 2;   // 2 表示第二个参数
}

// 求和答复
message addResReply{
    bool res = 1;
    int32 sum = 2;
}

// 服务定义(用于 RPC 框架,如 gRPC,定义接口方法)
service demoService{
    // 两数求和
    rpc GetTwoParamSum(addRequest) returns(addResReply);
}

根据msg.proto文件生成对应使用到的头文件跟源文件

bash 复制代码
 ./protoc.exe -I . --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc="grpc_cpp_plugin.exe" msg.proto

下面列举一个服务端,客户端的使用的实例:

服务端:

demo_server.h

bash 复制代码
#ifndef _DEMO_SERVER_H
#define _DEMO_SERVER_H

#include <iostream>
#include <cstdio>
#include <grpcpp/grpcpp.h>
#include "msg.grpc.pb.h"

class Demo_Server: public demo::demoService::Service
{
public:
    explicit Demo_Server();
    ~Demo_Server() override;

    // 实现远程调用接口
    virtual grpc::Status GetTwoParamSum(grpc::ServerContext* context, 
        const demo::addRequest* request, demo::addResReply* response) override;
};

#endif

demo_server.cpp

cpp 复制代码
# include "demo_server.h"

Demo_Server::Demo_Server(){

}

Demo_Server::~Demo_Server(){

}

/*
   参数:
    context: 上下文远程调用的额外信息
    request: 客户端传递数据参数
    response: 返回值
*/
grpc::Status Demo_Server::GetTwoParamSum(grpc::ServerContext* context, 
                                         const demo::addRequest* request, demo::addResReply* response) 
{
    int inParamA = request->parama();
    int inParamB = request->paramb();
    int iOutRes = inParamA + inParamB;
    response->set_res(true);
    response->set_sum(iOutRes);
    return grpc::Status::OK;
}

main.cpp

cpp 复制代码
#include <stdio.h>
#include <iostream>
#include <grpcpp/grpcpp.h>
#include "demo_server.h"

std::unique_ptr<grpc::Server> gServer;
// 设置服务参数,启动服务器
bool runServer(std::shared_ptr<Demo_Server> pService){
    grpc::ServerBuilder builder;
    builder.AddListeningPort("0.0.0.0:50052", grpc::InsecureServerCredentials()); // 第二个参数表示不安全连接
    builder.RegisterService(pService.get());
    gServer = builder.BuildAndStart();
    gServer->Wait();
    return true;
}

int main(){
    std::shared_ptr<Demo_Server> pServer = std::make_shared<Demo_Server>();
    runServer(pServer);
    return 0;
}

客户端:

bash 复制代码
#include <iostream>
#include <cstdio>
#include <grpcpp/grpcpp.h>
#include "msg.grpc.pb.h"

using namespace demo;

void runClient(){
    // 构建连接通道
    std::shared_ptr<grpc::Channel> channel = grpc::CreateChannel("127.0.0.1:50052", grpc::InsecureChannelCredentials());
    // 创建远程调用代理
    std::unique_ptr<demoService::Stub> pStub = demoService::NewStub(channel);
    // 通过代理远程调用服务端程序
    grpc::ClientContext comtext;
    addRequest addReq;
    addReq.set_parama(20);
    addReq.set_paramb(35);

    addResReply addRep;
    addRep.set_res(false);
    grpc::Status resState = pStub->GetTwoParamSum(&comtext, addReq, &addRep);

    if(resState.ok())
    {
        std::cout << "add result:" << addRep.sum() << std::endl;
    }
    else{
        std::cerr << "exec GetTwoParamSum error:" <<resState.error_code() << "" <<resState.error_message() << std::endl; 
    }
}

int main(){
    runClient();
    return 0;
}

运行效果:

资源链接:

grpc1.35编译好的window+msvc环境下的库,包含debug/release版本,提供使用实例资源-CSDN下载https://download.csdn.net/download/weixin_36323170/92626411?spm=1001.2014.3001.5503

相关推荐
-To be number.wan2 小时前
Python数据分析:英国电商销售数据实战
开发语言·python·数据分析
xb11322 小时前
C#生产者-消费者模式
开发语言·c#
电商API&Tina2 小时前
乐天平台 (Rakuten) 数据采集指南
大数据·开发语言·数据库·oracle·json
今儿敲了吗2 小时前
10| 扫雷
c++·笔记·学习
zhougl9962 小时前
Java内部类详解
java·开发语言
Grassto2 小时前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
代码游侠2 小时前
学习笔记——Linux内核与嵌入式开发3
开发语言·arm开发·c++·学习
怎么没有名字注册了啊3 小时前
C++ 进制转换
开发语言·c++
代码游侠3 小时前
C语言核心概念复习(二)
c语言·开发语言·数据结构·笔记·学习·算法