• Fastnet,三步完成高性能的网络开发


    前言

    在GO语言里,由于其天生的支持多并发,而且非常完善的实现了比线程更轻量级的协程的支持,使得GO一直在多并发的服务端组件的开发中占有较大的优势;特别是在云原生的大势来袭下;更多的搭建在云原生框架下的底层服务都是用了GO语言进行开发;服务端的底层开发就缺少不了网络通信的开发;今天咱们这个文章要给大家介绍的就是一款GO语言实现的,能非常方便就能实现高性能网络通信的开发包工具——Fastnet。

    Fastnet

    Fastnet的项目的Github地址

    http://github.com/gohutool/boot4go-fastnet

    Fastnet项目的创造思想来源于在GO语言里另一个以高并发,高性能著称的项目Fasthttp;Fasthttp实现比原生GO语言提供的http包要高至少10倍性能以上的http通信服务能力,被誉为当下最快的http GO语言包;有兴趣的朋友,可以查看笔者的另一篇文章《boot4go-gateway和nginx的性能测试大PK》;该文章介绍了使用fasthttp开发的一款Gateway产品,和使用Nginx作为Gateway进行性能测试的过程和PK结果;

    Fastnet采用fasthttp提供高性能http服务的实现思路,通过协程池,缓存池,对象池等实现技巧,将GO语言在多并发,高性能的优势更近一步的进行了提升和优化,从而实现了TCP/IP网络通信的高性能实现;Fastnet也作为了笔者另一个MQTT中间件产品的网络底层通讯的支持架构。

    使用Fastnet

    引入

    Fastnet只支持GO语言;首先引入fastnet包

    1. import (
    2. "github.com/gohutool/boot4go-fastnet"
    3. )

    初始化Listener

    作为网络通信;和http以及其他net包一样;服务端的编程都是从Listener开始; 在Listener初始化指定端口,

    1. l, err := net.Listen("tcp", ":9888")
    2. if err != nil {
    3. fmt.Println("Start server error " + err.Error())
    4. return
    5. }

    如上段代码所示, 初始化了一个服务端的Listener,端口指定为9888,Listener监听9888端口进行TCP/IP方式的通信;

    实现监听业务的Server

    Server是具体处理监听的端口的连接的对象,在监听建立成功以后,创建一个Server对象,该Server对象服务于Listener对象,当Listener对象Accept到客户端的连接以后,Server会处理该连接

    创建Server

    1. var s Server
    2. s = NewServer(WithMaxIdleWorkerDuration(10 * time.Second),
    3. WithMaxPackageFrameSize(1024*10)))

    上段代码,首先定义一个Server对象s; 然后通过fastnet提供的API,NewServer创建出一个Server对象,WithMaxIdleWorkerDuration是一个ServerOption对象,用来进行Server创建时的一些参数指定; 例如这里的WithMaxIdleWorkerDuration就是指定协程池的IDLE选项,10 * time.Second后如何协程没有任何处理内容,该协程将被协程池进行回收;还有更多的Options选项,可以查看github里的API文档

    事件监听

    fastnet通过事件的方式,将具体的处理逻辑交还给程序的开发者, fastnet封装了Accept, Read, Write,协议解析,协议封装等过程,作为开发者不需要关注这些过程,作为开发者,只需要关注在自己的具体业务上,比如解析出来的协议包具体应该去做怎样的业务处理, fastnet就是通过事件的方式,将通信中的过程封装到了内部,然后通过事件的方式,去触发具体的业务实现;

    1. decoder, _ := codec.VariableLengthFieldFrameDecoder(
    2. 1024*1024, 2, 0, func(variableLength uint64) uint64 {
    3. return 2 + variableLength
    4. })
    5. onClose := OnClose(func(ctx *RequestCtx, err error) {
    6. if err != nil {
    7. fmt.Printf("%v\n", err)
    8. }
    9. })
    10. onData := OnData(func(ctx *RequestCtx, b []byte) error {
    11. ctx.Write(b)
    12. // ctx.WriteToChannel(b)
    13. return nil
    14. })
    15. s.ByteBufferDecoder = decoder
    16. s.OnData = onData
    17. s.OnClose = onClose

    上述代码是一个标准的指定业务处理的Sample代码;在代码中指定了decoder是一个变长数据帧的协议包解析器,用来进行协议帧的解析, 接着定义了onClose的事件函数监听Close事件;定义了onData的事件函数监听数据包的解析成功的Data事件,然后指定给server对象,通过上面的处理,fastnet就可以知道协议的通信帧的协议格式,通过协议格式解析到一个协议包以后,就会触发onData事件,交给业务定义的onData函数进行处理;让建立的连接关闭以后,将触发OnClose事件,交个业务逻辑来处理;

    在fastnet里内置了场景的几种协议帧的解析器

    DelimiterBasedFrameDecoder

    LineBasedFrameEncoder

    FixedLengthFrameDecoder

    FixLengthFieldFrameDecoder

    LengthFieldBasedFrameDecoder

    也可以通过fastnet提供的ByteBufferDecoder的扩展机制,自己来进行协议栈的扩展

    启动服务

    完成Server对象的初始化和设置以后,就可以启动Server对象,来完成服务端的启动了;

    1. err = s.Serve(l)
    2. if err != nil {
    3. panic(err)
    4. }

    最后来看看效果

    在fastnet的项目中,自带了一个EchoServer的实现,实现了echo服务,通过echo服务我们可以进行fastnet的性能测试,可以完全纯净的看看TCP/IP通信的性能测试;

    使用tcpdebug进行简单的通讯测试

    使用Jmeter压力测试

    结束语

    本文介绍了GO语言开发的一款提供实现高性能TCP/IP网络编程的开发包fastnet; 文中简要的介绍了fastnet的基础用法,fastnet已经在笔者开发的mqtt的中间件产品里作为底层通讯架构的实现; fastnet不仅实现了高性能的TCP/IP通讯的开发架构,也在开发架构中提供了一些扩展的机制,包括协议栈的扩展,消息机制的扩展;更多的信息可以在github项目里查看。

    谢谢大家继续关注

  • 相关阅读:
    Mysql集群高可用架构MHA
    二元线性回归(自写梯度下降法与scikit-learn)
    ps怎么拼图,自学ps软件photoshop2022,PS制作拼图效果
    windows下MySQL服务不见,服务无法启动,服务闪退,提示“本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止”
    [第六篇]——云服务器
    服务器感染的病毒有哪些特点呢?
    三国志14信息查询小程序(历史武将信息一览)制作更新过程03-主要页面的设计
    LeetCode50天刷题计划第二季(Day 31 — 两数之和 II - 输入有序数组(11.10-11.20)分数到小数(11.30-12.30)
    【numpy】numpy.where的使用
    php 打印分页 一组数据不分页问题解决
  • 原文地址:https://blog.csdn.net/inthirties/article/details/126700874