第九十三篇 Protobuf总结

哈哈,好久没见了,虽然关注的人不是很多,对自己热衷的事情还是想记录下来,不论是想学的还是沉淀下来的在此能有些痕迹,希望自己坚持下来,不忘初心!

一、Protobuf介绍

https://developers.google.com/protocol-buffers

Protocol buffers
用于序列化结构化数据(比如XML),但更小、更快、更简单。您只需定义数据的结构化方式,然后就可以使用特殊生成的源代码轻松地向各种数据流写入和读取结构化数据,并使用各种语言。

这是官网的一段介绍,总的来说已经表达很清楚了,和我们现有的一些结构化数据类似,比如json,XML等等,但protocol buffers 他对需要结构化的数据类型要求更严格,这也使得再其序列化后能极大的压缩,使其运行比较快,存储上和传输上更小

XML、JSON、Protobuf 都具有数据结构化和数据序列化的能力
XML、JSON 更注重 数据结构化,关注人类可读性和语义表达能力。Protobuf 更注重 数据序列化,关注效率、空间、速度,人类可读性差,语义表达能力不足
Protobuf 的应用场景更为明确,XML、JSON 的应用场景更为丰富

在这里插入图片描述

为什么使用协议缓冲区?

我们将要使用的示例是一个非常简单的“地址簿”应用程序,它可以在文件中读取和写入人们的联系方式。地址簿中的每个人都有一个姓名、一个 ID、一个电子邮件地址和一个联系电话号码。

你如何序列化和检索这样的结构化数据?有几种方法可以解决这个问题:

  • 原始内存数据结构可以二进制形式发送/保存。随着时间的推移,这是一种脆弱的方法,因为接收/读取代码必须使用完全相同的内存布局、字节序等进行编译。此外,由于文件以原始格式累积数据,并且为该格式连接的软件副本是传播,很难扩展格式。
  • 您可以发明一种特殊方式将数据项编码为单个字符串——例如将 4
    个整数编码为“12:3:-23:67”。这是一种简单而灵活的方法,尽管它确实需要编写一次性的编码和解析代码,并且解析会产生很小的运行时成本。这最适合编码非常简单的数据。
  • 将数据序列化为 XML。这种方法可能非常有吸引力,因为
    XML(某种程度)是人类可读的,并且有许多语言的绑定库。如果您想与其他应用程序/项目共享数据,这可能是一个不错的选择。然而,众所周知,XML
    是空间密集型的,对它进行编码/解码会对应用程序造成巨大的性能损失。此外,导航 XML DOM 树比导航类中的简单字段通常要复杂得多。

协议缓冲区是解决这个问题的灵活、高效、自动化的解决方案。使用协议缓冲区,您可以编写.proto要存储的数据结构的描述。由此,protocol buffer 编译器创建了一个类,该类以高效的二进制格式实现 protocol buffer 数据的自动编码和解析。生成的类为组成协议缓冲区的字段提供 getter 和 setter,并将读取和写入协议缓冲区的细节作为一个单元处理。重要的是,协议缓冲区格式支持随着时间的推移扩展格式的想法,这样代码仍然可以读取用旧格式编码的数据。

二、语法介绍

很简单的列子,需要序列化的数据SearchRequest,和c,c++ 结构体struct 定义方式类似

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

String 类型的 query,编号是 1 (注:字段必须有编号且编号不允许重复)
int32 类型的 page_number,编号是 2

类型定义示例

首先定义关于phone的类型数据,分别是int和string

phone.proto

syntax = "proto3";

package com.hello.world;

message Phone{
  string name = 1;
  int64 number = 2;
}

再定义关于个人信息的一个proto文件,此proto文件中包含常用的所有类型数据,逐一列举出来

  1. 如何导入其他.proto文件
  2. 类型中如何使用数组,字典,对象,bool等
  3. 也可以增加required, 意味着必须提供该字段的值,否则该消息将被视为“未初始化”。序列化未初始化的消息将引发异常。解析未初始化的消息将失败。

people.proto

syntax = "proto3";

import "phone.proto";

# 包名
package com.hello.world;

message People{
  string name = 1;
  int32 age = 2;
}

message Information {
  int32 id = 1;
  string address = 2;
  double bid = 3;
  bool is_shortsightedness = 4;
  repeated string hobby = 5;
  map<string, int32> friends = 6;
  People people = 7;
  Phone phone = 8;
}

编译生成py文件可调用

# 安装 grpc 相关的 python 模块
pip install grpcio
# 安装 python 下的 protoc 编译器, 使用 protoc 编译 proto 文件, 生成 python 语言的实现
pip install grpcio-tools

参数解释

python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. helloworld.proto

python -m grpc_tools.protoc: python 下的 protoc 编译器通过 python 模块(module) 实现, 所以说这一步非常省心
--python_out=. : 编译生成处理 protobuf 相关的代码的路径, 这里生成到当前目录
--grpc_python_out=. : 编译生成处理 grpc 相关的代码的路径, 这里生成到当前目录
-I. helloworld.proto : proto 文件的路径, 这里的 proto 文件在当前目录

测试文件测试proto 文件

# !/usr/bin/python
# -*- coding: UTF-8 -*-

"""
@file:test.py
@time:2022/01/11

"""
import phone_pb2, people_pb2

information = people_pb2.Information()
information.id = 1
information.address = "shanghai"
information.bid = 3.1415926232323
information.is_shortsightedness = True
information.hobby.extend(["swimming", "coding", "sleep", "movie"])
information.friends.update({"bobcat": 16, "ocelot": 17})

information.people.CopyFrom(people_pb2.People(name="bob", age=18))
information.phone.CopyFrom(phone_pb2.Phone(name="huawei", number=6800))
print(information)

结果:

id: 1
address: "shanghai"
bid: 3.1415926232323
is_shortsightedness: true
hobby: "swimming"
hobby: "coding"
hobby: "sleep"
hobby: "movie"
friends {
  key: "bobcat"
  value: 16
}
friends {
  key: "ocelot"
  value: 17
}
people {
  name: "bob"
  age: 18
}
phone {
  name: "huawei"
  number: 6800
}


进程已结束,退出代码0

序列化和反序列化使用

information_serialize = information.SerializeToString()
print("serialize:", information_serialize)
print("serialize byte:", information.ByteSize())

"""
serialize: b'\x08\x01\x12\x08shanghai\x19\xc3\x191P\xfb!\t@ \x01*\x08swimming*\x06coding*\x05sleep*\x05movie2\n\n\x06ocelot\x10\x112\n\n\x06bobcat\x10\x10:\x07\n\x03bob\x10\x12B\x0b\n\x06huawei\x10\x905'
serialize byte: 101
"""

information_parse = people_pb2.Information()
information_parse.ParseFromString(information_serialize)
print("parse:", information_parse)

"""
parse: id: 1
address: "shanghai"
bid: 3.1415926232323
is_shortsightedness: true
hobby: "swimming"
hobby: "coding"
hobby: "sleep"
hobby: "movie"
friends {
  key: "bobcat"
  value: 16
}
friends {
  key: "ocelot"
  value: 17
}
people {
  name: "bob"
  age: 18
}
phone {
  name: "huawei"
  number: 6800
}
"""

protobuf 生成脚本

proto_generate.sh


BASEDIR=$(dirname "$0")
cd "$BASEDIR" || exit

PROTO_DIR="proto"
TARGER_DIR="generated"

generate() {
  python -m grpc_tools.protoc -I./$PROTO_DIR --python_out=./$TARGER_DIR "$1"
}

generate_all() {
  for proto in "$PROTO_DIR"/*.proto; do
    echo "protoc: $proto"
    generate "$proto"
  done
}

if [ $# -gt 0 ]; then
  generate "$1"
else
  generate_all
fi

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值