文章是我在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版本升级步骤详解** 在Web服务器领域,Nginx以其高性能、低内存消耗以及高并发处理能力而备受青睐。随着新版本的发布,可能会包含性能优化、安全修复和新特性,因此定期更新Nginx版本是必要的。本文将详细...
arm 架构 docker运行nginx镜像包,arm 架构 docker运行nginx镜像包,arm 架构 docker运行nginx镜像包,arm 架构 docker运行nginx镜像包,arm 架构 docker运行nginx镜像包,arm 架构 docker运行nginx镜像包,arm 架构...
现在,我们可以下载Nginx的源代码包`nginx-1.20.1.tar.gz`。你可以通过wget或者浏览器将文件下载到本地,然后解压: ```bash wget http://nginx.org/download/nginx-1.20.1.tar.gz tar -zxvf nginx-1.20.1.tar.gz cd...
实战nginx.pdf。主要内容包括:第1章 Nginx简介;第2章Nginx服务器安装与配置;第3章Nginx基本配置与优化;第4章Nginx与PHP;第5章Nginx与JSP、ASP.NET..第6章Nginx http负载均衡和反向代理;第7章Nginx 的rewrite...
这个名为"nginx-linux-arm64.zip"的压缩包提供的是专为ARM64架构(也称为AArch64)编译的Nginx版本,适用于基于Linux操作系统的64位ARM处理器设备,如树莓派、某些云服务器或嵌入式系统。无需繁琐的编译过程,只需...
Nginx 1.24.0 是 Nginx 开源项目发布的一个重要更新版本,该版本在性能优化、功能增强以及安全性提升方面带来了诸多改进。当您下载 Nginx 1.24.0 的压缩包时,您将获得一个包含 Nginx 源代码的压缩文件,通常命名为 ...
**Nginx 1.13.3 版本详解** Nginx 是一款高性能的 HTTP 和反向代理服务器,广泛应用于网站托管、负载均衡以及应用程序交付等领域。它以其高效、稳定和轻量级的特性著称,尤其在处理静态内容和高并发请求时表现优秀...
**Nginx与Nginx-RTMP及Nginx-HTTP-FLV模块** Nginx是一款高性能、轻量级的Web服务器/反向代理服务器,被广泛应用于高并发场景,尤其在处理静态文件、HTTP缓存以及反向代理等方面表现出色。Nginx以其高效的事件驱动...
在 Linux 系统上升级 Nginx 版本 Nginx 是一个流行的开源 Web 服务器软件,可以运行在多种操作系统上,其中包括 Linux。随着 Nginx 的不断更新和发展,升级 Nginx 版本成为一个不可避免的问题。本文将指导您在 ...
### Nginx 作为 Apache 和 JBoss 的替代方案 #### 背景介绍 随着互联网技术的不断发展,网站流量的增长对服务器性能提出了更高要求。Apache 和 JBoss 是两种广泛使用的 Web 服务器和应用服务器,但在高并发场景下,...
在Linux系统中,离线安装Nginx是一个常见的需求,特别是在没有互联网连接或者网络环境受限的服务器上。本文将详细讲解如何通过离线方式在Linux上安装Nginx,同时也会涉及Nginx依赖的软件如openssl和gcc的安装过程。 ...
**Nginx 本地文件映射详解** 在IT行业中,Nginx是一个广泛使用的高性能Web服务器和反向代理服务器,以其高效、稳定和轻量级的特性受到青睐。其中一个实用的功能是通过配置来映射本地文件,使得用户可以通过HTTP协议...
Nginx课件完整版.pdf Nginx是一款功能强大的网络服务器软件,能够提供高性能的Web服务器、反向代理、负载均衡等功能。本资源摘要信息将对Nginx的主要知识点进行详细的介绍。 什么是Nginx? Nginx是一个基于C语言...
Nginx 1.8.0 安装简述 Nginx 是一种流行的开源 Web 服务器软件,广泛应用于生产环境中。为了帮助读者快速掌握 Nginx 的安装过程,本文将详细介绍 Nginx 1.8.0 的安装步骤。 一、下载依赖项 在安装 Nginx 之前,...
在IT领域,尤其是在服务器配置和优化的过程中,ARM架构和Nginx扮演着至关重要的角色。ARM(Advanced RISC Machines)架构是一种广泛应用于嵌入式设备、移动设备以及高性能计算的处理器架构,以其低功耗和高效能而...
**Nginx 入门到实践:深入了解 Nginx 中间件** Nginx 是一款高性能的 HTTP 和反向代理服务器,广泛应用于互联网行业的网站部署和负载均衡。它以其轻量级、高并发处理能力而闻名,同时也常作为中间件在分布式系统中...
在Ubuntu 18.04系统中安装Nginx服务器是一项常见的任务,特别是在无互联网连接的环境下,离线安装显得尤为重要。本资源提供了一个适用于这种场景的解决方案,它包括了Ubuntu 18.04环境下Nginx的离线安装包。这个离线...
"GitLab系统中Nginx版本升级和配置" 在实际生产环境中,GitLab系统的Nginx版本升级和配置是一个非常重要的任务。为确保系统的稳定性和安全性,需要对GitLab系统中的Nginx版本进行升级和配置。本文将详细介绍如何...
《Nginx学习丛书:Nginx应用与提高》是一套深入探讨Nginx服务器的教程,涵盖了Nginx在各种场景下的应用和优化。这套资料的目的是帮助读者全面理解和掌握Nginx的强大功能,提升其在实际工作中的效能。 1. **第3章 ...
内网安装Nginx(离线)是一种常见的情况,特别是在企业环境中,由于安全政策或网络隔离,服务器可能无法直接访问互联网。Nginx是一个高性能的HTTP和反向代理服务器,常用于网站服务、负载均衡以及内容缓存。本文将...