首页
下载
文档
问答社区
视频
捐赠
源代码
AI 助理
赞助商
CRMEB
Apipost
腾讯云
微擎
禅道
51Talk
商业产品
Swoole AI 智能文档翻译器
Swoole-Compiler PHP 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
swoole coroutine http server 协程池模式的可行性
研究了一下协程版本的http server,发现在`start`方法中,处理请求比较粗暴,跟`go`的原生的`net/http`实现很像,一个请求就开一个协程。 swoole实现: ```c static PHP_METHOD(swoole_http_server_coro, start) { //..... while (hs->running) { auto conn = sock->accept(); if (conn) { zval zsocket; php_swoole_init_socket_object(&zsocket, conn); long cid = PHPCoroutine::create(&fci_cache, 1, &zsocket); zval_dtor(&zsocket); if (cid < 0) { goto _wait_1s; } } else { /* * Too many connection, wait 1s */ if (sock->errCode == EMFILE || sock->errCode == ENFILE) { _wait_1s: System::sleep(SW_ACCEPT_RETRY_TIME); } else if (sock->errCode == ETIMEDOUT || sock->errCode == SW_ERROR_SSL_BAD_CLIENT) { continue; } else if (sock->errCode == ECANCELED) { http_server_set_error(ZEND_THIS, sock); break; } else { http_server_set_error(ZEND_THIS, sock); php_swoole_fatal_error(E_WARNING, "accept failed, Error: %s[%d]", sock->errMsg, sock->errCode); break; } } } //..... } ``` go实现: ```go for { rw, err := l.Accept() if err != nil { select { case <-srv.getDoneChan(): return ErrServerClosed default: } if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue } return err } connCtx := ctx if cc := srv.ConnContext; cc != nil { connCtx = cc(connCtx, rw) if connCtx == nil { panic("ConnContext returned nil") } } tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // before Serve can return go c.serve(connCtx) } ``` 所以go方面有了一个新idea,`valyala/fasthttp`。那swoole在实现协程版本的http server时,是不是也可以借鉴一下,预先初始化一个worker pool,分配好相关资源,处理请求时,直接从协程池获取空闲worker进行处理,省去了分配资源的过程。
发布于3年前 · 33 次浏览 · 来自
讨论
church1117
研究了一下协程版本的http server,发现在`start`方法中,处理请求比较粗暴,跟`go`的原生的`net/http`实现很像,一个请求就开一个协程。 swoole实现: ```c static PHP_METHOD(swoole_http_server_coro, start) { //..... while (hs->running) { auto conn = sock->accept(); if (conn) { zval zsocket; php_swoole_init_socket_object(&zsocket, conn); long cid = PHPCoroutine::create(&fci_cache, 1, &zsocket); zval_dtor(&zsocket); if (cid < 0) { goto _wait_1s; } } else { /* * Too many connection, wait 1s */ if (sock->errCode == EMFILE || sock->errCode == ENFILE) { _wait_1s: System::sleep(SW_ACCEPT_RETRY_TIME); } else if (sock->errCode == ETIMEDOUT || sock->errCode == SW_ERROR_SSL_BAD_CLIENT) { continue; } else if (sock->errCode == ECANCELED) { http_server_set_error(ZEND_THIS, sock); break; } else { http_server_set_error(ZEND_THIS, sock); php_swoole_fatal_error(E_WARNING, "accept failed, Error: %s[%d]", sock->errMsg, sock->errCode); break; } } } //..... } ``` go实现: ```go for { rw, err := l.Accept() if err != nil { select { case <-srv.getDoneChan(): return ErrServerClosed default: } if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue } return err } connCtx := ctx if cc := srv.ConnContext; cc != nil { connCtx = cc(connCtx, rw) if connCtx == nil { panic("ConnContext returned nil") } } tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // before Serve can return go c.serve(connCtx) } ``` 所以go方面有了一个新idea,`valyala/fasthttp`。那swoole在实现协程版本的http server时,是不是也可以借鉴一下,预先初始化一个worker pool,分配好相关资源,处理请求时,直接从协程池获取空闲worker进行处理,省去了分配资源的过程。
赞
0
分享
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
评论
还没有评论!
微信公众号
热门内容
暂无回复的问答
- CodeGalaxy K3s 轻量集群节点之间如何实现负载均衡
- 关于openssl CURL WARNING swSSL_connect: SSL_connect(fd=69) failed. Error: error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small[1|394]
- 多个模型如何进行事务异常回退?
- websocket开启wss报错
- 协程tcp服务器如何使用多进程?recv()方法接收信息,打印出来的pid一直是同一个。没用使用到多进程啊。