文章插图
web服务器下载(web服务器是啥啊)
eJet Web服务器是利用GitHub上的开源项目 adif数据结构和算法库 和 ePump框架 , 用C语言开发的一个事件驱动模型、多线程、大并发连接的轻量级的高性能Web服务器 , 支持HTTP/1.0和HTTP/1.1协议 , 并支持HTTP Proxy、Tunnel等功能 。
在Linux下 , eJet Web服务器编译成动态库或静态库的大小约为300K , 可集成嵌入到任何应用程序中 , 增加应用程序使用HTTP通信和服务承载的能力 , 使其具备像Nginx服务器一样强大的Web功能 。
eJet Web服务器完全构建在ePump框架之上 , 利用ePump框架的多线程事件驱动模型 , 实现完整的HTTP请求<–>HTTP响应事务流程 。eJet并没有创建进程或线程 , 利用ePump框架的事件驱动多线程 , 高效地运用服务器的CPU处理能力 。
eJet接收和处理各TCP连接上的HTTP请求头和请求体 , 经过解析、校验、关联、实例化等处理 , 执行HTTP请求 , 或获取Web服务器特定目录下的文件 , 或代理客户端发起向源HTTP服务器的请求 , 或将HTTP请求通过FastCGI接口转发到CGI服务器 , 或将客户端HTTP请求交给上层设置的回调函数处理等 。所有处理结果 , 最终以HTTP响应方式 , 包括HTTP响应头和响应体 , 通过客户端建立的TCP连接 , 返回给客户端 。该TCP连接可以Pipe-line方式继续发送和接收多个HTTP请求和响应 。
eJet服务器提供了作为Web服务器所需的其他各项功能 , 包括基于TLS/SSL的安全和加密传输、虚拟主机、资源位置Location的各种匹配策略、对请求URI执行动态脚本指令(包括rewrite、reply、return、try_files等)、在配置文件中使用HTTP变量、正向代理和反向代理、HTTP Proxy、FastCGI、HTTP Proxy Cache功能、HTTP Tunnel、MultiPart文件上传、动态库回调或接口函数回调机制、HTTP日志功能、CDN分发等 。
eJet Web服务器采用JSon格式的配置文件 , 进行系统配置管理 。对JSon语法做了一定的扩展 , 使得JSon支持include文件指令 , 支持嵌入Script脚本程序语言 。使用扩展JSon功能的配置文件 , 可更加灵活、方便地扩展Web服务功能 。
eJet系统大量采用了Zero-Copy、内存池、缓存等技术 , 来提升Web服务器处理性能和效率 , 加快了请求响应的处理速度 , 支撑更大规模的并发处理能力 , 支持更大规模的网络吞吐容量等 。
eJet Web服务器既可以面向程序员、系统架构师提供应用程序开发接口或直接嵌入到现有系统中 , 也可以面向运维工程师部署完全类似Nginx Web服务器、Web Cache、CDN回源等商业服务系统 , 还是面向程序员提供学习、研究开发框架、通信系统等的理想平台 。
开发eJet Web服务器的原则是尽可能不依赖于第三方代码和库 , 降低版权和复杂部署等因素带来的潜在风险 。系统使用的第三方代码或库主要为:OpenSSL库、Linux系统自带的符合POSIX标准的正则表达式regex库 。gzip压缩需要依赖zlib开源库 , 目前没有添加进来 , 所以eJet Web服务器暂时不提供gzip、deflate的压缩支持 。
二. JSon格式的配置文件 2.1 JSON语法特点 JSON的全称是JavaScript Object Notation , 是一种轻量级的数据交换格式 。JSON的文本格式独立于编程语言 , 采用name:value对存储名称和数据 , 可以保存数字、字符串、逻辑值、数组、对象等数据类型 , 是理想的数据交换语法格式 , 简洁干练 , 易于扩展、阅读和编写 , 也便于程序解析和生成 。
正是由于JSon语法的简单和强扩展性、采用可保存各种数据类型的name/value对语法、可嵌套JSON子对象等特性 , 与配置文件的配置属性特别吻合 , 所以 , eJet系统使用JSon格式来保存、传递、解析系统配置文件 。
2.2 eJet配置文件对JSON的扩展 2.2.1 分隔符 eJet系统使用adif中的JSon库来解析、访问配置文件信息 。JSon语法缺省格式以冒号(:)来分隔name和value , 以单引号(')或双引号(")来包含name和value串 , 以逗号(,)作为name/value对的分隔符 , 以中括号[]表示数组 , 以大括号{}表示对象 。
eJet系统采用JSon作为配置文件语法规范 , 为了兼容传统配置文件的编写习惯 , 将JSon基础语法做了一些扩展 , 即分隔name与value的冒号(:)换成等于号(=) , 分隔name/value对之间的逗号(,)换成分号(;) , 其他基础语法不变 。
2.2.2 include指令 由于配置信息数据较大 , 需要使用不同的文件来保存不同的配置信息 , 借鉴C语言/PHP语言的include宏指令 , eJet系统的JSon语法引入了include指令 。扩展语法中将把"include"作为JSon语法的关键字 , 不会被当做对象名称和值内容来处理 , 而是作为嵌入另外一个文件到当前位置进行后续处理的特殊指令 。其语法规范如下:
include <配置文件名>; 解析JSon内容时 , 如果遇到include指令 , 就将include指令后面的文件内容加载到当前指令位置 , 作为当前文件内容的一部分 , 进行解析处理 。
2.2.3 单行注释和多行注释 为了增加配置文件中代码的可读性 , 需要对相关的定义添加详细说明、注解等内容 , 方便使用人员快速阅读和理解 。
为支持注释功能 , eJet系统的配置文件对JSON语法做了相应扩展 , 增加了单行注释符号#和多行注释(/* */) , 其语法规范如下:
# 这是单行注释 , 如果井号(#)不在JSon某个Key-Value对的引号里面 , 那么以井号开头 , 井号后面的内容都是注释/* 注意:多行注释是以连在一起的/和*开始 以连在一起的*和/结尾 , 中间的内容都是注释 多行注释开闭符号 , 必须不能在Key-Value对的引号里面 */ 注释的内容在解析时直接忽略跳过 , 不会被系统解析和处理 。
2.2.4 script语法 使用JSON格式的数据都是由name/value对构成 , eJet系统中需要在配置文件中支持Script脚本程序 , 灵活动态地处理HTTP请求 。
eJet配置文件对JSON语法格式扩展了一种固定名称的script对象 , 将名称"script"作为特殊对象的名称关键字 , 即以script为名称的对象 , 其内容不能作为JSON子对象处理 , 而是作为Script脚本程序内容 , 存放在对象名为script的对象中 。其语法规范如下:
script = { if ($request_uri ~* '^/topic/[0-9](*)/(.*)\.mp4$') { set $video_flag 1; }}; 在同一个JSon对象下 , 可以有多个script对象 , 自动构成script对象数组 。
另外 , 使用特殊的开闭标签<script>和</script> , 也可以定义脚本程序 。在这两个开闭标签中间的内容 , 即是Script脚本程序 , 并将这些内容存储到配置文件定义的任意name名称对象中 , 其语法规范如下:
cache file = <script> if ($request_uri ~* 'laoooke') return "${host_name}_${server_port}${req_path_only}${req_file_only}"; else if (!-f $root$request_path) { return "${host_name}_${server_port}${req_path_only}${index}"; } else if (!-x $root$request_path) { return "$root$request_path is not an executable file"; } else return "${request_header[host]}${req_path_only}else.html"; </script>; 这样 , "cache file"对象的内容就是一段脚本程序 , 需要在解释执行到这里时 , 才真正具有实际数据 。
三. eJet资源管理架构 3.1 三层资源定位架构 【web服务器下载 web服务器是啥啊】eJet Web服务器的资源管理结构分成三层:
- HTTP监听服务HTTPListen – 对应的是监听本地IP地址和端口后的TCP连接
- HTTP虚拟主机HTTPHost – 对应的是请求主机名称domain
- HTTP资源位置HTTPLoc – 对应的是主机下的各个资源目录
3.2 HTTP监听服务 – HTTPListen HTTP监听服务HTTPListen是指eJet Web服务器在启动时 , 需要绑定本地某个服务器IP地址和某个端口后 , 启动TCP监听服务 , 等候接收客户端发起TCP连接和HTTP请求数据 , 每个接受的HTTPCon连接一定属于某个HTTP监听服务HTTPListen 。严格来说 , HTTPListen负责接受HTTPCon连接 , 并将请求数据存储到HTTPCon的接收缓冲区 , 所以监听服务对应的是TC连接资源管理 , 即对应的是请求资源的domain和端口 。
HTTP监听服务的配置信息格式参考如下:
listen = { local ip = *; #192.168.1.151 port = 443; forward proxy = on; ssl = on; ssl certificate = cert.pem; ssl private key = cert.key; ssl ca certificate = cacert.pem; request process library = reqhandle.so script = { #reply 302 https://ke.test.ejetsrv.com:8443$request_uri; addResHeader X-Nat-IP $remote_addr; } host = {.....} host = {.....} host = {.....}} 一台物理服务器可以安装多个网卡 , 每个网卡配置一个独立IP地址 , HTTP监听服务可以监听某一个IP地址上的某个端口 , 也可以监听所有IP地址上的同一个端口 。能启动监听服务的端口数量理论上是65536个 , 其中小于1024的端口需要有root超户权限才能监听 。
HTTP监听服务HTTPListen依赖于底层ePump框架的eptcp_mlisten接口函数 , 通过该接口 , 让每一个epump监听线程都去监听指定IP地址和端口上的连接请求和数据请求服务 。对于支持REUSEPORT的操作系统内核 , 大量客户端发起的并发连接 , 将会通过内核accept系统调用均衡地分摊到各epump线程处理 , 对于不支持REUSEPORT的操作系统 , ePump框架负责大并发连接在各监听线程间的负载均衡 。
HTTP监听服务HTTPListen可以设置当前监听为需要SSL的安全连接 , 并配置SSL握手所需的私钥、证书等 。配置为SSL安全连接监听服务后 , 客户端发起的HTTP请求都必须是以https://开头的URL 。
在HTTP监听服务HTTPListen里 , 可以设置Script脚本程序 , 执行各种针对请求数据进行预判断和预处理的指令 。这些脚本程序的执行时机是在收到完整的HTTP请求头后进行的 。
eJet系统提供了动态库回调机制 , 使用动态库回调 , 既可以扩展eJet Web服务器能力 , 也可以将小型应用系统附着在eJet Web服务器上 , 处理客户端发起的HTTP请求 。
HTTP监听服务HTTPListen下可管理多个虚拟主机HTTPHost , 采用主机名称为索引主键的hashtab来管理下属的虚拟主机表 。当当前监听服务的端口收到TCP请求和数据后 , 根据Host请求头的主机名称 , 来精确匹配定位出该请求的HTTP虚拟主机HTTPHost 。
3.3 HTTP虚拟主机 – HTTPHost 在HTTPListen监听服务下 , 可以配置多个虚拟主机 , 虚拟主机HTTPHost是eJet Web服务器资源管理体系的第二层 , 将HTTPCon缓冲区的数据进行解析 , 创建HTTPMsg来保存解析后的HTTP请求数据 , HTTP协议规范中 , 请求头Host携带的值内容是URL中domain信息 , 所以HTTP虚拟主机HTTPHost , 对应的就是请求域名 , 或者就是一个网站 。一个监听服务HTTPListen下可以寄宿大量的通过虚拟主机HTTPHost来管理的网站 。
HTTP虚拟主机的配置信息格式参考如下:
host = { host name = *; #www.ejetsrv.com type = server | proxy | fastcgi; gzip = on; ssl certificate = cert.pem; ssl private key = cert.key; ssl ca certificate = cacert.pem; script = { #reply 302 https://ke.test.ejetsrv.com:8443$request_uri; addResHeader X-Nat-IP $remote_addr; } error page = { 400 = 400.html; 504 = 504.html; root = /opt/ejet/errpage; } root = /home/hzke/sysdoc; location = {...} location = {...} location = {...}} HTTP虚拟主机的名称一般是域名格式 , 即多级名称体系 , 包含顶级域名、二级域名、三级域名等 , 通过DNS系统 , 将该域名解析到当前eJet Web服务器所在的IP地址上 , 如果在该IP地址上启动HTTPListen服务 , 那么所有使用该域名的请求都会指向到对应的HTTPHost虚拟主机 。
eJet系统根据功能服务形式 , 对虚拟主机定义了几种类型:Server、Proxy、FastCGI等 , 这几种类型可以同时并存 , 可或在一起 。
虚拟主机HTTPHost下可以设置资源的缺省目录 , 下属的资源位置HTTPLoc都可以复用虚拟主机的缺省目录 。
如果当前虚拟主机HTTPHost的上级监听服务是建立在安全连接SSL上 , 那么在有多个网站即多个虚拟主机情况下 , 需要为每个网站配置属于该网站域名的证书、私钥等安全身份标识信息 , 客户端在向同一个监听服务发送请求后 , 采用TLS SNI机制和eJet中实现的SSL域名选择回调 , 来完成域名和证书的选择 。
HTTPHost虚拟主机下可以设置Script脚本程序 , 虚拟主机下的脚本程序被执行时机是在创建HTTPMsg实例 , 并设置完DocURI后开始执行资源位置实例化流程 , 在该流程中分别执行HTTPListen的Script脚本、HTTPHost的Script脚本、HTTPLoc的Script脚本 。脚本程序的执行按照上述优先级来进行 , 使用脚本程序的指令来预处理HTTP请求的各类数据 。
一个虚拟主机HTTPHost下可以配置多个资源位置HTTPLoc , 代表访问当前域名下的不同目录 。虚拟主机HTTPHost采用多种方式管理下属的资源位置HTTPLoc实例 , 主要包括三种:
- 精确匹配请求路径的虚拟主机表 – 以请求路径名称为索引的资源位置索引表
- 对请求路径前缀匹配的虚拟主机表 – 以请求路径前缀名称为索引的资源位置字典树
- 对请求路径进行正则表达式运算的虚拟主机表 – 对正则表达式字符串为索引建立的资源位置列表
3.4 HTTP资源位置 – HTTPLoc HTTP资源位置HTTPLoc代表的是请求资源在某个监听服务下的某个虚拟主机里的目录位置 , HTTPLoc代表的是请求路径 , 根据HTTPMsg中的客户端请求数据 , 最终基于各种资源匹配规则 , 找到HTTPListen、HTTPHost、HTTPLoc后 , 基本确定了当前请求的资源位置、处理方式等 。一个网站对应的虚拟主机下 , 可以有多种功能和资源类别的资源位置HTTPLoc , 如图像文件放置在image为根的目录下 , PHP文件需要采用FastCGI转发给php-fpm解释器等 。
HTTP资源位置的配置信息格式参考如下:
location = { type = server; path = [ "\.(h|c|apk|gif|jpg|jpeg|png|bmp|ico|swf|js|css)$", "~*" ]; root = /opt/ejet/httpdoc; index = [ index.html, index.htm ]; expires = 30D; cache_file = <script> if ($request_uri ~* 'laoke') return "${host_name}_${server_port}${req_path_only}${req_file_only}"; else if (!-f $root$request_path) { return "$root$request_path is not a regular file"; } else if (!-x $root$request_path) { return "$root$request_path is not an executable file"; } else return "${request_header[host]}${req_path_only}else.html"; </script>;}location = { path = [ '^/view/([0-9A-Fa-f]{32})$', '~*' ]; type = proxy; passurl = http://cdn.ejetsrv.com/view/$1; root = /opt/cache/; cache = on; cache file = /opt/cache/${request_header[host]}/view/$1;}location = { type = fastcgi; path = [ "\.(php|php?)$", '~*']; passurl = fastcgi://localhost:9000; index = [ index.php ]; root = /opt/ejet/php;}location = { path = [ '/' ]; type = server; script = { try_files $uri $uri/ /index.php?$query_string; }; index = [ index.php, index.html, index.htm ];} HTTP资源位置HTTPLoc是通过路径名path和匹配类型matchtype来作为其标识 , 路径名为配置中设置的名称 , 客户端请求的路径名通过匹配类型定义的匹配规则来跟设置的路径名进行匹配 , 如果符合匹配 , 则该请求使用此资源位置HTTPLoc 。
匹配规则matchtype一般定义在配置文件中path数组里的第二项 , 分为如下几种:
- 精准匹配 , 使用等于号'='
- 前缀匹配 , 使用'^~'这两个符号
- 区分大小写的正则表达式匹配 , 使用'~'符号
- 不区分大小写的正则表达式匹配 , 使用'~*'这两个符号
- 通用匹配 , 使用'/'符号 , 如果没有其他匹配 , 任何请求都会匹配到
eJet系统根据功能服务形式 , 对资源位置HTTPLoc定义了几种类型:Server、Proxy、FastCGI等 , 通常情况下 , 一个资源位置HTTPLoc只属于一种类型 。
HTTP资源位置HTTPLoc都需要一个缺省的根目录 , 指向当前资源所在的根路径 , 客户端请求的路径都是相对于当前HTTPLoc下的root跟目录来定位文件资源的 。对于Proxy模式 , 根目录一般充当缓存文件的根目录 , 即需要对Proxy代理请求回来的内容缓存时 , 都保存在当前HTTPLoc下的root目录中 。
每个HTTPLoc下都会有缺省文件选项 , 可以配置多个缺省文件 , 一般设置为index.html等 。使用缺省文件的情形是客户端发起的请求只有目录形式 , 如http://www.xxx.com/ , 这时该请求访问的是HTTPLoc的根目录 , eJet系统会自动地依次寻找当前根目录下的各个缺省文件是否存在 , 如果存在就返回缺省文件给客户端 。不过需要注意的是 , eJet系统中这个流程是在设置DocURI时处理的 。
HTTP资源位置如果是Proxy类型或FastCGI类型 , 则必须配置转发地址passurl , 转发地址passurl一般都为绝对URL地址 , 含有指向其他服务器的domain域名 , passurl的形式取决HTTPLoc资源类型 。
反向代理(Reverse Proxy)就是将HTTPLoc的资源类型设置为Proxy模式 , 通过设置passurl指向要代理的远程服务器URL地址 , 来实现反向代理功能 。在反向代理模式下 , passurl可以是含有匹配结果变量的URL地址 , 这个地址指向的是待转发的下一个Origin服务器 , 匹配变量如果为1、1、2等数字变量 , 即表示基于正则表达式匹配路径时 , 把第一个或第二个匹配字符串作为passurl的一部分 。当然passurl可以包含任何全局变量或配置变量 , 使用这些变量可以更灵活方便地处理转发数据 。
在反向代理模式下 , HTTPLoc资源位置下有一个cache开关 , 如果设置cache=on即打开Cache功能 , 则需要在当前HTTPLoc下设置cachefile缓存文件名 。对于不同的请求地址 , cachefile必须随着请求路径或参数的变化而变化 , 所以cachefile的取值设置需要采用HTTP变量 , 或者使用Script脚本来动态计算cachefile的取值 。
HTTPLoc下一般都会部署Script脚本程序 , 包括rewrite、reply、try_files等 , 根据请求路径、请求参数、请求头、源地址等信息 , 决定当前资源位置是否需要重写、是否需要转移到其他地址处理等 。
四. HTTP变量 4.1 HTTP变量的定义 HTTP变量是指在eJet Web服务器运行期间 , 能动态地访问HTTP请求、HTTP响应、HTTP全局管理等实例对象中的存储空间里的数据 , 或者访问HTTP配置文件的配置数据等等 , 针对这些存储空间的访问 , 而抽象出来的名称叫做HTTP变量 。
变量的引用必须以开头 , 后跟变量名 , 如果变量名后面还有连续紧随的其他字符串 , 则需用{}来包括住变量名 , 其基本格式为:开头 , 后跟变量名 , 如果变量名后面还有连续紧随的其他字符串 , 则需用来包括住变量名 , 其基本格式为:变量名称 , {变量名称} , 变量名称 , { 变量名称 } , 等等
4.2 HTTP变量的应用 使用HTTP变量的场景主要在JSon格式的配置文件中 , 给各个配置项目增加动态的可编程接口 , 就需要基于不同的HTTP请求的信息 , 做判断、比较、赋值、拷贝、串接等操作 , 这些都离不开变量 , 需要不同的变量名去访问不同HTTP请求中的不同信息内容 , 通过配置中使用变量:访问变量的值 , 进行条件判断、比较、匹配、加减乘除、赋值等 。变量的使用样例可参考如下:
access log = { log2file = on; log file = /var/log/access.log; format = [ '$remote_addr', '-', '[$datetime[stamp]]', '"$request"', '"$request_header[host]"', '"$request_header[referer]"', '"$http_user_agent"', '$status', '$bytes_recv', '$bytes_sent' ];}script = { reply 302 https://ke.test.ejetsrv.com:8443$request_uri;}cache file = /opt/cache/${request_header[host]}/view/$1;params = { SCRIPT_FILENAME = $document_root$fastcgi_script_name; QUERY_STRING = $query_string; REQUEST_METHOD = $request_method; CONTENT_TYPE = $content_type; CONTENT_LENGTH = $content_length;}script = { if ($query[fid]) cache file = $real_path$query[fid]$req_file_ext; else if ($req_file_only) cache file = $real_path$req_file_only;
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- 如何下载和安装方正仿宋简体字体
- 优化电脑性能:360软件管家下载“我思”软件的步骤
- 如何优化星愿浏览器下载提示功能
- 远程下载迅雷操作指南
- 如何在路由器中设置P2P下载限制
- 新如何更快速地下载和安装Office 2019?详细教程分享!
- 如何在火狐客户端中设置下载任务数量
- 如何下载植物大战僵尸三游戏
- 如何高效使用FlashFXP进行网页上传和下载
- 如何下载并安装PC版微信