需要学习nginx哪些内容?
- nginx使用,conf的配置
- nignx基础以及源码
- ngixn模块开发
nginx的优势
- 源码是c
- 文档齐全
- 开源社区活跃
- 性能高
一、nignx安装
1、安装步骤
安装pcre(用来正则表达式的)
下载地址 http://www.pcre.org/
安装zlib(用来压缩)
下载地址 http://www.zlib.net/
安装nginx(反向代理)
分别进入目录,执行以下命令就行
./configure make sudo make install
2、查看
在/usr/local/nginx文件夹中,有4个文件
conf 存放配置文件
html 存放网页
logs 存放日志
sbin 运行时可执行程序
3、测试
./sbin/nginx -c conf/nginx.conf
在浏览器中,输入当前主机的ip地址即可
比如我的是192.168.192.128,输入到浏览器即可
在页面中可以看到下图内容(nginx中默认的)
如果出现错误,查看端口是否被占用,如果占用就kill -9 [pid]
netstat -ntlp|grep 80
补充:
查看运行的nginx进程
ps aux|grep nginx
停止nginx
./sbin/nginx -s stop
二、配置conf文件
conf文件中有两类数据,一种是单行的,另外一种是block块
配置
1、worker_processes和worker_connections
worker_processes 4
表示会在主进程中启动4个子进程,也就是说总共会有5个进程,1个master进程,4个worker进程
worker_connections 1024;
表示连接池的最大数量为1024,每一个work进程都有一个连接池,每个连接池最大数量是1024,如果有4个work进程,那么总共最大连接数是4096
worker_processes 4; events { worker_connections 1024; }
测试
启动该配置
在浏览器访问服务器ip,会看到connect refuse
然后查看进程可以看到,1个主进程和4个子进程
查看网络状态,现在没有启动server,所以也就看不到东西
2、http server
在原来基础上,再增加http server相关配置,
表示意思:启动一个http server,监听在端口8888上,
worker_processes 4; events { worker_connections 1024; } http { server { listen 8888; } }
测试
这时候再启动,进入浏览器,输入 192.168.192.128:8888
是可以进入相关界面的,是nginx默认的页面
查看网络状态
第一行中代表 主进程,36384就是主进程的pid
但是第二行、第三行分别对应2个子进程,其中一个子进程是进行http请求,第二个子进程是(keepalive
)发送心跳包的
3、http中多个server
有4个server都去处理http协议
worker_processes 4; events { worker_connections 1024; } http { server { listen 8888; } server { listen 8889; } server { listen 8890; } server { listen 8891; } }
测试
可以发现4个端口都在一个进程(主进程)上面。listen在master进程上面,后面的处理在work进程上面
这时候访问192.169.192.128:8888,还是192.169.192.128:8889,都是nginx默认的界面,因为缺省了html
4、proxy_pass(反向代理)
根据http请求头,找到对应的location
也是11个状态里面的一个 ,NGX_HTTP_POST_REWRITE_PHASE
/前面是ip、端口或者 域名,/后面对应的是资源
下图中,server 8891访问的 html文件是/home/king/share/html
在server 8888中proxy_pass http://192.168.232.137:8891;
重定向到8891。因此访问8888和8891是一样的内容
worker_processes 4; events { worker_connections 1024; } http { server { listen 8888; location / { proxy_pass http://192.168.232.137:8891; } } server { listen 8889; } server { listen 8890; } server { listen 8891; location / { root /home/king/share/html; proxy_pass http://backend; } } }
5、加入负载均衡
假设已经有两个已启动的nginx
通过设置upstream
(把这个流转发出去的意思),,通过当前的主机去访问这两个服务器
proxy_pass http://backend;
去访问当前服务器的时候,就重定向到了指定的网页(upstream中的设置的两个)
weigth为权重,通过这种方式来实现负载均衡,weight可以自己调节
upstream backend { server 192.168.232.128 weight=2; server 192.168.232.132:8888 weight=1; } server { listen 8891; location / { root /home/king/share/html; proxy_pass http://backend; } }
完整配置
#进程数量 worker_processes 4; events { worker_connections 1024; } http { server { listen 8888; location / { proxy_pass http://192.168.232.137:8891; } } server { listen 8889; } server { listen 8890; } upstream backend { server 192.168.232.128 weight=2; server 192.168.232.132:8888 weight=1; } server { listen 8891; location / { root /home/king/share/html; proxy_pass http://backend; } } }
测试
访问192.168.192.128:8891,可以发现,每3次就有2次进入192.168.232.128的页面,每3次就有1次进入192.168.232.132:8888
三、源码阅读
1、worker_processes设置
在nginx.conf中有
ngx_core_commands
中的命令如果找到nignx.conf配置中有话,那么就会执行相应的部分,比如下面"worker_processes"
如果在conf文件中找到,那么就会执行ngx_set_worker_processes
static ngx_command_t ngx_core_commands[] = { ... { ngx_string("worker_processes"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_worker_processes, 0, 0, NULL }, ... };
ngx_set_worker_processes
将解析的参数通过变量ccf->worker_processes
赋值就行了
通过后续设置值,内容就存储到核心配置文件的变量里ngx_core_conf_t *ccf
static char * ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) conf; if (ccf->worker_processes != NGX_CONF_UNSET) { return "is duplicate"; } value = cf->args->elts; if (ngx_strcmp(value[1].data, "auto") == 0) { ccf->worker_processes = ngx_ncpu; return NGX_CONF_OK; } //value[0].data就是 命令本身,value[1].data是命令参数 value[1]这里指的是线程数,是字符串形式,要转成int ccf->worker_processes = ngx_atoi(value[1].data, value[1].len); if (ccf->worker_processes == NGX_ERROR) { return "invalid value"; } return NGX_CONF_OK; }
2、http
同样也有http的命令,这是一个块NGX_CONF_BLOCK
,也就是上图用花括号括起来,称为BLOCK。
通过读取conf中的http配置来启动http server,执行ngx_http_block
static ngx_command_t ngx_http_commands[] = { { ngx_string("http"), NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_http_block, 0, 0, NULL }, ngx_null_command };
ngx_http_block
ngx_http_block
这个启动过程中,包含着tcp server和http协议的处理
在ngx_http_init_phase_handlers
是http状态机启动,phase就是状态的意思,里面有很多枚举状态,如NGX_HTTP_SERVER_REWRITE_PHASE
等
在ngx_http_block
中,有ngx_http_optimize_servers
就是启动tcp server,其中cmcf->ports
是包含端口号的数组。
static char * ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ... //http状态机启动 if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) { return NGX_CONF_ERROR; } //启动tcp server if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) { return NGX_CONF_ERROR; } ... }
如何添加黑白名单?
方法1:tcp连接后:可以在建立连接(三次握手)之后,看它的ip地址,根据黑白名单,来看要不要执行后面的步骤
方法2:处理http头阶段:不对ip作限制,比如对pos或get请求作处理,在处理http头的阶段
方法3:对具体body 表单部分,进行处理,确定该部分是否要发送