gRPC是什么?

gRPC是什么可以用官网的一句话来概括

A high-performance, open-source universal RPC framework

所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样。如下图所示就是一个典型的RPC结构图。

 
 
 
 
 
 
 
 
 
 
 
RPC通信

gRPC有什么好处以及在什么场景下需要用gRPC

既然是server/client模型,那么我们直接用restful api不是也可以满足吗,为什么还需要RPC呢?下面我们就来看看RPC到底有哪些优势

gRPC vs. Restful API

gRPC和restful API都提供了一套通信机制,用于server/client模型通信,而且它们都使用http作为底层的传输协议(严格地说, gRPC使用的http2.0,而restful api则不一定)。不过gRPC还是有些特有的优势,如下:

  • gRPC可以通过protobuf来定义接口,从而可以有更加严格的接口约束条件。关于protobuf可以参见笔者之前的小文Google Protobuf简明教程
  • 另外,通过protobuf可以将数据序列化为二进制编码,这会大幅减少需要传输的数据量,从而大幅提高性能。
  • gRPC可以方便地支持流式通信(理论上通过http2.0就可以使用streaming模式, 但是通常web服务的restful api似乎很少这么用,通常的流式数据应用如视频流,一般都会使用专门的协议如HLS,RTMP等,这些就不是我们通常web服务了,而是有专门的服务器应用。)

使用场景

  • 需要对接口进行严格约束的情况,比如我们提供了一个公共的服务,很多人,甚至公司外部的人也可以访问这个服务,这时对于接口我们希望有更加严格的约束,我们不希望客户端给我们传递任意的数据,尤其是考虑到安全性的因素,我们通常需要对接口进行更加严格的约束。这时gRPC就可以通过protobuf来提供严格的接口约束。
  • 对于性能有更高的要求时。有时我们的服务需要传递大量的数据,而又希望不影响我们的性能,这个时候也可以考虑gRPC服务,因为通过protobuf我们可以将数据压缩编码转化为二进制格式,通常传递的数据量要小得多,而且通过http2我们可以实现异步的请求,从而大大提高了通信效率。

但是,通常我们不会去单独使用gRPC,而是将gRPC作为一个部件进行使用,这是因为在生产环境,我们面对大并发的情况下,需要使用分布式系统来去处理,而gRPC并没有提供分布式系统相关的一些必要组件。而且,真正的线上服务还需要提供包括负载均衡,限流熔断,监控报警,服务注册和发现等等必要的组件。不过,这就不属于本篇文章讨论的主题了,我们还是先继续看下如何使用gRPC。

gRPC HelloWorld实例详解

gRPC的使用通常包括如下几个步骤:

  1. 通过protobuf来定义接口和数据类型
  2. 编写gRPC server端代码
  3. 编写gRPC client端代码
    下面来通过一个实例来详细讲解上述的三步。
    下边的hello world实例完成之后,其目录结果如下:

    project helloworld

定义接口和数据类型

  • 通过protobuf定义接口和数据类型
syntax = "proto3";

package rpc_package;

// define a service
service HelloWorldService {
// define the interface and data type
rpc SayHello (HelloRequest) returns (HelloReply) {}
} // define the data type of request
message HelloRequest {
string name = 1;
} // define the data type of response
message HelloReply {
string message = 1;
}
  • 使用gRPC protobuf生成工具生成对应语言的库函数
python -m grpc_tools.protoc -I=./protos --python_out=./rpc_package --grpc_python_out=./rpc_package ./protos/user_info.proto

这个指令会自动生成rpc_package文件夹中的helloworld_pb2.pyhelloworld_pb2_grpc.py,但是不会自动生成__init__.py文件,需要我们手动添加

关于protobuf的详细解释请参考Google Protobuf简明教程

gRPC server端代码

#!/usr/bin/env python
# -*-coding: utf-8 -*- from concurrent import futures
import grpc
import logging
import time from rpc_package.helloworld_pb2_grpc import add_HelloWorldServiceServicer_to_server, \
HelloWorldServiceServicer
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply class Hello(HelloWorldServiceServicer): # 这里实现我们定义的接口
def SayHello(self, request, context):
return HelloReply(message='Hello, %s!' % request.name) def serve():
# 这里通过thread pool来并发处理server的任务
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) # 将对应的任务处理函数添加到rpc server中
add_HelloWorldServiceServicer_to_server(Hello(), server) # 这里使用的非安全接口,世界gRPC支持TLS/SSL安全连接,以及各种鉴权机制
server.add_insecure_port('[::]:50000')
server.start()
try:
while True:
time.sleep(60 * 60 * 24)
except KeyboardInterrupt:
server.stop(0) if __name__ == "__main__":
logging.basicConfig()
serve()

gRPC client端代码

#!/usr/bin/env python
# -*- coding: utf-8 -*- from __future__ import print_function
import logging import grpc
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
from rpc_package.helloworld_pb2_grpc import HelloWorldServiceStub def run():
# 使用with语法保证channel自动close
with grpc.insecure_channel('localhost:50000') as channel:
# 客户端通过stub来实现rpc通信
stub = HelloWorldServiceStub(channel) # 客户端必须使用定义好的类型,这里是HelloRequest类型
response = stub.SayHello(HelloRequest(name='eric'))
print ("hello client received: " + response.message) if __name__ == "__main__":
logging.basicConfig()
run()

演示

先执行server端代码

python hello_server.py

接着执行client端代码如下:

➜  grpc_test python hello_client.py
hello client received: Hello, eric!

References

作者:geekpy
链接:https://www.jianshu.com/p/9c947d98e192
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

MYSQL中 ENUM、SET 类型(建议用tinyint代替)的更多相关文章

  1. MYSQL中 ENUM 类型

    MYSQL中 ENUM 类型的详细解释 ENUM类型 ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串(&quo ...

  2. mysql中enum的用法

    字段 类型 长度/值*1 整理 属性 Null 默认2 额外 注释 enum         说明:enum类型的字段,若长度值写长度1/2,报错 (1)  数据长度为1,则为0,1,2… (2)   ...

  3. Mysql中的一些类型

    列类型--整数类型Tinyint:迷你整形 一个字节=8位 最大能表示的数值是0-255 实际区间 -128~127Smallint:小整形 两个字节 能表示0-65535Mediumint:中整型 ...

  4. 解析MySQL中存储时间日期类型的选择问题

    解析MySQL中存储时间日期类型的选择问题_Mysql_脚本之家 https://www.jb51.net/article/125715.htm 一般应用中,我们用timestamp,datetime ...

  5. mysql中存储字段类型的查询效率

    检索性能从快到慢的是(此处是听人说的): 第一:tinyint,smallint,mediumint,int,bigint第二:char,varchar第三:NULL 解释(转载): 整数类型1.TI ...

  6. MySQL 中的数字类型

    MySQL 中数据类型常用的就三大类: 数字类型/numeric types 日期和时间/date and time types 字符类型/string (character and byte) ty ...

  7. 关于MySql中的varchar类型

    今天新开始的项目在做数据库设计,发现自己对MySql的varchar类型还不熟悉,故又上网收集资料整理如下. 1.varchar类型的变化 MySQL 数据库的varchar类型在4.1以下的版本中的 ...

  8. mysql中的timestamp类型时间比较:unix_timestamp函数

    在mysql中,某字段的类型设置为了timestamp,那么我们现在希望取出指定时间段的记录,该如何做呢? 在php中有time()和strtotime()来进行日期和时间戳的格式化,而在mysql中 ...

  9. MySql中的时间类型datetime,timestamp,date,year比较

    MySQL日期类型.日期格式.存储空间.日期范围比较.日期类型        存储空间       日期格式                 日期范围------------ ---------   ...

  10. MySql中的varchar类型

    转载:http://www.cnblogs.com/doit8791/archive/2012/05/28/2522556.html 1.varchar类型的变化 MySQL 数据库的varchar类 ...

随机推荐

  1. delphi中的Label控件背景透明

    Label1.Transparent:=true;你在它的属性窗口把它的Transparent属性改成TRUE就行了 来自为知笔记(Wiz)

  2. windows xp 无法连接wpa无线网络

    其实以前一直是可以的,不知为什么前几天忽然就不能加入原有的无线网了.我的无线网是WPA加密的,采用DHCP分配IP(但针对特定MAC地址分配静态IP). 在网上找了许久,有的网友认为应该把无线网卡(那 ...

  3. C 语言文件操作

    C 语言文件操作 1. 数据流:     程序与数据的交互以流的形式进行.fopen 即打开数据流,fclose 即刷新数据流.     所谓数据流,是一种抽象,表示这段数据像流一样,需要逐步接收,不 ...

  4. 【java】String类和StringBuffer类常用操作

    String类是字符串常量,是不可更改的常量.而StringBuffer是字符串变量,它的对象是可以扩充和修改的.StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于Stri ...

  5. 数值的整数次方(剑指offer面试题11)

    实现函数 double Power(double base, int exponent),即乘方运算. 考虑问题 exponet < 0 , 可以转化为 1.0 / Power(base, -1 ...

  6. 14.allegro.PCB设计前工作[原创]

    一.设置板子大小 -- ----- 板子边框 2种设置outline方法,创建2个KI,两个keepin,,r:允许布线区:p允许摆放元件的区域 法一:直接添加线 ①Board Geometry(最外 ...

  7. plsql programming 04 条件和顺序控制

    1. 条件语句 if salary > 40000 or salary is NULL then give_bonus(employee_id, 500); end if; if conditi ...

  8. Java关键字static、final

    static  1. static变量     按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量:另一种是没有被static修饰的变量,叫实例变量.两者的 ...

  9. Windows 桌面软件:不绑定bing搜索的缤纷桌面

    bing:世界上最好的壁纸提供商  ^.^一直垂涎着Bing的壁纸,总是想找机会来一番邂逅. 之前使用bing自家的缤纷桌面.这个软件缺点就是和bing搜索绑定太厉害,放在桌面上感觉那个黑色的条框很碍 ...

  10. Spring 实践 -AOP

    Spring 实践 标签: Java与设计模式 AOP引介 AOP(Aspect Oriented Programing)面向切面编程采用横向抽取机制,以取代传统的纵向继承体系的重复性代码(如性能监控 ...