免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: linux_c_py_php
打印 上一主题 下一主题

[C++] [如何用状态机思想降低Server端开发复杂度? (GIT分支提供http server的实现框架示例) [复制链接]

论坛徽章:
5
技术图书徽章
日期:2013-08-17 07:26:49双子座
日期:2013-09-15 16:46:29双子座
日期:2013-09-25 08:17:09技术图书徽章
日期:2013-09-25 09:11:42天秤座
日期:2013-10-01 16:25:34
11 [报告]
发表于 2012-10-20 23:21 |只看该作者
linux_c_py_php 发表于 2012-10-20 23:18
说的简单, 但能正确的设计估计你是做不到了.

如果我不提状态机, 也许你永远也不懂, 所以你也永远到不了这 ...


正确设计服务器端代码吗? 确实做不到...

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
12 [报告]
发表于 2012-10-20 23:23 |只看该作者
本帖最后由 linux_c_py_php 于 2012-10-20 23:25 编辑

现实就是这样的, 我认为我分享的东西很多人是没有掌握的, 我觉得真的能把我说的理解了掌握了, 肯定比你看N多开源代码都管用.

但是, 我不知道让一个对这方面还不太熟练的同学彻头彻尾的理解我的意思是否有点牵强, 因为毕竟我也是坎坷一路才有了这些思考与积累, 我个人觉得是挺不容易的, 虽然东西看起来不多, 但一个清晰的思维与实现方式绝对是练出来的内功.

__BlueGuy__ 发表于 2012-10-20 23:21
正确设计服务器端代码吗? 确实做不到...

论坛徽章:
5
技术图书徽章
日期:2013-08-17 07:26:49双子座
日期:2013-09-15 16:46:29双子座
日期:2013-09-25 08:17:09技术图书徽章
日期:2013-09-25 09:11:42天秤座
日期:2013-10-01 16:25:34
13 [报告]
发表于 2012-10-20 23:27 |只看该作者
本帖最后由 __BlueGuy__ 于 2012-10-20 23:29 编辑

我服务器一点不会, 多写点注释啊...
而且我在windows下也没法跑,没法调试...

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
14 [报告]
发表于 2012-10-20 23:33 |只看该作者
本帖最后由 linux_c_py_php 于 2012-10-20 23:39 编辑

再分享点个人经历吧, 在做XMPP集群的时候, 需要做很多机器人来为其他客户端提供服务, 这些机器人我们开发有自己的机器人开发框架, 但还是I/O方面是基于Jabberd的mio框架.

这个机器人框架不是我开发的, 我工作的任务是为机器人框架开发module, 也就是上面说的plugin, 对于每一个请求, 我的plugin都会被回调, 比如我做了一个proxy module, 对于每一个请求, 我的module会将请求转发到线下一份, 而这个转发过程不是说阻塞在i/o loop里的, 而是在程序启动时该module就创建了一个线程池, 每次回调proxy module, 我只是把请求丢到线程池里就立即返回OK了, 线程池里慢慢去转发多慢都无所谓.

但这个机器人框架和我提到的框架的一个重大区别就是是否允许客户端等待请求, 这个机器人框架是不支持的, 也就是要求所有的plugin回调立即返回, 如果它阻塞在那里, 那么整个event loop就阻塞了. 而我这里贴的, 就是允许插件不立即返回的, 我允许插件异步的去处理, 同时我还允许插件在处理完毕后将结果返回到event loop里, 参与client的应答, 而这个等待的过程是不阻塞event loop实现的(聪明的读者会发现, 其实这个框架的event loop就是轮询的去问一个插件是否完成了, 插件自身处理完成后也是通过事件机制异步完成应答传递的, 整个过程是异步无锁状态推动的.).


再有一点, 我说的估计很多人都会认同, 并且觉得这个开发框架或者说模式是很给力的, 因为:

几乎绝大多数程序员做Server开发都普遍的只会两种做法:

1, 有阻塞操作就一个线程一个client, 阻塞的去处理, 靠线程数撑连接.
2, 没有阻塞操作的就epoll, 解析出来一个请求立马处理完就发送应答.

我提到的开发模式或者思路就是将1,2融合起来, 可以称作万能的异步框架. (现在我已经开始转移分布式的学习了, 能够更好的将分布式算法和Server开发能力结合.)

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
15 [报告]
发表于 2012-10-20 23:43 |只看该作者
其实你做的所有努力,都是在模拟一个非抢占式多线程,即coroutine(或者可以说是continuation)。

在有coroutine概念的语言中(比如Lua和Python),Web框架可以大量用到coroutine的方式,去在阻塞操作的时候,偷偷设置状态然后return掉,下次事件到来的时候,会被在当前位置唤醒,总的来说就是单线程的。但是写出来的代码看上去就和多线程一样。只要大家都默契地在阻塞操作中异步,然后yield,那么就不会造成event loop的block。

但是,如果有MySQL的情况怎么办?这时就需要真的多线程了,因为MySQL必定阻塞,为了能多任务下去,就必须抢占掉阻塞的那个任务,而coroutine做不到抢占。我们可以在coroutine的框架上加上多个线程(真正的多线程)的通知机制,控制线程本身依然是单线程的,而其他线程去处理那些不得不去抢占的工作,这就是LZ代码的意义所在。

OwnWaterloo好像说过一句话:“没有了coroutine,我连代码都不知道怎么写的”,说的就是这种情况。像楼主那样,手动状态机+轮转来模拟coroutine的,又有几个呢?

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
16 [报告]
发表于 2012-10-20 23:50 |只看该作者
恩, 你说的是正确的, 从代码工作方式上来看, 就是状态的修改, 以及轮询的检测, 并将阻塞逻辑做到独立线程中, 最终整个过程达到一个异步.

你说有几个, 那我必须告诉你nginx, lighttpd这两款, 甚至将来更多的需要慢操作的服务器都有能力选择这种设计方法, 而且这也是它们那样做的.

我们不需要讨论有几个, 我只是让大家能够阅读理解掌握Server端的设计方法.

可以这么说, 就连apache现在都开始放弃多线程(1线程撑1个连接, 大量的线程切换消耗)转向该架构方式了, 并用数据证明自己比lighttpd/nginx实现的还要快, 我觉得这已经是事实证明毫无问题的, 不仅是效率, 成本, 连接数, I/O, 都毫无问题.

如果你想说现在服务器性能好, 多线程, 多进程一样做, 而且更简单, 那也是没问题的, 至少在同事圈里, 公司的公共库里, 大家还是老办法开发, 阻塞多线程, 不阻塞单线程loop.

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
17 [报告]
发表于 2012-10-20 23:57 |只看该作者
不知道兄台是做什么方面开发工作的.

如果是从事Server开发的话, 我当时一旦看到类似的设计问题可都是眼冒金光来不及的想学, 看你的回复虽然在点上, 但显得没什么热情, 可能你不能体会做这方面研究的乐趣吧, 或者说这种设计方式你也有经验了, 或者你是玩kernel的, 对我等应用层开发视如小菜一碟 -.-#

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
18 [报告]
发表于 2012-10-21 00:03 |只看该作者
还有, 不要忽悠我Python web, 我已经开发过好一阵了, 很明显是nginx + uwsgi, uwsgi作为一个plugin做异步回调处理, 创建连接到uwsgi server, 按照wsgi协议转发http请求给uwsgi server, uwsgi server跑python处理http请求, 走url dispatch匹配 + views+model 处理之后将应答从uwsgi server发回到nginx下的uwsgi plugin, 最终发回浏览器.



starwing83 发表于 2012-10-20 23:43
其实你做的所有努力,都是在模拟一个非抢占式多线程,即coroutine(或者可以说是continuation)。

在有c ...

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
19 [报告]
发表于 2012-10-21 00:05 |只看该作者
这种单线程server断select的方式,很久很久以前就很普及了。
只是写代码麻烦,很多“粗旷”的程序员,不喜欢费这份精力。

10多年前的boa
http://sourceforge.net/projects/boa/files/boa/

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
20 [报告]
发表于 2012-10-21 00:06 |只看该作者
在nginx/lighttpd下的任何服务于fcgi之类动态脚本的plugin都是如此框架 我就是研究源码学来的, 所以我觉得你说模拟什么多线程, 什么谁说XXX, 对我来说没有多大益处, 只能当白话.

linux_c_py_php 发表于 2012-10-21 00:03
还有, 不要忽悠我Python web, 我已经开发过好一阵了, 很明显是nginx + uwsgi, uwsgi作为一个plugin做异步回 ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP