直到响应发送回client端,所生成的二进制文件在

pip install protobuf

gRPC 简介:

gRPC 是意气风发款高品质、开源的 RPC 框架,产自 谷歌,基于 ProtoBuf 类别化契约进行支付,匡助三种语言(Golang、Python、Java等卡塔尔,本篇只介绍 Python 的 gRPC 使用。因为 gRPC 对 HTTP/2 左券的支撑使其在 Android、IOS 等顾客端后端服务的开荒领域有所能够的前途。gRPC 提供了风姿罗曼蒂克种简易的点子来定义服务,同期顾客端能够丰裕利用 HTTP/2 stream 的表征,进而拉动节省带宽、减少 TCP 的总是次数、节省CPU的利用等。

在安排好grpc的xxx.proto之后要保障java那边的这些文件要平等(并非风姿罗曼蒂克体,service开头必要完全相像)

使用

  1. 创建 demo python 工程
![](https://upload-images.jianshu.io/upload_images/208550-efc7e919daa289de.png)

Paste_Image.png
  1. 在 example 包中编辑 person.proto

    syntax = "proto3";
    package example;
    
    message person {   
        int32 id = 1;
        string name = 2;
    }
    
    message all_person {    
        repeated person Per = 1;
    }
    
  2. 进入 demo 工程的 example 目录,使用 protoc 编译 person.proto

$ protoc --python_out=. person.proto
就能够转移 person_pb2.py 文件

  1. 在 python 工程中选择 protobuf 进行系列化与反连串化
    main.py:

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    from example import person_pb2
    
    # 为 all_person 填充数据
    pers = person_pb2.all_person()
    p1 = pers.Per.add()
    p1.id = 1
    p1.name = 'xieyanke'
    p2 = pers.Per.add()
    p2.id = 2
    p2.name = 'pythoner'
    
    # 对数据进行序列化
    data = pers.SerializeToString()
    
    # 对已经序列化的数据进行反序列化
    target = person_pb2.all_person()
    target.ParseFromString(data)
    print(target.Per[1].name)  #  打印第一个 person name 的值进行反序列化验证
    

  • 沟通能够加 QQ 群:397234385
  • 可能 QQ 扫码入群:

必威手机官网 1

qq群.jpg

条件筹算

  1. python版本2.7及以上
  2. 设置pip管理软件
  3. pip install grpc
  4. python,查看importgrpc是或不是成功,缺什么装什么
    此地装情形太辛劳,下载了个docker镜像,直接行使了,镜像名grpc/python,用着很有益于

 

安装:

  1. gRPC 的安装:

$ pip install grpcio

  1. 安装 ProtoBuf 相关的 python 依赖库:

$ pip install protobuf

  1. 设置 python grpc 的 protobuf 编写翻译工具:

$ pip install grpcio-tools

  • grpcio==1.4.0
  • grpcio-tools==1.4.0
  • xxx.proto 没有错,只必要这么多少个文书
  • 编译xxx.proto的命令

ProtoBuf: 是意气风发套完整的 IDL(接口描述语言卡塔 尔(英语:State of Qatar),出自Google,基于 C++ 举行的得以完结,开拓人士能够依据 ProtoBuf 的言语专门的学问生成两种编制程序语言(Golang、Python、Java 等卡塔尔的接口代码,本篇只陈说 Python 的根基操作。传闻 ProtoBuf 所生成的二进制文件在仓储功效上比 XML 高 3~10 倍,况兼管理质量高 1~2 个数据级,那也是采用 ProtoBuf 作为类别化方案的三个重要因素之风度翩翩。

编辑proto文件

预备大器晚成份proto文件

syntax = "proto3";
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

2.grpc的python protobuf相关的编写翻译工具

实践:

上面大家使用 gRPC 定义叁个接口,该接口落成对传播的数码实行大写的格式化管理。

  • 始建项目 python demo 工程:
![](https://upload-images.jianshu.io/upload_images/208550-bd34d08e0c12cdeb.png)

Paste_Image.png
  1. client目录下的 main.py 完成了客商端用于发送数据并打字与印刷接收到 server 端管理后的数额
  1. server 目录下的 main.py 达成了 server 端用于收纳客商端发送的数量,并对数据开展大写管理后回来给顾客端
  2. example 包用于编写 proto 文件并生成 data 接口
  • 定义 gRPC 接口:
syntax = "proto3";
package example;
service FormatData {
  rpc DoFormat(Data) returns (Data){}
}
message Data {
  string text = 1;
}
  • 编译 protobuf:

$ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./data.proto #在 example 目录中举行编写翻译,会变卦:data_pb2.py 与 data_pb2_grpc.py

  • 实现 server 端:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import grpc
import time
from concurrent import futures
from example import data_pb2, data_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_HOST = 'localhost'
_PORT = '8080'

class FormatData(data_pb2_grpc.FormatDataServicer):
    def DoFormat(self, request, context):
        str = request.text
        return data_pb2.Data(text=str.upper())

def serve():
    grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
    data_pb2_grpc.add_FormatDataServicer_to_server(FormatData(), grpcServer)
    grpcServer.add_insecure_port(_HOST + ':' + _PORT)
    grpcServer.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        grpcServer.stop(0)

if __name__ == '__main__':
    serve()
  • 实现 client 端:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import grpc
from example import data_pb2, data_pb2_grpc

_HOST = 'localhost'
_PORT = '8080'

def run():
    conn = grpc.insecure_channel(_HOST + ':' + _PORT)
    client = data_pb2_grpc.FormatDataStub(channel=conn)
    response = client.DoFormat(data_pb2.Data(text='hello,world!'))
    print("received: " + response.text)

if __name__ == '__main__':
    run()
  • 实行验证结果:
  1. 先运转 server,之后再实行 client
  1. client 侧调控台如果打字与印刷的结果为:“received: HELLO,WO中华VLD!” ,注脚gRPC 接口定义成功

  • 交换能够加 QQ 群:397234385
  • 照旧 QQ 扫码入群:

必威手机官网 2

qq群.jpg

作者既想用django的model又想用grpc该如何是好吧,django是叁个劳务,grpc是二个劳务,直接暴力把grpc代码参加django是不能够使用models和views的。

安装:

  1. 安装 protoc :Protoc下载地址,能够依据自身的系统下载相应的 protoc,windows 客户统一下载 win32 版本。
  2. 配备 protoc 到系统的遇到变量中,推行如下命令查看是不是安装成功:

$ protoc --version
即使符合规律打字与印刷 libprotoc 的版本新闻就标记 protoc 安装成功

  1. 安装 ProtoBuf 相关的 python 依赖库

$ pip install protobuf

编辑proto文件

同上

 

import os
from concurrent import futures

import grpc
import time

import bus_pb2
import bus_pb2_grpc

import django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")

django.setup()

from enterprise.views import enterprise_list, add_enterprise

_ONE_DAY_IN_SECONDS = 60 * 60 * 24


class Greeter(bus_pb2_grpc.BusInfoServicer):
    def BusMethod(self, request, context):
        if request.method == 'e':
            response = enterprise_list(request)
            return bus_pb2.BusReply(data=response['data'], code=response['code'], message=response['msg'])
        elif request.method == 'a':
            response = add_enterprise(request)
            return bus_pb2.BusReply(message=response['msg'])
        return bus_pb2.BusReply(message='')


if __name__ == '__main__':
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    bus_pb2_grpc.add_BusInfoServicer_to_server(Greeter(), server)
    server.add_insecure_port('0.0.0.0:50051')
    server.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)

编排顾客端文件

为了调用服务端的方法,首先要求创设一个或几个stub:
梗塞式stub:rpc调用会拥塞等待服务端响应后重返音讯或极其音信
非窒碍式stub:非窒碍调用方式,响应异步再次来到

package com.weibo.dorteam.grpc;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;

import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class helloClient {


    private static final Logger logger = Logger.getLogger(helloClient.class.getName());

    private final ManagedChannel channel;
    private final GreeterGrpc.GreeterBlockingStub blockingStub;

    /** Construct client connecting to HelloWorld server at {@code host:port}. */
    // 首先,我们需要为stub创建一个grpc的channel,指定我们连接服务端的地址和端口
    // 使用ManagedChannelBuilder方法来创建channel
    public helloClient(String host, int port) {
        channel = ManagedChannelBuilder.forAddress(host, port)
        // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
        // needing certificates.
        .usePlaintext(true)
        .build();
        // 使用我们从proto文件生成的GreeterGrpc类提供的newBlockingStub方法指定channel创建stubs
        blockingStub = GreeterGrpc.newBlockingStub(channel);
    }

    public void shutdown() throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }
    // 调用服务端方法
    /** Say hello to server. */
    public void greet(String name) {
        logger.info("Will try to greet " + name + " ...");
        // 创建并定制protocol buffer对象,使用该对象调用服务端的sayHello方法,获得response
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloReply response;
        try {
            response = blockingStub.sayHello(request);
        // 如果有异常发生,则异常被编码成Status,可以从StatusRuntimeException异常中捕获
        } catch (StatusRuntimeException e) {
            logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
            return;
        }
        logger.info("Greeting: " + response.getMessage());
    }

    /**
     * Greet server. If provided, the first element of {@code args} is the name to use in the
     * greeting.
     */
    public static void main(String[] args) throws Exception {
        helloClient client = new helloClient("localhost", 50051);
        try {
            /* Access a service running on the local machine on port 50051 */
            String user = "world";
            if (args.length > 0) {
                user = args[0]; /* Use the arg as the name to greet if provided */
            }
            client.greet(user);
        } finally {
            client.shutdown();
        }
    }
}

 

明天在做微服务这一块,后端与java同盟,本人是python的,所以思考接收grpc,一点思谋是grpc是http2.0,另一些虚构是那么些供给的:卡塔 尔(阿拉伯语:قطر‎

遭逢标题

I. pom execution报错:
倍感疑似包重视冲突的标题。。。未解

Multiple annotations found at this line:
    - Execution default of goal org.xolstice.maven.plugins:protobuf-maven-plugin:0.5.0:compile-custom failed: An API 
     incompatibility was encountered while executing org.xolstice.maven.plugins:protobuf-maven-plugin:0.5.0:compile-custom: 
     java.lang.NoSuchMethodError: org.codehaus.plexus.util.DirectoryScanner.setupMatchPatterns()V 
     ----------------------------------------------------- realm = plugin>org.xolstice.maven.plugins:protobuf-maven-plugin:
     0.5.0--726595060 strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy urls[0] = file:/Users/liuyu9/.m2/
     repository/org/xolstice/maven/plugins/protobuf-maven-plugin/0.5.0/protobuf-maven-plugin-0.5.0.jar urls[1] = file:/Users/
     liuyu9/.m2/repository/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar urls[2] = file:/Users/liuyu9/.m2/
     repository/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar urls[3] = file:/Users/liuyu9/.m2/repository/com/
     google/guava/guava/18.0/guava-18.0.jar urls[4] = file:/Users/liuyu9/.m2/repository/org/apache/maven/plugin-tools/
     maven-plugin-annotations/3.4/maven-plugin-annotations-3.4.jar urls[5] = file:/Users/liuyu9/.m2/repository/org/codehaus/
     plexus/plexus-utils/3.0.22/plexus-utils-3.0.22.jar urls[6] = file:/Users/liuyu9/.m2/repository/org/codehaus/plexus/plexus-
     component-annotations/1.6/plexus-component-annotations-1.6.jar urls[7] = file:/Users/liuyu9/.m2/repository/org/
     sonatype/aether/aether-util/1.7/aether-util-1.7.jar urls[8] = file:/Users/liuyu9/.m2/repository/org/codehaus/plexus/plexus-
     interpolation/1.14/plexus-interpolation-1.14.jar urls[9] = file:/Users/liuyu9/.m2/repository/org/sonatype/plexus/plexus-
     sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar urls[10] = file:/Users/liuyu9/.m2/repository/org/sonatype/plexus/plexus-
     cipher/1.4/plexus-cipher-1.4.jar Number of foreign imports: 4 import: Entry[import org.sonatype.plexus.build.incremental 
     from realm ClassRealm[plexus.core, parent: null]] import: Entry[import org.codehaus.plexus.util.Scanner from realm 
     ClassRealm[plexus.core, parent: null]] import: Entry[import org.codehaus.plexus.util.AbstractScanner from realm 
     ClassRealm[plexus.core, parent: null]] import: Entry[import from realm ClassRealm[project>grpcTest:grpcTest:0.0.1-
     SNAPSHOT, parent: ClassRealm[maven.api, parent: null]]] ----------------------------------------------------- 
     (org.xolstice.maven.plugins:protobuf-maven-plugin:0.5.0:compile-custom:default:generate-sources)
    - Execution default of goal org.xolstice.maven.plugins:protobuf-maven-plugin:0.5.0:compile failed: An API 
     incompatibility was encountered while executing org.xolstice.maven.plugins:protobuf-maven-plugin:0.5.0:compile: 
     java.lang.NoSuchMethodError: org.codehaus.plexus.util.DirectoryScanner.setupMatchPatterns()V 
     ----------------------------------------------------- realm = plugin>org.xolstice.maven.plugins:protobuf-maven-plugin:
     0.5.0--726595060 strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy urls[0] = file:/Users/liuyu9/.m2/
     repository/org/xolstice/maven/plugins/protobuf-maven-plugin/0.5.0/protobuf-maven-plugin-0.5.0.jar urls[1] = file:/Users/
     liuyu9/.m2/repository/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar urls[2] = file:/Users/liuyu9/.m2/
     repository/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar urls[3] = file:/Users/liuyu9/.m2/repository/com/
     google/guava/guava/18.0/guava-18.0.jar urls[4] = file:/Users/liuyu9/.m2/repository/org/apache/maven/plugin-tools/
     maven-plugin-annotations/3.4/maven-plugin-annotations-3.4.jar urls[5] = file:/Users/liuyu9/.m2/repository/org/codehaus/
     plexus/plexus-utils/3.0.22/plexus-utils-3.0.22.jar urls[6] = file:/Users/liuyu9/.m2/repository/org/codehaus/plexus/plexus-
     component-annotations/1.6/plexus-component-annotations-1.6.jar urls[7] = file:/Users/liuyu9/.m2/repository/org/
     sonatype/aether/aether-util/1.7/aether-util-1.7.jar urls[8] = file:/Users/liuyu9/.m2/repository/org/codehaus/plexus/plexus-
     interpolation/1.14/plexus-interpolation-1.14.jar urls[9] = file:/Users/liuyu9/.m2/repository/org/sonatype/plexus/plexus-
     sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar urls[10] = file:/Users/liuyu9/.m2/repository/org/sonatype/plexus/plexus-
     cipher/1.4/plexus-cipher-1.4.jar Number of foreign imports: 4 import: Entry[import org.sonatype.plexus.build.incremental 
     from realm ClassRealm[plexus.core, parent: null]] import: Entry[import org.codehaus.plexus.util.Scanner from realm 
     ClassRealm[plexus.core, parent: null]] import: Entry[import org.codehaus.plexus.util.AbstractScanner from realm 
     ClassRealm[plexus.core, parent: null]] import: Entry[import from realm ClassRealm[project>grpcTest:grpcTest:0.0.1-
     SNAPSHOT, parent: ClassRealm[maven.api, parent: null]]] ----------------------------------------------------- 
     (org.xolstice.maven.plugins:protobuf-maven-plugin:0.5.0:compile:default:generate-sources)

由来:M2E的bug eclipse版本过低


更新eclipse为新型版,删除全数.project文件夹,重新更新project

II. 编写翻译protoc-gen-grpc-java插件时报错:

fatal error: ‘google/protobuf/io/zero_copy_stream.h’ file not found

由来:找不干净文件,因为macos系统绝非将/usr/local作为寻找头文件和库的暗中认可路线
解决:export CXXFLAGS=”-I/usr/local/include” LDFLAGS=”-L/usr/local/lib”

III. 生成的grpc通信代码GreeterGrpc编写翻译报错

报错内容:

Multiple markers at this line
    - Method breakpoint:GreeterGrpc$GreeterImplBase [entry] - bindService()
    - The method bindService() of type GreeterGrpc.GreeterImplBase must override a superclass 
     method
    - implements io.grpc.BindableService.bindService

Multiple markers at this line
    - The method invoke(Req, StreamObserver<Resp>) of type GreeterGrpc.MethodHandlers<Req,Resp> 
     must override a superclass method
    - implements io.grpc.stub.ServerCalls.UnaryRequestMethod<Req,Resp>.invoke

Multiple markers at this line
    - implements io.grpc.stub.ServerCalls.StreamingRequestMethod<Req,Resp>.invoke
    - The method invoke(StreamObserver<Resp>) of type GreeterGrpc.MethodHandlers<Req,Resp> must 
     override a superclass method

由来:同难点I,由于M2E插件版本过低有bug
废除办法:更新M2E,可能更新eclipse为新型版

 

运行命令后会生成xxx_pb2.py 和 xxx_pb2_grpc.py三个文件,接下去重视来了(拍桌子)

编纂顾客端文件

同上

 

https://grpc.io/docs/quickstart/python.html
然则在教程里clone的要命项目其实是大,不鲜明哪些是须要的,经过测量检验后交给必要的:

应用python的client端去拜会java的server端

docker run -i -t -v /data0/liuyu9/test/grpc/python-grpc:/python-grpc grpc/python python /python-grpc/helloClient.py
出口结果为:hello you

若不适用grpc/python的镜像,物理机的python需求设置grpc,安装进度中,版本及各个信任包的冲突非常辛劳。。。未有意志力了


 

开首尝试是在python脚本中与java对接接口,平时官方文书档案的风姿罗曼蒂克顿学习,成功调通了接口

使用protoc命令生成相关类文件

docker run -i -t -v /data0/liuyu9/test/grpc/python-grpc:/python-grpc grpc/python python -m grpc.tools.protoc -I /python-grpc --python_out=/python-grpc --grpc_python_out=/python-grpc /python-grpc/hello.proto

钦点protos文件的门路,以致出口路线,并点名proto 文件

本文由必威发布于必威-编程,转载请注明出处:直到响应发送回client端,所生成的二进制文件在

相关阅读