Go 编程:借一个 udpserver 用用

既然写了一个 tcpserver, 乘机把之前借用的一个 udpserver 整理一下。当然这个项目是借用的,常说庸才模仿,天才抄袭,这次就算抄袭吧(偷笑)。

具体项目地址请参见: github.com/x-mod/thriftudp

tcpudp的区别,此类面试题就不解释了。udp其协议本身特点决定了它非常适合如日志、监控等数据收集类场景,即在不影响程序性能的基础上提升程序的可监测性(Measurability).

既然是借用的,不妨看看借用的项目: Jaeger, 以下是Jaeger实现架构图:

jaeger arch v1

从图中可以看出,Jaeger是使用UDP协议作为实现jaeger-clientjaeger-agent之间的基础通信协议。其它网路组件直接则通过TCP通信。无论是UDP还是TCP均不属于应用层协议,在应用层同样需要选择或设计相应的应用级协议格式。如今很少设计自定义的协议格式,通常会采用ProtoBufferThrift等此类专门IDL,进行接口定义。深入研究Jaeger代码,就会发现,同一个项目中不但用了Thrift,同时也使用了ProtoBuffer,只是具体使用场景不同。

为什么Thrift更加适合在UDP协议上使用呢?

ProtoBufferThrift本质上并无太大差别,都是专门针对字节序列化与反序列化的定义与生成工具而已。但是Thrift有一个更加适合UDP通信的关键字,即oneway关键字,其意思就是不用等待响应返回。在TCP上通信,通常是需要等待请求返回的。而UDP不需要,发出去了是可以不管是否成功的。看起来非常的不合理,但是如果UDP只是在本机HOST的回环接口上进行数据交互,基本不会出现网络原因导致的数据包丢失问题。

想法很好,不幸的是,官方apache/thrift在生成的框架代码以及样例中均不提供UDP实现。所以就照着Jaeger项目写了一个,方便以后使用。

主要针对Jaeger项目的变化是:

  • 支持新的thrift版本
  • 独立的udpserver框架

该项目的使用非常简单,步骤如下:

  • 按照thrift语法进行接口定义
  • 使用thrift生成框架代码
  • 具体Client/Server端代码实现

更多细节可以参考项目的样例程序thriftudp/example