- 全局消息设计
1.1 原理
以往单线程全局消息的发送通过for循环的方式遍历每个msgque,给每个msgque发送一份数据拷贝。下面看如何利用go中channel机制设计全局消息,而不是轮询。
c chan struct{} ,通常struct{}类型channel的用法是使用同步,struct{}当做一个普通的数据类型,一般不需要往channel里面写数据。只有读等待,而读等待会在channel被关闭的时候返回。所以在close(c)的时候, 在所有等待接收c消息的groutine都会接收到消息。
所以为每个msgque写分配一个goroutine,接收到c的信息执行一次广播,并行实现。
在antnet设计中,利用goroutine的上述原理设计广播消息。所有msgque都会接收gmsg中的chan消息通知,读取gmsg中的msg以及执行处理msg的条件函数func()。func()可实现组播的功能或者其他限制条件。
(图1.1 全局消息结构)
gmsg初始化,当前gmsgId对应的全局消息初始化好chan
(图1.2 全局消息初始化)
新建msgque的时候把当前全局gmsgId赋值给msgque的gmsgId,用于接收gmsg消息
(图1.3 消息队列初始化全局消息)
msgque通过gmsgId获取gmsg队列中的全局消息gmsg,接收消息,计算前置条件处理全局消息。
(图1.4 消息队列处理全局消息)
发送全局消息,获得当前的全局消息,往gmsg中写入要发送的全局消息msg,以及限制条件func,close(gmsg.c)关闭chan,在所有的msgque中会接收到chan通知,达成发送全局消息的目的。
(图1.5 发送全局消息)
- Goroutine设计
主要介绍在系统中goroutine的设计,同步问题,错误处理,开机启动,停机处理和检查等。
2.1 go中的异常处理
(图2.1 异常处理)
函数try用于goroutine中使用,在fun()执行异常,defer中的recover()会捕获到panic。handle函数是用户自定义的异常处理函数,如果有handle会执行handle,没有handle会把当前panic的堆栈信息打印出来。程序从宕机点退出当前正在执行的函数后继续执行。