# goznix **Repository Path**: bidmatrix/goznix ## Basic Information - **Project Name**: goznix - **Description**: go练习项目 - **Primary Language**: Go - **License**: BSD-4-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-05-25 - **Last Updated**: 2025-01-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 源码链接:https://github.com/aceld/zinx #### 读写任务队列设计 ![img.png](resource/img.png) #### Chapter19 已经将连接的读写业务分离成Reader和Writer两个协程来处理。 在添加Worker Pool工作池后,Reader将收到Client客户端的Request请求, 将请求交给Worker Pool中的TaskQueue消息队列,Reader作为消息的生产者,而每条消息任务队列均会有一个Worker进行消费, 并且在消费之后会将数据交给Writer进行写操作,然后传给远程客户端。这样消息通过Worker Pool传播的目的是,无论连接数量为多少, 最终处理消息业务逻辑程序的是并行Worker,即计算业务逻辑的Goroutine协程数量是固定的。 可以在大量读写吞吐和并发的情况下限定Goroutine泛滥过多而导致性能下降的情况。 消息队列和任务工作池通过上述代码的结果来看已经可以提供相关功能了。 那么设计WorkerPool的意义在哪里?从当前的Zinx框架的设计可以看出来, 如果一个客户端连接过来,服务器端会启动一个Reader协程和一个Write协程, 这两个协程实则是在处理I/O的读写状态,而且在网络上没有数据传输的情况下是一个阻塞的状态。 本书在前面章节的内容中介绍过,一个流程如果阻塞是不会占用CPU资源的。在网络上有传输的数据对于读写的计算也必须让CPU承担。 可以理解为对于I/O读写的计算部分成本开发者无法优化,或者不应该优化。因此只剩下了将数据读取到用户态应用程序内存中对数据的业务逻辑处理部分。 如果框架没有添加WorkerPool工作池的功能,则对于整体功能来看毫无影响,但是一个连接对应一个业务处理的Goroutine,随着连接数量的增加, 服务器端的Goroutine的数量也相应地增加,而这些Goroutine并不会出现阻塞等现象,大部分逻辑都在计算业务,这样便将业务的处理优先级最大化了, 但是Goroutine的数量剧增会导致切换的频率变高,当超过计算机硬件可以承受的某个阈值时,程序将会立刻变得缓慢,如果连接此时继续增加,将会引起恶性循环, 从而导致程序资源被撑爆而导致进程死亡。WorkerPool实则是控制服务器端程序的最大切换处理业务频率的工具,大量的连接经过漏斗供给计算业务后,速度将得到控制。 #### Chapter 20: 之前给Connection提供了一个发消息的方法SendMsg( ),此方法将数据发送到一个无缓冲的Channel中的msgChan, 但是如果客户端连接比较多,导致对方处理不及时,则可能会出现短暂的阻塞现象,所以可以提供具有一定缓冲的发消息方法,提高非阻塞的发送体验 在一个连接的创建周期中,有两个时刻开发者需要注册业务回调功能,执行一些用户自定义的业务,这两个时刻分别是创建连接之后和断开连接之前。 为了满足这个需求,Zinx需增添连接创建后和断开前触发的回调业务函数,一般称作Hook(钩子)函数。 新增了相关的4个Hook方法,分别如下。 (1)SetOnConnStart:设置当前Server所有连接在创建时需要回调的Hook函数。 (2)SetOnConnStop:设置当前Server所有连接在断开时需要回调的Hook函数。 (3)CallOnConnStart:调用连接创建之后需要回调的业务方法。 (4)CallOnConnStop:调用连接停止之前需要回调的业务方法。 其中SetOnConnStart( )和SetOnConnStop( )两种方法的形参均为func(IConnection)函数类型 ,表示这两种方法为注册方法,需要先定义好具体的func(IConnection)函数,再注册进来。 在Server实现层添加OnConnStart、OnConnStop两个Hook函数 20.2 Zinx的连接属性设置当连接处理的时候,业务开发者希望能够让连接绑定一些用户的数据或者参数,然后Handle处理业务的时候可以从连接获取传递的参数, 进行业务逻辑处理。Zinx为了具备这个能力,需要为当前连接设定一些传递参数的接口或者方法,本节将实现连接属性设置的能力。