纠纷奇闻作文社交美文家庭
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

18Nginx入门教程Nginx的基础架构解析(下)

6月26日 栀璃鸢投稿
  1。Nginx模块1。1Nginx中的模块化设计
  Nginx的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩展。Nginx将各功能模块组织成一条链,当有请求到达的时候,请求依次经过这条链上的部分或者全部模块,进行处理。例如前面讲到的http请求,会有11个处理阶段,而每个阶段有对应着许多在此阶段生效的模块对该http请求进行处理。同时,Nginx开放了第三方模块编写功能,用户可以自定义模块,控制http请求的处理与响应,这种高度可定制化催生了Nginx的大量第三方模块,也使得Nginx定制化开发在各大互联网公司十分流行。1。2Nginx中的模块分类
  关于Nginx模块的分类有很多种方式,目前网上博客中写的较多的是按照功能进行分类,有如下几大类:event模块:搭建独立于操作系统的事件处理机制的框架,以及提供各种具体事件的处理。代表性的模块有:ngxeventsmodule,ngxeventcoremodule,handler模块:主要负责处理客户端请求并产生待响应的内容,比如ngxhttpstaticmodule模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出;filter模块:主要负责处理输出的内容,包括修改输出内容。代表性的模块有:upstream模块:该类模块都是用于实现反向代理功能,将真正的请求转发到后端服务器上,并从后端服务器上读取响应,发回给客户端。比如前面介绍到转发http、websocket、grpc、rtmp等协议的模块都可以划分为这一类;负载均衡模块:负载均衡的模块,实现相应算法。这类模块都是用于实现Nginx的负载均衡功能。extend模块:又称第三方模块,非Nginx官方提供,由各大企业的开发人员结合自身业务开发而成。Nginx提供了非常好的模块编写机制,遵循相关的标准可以很快定制出符合我们业务场景的模块,而且内部调用Nginx内部提供的方法进行处理,使得第三方模块往往都具备很好的性能
  对于官方提供的模块,我们可以直接在官网文档上学习,学习的方式和学习其他互联网组件的方式一致,首先学习如何使用,在用至熟练后可以深入分析其源码了解功能实现背后的原理。
  我们以前面介绍到的Nginx的限速模块(limitreq模块)进行说明。首先是掌握该模块的用法,在该模块的官方地址中,有关于该模块的详细介绍,包括该模块提供的所有指令以及所有变量说明。此外,还有比较丰富的指令用例。在多次使用该指令并自认为掌握了该模块的用法之后,想了解限速背后的原理以及相关算法时,就可以深入到源码学习了。
  进入Nginx的源码目录,使用ls查看源码文件,限速模块是在http目录中的。〔rootservernginx1。17。6〕cdsrc〔rootserversrc〕lscoreeventhttpmailmiscosstream〔rootserversrc〕lshttpmodulesngxhttplimit。chttpmodulesngxhttplimitconnmodule。chttpmodulesngxhttplimitreqmodule。c代码块12345678
  找到Nginx模块对应的代码文件后,我们就可以阅读里面的代码进行学习。往往源码的阅读是枯燥无味的,我们可以借助海量的网络资源辅助我们学习。这里就有一篇文章,作者深入分析了Nginx的限流模块的源码以及相应限流算法,最后进行了相关的实验测试。通过这样一个个模块深入学习,最后在使用每一个Nginx指令时,也会非常熟练,最后成为Nginx高手。1。3如何学习和使用第三方模块
  这里我们演示在Nginx中使用第三方模块。Openresty社区提供了一款Nginx中的Echo模块,即echonginxmodule。在Nginx中添加了该模块后,我们在配置文件中可以使用该模块提供的echo指令返回用户响应,简单方便。该模块的源码在github上,并且有良好的文档和使用示例,非常方便开发者使用。
  现在我们在Nginx的源码编译阶段加入该第三方模块,具体操作如下:〔rootservershencong〕pwdrootshencong〔rootservershencong〕mkdirnginxecho下载nginx源码包和第三方模块的源码包〔rootservershencong〕wgethttp:nginx。orgdownloadnginx1。17。6。tar。gz〔rootservershencong〕wgethttps:github。comopenrestyechonginxmodulearchivev0。62rc1。tar。gz解压〔rootservershencong〕tarxzfnginx1。17。6。tar。gz〔rootservershencong〕tarxzfv0。62rc1。tar。gz〔rootservershencong〕lsechonginxmodule0。62rc1nginx1。17。6nginx1。17。6。tar。gznginxechov0。62rc1。tar。gz〔rootservershencong〕cdnginx1。17。6使用addmodule添加第三方模块,参数为第三方模块源码〔rootservershencong〕。configureprefixrootshencongnginxechoaddmodulerootshencongechonginxmodule0。62rc1
  编译完成后,我们就可以去nginxecho目录中的nginx。conf文件中添加echo指令。准备如下的配置(可以参参考社区提供的示例):。。。http{server{listen80;charsetkoi8r;accessloglogshost。access。location{indexindex。htmlindex。}新增测试echo指令配置locationtimedhello{echohelloworldtakesaboutechotimerelapsedsec。;echohiyaigortakesaboutechotimerelapsedsec。;}locationechowithsleep{ensuretheclientcanseepreviousoutputimmediatelyechosleep2。5;insecechohellotakesaboutechotimerelapsedsec。;}}}。。。
  启动Nginx后,我们就可以在浏览器上请求者两个URI地址,看到相应echo返回的信息了。第二个配置是使用了echosleep指令,会使得请求在休眠2。5s后才返回。1。4如何编写自己的模块
  想要编写Nginx模块,首先需要对Nginx模块中的源码以及相关的数据结构有所了解,还要知晓NginxHTTP模块的调用流程。假设我要实现前面第三方模块Echo的最简单形式,即只输出相应的字符串即可。假定模块支持的指令名称还是echo,这个echo指令需要跟一个参数,即输出的字符串。我们需要做如下几步:确定模块名称,以及模块中的指令以及参数,还有运行的环境。这里涉及的结构是ngxcommandt,它定义了模块里的所有指令格式。下面的代码表示该模块中只有一个echo指令,它出现的上下文环境为location,且有一个参数(NGXCONFTAKE1)。当某个配置块中出现echo指令时,Nginx将调用ngxhttpecho方法。然后在该方法中,会设置处理请求的handler,这个handler就是处理请求的方法。staticngxcommandtngxhttpechocommands〔〕{{ngxstring(echo),指令名称,利用ngxstring宏定义NGXHTTPLOCCONFNGXCONFTAKE1,用在location指令块内,且有1个参数ngxhttpecho,处理回调函数NGXHTTPLOCCONFOFFSET,offsetof(ngxhttpecholocconft,ed),指定参数读取位置NULL},ngxnullcommand};完成请求处理的handler函数,最重要的部分就在这里;staticcharngxhttpecho(ngxconftcf,ngxcommandtcmd,voidconf){找到指令所属的配置块,这里我们限定echo指令的上下文环境只有locationclcfngxhttpconfgetmodulelocconf(cf,ngxhttpcoremodule);指定处理的。。。returnNGXCONFOK;}staticngxinttngxhttpechohandler(ngxhttprequesttr){。。。向用户发送相应包returnngxhttpoutputfilter(r,out);}一些收尾工作,比如配置模块介入http请求的哪些阶段等。Httpcontextofthemodulestaticngxhttpmoduletngxhttpechomodulectx{NULL,preconfigurationNULL,postconfigurationNULL,createmainconfigurationNULL,initmainconfigurationNULL,createserverconfigurationNULL,mergeserverconfigurationngxhttpechocreatelocconf,createlocationconfigrationngxhttpechomergelocconfmergelocationconfigration};Modulengxmoduletngxhttpechomodule{NGXMODULEV1,ngxhttpechomodulectx,modulecontextngxhttpechocommands,moduledirectivesNGXHTTPMODULE,moduletypeNULL,initmasterNULL,initmoduleNULL,initprocessNULL,initthreadNULL,exitthreadNULL,exitprocessNULL,exitmasterNGXMODULEV1PADDING};
  完成以上几步,一个简易的自定义模块就算大功告成了。接下来我们动手完成第一个自定义的模块,将其编译进Nginx二进制文件中并进行测试。2。案例
  我们来完成一个简单的自定义http模块,来实现前面Echo模块的最简单形式,即使用指令输出hello,world字符串。首先新建一个目录echonginxmodule,然后在目录下新建两个文件config和ngxhttpechomodule。c〔rootserverechonginxmodule〕pwdrootshencongechonginxmodule〔rootserverechonginxmodule〕lsconfigngxhttpechomodule。c
  两个文件内容分别如下:〔rootserverechonginxmodule〕catconfigngxaddonnamengxhttpechomodule指定模块名称HTTPMODULESHTTPMODULESngxhttpechomodule指定模块源码路径NGXADDONSRCSNGXADDONSRCSngxaddondirngxhttpechomodule。c〔rootserverechonginxmodule〕catngxhttpechomodule。cincludengxconfig。hincludengxcore。hincludengxhttp。hModuleconfigtypedefstruct{}staticcharngxhttpecho(ngxconftcf,ngxcommandtcmd,voidconf);staticvoidngxhttpechocreatelocconf(ngxconftcf);staticcharngxhttpechomergelocconf(ngxconftcf,voidparent,voidchild);定义指令staticngxcommandtngxhttpechocommands〔〕{{ngxstring(echo),指令名称,利用ngxstring宏定义NGXHTTPLOCCONFNGXCONFTAKE1,用在location指令块内,且有1个参数ngxhttpecho,处理回调函数NGXHTTPLOCCONFOFFSET,offsetof(ngxhttpecholocconft,ed),指定参数读取位置NULL},ngxnullcommand};Httpcontextofthemodulestaticngxhttpmoduletngxhttpechomodulectx{NULL,preconfigurationNULL,postconfigurationNULL,createmainconfigurationNULL,initmainconfigurationNULL,createserverconfigurationNULL,mergeserverconfigurationngxhttpechocreatelocconf,createlocationconfigrationngxhttpechomergelocconfmergelocationconfigration};Modulengxmoduletngxhttpechomodule{NGXMODULEV1,ngxhttpechomodulectx,modulecontextngxhttpechocommands,moduledirectivesNGXHTTPMODULE,moduletypeNULL,initmasterNULL,initmoduleNULL,initprocessNULL,initthreadNULL,exitthreadNULL,exitprocessNULL,exitmasterNGXMODULEV1PADDING};Handlerfunctionstaticngxinttngxhttpechohandler(ngxhttprequesttr){获取指令的参数elcfngxhttpgetmodulelocconf(r,ngxhttpechomodule);if(!(rmethod(NGXHTTPHEADNGXHTTPGETNGXHTTPPOST))){如果不是HEADGETPUT请求,则返回405NotAllowed错误returnNGXHTTPNOTALLOWED;}rheadersout。contenttype。lensizeof(texthtml)1;rheadersout。contenttype。data(uchar)rheadersout。statusNGXHTTPOK;rheadersout。contentlengthnelcfed。if(rmethodNGXHTTPHEAD){rcngxhttpsendheader(r);if(rc!NGXOK){}}bngxpcalloc(rpool,sizeof(ngxbuft));if(bNULL){ngxlogerror(NGXLOGERR,rconnectionlog,0,Failedtoallocateresponsebuffer。);returnNGXHTTPINTERNALSERVERERROR;}out。out。nextNULL;bposelcfed。blastelcfed。data(elcfed。len);bmemory1;blastbuf1;rcngxhttpsendheader(r);if(rc!NGXOK){}向用户发送相应包returnngxhttpoutputfilter(r,out);}staticcharngxhttpecho(ngxconftcf,ngxcommandtcmd,voidconf){clcfngxhttpconfgetmodulelocconf(cf,ngxhttpcoremodule);指定处理的ngxconfsetstrslot(cf,cmd,conf);returnNGXCONFOK;}staticvoidngxhttpechocreatelocconf(ngxconftcf){confngxpcalloc(cfpool,sizeof(ngxhttpecholocconft));if(confNULL){returnNGXCONFERROR;}confed。len0;confed。dataNULL;}staticcharngxhttpechomergelocconf(ngxconftcf,voidparent,voidchild){ngxconfmergestrvalue(confed,preved,);returnNGXCONFOK;}
  这样一个第三方模块包就完成了,接下来我们要向之前使用第三方模块一样,将它编译进Nginx,具体操作如下。〔rootservershencong〕cdnginx1。17。6〔rootservernginx1。17。6〕。configureprefixrootshencongnginxechoaddmodulerootshencongechonginxmodule。。。〔rootservernginx1。17。6〕makemakeinstall。。。〔rootservernginx1。17。6〕cd。。nginxechosbin〔rootserversbin〕。nginxVnginxversion:nginx1。17。6builtbygcc4。8。520150623(RedHat4。8。539)(GCC)configurearguments:prefixrootshencongnginxechoaddmodulerootshencongechonginxmodule
  接下来,我们只要在nginx。conf中加入我们的指令,并给一个参数,就能看到我们自定义的输出了。。。。http{。。。server{listen80;location{indexindex。htmlindex。}locationtest{echohello,}。。。}}。。。
  最后我们请求主机的80端口,URItest,浏览器输出hello,world,说明我们的自定义模块成功了!
  3。小结
  在Nginx基础架构介绍的最后,主要是介绍了Nginx的模块设计以及相应的模块用法。最后,我们简单给出了一个简单编写自己模块的案例作为本章的实战案例。希望这一节之后,大家能对Nginx的模块化设计有所了解,并有兴趣在模块的源码方向深入学习。
搜索 投诉 评论 转载

黑龙江著名的抗日抗俄英雄袁寿山将军位于黑龙江省杜尔伯特蒙古族自治县一心乡胜利村G331国道西侧,有一公园,因园内山丘上葬有著名抗日抗俄将领袁寿山将军而得名寿山公园。为了迎接大庆黑龙江第五次旅发大会,现更名为寿山……18Nginx入门教程Nginx的基础架构解析(下)1。Nginx模块1。1Nginx中的模块化设计Nginx的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便于开发,同时也便于对……迪丽热巴穿搭反差太戳人!台上是风情万种的大明星,私服却接地气Hi,这里是搭搭,一个专注穿衣打扮,专属你美丽的时尚达人!自带异域风情的迪丽热巴,因为颜值在娱乐圈内处于第一阶梯,因此被大家记住。拥有建模脸不算什么,就连身材也是一……哲学家的疑惑粒子不断细分下去,到底有没有一个尽头?德国古典哲学家康德在《纯粹理性批判》中系统提出二律背反的现象,这是经验论和唯理论长期争执不下的四种命题。每一个命题都有两个对立且符合形式逻辑的解释。这种正反命题都合理且又对立的……苹果公司突然发布首个安全响应系统,以后不会为了更新等待而发愁2022年11月17日凌晨,苹果公司突然发布了首个iOS16。2(a)安全响应系统,而就在昨天间隔24小时苹果公司才发布iOS16。2beta3的测试版本。今天早上打开手……乐福谈连败我们还有很长的路要走要去赢下这些很接近的比赛直播吧11月12日讯NBA常规赛,骑士客场惜败勇士,苦吞3连败。赛后记者问到了队内老将乐福对于最近比赛的看法,乐福说:我们还有很长的路要走。某些球队会以其他方式反弹,我们……完婚后第40天保罗乔治晒婚纱照,一家五口合照幸福NBA休赛期不少球员都举行了婚礼,快船球星保罗乔治和妻子丹妮拉相恋十年,最终携手迈入了婚姻的殿堂,两人十年间生了三个孩子,两个女儿,一个儿子,32岁的保罗乔治儿女双全,两人在意……洗浴中心有何猫腻?为何有人放弃酒店,再晚也要在此过夜今天小编告诉你,为何有些游客放弃酒店,选择在足浴中心过夜。你相信大家都经历过半夜抵达外地的情况,凌晨半夜抵达陌生城市,第一要做的就是住所。(此处已添加小程序,请到今日头条……金彭贝感谢巴黎球迷支持内心深受触动,你们的士兵会尽快归来直播吧3月5日讯由于跟腱受伤,巴黎圣日耳曼后卫金彭贝赛季报销。主场迎战南特的比赛,巴黎圣日耳曼球迷用横幅表达了对这名法国国脚的支持,他们写道:一名士兵总是会回来参加战斗,我们不……专家点评丨推动产业振兴壮大实体经济夏杰长此次湖南出台《关于打好经济增长主动仗实现经济运行整体好转的若干政策措施》,从推动产业振兴,不断壮大实体经济的角度来看,主要有如下几个方面:第一,加强市场主体培……体博会精彩抢先看灌篮高手集结武汉,现场燃起篮球火!动起来,购精彩4月13日4月16日2023武汉体育消费博览会将在武汉国际会展中心举办面积3。5万平米的体博会如何打卡?现场到底怎么玩儿?体博……vivo年度影像旗舰?蔡司全焦段四摄自研V2芯片,6499元11月22日晚上,vivo发布了最新的旗舰产品vivoX90系列。其中,备受关注的一款就是vivoX90Pro,这款机型不管是在影像功能还是核心性能上都得到了明显的升级。而在价……
育碧挫败维旺迪收购企图Intel将操刀根治Chrome多年顽疾微软新一代Windows抢先体验这画面如何?第一次!中国开源喜获国际认可NBA收官在即!冲刺各大奖项,得分王最激烈,篮板助攻榜无悬念新版Cortana上架微软弱化其在Win10中存在提高生产力抖音毕业季短视频最火十大高校最火BGM出炉任天堂社长自曝Switch2强化一方独占IP多人游戏体验更出王者荣耀这三位法师英雄,正逐渐被版本淘汰,萌新最爱甄姬在列广州发放3000万元消费券全国人民都能领石油什么时候用光?最牛分享平台Instagram晒今年最火图片
程序员那么可爱男装逼耍帅,女花痴傻白甜,程序员风评被害这些你未必知道种新式接吻方法让更兴奋中国五千年来就没产生过像微软这样的大企业,为啥?任正非说透了 奇怪的小狮子洁面仪真假火眼金睛带你分辨洁面仪真假失德明星直播带货几个热点讨论西安为何能成为副省级城市?与计划单列市相比,又有什么区别?体检常识认识日常体检中的四大误区倪萍姥姥,人间清醒羽绒服怎么挑羽绒服如何挑选燃油电动混动车,哪种更好?开了凯美瑞混动才知道,差别很大胡文海事件真相,杀坏官的是英雄还是恶魔

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形