nginx源码分析—模块及其初始化

Content

0.

1. nginx有哪些模块?

2. nginx如何描述这些模块?

2.1 模块数据结构

2.1.1 ngx_module_t结构

2.1.2 ngx_command_t结构

2.2 模块类图

3. nginx如何组织这些模块?

3.1 全局数组ngx_modules

3.2 模块组织结构图

4. nginx的模块种类

5. nginx如何初始化这些模块?

5.1 静态初始化

5.2 动态初始化

5.2.1 index字段的初始化

5.2.2 ctx_index字段的初始化

5.2.3 其他初始化

6. 小结

  

0.

 

本文以nginx-1.0.4版本为例,介绍nginx的模块及其初始化。.表示nginx-1.0.4源代码目录,本文为/usr/src/nginx-1.0.4

 

1. nginx有哪些模块?

 

要知道nginx有哪些模块,一个快速的方法就是编译nginx。编译之后,会在源代码根目录下生成objs目录,该目录中包含有ngx_auto_config.hngx_auto_headers.h,以及ngx_modules.c文件,当然,还有Makefile文件等。

 

其中,生成的ngx_modules.c文件中,重新集中申明(使用extern关键字)nginx配置的所有模块,这些模块可通过编译前的configure命令进行配置,即设置哪些模块需要编译,哪些不被编译。如下。

 

 1 00001:
 2 00002: #include <ngx_config.h>
 3 00003: #include <ngx_core.h>
 4 00004:
 5 00005:
 6 00006:
 7 00007: extern ngx_module_t ngx_core_module;
 8 00008: extern ngx_module_t ngx_errlog_module;
 9 00009: extern ngx_module_t ngx_conf_module;
10 00010: extern ngx_module_t ngx_events_module;
11 00011: extern ngx_module_t ngx_event_core_module;
12 00012: extern ngx_module_t ngx_epoll_module;
13 00013: extern ngx_module_t ngx_http_module;
14 00014: extern ngx_module_t ngx_http_core_module;
15 00015: extern ngx_module_t ngx_http_log_module;
16 00016: extern ngx_module_t ngx_http_upstream_module;
17 00017: extern ngx_module_t ngx_http_static_module;
18 00018: extern ngx_module_t ngx_http_autoindex_module;
19 00019: extern ngx_module_t ngx_http_index_module;
20 00020: extern ngx_module_t ngx_http_auth_basic_module;
21 00021: extern ngx_module_t ngx_http_access_module;
22 00022: extern ngx_module_t ngx_http_limit_zone_module;
23 00023: extern ngx_module_t ngx_http_limit_req_module;
24 00024: extern ngx_module_t ngx_http_geo_module;
25 00025: extern ngx_module_t ngx_http_map_module;
26 00026: extern ngx_module_t ngx_http_split_clients_module;
27 00027: extern ngx_module_t ngx_http_referer_module;
28 00028: extern ngx_module_t ngx_http_rewrite_module;
29 00029: extern ngx_module_t ngx_http_proxy_module;
30 00030: extern ngx_module_t ngx_http_fastcgi_module;
31 00031: extern ngx_module_t ngx_http_uwsgi_module;
32 00032: extern ngx_module_t ngx_http_scgi_module;
33 00033: extern ngx_module_t ngx_http_memcached_module;
34 00034: extern ngx_module_t ngx_http_empty_gif_module;
35 00035: extern ngx_module_t ngx_http_browser_module;
36 00036: extern ngx_module_t ngx_http_upstream_ip_hash_module;
37 00037: extern ngx_module_t ngx_http_stub_status_module;
38 00038: extern ngx_module_t ngx_http_write_filter_module;
39 00039: extern ngx_module_t ngx_http_header_filter_module;
40 00040: extern ngx_module_t ngx_http_chunked_filter_module;
41 00041: extern ngx_module_t ngx_http_range_header_filter_module;
42 00042: extern ngx_module_t ngx_http_gzip_filter_module;
43 00043: extern ngx_module_t ngx_http_postpone_filter_module;
44 00044: extern ngx_module_t ngx_http_ssi_filter_module;
45 00045: extern ngx_module_t ngx_http_charset_filter_module;
46 00046: extern ngx_module_t ngx_http_userid_filter_module;
47 00047: extern ngx_module_t ngx_http_headers_filter_module;
48 00048: extern ngx_module_t ngx_http_copy_filter_module;
49 00049: extern ngx_module_t ngx_http_range_body_filter_module;
50 00050: extern ngx_module_t ngx_http_not_modified_filter_module;
51 00051:
View Code

 

很显然,这些模块均是在此处用extern进行申明,以表明其他模块可以访问,而对其本身的定义和初始化ngx_module_t结构在其对应的.c文件中进行。例如,ngx_core_module模块便是在./src/core/nginx.c文件中定义并进行静态初始化。实际上,ngx_core_module是一个全局的结构体对象,其他模块类同。如下。

 

ngx_module_t  ngx_core_module = {NGX_MODULE_V1,&ngx_core_module_ctx,                  /* module context */ngx_core_commands,                     /* module directives */NGX_CORE_MODULE,                       /* module type */NULL,                                  /* init master */NULL,                                  /* init module */NULL,                                  /* init process */NULL,                                  /* init thread */NULL,                                  /* exit thread */NULL,                                  /* exit process */NULL,                                  /* exit master */NGX_MODULE_V1_PADDING
};

 

 

2. nginx如何描述这些模块?

 

2.1 模块数据结构

 

2.1.1 ngx_module_t结构

 

nginx的模块化架构最基本的数据结构为ngx_module_t,因此,此处,我们先分析这个结构,在./src/core/ngx_conf_file.h文件中定义。如下,//后的内容为笔者加入的注释。

 

 1 00107: #define NGX_MODULE_V1    0, 0, 0, 0, 0, 0, 1         //该宏用来初始化前7个字段
 2 00108: #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 //该宏用来初始化最后8个字段
 3 00109:
 4 00110: struct ngx_module_s{
 5 00111:    ngx_uint_t    ctx_index;  //分类模块计数器
 6 00112:    ngx_uint_t    index;      //模块计数器
 7 00113:
 8 00114:    ngx_uint_t    spare0;
 9 00115:    ngx_uint_t    spare1;
10 00116:    ngx_uint_t    spare2;
11 00117:    ngx_uint_t    spare3;
12 00118:
13 00119:    ngx_uint_t    version;    //版本
14 00120:
15 00121:    void          *ctx;       //该模块的上下文,每个种类的模块有不同的上下文
16 00122:    ngx_command_t *commands;  //该模块的命令集,指向一个ngx_command_t结构数组
17 00123:    ngx_uint_t    type;       //该模块的种类,为core/event/http/mail中的一种
18 00124:    //以下是一些callback函数
19 00125:    ngx_uint_t    (*init_master)(ngx_log_t *log);      //初始化master
20 00126:
21 00127:    ngx_uint_t    (*init_module)(ngx_cycle_t *cycle);  //初始化模块
22 00128:
23 00129:    ngx_uint_t    (*init_process)(ngx_cycle_t *cycle); //初始化工作进程
24 00130:    ngx_uint_t    (*init_thread)(ngx_cycle_t *cycle);  //初始化线程
25 00131:    void          (*exit_thread)(ngx_cycle_t *cycle);  //退出线程
26 00132:    void          (*exit_process)(ngx_cycle_t *cycle); //退出工作进程
27 00133:
28 00134:    void          (*exit_master)(ngx_cycle_t *cycle);  //退出master
29 00135:
30 00136:    uintptr_t     spare_hook0;  //这些字段貌似没用过
31 00137:    uintptr_t     spare_hook1;
32 00138:    uintptr_t     spare_hook2;
33 00139:    uintptr_t     spare_hook3;
34 00140:    uintptr_t     spare_hook4;
35 00141:    uintptr_t     spare_hook5;
36 00142:    uintptr_t     spare_hook6;
37 00143:    uintptr_t     spare_hook7;
38 00144: };

 

其中,init_master, init_module, init_process, init_thread, exit_thread, exit_process, exit_master分别在初始化master、初始化模块、初始化工作进程、初始化线程、退出线程、退出工作进程、退出master时被调用。

 

2.1.2 ngx_command_t结构

 

模块的命令集commands指向一个ngx_command_t结构数组,在./src/core/ngx_conf_file.h文件中定义。如下,//后的内容为笔者加入的注释。

 

 1 00077: struct ngx_command_s {
 2 00078:    ngx_str_t     name;  //命令名
 3 00079:    ngx_uint_t    type;  //命令类型
 4 00080:    char          *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 5 00081:    ngx_uint_t    conf;
 6 00082:    ngx_uint_t    offset;
 7 00083:    void          *post;
 8 00084: };
 9 00085:
10 00086: #define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL }  //空命令

 

2.2 模块类图

 

nginxC语言开发的开源高性能web server,其代码中大量使用了callback方式,例如模块结构ngx_module_t中的init_master等。实际上,我们可以将ngx_module_t看作C++的一个类,其中的数据字段便是其属性,而那些callback便是该类的操作。

 

——这应该就是nginx的模块化思想。画出的ngx_module_t的类图如下。

3.nginx如何组织这些模块?

 

3.1 全局数组ngx_modules

 

由第1节,我们知道,nginx拥有几十个模块,那么,这些模块是如何组织的呢?

 

——保存在一个全局指针数组ngx_modules[]中,数组的每一个元素均为一个全局ngx_module_t对象的指针。如下。请参考./objs/ngx_modules.c文件中的定义。

 

 1 00052: ngx_module_t *ngx_modules[] = {
 2 00053:    &ngx_core_module,
 3 00054:    &ngx_errlog_module,
 4 00055:    &ngx_conf_module,
 5 00056:    &ngx_events_module,
 6 00057:    &ngx_event_core_module,
 7 00058:    &ngx_epoll_module,
 8 00059:    &ngx_http_module,
 9 00060:    &ngx_http_core_module,
10 00061:    &ngx_http_log_module,
11 00062:    &ngx_http_upstream_module,
12 00063:    &ngx_http_static_module,
13 00064:    &ngx_http_autoindex_module,
14 00065:    &ngx_http_index_module,
15 00066:    &ngx_http_auth_basic_module,
16 00067:    &ngx_http_access_module,
17 00068:    &ngx_http_limit_zone_module,
18 00069:    &ngx_http_limit_req_module,
19 00070:    &ngx_http_geo_module,
20 00071:    &ngx_http_map_module,
21 00072:    &ngx_http_split_clients_module,
22 00073:    &ngx_http_referer_module,
23 00074:    &ngx_http_rewrite_module,
24 00075:    &ngx_http_proxy_module,
25 00076:    &ngx_http_fastcgi_module,
26 00077:    &ngx_http_uwsgi_module,
27 00078:    &ngx_http_scgi_module,
28 00079:    &ngx_http_memcached_module,
29 00080:    &ngx_http_empty_gif_module,
30 00081:    &ngx_http_browser_module,
31 00082:    &ngx_http_upstream_ip_hash_module,
32 00083:    &ngx_http_stub_status_module,
33 00084:    &ngx_http_write_filter_module,
34 00085:    &ngx_http_header_filter_module,
35 00086:    &ngx_http_chunked_filter_module,
36 00087:    &ngx_http_range_header_filter_module,
37 00088:    &ngx_http_gzip_filter_module,
38 00089:    &ngx_http_postpone_filter_module,
39 00090:    &ngx_http_ssi_filter_module,
40 00091:    &ngx_http_charset_filter_module,
41 00092:    &ngx_http_userid_filter_module,
42 00093:    &ngx_http_headers_filter_module,
43 00094:    &ngx_http_copy_filter_module,
44 00095:    &ngx_http_range_body_filter_module,
45 00096:    &ngx_http_not_modified_filter_module,
46 00097:    NULL
47 00098: };
48 00099:

 

3.2 模块组织结构图

 

44个模块,这些模块的组织结构图如下所示,因模块较多,图中只画出一部分有代表性的重要模块。 

4. nginx的模块种类

 

在对全局数组ngx_modules进行初始化时,即对每一个模块进行了静态初始化。其中对模块的type字段的初始化是通过以下4个宏进行的。

 

(1) 文件./src/core/ngx_conf_file.h

 

1 #define NGX_CORE_MODULE      0x45524F43   /* "CORE" */
2 #define NGX_CONF_MODULE      0x464E4F43   /* "CONF" */

 

(2) 文件./src/event/ngx_event.h

 

1 #define NGX_EVENT_MODULE      0x544E5645  /* "EVNT" */
2 #define NGX_EVENT_MODULE      0x544E5645  /* "EVNT" */

 

(3) 文件./src/http/ngx_http_config.h

 

1 #define NGX_HTTP_MODULE       0x50545448  /* "HTTP" */

 

即模块种类宏,定义为一个十六进制的数,这个十六进制的数就是其类型对应的ASCII码。因此,nginx共有4种类型的模块,分别为"CORE","CONF","EVNT","HTTP"

 

实际上,如果在configure阶段,使用了"--with-mail"参数,mail模块将被编译进来,其对应的宏如下。

 

1 #define NGX_MAIL_MODULE       0x4C49414D  /* "MAIL" */

 

因此,严格来讲,nginx5中类型的模块,"CORE","CONF","EVNT","HTTP","MAIL"

5. nginx如何初始化这些模块?

 

5.1 静态初始化

 

即编译期间完成的数据成员初始化。记mname为某个模块的名字,其静态初始化过程如下。

(1) 用宏NGX_MODULE_V1初始化前7个字段

(2) 用全局对象ngx_mname_module_ctx的地址初始化ctx指针

(3) 用全局数组ngx_mname_commands[]初始化commands指针

(4) 用宏NGX_CORE_MODULE等初始化type字段

(5) 初始化init_mastercallback

(6) 用宏NGX_MODULE_V1_PADDING初始化最后8个字段

 

由此可见,在定义该模块(全局结构对象)时,将其ctx_indexindex均初始化为0。因此,模块的静态初始化(数据成员初始化)实际上只是对模块上下文、模块命令集和模块类型进行初始化。

 

5.2动态初始化

 

nginx运行(启动)初期,对模块本身的初始化。

 

5.2.1 index字段的初始化

 

 

 

对各个模块的index字段的初始化是在main函数中进行的,如下。

 

00325:    ngx_max_module = 0;
00326:    for (i = 0; ngx_modules[i]; i++) {
00327:       ngx_modules[i]->index = ngx_max_module++;
00328:    }

 

 

可见,该for-loop执行后,每个模块的index值便是其在ngx_modules[]数组中的下标值,且全局变量ngx_max_module为模块个数,对于本例来讲,ngx_max_module=44

 

5.2.2 ctx_index字段的初始化

 

(1) "EVNT"类型的模块

 

 1 00877: static char *
 2 00878: ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 3 00879: {
 4 00880:    char    *rv;
 5 00881:    void    ***ctx;
 6 00882:    ngx_uint_t    i;
 7 00883:    ngx_conf_t    pcf;
 8 00884:    ngx_event_module_t *m;
 9 00885:
10 00886:    /* count the number of the event modules and set up their indices */
11 00887:
12 00888:    ngx_event_max_module = 0;
13 00889:    for (i = 0; ngx_modules[i]; i++) {
14 00890:       if (ngx_modules[i]->type ! = NGX_EVENT_MODULE) {
15 00891:          continue;
16 00892:       }
17 00893:
18 00894:       ngx_modules[i]->ctx_index = ngx_event_max_module++;
19 00895:    }
20 00896:
21 ...

 

5.2.3其他初始化

 

其他的初始化工作,将在nginx启动及其进程启动分析中介绍。

 

6. 小结

 

本文主要讲述了nginx的模块及其初始化,包括所有模块的组织,及模块的静态初始化和部分动态初始化。

 

 

Reference

nginx-1.0.4源码

http://nginx.org/en

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/canxuexiecheng/articles/3276551.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 网络相关,Linux系统管理员必备的21个网络相关监控

Linux系统管理员必备的21个网络相关监控1. ntopngntopng 是 ntop 的升级版&#xff0c;它提供了一个能通过浏览器进行网络监控的图形用户界面。它还有其他用途&#xff0c;如&#xff1a;地理定位主机&#xff0c;显示网络流量和 ip流量分布并能进行分析。2. iftopiftop 类似于…

固态硬盘 linux 文件系统,SSD是否需要使用特别的文件系统?

用认真的态度与专业的情怀倾注于存储&#xff0c;欢迎关注我&#xff0c;与我交流哦&#xff01;我们常用的电脑系统主要是Windows和Linux&#xff0c;其中&#xff0c;Windows系统中常用的文件系统主要是FAT和NFTS&#xff0c;FAT是旧Windows和U盘用的较多&#xff0c;最新Win…

java二维数组数字数显次数_【每日一题】118.数组中数字出现的次数

关注我们获取更多计算机考研信息? 今日习题在一个数组 nums 中除一个数字只出现一次之外&#xff0c;其他数字都出现了三次。请找出那个只出现一次的数字。示例 1&#xff1a;输入&#xff1a;nums [3,4,3,3]输出&#xff1a;4示例 2&#xff1a;输入&#xff1a;nums [9,1,…

微软的转型中?

北京时间8月23日夜&#xff0c;微软在其官网上发表新闻称&#xff0c;微软首席执行官Steve Ballmer将在12个月内退休。 微软在这篇《微软CEO Steve Ballmer将在12个月内退休》新闻中表示&#xff0c;其首席执行官Steve Ballmer已决定将在12个月内退休&#xff0c;尤其是当新的首…

k均值的损失函数_一种基于均值不等式的Listwise损失函数

1 前言1.1 Learning to Rank 简介Learning to Rank (LTR) , 也被叫做排序学习, 是搜索中的重要技术, 其目的是根据候选文档和查询语句的相关性对候选文档进行排序, 或者选取topk文档. 比如在搜索引擎中, 需要根据用户问题选取最相关的搜索结果展示到首页. 下图是搜索引擎的搜索…

HBase 集群搭建

文章目录 安装前准备兼容性官方网址 集群搭建搭建 Hadoop 集群搭建 Zookeeper 集群解压缩安装配置文件高可用配置分发 HBase 文件 服务的启停启动顺序停止顺序 验证进程查看 Web 端页面 安装前准备 兼容性 1&#xff09;与 Zookeeper 的兼容性问题&#xff0c;越新越好&#…

在哪个Linux发行版上运行python,怎么在linux上运行python

Linux默认是已经安装好了Python程序目前来说&#xff0c;大多数的Linux发行版是安装了两个版本的Python程序一个是Python 2.x一个是Python 3.x一些系统自带的程序文件需要Python 2的支持&#xff0c;另外Python 3又是大势所趋所以&#xff0c;我们最好不要动系统的Python版本需…

职场上个人的核心技术_职场上,这3种人表面老实,实际却是个“高手”,要远离...

职场上&#xff0c;这3种人表面老实&#xff0c;实际却是个“高手”&#xff0c;要远离&#xff01;在职场生活中&#xff0c;每一步都需要走好&#xff0c;因为你不慎走错了一步也就可能满盘皆输。而公司里面也有一种比较特殊的情况&#xff0c;也就是有这么3种类型的人&#…

linux编程参数列表,Linux编程 14 文件权限(用户列表passwd,用户控制shadow,useradd模板与useradd命令参数介绍)...

一. 概述linux安全系统的核心是用户账户。 创建用户时会分配用户ID(UID)。 UID是唯一的&#xff0c;但在登录系统时不是用UID&#xff0c;而是用登录名。在讲文件权限之之前&#xff0c;先了解下linux是怎样处理用户账户的。以及用户账户需要的文件和工具&#xff0c;这样处理文…

GitHub托管BootStrap资源汇总(持续更新中…)

Twitter BootStrap已经火过大江南北&#xff0c;对于无法依赖美工的程序员来说&#xff0c;这一成熟前卫的前端框架简直就一神器&#xff0c;轻轻松松地实现出专业的UI效果。GitHub上相关的的开源项目更是层出不穷&#xff0c;在此整理列举一些感觉不错的组件或增强实现&#x…

aix linux运维,运维老司机分享的八个AIX日常运维经验及案例

原文来自微信公众号&#xff1a;AIX专家俱乐部【经验分享】在AIX启动时&#xff0c;打开debug模式经常遇到aix无法启动&#xff0c;但又不知道pending在哪&#xff0c;因此打开启动过程的debug模式&#xff0c;对于诊断问题有很大的帮帮助。下面是打开debug的方法&#xff1a;打…

php 区块链算法_PoW/BFT等5种主流区块链共识算法的开源代码实现

共识算法是实现自主产权区块链的必不可少的关键环节&#xff0c;本文列出社区中相对成熟的区块链共识算法开源实现&#xff0c;包括BFT共识、Raft共识、Paxos共识、PoW共识等&#xff0c;可供希望开发自主产权区块链的团队参考学习。相关推荐&#xff1a;区块链开发系列教程1、…

[每日一题] 11gOCP 1z0-052 :2013-09-1 RMAN-- repair failure........................................A20...

转载请注明出处&#xff1a;http://blog.csdn.net/guoyjoe/article/details/10859315 正确答案&#xff1a;D 一、模拟上题的错误&#xff1a; &#xff11;、删除4号文件 [oraclemydb ~]$ cd /u01/app/oracle/oradata/ocm/ [oraclemydb ocm]$ rm -rf users01.dbf&#xff12;、…

kafka集群 kubernetes_为什么 Kubernetes 如此受欢迎?

点击上方蓝色“火丁笔记”关注我们&#xff0c;设个星标&#xff0c;每天学习全栈知识在撰写本文时&#xff0c;Kubernetes 已有 6 年历史[1]了&#xff0c;在过去的两年中&#xff0c;它的流行度不断提高&#xff0c;一直是最受欢迎的平台之一[2]。今年&#xff0c;它成为最受…

android 动画 返回,Android“菜单图标变返回”动画

此例用到SVG动画&#xff0c;其中涉及三个XML文件&#xff0c;分别为&#xff1a;Vector矢量图&#xff0c;objectAnimator动画&#xff0c;以及一个animated-vector文件将前两个文件联合起来。1.在drawable文件夹下新建vector文件描述矢量图android:height"200dp"an…

全志A10 Bootload加载过程分析

A10的启动过程大概可分为5步&#xff1a;BootRom&#xff0c;SPL&#xff0c;Uboot&#xff0c;Kernel&#xff0c;RootFileSystem。本文只关注镜像的加载过程&#xff0c;分析RootRom->SPL->Uboot的启动流程。系统上电后&#xff0c;ARM处理器在复位时从地址0x000000开始…

android老 电池,为什么安卓手机不会因为电池的老化而降频呢?

前段时间&#xff0c;苹果手机的降频事件也是闹的沸沸扬扬&#xff0c;库克也为此进行了公开道歉&#xff0c;各位的吃瓜群众也是看的不亦乐乎&#xff0c;于是&#xff0c;也有不少的小伙伴会问&#xff1a;“为什么安卓手机不会因为电池的老化而降频&#xff1f;”今天&#…

android 5.0.1 libdvm.so,Android逆向进阶—— 脱壳的奥义(基ART模式下的dump)

本文作者&#xff1a;i春秋作家HAI_ZHU000 前言市面上的资料大多都是基于Dalvik模式的dump&#xff0c;所以这此准备搞一个ART模式下的dump。Dalvik模式是Android 4.4及其以下采用的模式&#xff0c;之后到了Android 5.0 之后就是ART模式&#xff0c;关于这两个模式的详细内容&…

android+3.0新加的动画,Android动画片

使用Android两年多了&#xff0c;工作中的动画也动能应付&#xff0c;自认为Android中的动画自己也能用个八九不离十&#xff0c;结果我在学习[Periscope点赞效果](http://www.jianshu.com/p/03fdcfd3ae9c)的时候发现动画的这些高级功能我从没用过、也没见过&#xff0c;静下来…

在线打开html文件,html是什么文件?html文件怎么打开?

html是什么&#xff1f;html即超文本标记语言&#xff0c;现在大多网页都是html的格式。而所谓的html文件是一种超文本文件&#xff0c;其中超文本可以是图片或音乐等非文字元素&#xff0c;使用很广泛。但是很多用户都不太明白html是什么文件&#xff1f;也不清楚html文件要如…