热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Netty框架中运用Protobuf实现高效通信协议

在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。

Netty中使用protobuf

  1. 环境准备

下载protoc代码生成器和源码包:http://code.google.com/p/protobuf/downloads/list

  • protobuf-2.4.1.tar.bz2:主要是生成protobuf-2.4.1.jar,操作需要安装maven,可以到网上下载这个Jar包,所以这里略。
  • protoc-2.4.1-win32.zip:生成XXX.Proto执行文件。

     

    参考http://blog.csdn.net/dreamdoc/article/details/6577180相关代码

     

  1. 制作.Proto文件

格式参考如下:

注:可以按如上内容编写文本文件,然后修改后缀为.Proto。

  1. proto文件结构

从上面的代码可以看出,proto文件的结构非常简单。

  • package java_package 定义生成的java类的package名称。
  • message定义一种类型,类型以Java中的一个class,Book是类名,在生成Java代码时,就是使用这个类名。
  • option optimize_for = LITE_RUNTIME:表示生成的java代码继承GeneratedMessageLite ,继承GeneratedMessageLite的好处是可张念以用jboss提供的编解码器,可以认为是必写项。

 

  • 该类型中包含的字段格式: [限定符 类型 字段名称 = tag [default = 默认值]]

 

  1. 支持的默认类型

.proto Type

Notes

C++ Type

Java Type

double

 

double

double

float

 

float

float

int32

Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.

int32

int

int64

Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.

int64

long

uint32

Uses variable-length encoding.

uint32

int1

uint64

Uses variable-length encoding.

uint64

long1

sint32

Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.

int32

int

sint64

Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.

int64

long

fixed32

Always four bytes. More efficient than uint32 if values are often greater than 228.

uint32

int1

fixed64

Always eight bytes. More efficient than uint64 if values are often greater than 256.

uint64

long1

sfixed32

Always four bytes.

int32

int

sfixed64

Always eight bytes.

int64

long

bool

 

bool

boolean

string

A string must always contain UTF-8 encoded or 7-bit ASCII text.

string

String

bytes

May contain any arbitrary sequence of bytes.

string

ByteString

    除此之外,还支持枚举,自定义类型等。

  1. protobuf的限定符

  • required:一个格式良好的消息一定要含有1个这种字段。表示该值是必须要设置的;如果该项不设值,在序列化时会抛出RuntimeException,推荐不使用该字段,该字段一旦使用,无法更改。

     

    由于一些历史原因,基本数值类型的repeated的字段并没有被尽可能地高效编码。在新的代码中,用户应该使用特殊选项[packed=true]来保证更高效的编码。如:repeated int32 samples = 4 [packed=true];

     

    required是永久性的:在将一个字段标识为required的时候,应该特别小心。如果在某些情况下不想写入或者发送一个required的字段,将原始该字段修饰符更改为optional可能会遇到问题——旧版本的使用者会认为不含该字段的消息是不完整的,从而可能会无目的的拒绝解析。在这种情况下,你应该考虑编写特别针对于应用程序的、自定义的消息校验函数。Google的一些工程师得出了一个结论:使用required弊多于利;他们更愿意使用optional和repeated而不是required。当然,这个观点并不具有普遍性。

     

  • optional:消息格式中该字段可以有0个或1个值(不超过1个)。不存在时使用默认值,默认值可自定义如[default = 10]。系统默认值如下:int = 0,bool = false,string=""

     

  • repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复,相当于java中的List。

     

  1. guide style

Protocol Buffers官方提供了一个Guide Style。其中介绍了一些定义proto的优秀实践。一句话总结就是名称时,message名称以驼峰方式定义,字段名则需要以如author_name方式定义。字段名在生成Java代码时,会自动转换为符合Java风格的命名方式。

  1. 生成. Java文件

将编写的.Proto文件与下载的protoc.exe文件放在同一指定的目录,进入dos并系统编译命令:protoc XXX.proto --java_out=C:/,这时会在你所指令的目录生成相应的java文件。

  1. 它的一些缺点

  • 不支持大数据集的处理,少于1M
  • 不支持Date,Map这些Java内建的对象

 

  1. 客户端示例

  • 如果Message类中用到repeated 定义的类型,则在客户端中按如下代码操作: builder.addBody(Message.Body.newBuilder().setContent(bytes).build());
  • 也可用下面默认的方式传输二进制,这时在节点7中就要使用默认的protobuf解码方式,

    byte[] test = "asdfa".getBytes();        

    ChannelBuffer channelBuffer = ChannelBuffers.buffer(test.length);

    // 将 获得到的数组写入 channelBuffer中

    channelBuffer.writeBytes(test);

    // 发送到服务器端

    ChannelFuture lastWriteFuture = channel.write(channelBuffer);

  1. 服务器端示例

  1. ServerHandler示例

  • 如果使用默认的Protobuf解码方式传输二进制,则接收时按以下代码接收:

if((e.getMessage() instanceof ChannelBuffer)){

        ChannelBuffer channelBuffer =(ChannelBuffer)e.getMessage();

        byte[] bytes = channelBuffer.array();

}

  1. PipelineFactory示例

  • 其中,以下两行代码是默认的Protobuf解码类型,如果到自定义解码,这两行可以注释掉,反之把自定义的加码解码注释掉.

pipeline.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());

pipeline.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());

  • org.jboss.netty.handler.codec.frame ,这个包里面有三种封包方法(主要用在传输字符串):

    1.DelimiterBasedFrameDecoder 是利用分隔符来进行包的界定;2.FixedLengthFrameDecoder 是利用固定的长度来进行包的界定;3.LengthFieldBasedFrameDecoder 和 LengthFieldPrepender 是利用在发送数据的时候在里面加上头字段,头字段里面包含了包的长度。


推荐阅读
  • 在多模块项目中,项目A作为一个独立的工具包,不依赖于任何第三方库。其目录结构如下:`--src--main--java--resources`。当将项目A打包成JAR文件后,发现无法正确访问`resources`目录下的文件资源。这一问题可能源于JAR文件的构建配置或类路径设置不当,需要仔细检查Maven或Gradle的构建脚本,确保资源文件被正确包含并加载。 ... [详细]
  • 如果程序使用Go语言编写并涉及单向或双向TLS认证,可能会遭受CPU拒绝服务攻击(DoS)。本文深入分析了CVE-2018-16875漏洞,探讨其成因、影响及防范措施,为开发者提供全面的安全指导。 ... [详细]
  • 分布式开源任务调度框架 TBSchedule 深度解析与应用实践
    本文深入解析了分布式开源任务调度框架 TBSchedule 的核心原理与应用场景,并通过实际案例详细介绍了其部署与使用方法。首先,从源码下载开始,详细阐述了 TBSchedule 的安装步骤和配置要点。接着,探讨了该框架在大规模分布式环境中的性能优化策略,以及如何通过灵活的任务调度机制提升系统效率。最后,结合具体实例,展示了 TBSchedule 在实际项目中的应用效果,为开发者提供了宝贵的实践经验。 ... [详细]
  • 如何在Spark数据排序过程中有效避免内存溢出(OOM)问题
    本文深入探讨了在使用Spark进行数据排序时如何有效预防内存溢出(OOM)问题。通过具体的代码示例,详细阐述了优化策略和技术手段,为读者在实际工作中遇到类似问题提供了宝贵的参考和指导。 ... [详细]
  • Java 点餐系统源代码附带管理后台(免费提供)
    本项目提供了一套基于 Java 的点餐系统,包括前端小程序和后端管理平台。采用 Spring Boot 和 SSM 框架,结合 MySQL 和 Redis 数据库技术,适用于学习和二次开发。有需要源代码的开发者可以通过私信联系,免费获取下载链接。 ... [详细]
  • 在 Kubernetes 中,Pod 的调度通常由集群的自动调度策略决定,这些策略主要关注资源充足性和负载均衡。然而,在某些场景下,用户可能需要更精细地控制 Pod 的调度行为,例如将特定的服务(如 GitLab)部署到特定节点上,以提高性能或满足特定需求。本文深入解析了 Kubernetes 的亲和性调度机制,并探讨了多种优化策略,帮助用户实现更高效、更灵活的资源管理。 ... [详细]
  • 在尝试为 Unity 编译一个简单的 Java 库时,运行 `ant jar` 命令后遇到了 Java I/O 异常。具体错误信息为“无法启动程序 ${aAPT},错误代码 2”,这通常表示指定的文件或目录不存在。此问题可能是由于环境配置不正确或路径设置有误导致的。建议检查相关路径和环境变量,确保所有依赖项都已正确安装和配置。 ... [详细]
  • 本文探讨了基于点集估算图像区域的Alpha形状算法在Python中的应用。通过改进传统的Delaunay三角剖分方法,该算法能够生成更加灵活和精确的形状轮廓,避免了单纯使用Delaunay三角剖分时可能出现的过大三角形问题。这种“模糊Delaunay三角剖分”技术不仅提高了形状的准确性,还增强了对复杂图像区域的适应能力。 ... [详细]
  • 掌握PHP编程必备知识与技巧——全面教程在当今的PHP开发中,了解并运用最新的技术和最佳实践至关重要。本教程将详细介绍PHP编程的核心知识与实用技巧。首先,确保你正在使用PHP 5.3或更高版本,最好是最新版本,以充分利用其性能优化和新特性。此外,我们还将探讨代码结构、安全性和性能优化等方面的内容,帮助你成为一名更高效的PHP开发者。 ... [详细]
  • 基于域名、端口和IP的虚拟主机构建方案
    本文探讨了在单台物理服务器上构建多个Web站点的虚拟主机方案,详细介绍了三种主要的虚拟主机类型:基于域名、基于IP地址和基于端口的虚拟主机。每种类型的实现方式及其优缺点均进行了深入分析,为实际应用提供了全面的技术指导。 ... [详细]
  • 如何使用R语言高效连接并操作MySQL数据库
    如何使用R语言高效连接并操作MySQL数据库 ... [详细]
  • 大家好,我是梅巴哥er。本文将深入探讨Redux框架中的第三个实战案例,具体实现每两秒自动点击按钮以触发颜色变化的功能。该案例中,一个关键点在于是否需要使用异步操作来处理定时任务,我们将详细分析其必要性和实现方式。通过这一实例,读者可以更好地理解Redux在实际项目中的应用及其异步处理机制。 ... [详细]
  • 深入解析Spring Boot启动过程中Netty异步架构的工作原理与应用
    深入解析Spring Boot启动过程中Netty异步架构的工作原理与应用 ... [详细]
  • 初探设计模式之代理模式:原理与应用解析
    在设计模式中,代理模式通过一个代理对象来控制对真实对象的访问。UML图展示了代理类(如MathProxy)维护了一个引用,使得代理能够访问实际的主题对象。代理模式不仅能够延迟初始化昂贵的对象,还能在访问前后添加额外的操作,如权限检查或日志记录。这种模式在远程服务调用、虚拟代理和智能引用等方面有广泛应用。 ... [详细]
  • 本文详细介绍了使用响应文件在静默模式下安装和配置Oracle 11g的方法。硬件要求包括:内存至少1GB,具体可通过命令`grep -i memtotal /proc/meminfo`进行检查。此外,还提供了详细的步骤和注意事项,确保安装过程顺利进行。 ... [详细]
author-avatar
-____Ddddear_534
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有