`
javasogo
  • 浏览: 1775677 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

[原创] 超越nginx

阅读更多
文章是我在baidu的博客上写的,这里专业人士比较多,以后就在这里首发了,这个题目有些大(总要吸引一下游客么) ,全面超越Nginx是很困难的一件事情,毕竟运营了那么长时间,稳定性+性能+扩展性才是综合指标,现在说的超越指的是在内存控制和性能两个简单的方面,就算仅仅是代码书写上,Nginx也是我见过的最规范的c代码,超越无从谈起。下面和正文:
当初打算扩展修改nginx,因为代码的阅读困难也就放弃了,很多事情都是作起来比想象的容易,自己写代码之初并没有指望程序能有所突破,在局部超越 nginx,等走到这一步回过头来看看。有种“山穷水尽疑无路,柳暗花明又一村”的感觉,说实话,nginx的代码写得够好了,至少对于c的代码我很少见 过比他更优雅的,毕竟也是一个人写的代码,能跟apache有得一拼甚至超越(代码规范清晰方面),这很不容易了,但即使是这样的代码,没有作者的中文文 档我们阅读代码也是很难懂的,我就是被吓了回来,在linux下基本的调试环境都建立不起来,归根结底还是不理解他的模型,nginx的代码有别于一般的 c工程代码,他很多文件是在编译时选择的(类似于apache),模块是根据配置文件生成一个c文件然后编译的,所以象我这样的新手就很难理解和调试,没 办法建立起来调试环境还何谈理解其架构?
幸好,这是个互联网的时代,牛人有的是,尽管很少,网上还是得到了很多的帮助。
其中一个就是smartc项目(向作者表示感谢),是一个国内人写的静态服务器和反响代理软件,作者声称自己大量阅读了nginx和lighttpd等代 码,借鉴了其中优秀的部分,但缺点跟nginx一样,代码注释都太少,还好,国人的代码量比较少,很容易很出架构的思路,后来一对比,果然跟nginx的 思路很象,于是大量参阅了它。
对于复杂一些的c工程文件,一定要有个合理的架构,不然代码逻辑分支多了之后维护就是分麻烦,对于socket网络程序尤其如此,本身还有一些网络超时、 异常中断等不确定因素,如果都是流水式的调用很难对分配的内存有个合理的控制,用函数指针实现类似于面相对想语言中的委托的方法就是不错的方法 (nginx等都是基于此的),我最开始的时候也是流水式的程序控制,发现程序需要一个数据容器全局表,维护相当麻烦,既然是全局表,在网络变成中往往与 fd挂钩,初始化容器的数量是很大的,而利用率确很低,如果每次增加新的模块就要改动全局表不是一个好主意,你会发现系统开发到一定阶段的时候全局表非常 大而且复杂,很多模块的临时数据都要有个容器,不然对于timeout的异常就很容易造成内存泄露,你无法精确控制问题发生在哪个地方。
基于函数指针的方法实现handle委托就不一样了,我设置的几个全局表是这样的:
typedef struct _FdTable {
int begintime;//开始连接的时间,或者再次重新初始化厚的时间
struct {
void *readData;
void *writeData;
void *errorData;
void (*readHandler)(int fd, void *data);
void (*writeHandler)(int fd, void *data);
void (*errorHandler)(int fd, void *data);
}ops;
}FdTable;
一个时间搓、一组操作数据的指针,对于网络上所有的事件都简化抽象成in和out两个事件,然后还有一个errorHandler,这样循环部分就可以不 断地循环事件,然后抽象地处理,具体函数的指针会在不同的函数进行控制,比如对于web服务器是这样一个流程:
connected触发socketConnecedHandler(int fd, void *data);,事件到达就将该函数赋值给FdTable的void (*readHandler)(int fd, void *data),然后监视In事件,SocketIn实践就可以触发SocketReadhandler(int fd, void *data),在此函数内部就可以调用ParseHttpHeader(int fd, void *data),如果没有完成一次性的读取,可以循环上一个过程,ParseHttpHeader结束后就可以进入逻辑判断过程:比如对于GET,交给 GetHttpHandler(int fd, void *data),posti交给PostHttpHandler(int fd, void *data),反向代理交给ProxySendHandler(int fd, void *data)......等等,然后所有的过程都是不断的循环执行事件引发的handle指针函数,每个过程将相应的错误错里函数赋值给全局容,这样就可 以委托式地进行处理,而不用关心程序执行到哪一个阶段,哪一个逻辑,具体功能由逻辑代码实现,这样的流程就可以让开发者腾出更多的时间用于实现具体功能, 某一个单独的模出现问题也不会影响到其他的业务流程,需要的逻辑数据就放在下一个逻辑的data里面,不需要的执行完毕或则错误就执行相应的 handlError函数,这就是架构的魅力!

通过一系列的改进,我的webserver总于可以压载100万次无故障,执行效率高于nginx20%(静态文件)左右,下面是基本的ab测试:
我的server:
Requests per second: 8358.26 [#/sec] (mean)
Time per request: 11.964 [ms] (mean)
Time per request: 0.120 [ms] (mean, across all concurrent requests)
Transfer rate: 1902.01 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 4 1.8 4 21
Processing: 1 6 3.0 6 38
Waiting: 0 4 1.9 3 20
Total: 4 10 3.9 10 55

Percentage of the requests served within a certain time (ms)
50% 10
66% 10
75% 10
80% 11
90% 14
95% 17
98% 21
99% 32
100% 55 (longest request)
nginx:
Requests per second: 6048.14 [#/sec] (mean)
Time per request: 15.508 [ms] (mean)
Time per request: 0.155 [ms] (mean, across all concurrent requests)
Transfer rate: 1902.01 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.6 0 13
Processing: 3 14 1.8 15 33
Waiting: 2 14 1.7 15 33
Total: 8 15 1.3 15 35

Percentage of the requests served within a certain time (ms)
50% 15
66% 15
75% 15
80% 15
90% 15
95% 16
98% 18
99% 21
100% 35 (longest request)
以上测试我的服务器没有开启任何缓存,都是通过sendfile读取文件发送,100用户模拟10万次访问

现在总于可以放心的在此基础上去完善功能了,以前总是些一段代码就发现段错误问题,并且在多线程状态下根本追踪不到错误源。
理解了架构具体代码倒是很简单的事情,不敢说我的服务器比nginx有优势(毕竟需要实践检验),但相信可以满足我的要求:世上的解决方案无数种,但我只要最适合我的哪一种。
没有打算将这个服务器做成通用的web服务器,因为很多功能我们根本不需要,只是想在一个稳定的高效的静态文件基础之上构建一套服务,这套服务要具备接近于静态文件的处理速度,稳定高效,才会有上层建筑。
分享到:
评论

相关推荐

    nginx 离线安装包nginx 离线安装包

    nginx 离线安装包nginx 离线安装包

    nginx镜像资源nginx镜像资源nginx镜像资源nginx镜像资源nginx镜像资源nginx镜像资源

    nginx镜像资源nginx镜像资源nginx镜像资源nginx镜像资源nginx镜像资源nginx镜像资源

    Nginx安装包Nginx安装包

    Nginx安装包Nginx安装包

    一分钟搞定 Nginx反向代理 nginx域名代理

    3.找到D:\nginx\conf下nginx.conf文件用记事本打开 在文段末尾大括号前加上 include proxy.conf;(就是加载刚刚新建的那个文件(注意路径)) 4.进入cmd 进入D盘: d: 进到nginx文件夹下:cd nginx 启动nginx.exe:...

    nginx替代方案,nginx代替apache与jboss

    nginx替代apache,nginx替代方案,nginx代替apache与jbos,nginx+jboss结合

    centos8 nginx1.20.1 与nginx配置文件

    nginx.conf nginx-1.20.1.tar.gz 这是关于centos8的nginx 和nginx 的配置https文件

    nginx-1.13.3,nginx1.13.3不存在信息泄漏漏洞安全稳定nginx版本

    亲测好用.nginx-1.13.3,nginx1.13.3不存在信息泄漏漏洞安全稳定nginx版本,不存在漏洞 nginx-1.13.3 nginx1.13.3 安全稳定 nginx版本

    Nginx 1.22.0 Linux 版本,解压安装。

    Nginx 1.22.0 Linux 版本,解压安装。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型...

    nginx安装环境及nginx_1.18.0安装包

    nginx安装环境及nginx_1.18.0安装包,gcc、g++、pcre、zlib、nginx包

    nginx实战-nginx

    第1章 Nginx简介.pdf第2章 Nginx服务器的安装与配置.pdf第3章 Nginx的基本配置与优化.pdf第4章 Nginx与PHP(FastCGI)的安装、配置与优化.pdf第5章 Nginx与JSP、ASP.NET、Perl的安装与配置.pdf第6章 Nginx HTTP负载...

    Nginx入门到实践 Nginx 中间件

    Nginx入门到实践 Nginx 中间件Nginx入门到实践 Nginx 中间件

    nginx-1.23.1.zip

    nginx/Windows-1.23.1 Nginx(发音为“engine X”[9] /ˌɛndʒɪnˈɛks/ EN-jin-EKS),风格化为NGIИX,是一个Web服务器,也可以用作反向代理,负载平衡器,邮件代理和HTTP缓存。该软件由Igor Sysoev创建,并于...

    Nginx 全能HTTP+Web 指南 完整版pdf

    Nginx全能指南是一本介绍Nginx服务器的书,首先,简要介绍Nginx的基本概念和作用,如反向代理、负载均衡等。然后,列举Nginx的优点,如高性能、可扩展性、稳定性等。接着,介绍如何安装和配置Nginx,并提供一些实用...

    nginx命令参数用法详细介绍

    nginx命令参数用法详细介绍 nginx命令:启动nginx  在Windows上安装好nginx后,我们需要启动nginx服务,启动nginx服务的命令行操作主要有两种方式,即 C:/nginx-0.8.53>nginx.exe  或者 C:/nginx-0.8.53>start ...

    实战nginx.pdf

    实战nginx.pdf。主要内容包括:第1章 Nginx简介;第2章Nginx服务器安装与配置;第3章Nginx基本配置与优化;第4章Nginx与PHP;第5章Nginx与JSP、ASP.NET..第6章Nginx http负载均衡和反向代理;第7章Nginx 的rewrite...

    nginx1.21.5 nginx.conf配置文件

    nginx1.21.5 nginx.conf配置文件

    nginx-upstream-jvm-route 和 nginx 对应版本,亲测可用

    此资源有两个文件,含 nginx-upstream-jvm-route 和 nginx 对应版本,都是tar.gz文件。 安装方法网上很多就不写了,亲测可用。 不用担心版本不匹配造成安装失败,再浪费积分去到处下载尝试的烦恼。 此资源有两个文件...

    Nginx全套学习指南

    第1章 Nginx简介 第2章 Nginx服务器的安装与配置 第3章 Nginx的基本配置与优化 第4章 Nginx与PHP(FastCGI)的安装、配置与优化 第5章 Nginx与JSP、ASP.NET、Perl的安装与配置 第6章 Nginx HTTP负载均衡和反向代理的...

    Nginx服务器的安装与配置.pdf

    Nginx官网配置.pdf Nginx基本配置.pdf Nginx模块.pdf Nginx指南.pdf 第1章 Nginx简介.pdf 第2章 Nginx服务器的安装与配置.pdf 第3章 Nginx的基本配置与优化.pdf 第4章 Nginx与PHP(FastCGI)的安装、配置与优化.pdf 第...

Global site tag (gtag.js) - Google Analytics