您的位置 首页 golang

基于golang的高性能API网关goku底层开发框架的设计与实现1

微服务 、服务网格大行其道的今天,API网关由于其在API服务治理与安全维护方面的功能,使得它在企业数字化的过程中,扮演的角色越来越重要。goku作为国内首个开源Go语言API网关,由于其出色的性能,越来越值得我们关注。此外由于项目还处于快速发展阶段,文档、设计说明、社区还没有跟上脚步,所以作为学习者、使用者来讲的,还是有些不方便。本系列,作者从学习者的角度,帮大家尝尝鲜、趟趟路。

goku代码的仓库

从goku的go.mod文件看到,它引用了另一个项目 github .com/eolinker/eosc v0.3.6。然后细致阅读发现,这个eosc目标是定位成高性能中间件底层开发框架。goku里面的很多功能,例如基于raft协议来实现集群高可用、通信控制模块、 进程管理 等。所以这篇文章,给大家详细介绍下它的设计思想与实现。

首先,我们先来看下代码中基于raft协议的状态存储。为了演示多节点,我在本地起了2个进程。

实验总体流程

  1. 在端口9400启动程序1
  2. 在端口9500启动程序2,然后将2加入到到1中。

操作详解

1.首先设置一系列的相关 环境变量 。为了演示方便,我们直接在env/config.go文件代码init方法里面hard code了。然后通过下面所示通过 pycharm 启动。

 func init() {
SetEnv("DATA_DIR","/tmp/eosc/s/data_dir")
SetEnv("PID_FILE","/tmp/eosc/s/pid_file")
SetEnv("LOG_DIR","/tmp/eosc/s/log_dir")
SetEnv(" socket _DIR","/tmp/eosc/s/socket_dir")
SetEnv(" extends _DIR","/tmp/eosc/s/extends_dir")  

pycharm调用命令行start启动

2.为模拟分布式环境,我们在本机上9500端口启动了另外一个eoserver。所做的2处修改如下:

启动监听端口修改

发送join请求的广播端口相应修改

3.查看当前2个进程的状态,下面2个 可执行文件 所在地址,可以通过pycharm的终端执行记录看到

cd / private /var/folders/bp/c77klkgj01b8m_2j87rpsgyc0000gq/T/

./___11go_build_main_go info

监听9400端口服务状态

./___8go_build_github_com_eolinker_eosc_app_eoserver info

监听9500端口服务状态

通过上面的结果看到,2个进程服务的状态都是 stand ,而且是single,暂时没有开启选举算法,分出个leader、follower。

3. 9500端口的进程加入9400端口的进程,组成高可用集群。为了演示,所以没有至少开启3个进程。其中 ___8go_build_github_com_eolinker_eosc_app_eoserver 是监听9500的进程

./___8go_build_github_com_eolinker_eosc_app_eoserver join –ip= 127.0.0.1 –addr=127.0.0.1:9400

4.再次查看2个进程的状态

./___8go_build_github_com_eolinker_eosc_app_eoserver info

[ raft ]

ID: 2

Address:

Key: f650498f-2885-fda1-682a-956c9d81783a

Status: cluster

State: StateFollower

Term: 3

Leader: 1

./___11go_build_main_go info

[Raft]

ID: 1

Address:

Key: a5fbac03-565e-4d57-36b2-833253b76ee4

Status: cluster

State: StateLeader

Term: 3

Leader: 1

这个地方的底层实现使用的就是etcd里面的raft选举,具体的实现与学习资料可以看官网的介绍

#section-documentation

然后oschina上面有个哥们写的博客也不错

另外 知乎 上有个, 动画讲解-raft协议选举机制 ,了解概念可以看

上面的链接提供给大家做个参考。总之goku里面就是用它来实现高可用,同时保持状态的一致性。

进程管理

eosc的进程管理思路,很值得学习。尤其是他基于golang实现的守护进程管理,很有意思。给大家简单演示下。

  1. 通过golang运行时的机制,在main.go的init方法里面建立稍后启动的子进程与处理逻辑方法的关联

注册子进程方法

2.由于我们启动的命令的输入参数是start,程序借用github.com/urfave/cli/v2 库,来解析命令,调用对应的StartFunc方法

启动命令

解析start命令

3.StartFunc函数里面会调用StartMaster方法启动一个子进程,注意重点来了。这个方法的第一句:cmd, err := process.Cmd(eosc.ProcessMaster, args)。里面启动的子进程还是主进程程序,但是参数不再是start了,而是___go_build_github_com_eolinker_eosc_app_eoserver: master,这样导致再次运行的子进程不会被github.com/urfave/cli/v2库再次解析运行StartFunc了,因为它的参数不再是start了。那什么时候运行上面main.go里面注册的方法process_master.Process呢?接着向下看

设置子进程参数与命令路径

4.process模块的init方法会在引用的时候,自动调用。这个地方通过环境变量来控制runIdx的值,是的主进程的runIdx=0,子进程的runIdx>0,这个runIdx在后面会控制子进程的逻辑执行。

通过环境变量设置runIdx值

5.process模块的Run方法,通过runIdx控制是否进入执行。我们看到上面的逻辑,主进程的runIdx时0,子进程的肯定大于0.而main.go的第一句就是运行process.Run().通过这种方式实现了,子进程master的逻辑运行

 // run process
func Run()  bool  {
   if runIdx > 0 {
      ph,  exists  := processHandlers[os.Args[0]]
      if exists {
         //defer func() {
         // if v := recover(); v != nil {
         //    log.Error("Run recover: ", os.Args[0], " ", v)
         // }
         //}()
         ph()
         return true
      }
   }

   return false
}  

main.go主逻辑

今天给大家简单介绍了eosc的选举和进程管理。之后接着给大家深入介绍goku的思想与实现

文章来源:智云一二三科技

文章标题:基于golang的高性能API网关goku底层开发框架的设计与实现1

文章地址:https://www.zhihuclub.com/86698.shtml

关于作者: 智云科技

热门文章

网站地图