ST源码分析-proxy

SRS 的社群来了,想加入微信社群的朋友请购买《SRS原理》电子书,里有更高级的内容与答疑服务。


本文主要讲解,ST 提供的示例程序 proxy ,make 编译之后,会在 obj 目录生成 proxy 可执行文件,如下:

proxy 是一个流量代理程序,可以把TCP流量转发给远程服务器,使用命令如下:

用 -X 是只开启一个进程,简单起见,先讲解单进程的逻辑。

./obj/proxy -X -l 192.168.0.122:8999 -r 124.223.94.246:80

上面的命令,会把所有访问 192.168.0.122 机器的 8999 端口的TCP流量,全部转发给 124.223.94.246:80

接下来,用 Clion 搭建好 proxy 的可视化调试环境,跟之前的 lookupdns 一样,可以看之前的文章《ST源码分析-Clion调试


proxy 程序的单进程逻辑 比较简单,流程图如下:

从上图可以看到,除了 idle 协程,其他所有协程做的事情都是对于 在 系统线程 看来都是非阻塞,非阻塞协程干的话,就是把 需要监听的 fd 放进去全局变量 fd_set,然后由 idle 协程 执行 select() 函数阻塞,等待信号。ST的调度策略是 _ST_RUNQ 里面已经没有协程要运行了,才会切换到 idle 协程来阻塞。

proxy 程序的单进程逻辑 看上面的流程图,跟自己看代码就能理解,比较简单。


下面开始讲解 proxy 的多进程模式。只需要 把 -X 命令行参数去掉,就会执行 set_concurrency() 函数,如下图:

去掉 -X 参数之后, proxy 就会调用 start_daemon() 函数 进入守护进程模式,clion 就不好调试了,只能用 gdb 。

相比于单进程模式,多进程 只是多掉了两个函数 。

1,start_daemon(),进入守护进程模式

2, set_concurrency() ,开启多进程处理请求。

所以 重点分析一下 set_concurrency() 函数就足够了,代码如下图:

上图代码很简单,没有 watchdog 机制,只是 fork() 了好几个进程。下面就来讲解 fork 这么多进程之后,对后续的逻辑有什么影响。

fork 之后,后续的进程 会把变量srv_nfd 都拷贝一份,但是 fd 本身是一个 int,只是一个底层描述符列表的索引,可以理解为指针,即使是多进程,系统 fd 底层还是用的同一个。也就是说 多个进程 的 idle 协程 同时 select 监听这个 srv_nfd

我们看一下这种情况,如果一个客户端来了,是不是所有 进程的 select() 都会激活。在 select() 函数后面 加入 调试代码,如下:

/* Open and write */
    char file_name[80] = "/home/ubuntu/Documents/st-1.9/obj/pid_";
    char pid_name[20] = {0};
    sprintf(pid_name,"%d",(int)getpid());
    strcat(file_name,pid_name);
    int log_fd = open(file_name, O_CREAT | O_WRONLY | O_TRUNC, 0644);
    write(log_fd, file_name, strlen(file_name));
    close(log_fd);

如果触发惊群,一个客户端来了,有多少个进程就会创建多少个 pid_xxx文件。我是 16 核,所以是16进程。

如上图所示,只有两个文件,一个是本地客户端的,一个是远程触发的。所以多进程 select() 同一个套接字不会触发惊群。

epoll_wait() 的惊群讨论,推荐阅读以下文章:

1, 《关于linux中select和epoll是否存在惊群效应的争执》

2,《Epoll 新增 EPOLLEXCLUSIVE 选项解决了新建连接的’惊群‘问题》

proxy 多进程分析完毕。


相关阅读:

  1. 《关于linux中select和epoll是否存在惊群效应的争执》

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loken2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值