免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3739 | 回复: 5
打印 上一主题 下一主题

coro在异步事件web框架(例如mojo)的使用 [复制链接]

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2018-03-07 11:37 |只看该作者 |倒序浏览
一直觉得,AE和coro是perl网络编程的的一大杀器。
不过怎么在异步事件的web框架中使用coro,一直也没解决。
期望的模型:
监听web请求
起coro异步处理
在coro内部,可以实现类似同步阻塞.关键是多次。
回头看,这其实是个很初级的的问题,不过还是困扰了很久。
现在都决定转到python去了(gevent轻松愉快),突然某天灵光一现给搞定了。
万一有人觉得有用呢。
以mojo为例。
  1. #!/usr/bin/env perl
  2. #验证mojo里面可以放协程(ok)
  3. use Mojolicious::Lite;
  4. use Coro;
  5. use AnyEvent;
  6. use Coro::AnyEvent;
  7. #use Mojo::Server::Prefork;
  8. #get '/' => sub {
  9. get '/' => unblock_sub {
  10. my $self = shift;
  11. Coro::AnyEvent::sleep 1;
  12. $self->render(text => $self->tx->remote_address);
  13. #$self->render(text => $msg);
  14. #$self->render(text => "hello mojo");
  15. };
  16. # app->config(hypnotoad => {listen => ['http://*:3080']});
  17. app->start;
复制代码


是不是很简单,就为了这么简单的一行替换,郁闷了n久啊。
这回好了,在顶层回调函数里面可以ping,http_get,snmp, 世界一下美好了,再也不用担心回调陷阱了,也不用mojo:elay

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
2 [报告]
发表于 2018-03-07 13:36 |只看该作者

安利一个高性能的perl web框架

本帖最后由 laputa73 于 2018-03-07 13:40 编辑

顺便安利一个高性能的perl http sever.
一般的印象里面,脚本语言的web框架就是低效的代名词。
引入一波事件驱动以后,这个性能普遍有了突飞猛进。
当初做web服务框架选型的时候,一个小兄弟选中了这个
AnyEvent::HTTP::Server;
https://github.com/Mons/AnyEvent-HTTP-Server-II
作者的benchemark可以参考。
Benchmarks
Benchmarking tool weighttp -c 100 -n 10000 http://localhost:8080/
Example app HTTP server on port 8080, which should reply with string "Good"
All files are located under benchmaks/

  • AnyEvent::HTTP::Server-II (1 worker)
    finished in 1 sec, 295 millisec and 127 microsec, 7721 req/s, 912 kbyte/s
  • AnyEvent::HTTP::Server-II ( 4 workers)
    finished in 0 sec, 552 millisec and 381 microsec, 18103 req/s, 2139 kbyte/s
  • AnyEvent::HTTP::Server (previous)
    finished in 3 sec, 421 millisec and 143 microsec, 2922 req/s, 278 kbyte/s
  • AnyEvent::HTTPD (v0.93t)
    finished in 18 sec, 622 millisec and 941 microsec, 536 req/s, 99 kbyte/s
  • Twiggy (v0.1021)
    finished in 1 sec, 630 millisec and 908 microsec, 6131 req/s, 272 kbyte/s
  • Starman (--workers 1) (v0.3006)
    finished in 2 sec, 469 millisec and 571 microsec, 4049 req/s, 511 kbyte/s
  • Starman (--workers 4) (best for my 4 core)
    finished in 1 sec, 102 millisec and 631 microsec, 9069 req/s, 1161 kbyte/s
  • Pyton Twisted (I'm not a python programmer, so code may be not efficient)
    finished in 4 sec, 122 millisec and 587 microsec, 2425 req/s, 355 kbyte/s
  • Node.js
    finished in 1 sec, 766 millisec and 696 microsec, 5660 req/s, 790 kbyte/s
  • Nginx
      location / { perl 'use nginx; sub { $_[0]->send_http_header(q{text/plain}); $_[0]->print(q{Good}); return OK; }'; }
    finished in 0 sec, 290 millisec and 380 microsec, 34437 req/s, 5515 kbyte/s
  • Raw TCP/HTTP server (perl+ev with no logic or parsing)
      For source look into benchmarks/ev-raw.pl
    finished in 0 sec, 306 millisec and 259 microsec, 32652 req/s, 2678 kbyte/s


   注意 ,这个只是个webserver,性能的主要瓶颈其实是在后面的业务代码。而且,这个server并不遵循psgi规范。
   同样,这个也可以和coro整合
  1. #!/bin/env perl
  2. #AEHTTP+coro+AE::ping(ok)
  3. use Coro;
  4. use Coro::EV;
  5. use AnyEvent;
  6. use Coro::AnyEvent;
  7. use AnyEvent::Ping;

  8. use AnyEvent::HTTP::Server;
  9. use EV;


  10. sub pingr($){
  11. my ($ip) = @_;
  12. return if not defined $ip;
  13. my $ping = AnyEvent::Ping->new;
  14. #push @coro, async {
  15. $ping->ping($ip, 1, Coro::rouse_cb );
  16. my @result = Coro::rouse_wait;
  17. print "Result($ip): ", $result[0][0][0]," in ", $result[0][0][1], " seconds\n";
  18. #}
  19. }

  20. my $ipn=0;
  21. my $s = AnyEvent::HTTP::Server->new(
  22. host => '127.0.0.1',
  23. port => 5000,
  24. cb => sub {
  25. my $req = shift;
  26. #$ipn++; //放在这里是不安全的。事件处理不是协程,不是顺序的。
  27. #return sub { //这样不行
  28. return unblock_sub { #这样可以
  29. my ($is_last, $bodypart) = @_;

  30. #Coro::AnyEvent::sleep 1;
  31. $ipn++; //放在这里是协程安全的
  32. pingr("192.168.6.".$ipn);
  33. $req->reply(200, "<h1>Reply message:$ipn</h1>", headers => { 'content-type' => 'text/html' });
  34. }
  35. }
  36. );
  37. $s->listen;
  38. $s->accept;
  39. EV::loop();

复制代码

  

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
3 [报告]
发表于 2018-03-07 13:36 |只看该作者
本帖最后由 laputa73 于 2018-03-07 13:39 编辑

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
4 [报告]
发表于 2018-03-07 13:38 |只看该作者
本帖最后由 laputa73 于 2018-03-07 17:27 编辑


  

论坛徽章:
0
5 [报告]
发表于 2018-03-09 19:45 |只看该作者
回复 1# laputa73

想请教一下,用Mojo:elay是否也是一样的效果?

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
6 [报告]
发表于 2018-03-12 09:49 |只看该作者
回复 5# maybenot

应该说,是类似的效果,初衷都是解决事件编程的回调问题
但是delay是不可以嵌套的,只是实现了回调语法的美化,把多个回调转成链式.
而coro的写法,则是彻底把回调变成了同步的写法.
简单场景差别不大.但是比如有逻辑分支的场景
ret=httget(url1)
if ret==A  httpget(url2)
else httpget(url3)
用delay写就困难了.

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP