91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

gRPC HelloWorld測試

發布時間:2020-06-23 20:48:04 來源:網絡 閱讀:209637 作者:九月朦朧 欄目:編程語言

一、概述

What's gRPC?
gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.(gRPC是可以在任何環境中運行的現代的開源高性能RPC框架。它可以通過可插拔的支持來有效地連接數據中心內和跨數據中心的服務,以實現負載平衡,跟蹤,運行狀況檢查和身份驗證。它也適用于分布式計算的最后一英里,以將設備,移動應用程序和瀏覽器連接到后端服務。)
我們可以用一句話來概括:A high-performance, open-source universal RPC framework
RPC(remote procedure call 遠程過程調用)框架實際是提供了一套機制,使得應用程序之間可以進行通信,而且也遵從server/client模型。使用的時候客戶端調用server端提供的接口就像是調用本地的函數一樣。

so
在什么情況下需要使用gRPC呢?
需要對接口進行嚴格約束的情況,比如我們提供了一個公共的服務,很多人,甚至公司外部的人也可以訪問這個服務,這時對于接口我們希望有更加嚴格的約束,我們不希望客戶端給我們傳遞任意的數據,尤其是考慮到安全性的因素,我們通常需要對接口進行更加嚴格的約束。這時gRPC就可以通過protobuf來提供嚴格的接口約束。
對于性能有更高的要求時。有時我們的服務需要傳遞大量的數據,而又希望不影響我們的性能,這個時候也可以考慮gRPC服務,因為通過protobuf我們可以將數據壓縮編碼轉化為二進制格式,通常傳遞的數據量要小得多,而且通過http2我們可以實現異步的請求,從而大大提高了通信效率。
但是,通常我們不會去單獨使用gRPC,而是將gRPC作為一個部件進行使用,這是因為在生產環境,我們面對大并發的情況下,需要使用分布式系統來去處理,而gRPC并沒有提供分布式系統相關的一些必要組件。而且,真正的線上服務還需要提供包括負載均衡,限流熔斷,監控報jing,服務注冊和發現等等必要的組件。

二、測試

接下來開始gRPC的Hello World測試
gRPC的使用通常包括如下幾個步驟:
1、通過protobuf來定義接口和數據類型
2、編寫gRPC server端代碼
3、編寫gRPC client端代碼

1、通過protobuf來定義接口和數據類型

我實在mac中使用的python,mac中自帶python2,因為需要,自己安裝了python3。
首先pip3 安裝grpc和protobuf

(lxc) liuxuchong:untitled liuxuchong$  pip3 install grpcio
Collecting grpcio
  Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out. (read timeout=15)")': /packages/0d/27/0413a5dffd7ddca4ea43cffd22f46ec2b26a5ed18c974e4448763e758a9b/grpcio-1.25.0-cp37-cp37m-macosx_10_9_x86_64.whl
  Downloading https://files.pythonhosted.org/packages/0d/27/0413a5dffd7ddca4ea43cffd22f46ec2b26a5ed18c974e4448763e758a9b/grpcio-1.25.0-cp37-cp37m-macosx_10_9_x86_64.whl (2.3MB)
    100% |████████████████████████████████| 2.3MB 8.1kB/s 
Collecting six>=1.5.2 (from grpcio)
  Using cached https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl
Installing collected packages: six, grpcio
Successfully installed grpcio-1.25.0 six-1.13.0

(lxc) liuxuchong:untitled liuxuchong$  pip3 install protobuf
Collecting protobuf
  Downloading https://files.pythonhosted.org/packages/a5/c6/a8b6a74ab1e165f0aaa673a46f5c895af8780976880c98934ae82060356d/protobuf-3.10.0-cp37-cp37m-macosx_10_9_intel.whl (1.4MB)
    100% |████████████████████████████████| 1.4MB 83kB/s 
Requirement already satisfied: setuptools in ./venv/lxc/lib/python3.7/site-packages/setuptools-40.8.0-py3.7.egg (from protobuf) (40.8.0)
Requirement already satisfied: six>=1.9 in ./venv/lxc/lib/python3.7/site-packages (from protobuf) (1.13.0)
Installing collected packages: protobuf
Successfully installed protobuf-3.10.0

定義protobuf

下面定義一個簡單的protobuf文件,在其中聲明一個grpc服務。
創建一個proto目錄,并在其中創建grpchello.proto文件,如下內容。

syntax = "proto3";
package grpcDemo;

message HelloRequest {
   string name = 1;
}

message HelloReply {
   string message = 1;
}

service gRPC {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

編譯protobuf

使用protobuf的編譯器,為我們生成python版本的Message定義和服務的架手腳。

lxc) liuxuchong:untitled liuxuchong$  python -m grpc-tools.protoc -I./proto --python_out=. --grpc_python_out=. grpchello.proto
/Users/liuxuchong/PycharmProjects/untitled/venv/lxc/bin/python: Error while finding module specification for 'grpc-tools.protoc' (ModuleNotFoundError: No module named 'grpc-tools')

提示我們沒有安裝grpc-tools,用pip安裝一下

python3 -m pip install --user grpcio-tools

然后在運行上面的命令

在當前目錄下,生成2個文件:

  • grpchello_pb2.py
  • grpchello_pb2_grpc.py

查看第一個文件,消息定義文件:

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: grpchello.proto

import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()

DESCRIPTOR = _descriptor.FileDescriptor(
  name='grpchello.proto',
  package='grpcDemo',
  syntax='proto3',
  serialized_options=None,
  serialized_pb=_b('\n\x0fgrpchello.proto\x12\x08grpcDemo\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2B\n\x04gRPC\x12:\n\x08SayHello\x12\x16.grpcDemo.HelloRequest\x1a\x14.grpcDemo.HelloReply\"\x00\x62\x06proto3')
)

_HELLOREQUEST = _descriptor.Descriptor(
  name='HelloRequest',
  full_name='grpcDemo.HelloRequest',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  fields=[
    _descriptor.FieldDescriptor(
      name='name', full_name='grpcDemo.HelloRequest.name', index=0,
      number=1, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=_b("").decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=29,
  serialized_end=57,
)

然后看下grpc服務定義:

from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()

DESCRIPTOR = _descriptor.FileDescriptor(
  name='grpchello.proto',
  package='grpcDemo',
  syntax='proto3',
  serialized_options=None,
  serialized_pb=_b('\n\x0fgrpchello.proto\x12\x08grpcDemo\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2B\n\x04gRPC\x12:\n\x08SayHello\x12\x16.grpcDemo.HelloRequest\x1a\x14.grpcDemo.HelloReply\"\x00\x62\x06proto3')
)

_HELLOREQUEST = _descriptor.Descriptor(
  name='HelloRequest',
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()

DESCRIPTOR = _descriptor.FileDescriptor(
  name='grpchello.proto',
  package='grpcDemo',
  syntax='proto3',
  serialized_options=None,
  serialized_pb=_b('\n\x0fgrpchello.proto\x12\x08grpcDemo\"\x1c\n\x0cHelloRequest\\
x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x011
 \x01(\t2B\n\x04gRPC\x12:\n\x08SayHello\x12\x16.grpcDemo.HelloRequest\x1a\x14.grpcc
Demo.HelloReply\"\x00\x62\x06proto3')
)

_HELLOREQUEST = _descriptor.Descriptor(
  name='HelloRequest',
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc

import grpchello_pb2 as grpchello__pb2

class gRPCStub(object):
  # missing associated documentation comment in .proto file
  pass

  def __init__(self, channel):
    """Constructor.

    Args:
      channel: A grpc.Channel.
    """
    self.SayHello = channel.unary_unary(
        '/grpcDemo.gRPC/SayHello',
        request_serializer=grpchello__pb2.HelloRequest.SerializeToString,
        response_deserializer=grpchello__pb2.HelloReply.FromString,
        )

class gRPCServicer(object):
  # missing associated documentation comment in .proto file
  pass

  def SayHello(self, request, context):
    # missing associated documentation comment in .proto file
    pass
    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
    context.set_details('Method not implemented!')
    raise NotImplementedError('Method not implemented!')

def add_gRPCServicer_to_server(servicer, server):
  rpc_method_handlers = {
      'SayHello': grpc.unary_unary_rpc_method_handler(
          servicer.SayHello,
          request_deserializer=grpchello__pb2.HelloRequest.FromString,
          response_serializer=grpchello__pb2.HelloReply.SerializeToString,
      ),
  }
  generic_handler = grpc.method_handlers_generic_handler(
      'grpcDemo.gRPC', rpc_method_handlers)
  server.add_generic_rpc_handlers((generic_handler,))
  • 在grpc服務架手腳定義中,定義了gRPCStub,這是給client端使用,調用grpc服務的。
  • 定義的服務類gRPCServicer,方法SayHello需要我們在子類中進行實現。定義的add_gRPCServicer_to_server方法,用于把實現的類和grpc API調用注冊起來。

這里使用的幾個主要方法(類):

  • grpc.server – Creates a Server with which RPCs can be serviced
  • grpc.method_handlers_generic_handler – Creates a GenericRpcHandler from RpcMethodHandlers.
  • grpc.unary_unary_rpc_method_handler – Creates an RpcMethodHandler for a unary-unary RPC method.

實現服務

在我們的實現服務的類中,使用服務方法,并在網絡中暴露出來。

# -*- coding: utf-8 -*-
import grpc
import time
from concurrent import futures 
import grpchello_pb2, grpchello_pb2_grpc

_HOST = 'localhost'
_PORT = '8188'

_ONE_DAY_IN_SECONDS = 60 * 60 * 24

class gRPCServicerImpl(grpchello_pb2_grpc.gRPCServicer):

    def SayHello(self, request, context):
        print ("called with " + request.name)
        return grpchello_pb2.HelloReply(message='Hello, %s!' % request.name)

def serve():
  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
  grpchello_pb2_grpc.add_gRPCServicer_to_server(gRPCServicerImpl(), server)
  server.add_insecure_port('[::]:'+_PORT)
  server.start()
  try:
    while True:
      time.sleep(_ONE_DAY_IN_SECONDS)
  except KeyboardInterrupt:
    server.stop(0)

if __name__ == '__main__':
    serve()

這里包括2個實現:

  • 1、在grpc的API的實現(服務實現類)gRPCServicerImpl中,實現SayHello方法。
  • 2、然后,定義網絡服務和端口,把grpc的API注冊到網絡服務的處理上。這里簡單利用了grpc.server類。

使用客戶端client

在客戶端,調用grpc的服務API。

# -*- coding: utf-8 -*-
"""The Python implementation of the gRPC client."""
from __future__ import print_function
import grpc
from grpchello_pb2  import *    ## or import grpchello_pb2
from grpchello_pb2_grpc import *
## No grpcDemo!  from grpcDemo import grpchello_pb2, grpchello_pb2_grpc #error!

_PORT = '8188'

def run():
    conn = grpc.insecure_channel(_HOST + ':' + _PORT)
    client = gRPCStub(channel=conn)
    response = client.SayHello(HelloRequest(name='lxc'))
    print("received: " + response.message)

## 
if __name__ == '__main__':

    if len(sys.argv)== 2:
        print (sys.argv[1])
        _HOST = sys.argv[1]
    else:
        _HOST = 'localhost'

    #    
    run()

說明:

  • 1、 def insecure_channel(target, options=None):
    – Creates an insecure Channel to a server.
  • 2、 客戶端使用服務的Stub,調用API。

測試

分別啟動服務,然后再啟動客戶端,可以看到調用結果。
也可以啟動java、c#版本的grpc服務端、客戶端,都能調用成功。

然后運行

(lxc) liuxuchong:untitled liuxuchong$  python3 grpchello_pb2.py
Traceback (most recent call last):
  File "grpchello_pb2.py", line 7, in <module>
    from google.protobuf import descriptor as _descriptor
ModuleNotFoundError: No module named 'google'

提示沒有google模版
網上查了一下解決方法如下

pip3 install google
pip3 install protobuf

然后運行另一個py文件

python3 grpchello_pb2_grpc.py
Traceback (most recent call last):
  File "grpchello_pb2_grpc.py", line 2, in <module>
    import grpc

奇怪,剛才明明裝了,還提示沒有模版,又裝了一次

pip3 install grpcio
Collecting grpcio
  Using cached https://files.pythonhosted.org/packages/0d/27/0413a5dffd7ddca4ea43cffd22f46ec2b26a5ed18c974e4448763e758a9b/grpcio-1.25.0-cp37-cp37m-macosx_10_9_x86_64.whl
Requirement already satisfied: six>=1.5.2 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from grpcio) (1.13.0)
Installing collected packages: grpcio
Successfully installed grpcio-1.25.0

果然剛才裝的丟了。。。
然后運行python3 get_service.py

gRPC HelloWorld測試
打開一個新的窗口運行
python3 client.py
gRPC HelloWorld測試

在原來的窗口可以看到called with lxc
gRPC HelloWorld測試

參考資料:
https://www.jianshu.co×××c947d98e192
https://blog.csdn.net/whereismatrix/article/details/78595550

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伊春市| 沿河| 仁怀市| 枝江市| 宜宾市| 普定县| 关岭| 盐城市| 寻乌县| 昌黎县| 漾濞| 潢川县| 张家港市| 九寨沟县| 樟树市| 长兴县| 易门县| 利津县| 阿拉善右旗| 德安县| 北碚区| 岫岩| 杨浦区| 株洲市| 长寿区| 芦山县| 峨眉山市| 湘潭县| 襄樊市| 阿荣旗| 喀喇沁旗| 崇礼县| 金塔县| 八宿县| 丰顺县| 万安县| 承德市| 贵阳市| 昌平区| 盐边县| 西和县|