多进程端口监听 How nginx processes a request Server names
网络编程( 六):端口那些事儿 - 知乎专栏 https://zhuanlan.zhihu.com/p/20365900
不停服务reload、restart
多进程端口监听
我们都有一个计算机网络的常识:不同的进程不能使用同一端口。
如果一个端口正在被使用,无论是TIME_WAIT、CLOSE_WAIT、还是ESTABLISHED状态。 这个端口都不能被复用,这里面自然也是包括不能被用来LISTEN(监听)。
但这件事也不是绝对的,之前跟大家讲进程的创建过程提到过一件事: 当进程调用fork(2)系统调用的时候,会发生一系列资源的复制,其中就包括句柄。 所以,在调用fork(2)之前,打开任何文件,监听端口产生的句柄也将会被复制。
通过这种方式,我们就可以达成"多进程端口监听"。
但,这又有什么用呢?
我们大名鼎鼎的Nginx就是通过这种手法让多个进程同时监听在HTTP的服务端口上的, 这么做的好处就在于,当外部请求到达,Linux内核会保证多个进程只会有一个accept(2) 成功,这种情况下此端口的服务可用性就和单个进程存在与否无关。 Nginx正是利用这一点达成“不停服务reload、restart”的。
How nginx processes a request http://nginx.org/en/docs/http/request_processing.html
【
配置文件中的server_name去匹配请求头的Host字段,去路由至该Host-server_name的文件目录,本机或异机;
server_name为空字符串,去匹配请求头中缺失Host的情况;
】
How nginx processes a request
How to prevent processing requests with undefined server names Mixed name-based and IP-based virtual servers A simple PHP site configuration |
Name-based virtual servers
nginx first decides which server should process the request. Let’s start with a simple configuration where all three virtual servers listen on port *:80:
- server {
- listen 80;
- server_name example.org www.example.org;
- ...
- }
- server {
- listen 80;
- server_name example.net www.example.net;
- ...
- }
- server {
- listen 80;
- server_name example.com www.example.com;
- ...
- }
In this configuration nginx tests only the request’s header field “Host” to determine which server the request should be routed to. If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port. In the configuration above, the default server is the first one — which is nginx’s standard default behaviour. It can also be set explicitly which server should be default, with the default_server
parameter in the listen directive:
- server {
- listen 80 default_server;
- server_name example.net www.example.net;
- ...
- }
The
default_server
parameter has been available since version 0.8.21. In earlier versions thedefault
parameter should be used instead.
Note that the default server is a property of the listen port and not of the server name. More about this later.
How to prevent processing requests with undefined server names
If requests without the “Host” header field should not be allowed, a server that just drops the requests can be defined:
- server {
- listen 80;
- server_name "";
- return 444;
- }
Here, the server name is set to an empty string that will match requests without the “Host” header field, and a special nginx’s non-standard code 444 is returned that closes the connection.
Since version 0.8.48, this is the default setting for the server name, so the
server_name ""
can be omitted. In earlier versions, the machine’s hostname was used as a default server name.
Mixed name-based and IP-based virtual servers
Let’s look at a more complex configuration where some virtual servers listen on different addresses:
- server {
- listen 192.168.1.1:80;
- server_name example.org www.example.org;
- ...
- }
- server {
- listen 192.168.1.1:80;
- server_name example.net www.example.net;
- ...
- }
- server {
- listen 192.168.1.2:80;
- server_name example.com www.example.com;
- ...
- }
In this configuration, nginx first tests the IP address and port of the request against the listendirectives of the server blocks. It then tests the “Host” header field of the request against theserver_name entries of the server blocks that matched the IP address and port. If the server name is not found, the request will be processed by the default server. For example, a request for www.example.com
received on the 192.168.1.1:80 port will be handled by the default server of the 192.168.1.1:80 port, i.e., by the first server, since there is no www.example.com
defined for this port.
As already stated, a default server is a property of the listen port, and different default servers may be defined for different ports:
- server {
- listen 192.168.1.1:80;
- server_name example.org www.example.org;
- ...
- }
- server {
- listen 192.168.1.1:80 default_server;
- server_name example.net www.example.net;
- ...
- }
- server {
- listen 192.168.1.2:80 default_server;
- server_name example.com www.example.com;
- ...
- }
A simple PHP site configuration
Now let’s look at how nginx chooses a location to process a request for a typical, simple PHP site:
- server {
- listen 80;
- server_name example.org www.example.org;
- root /data/www;
- location / {
- index index.html index.php;
- }
- location ~* \.(gif|jpg|png)$ {
- expires 30d;
- }
- location ~ \.php$ {
- fastcgi_pass localhost:9000;
- fastcgi_param SCRIPT_FILENAME
- $document_root$fastcgi_script_name;
- include fastcgi_params;
- }
- }
nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. In the configuration above the only prefix location is “/
” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier.
Note that locations of all types test only a URI part of request line without arguments. This is done because arguments in the query string may be given in several ways, for example:
- /index.php?user=john&page=1
- /index.php?page=1&user=john
Besides, anyone may request anything in the query string:
- /index.php?page=1&something+else&user=john
Now let’s look at how requests would be processed in the configuration above:
- A request “
/logo.gif
” is matched by the prefix location “/
” first and then by the regular expression “\.(gif|jpg|png)$
”, therefore, it is handled by the latter location. Using the directive “root /data/www
” the request is mapped to the file/data/www/logo.gif
, and the file is sent to the client. - A request “
/index.php
” is also matched by the prefix location “/
” first and then by the regular expression “\.(php)$
”. Therefore, it is handled by the latter location and the request is passed to a FastCGI server listening on localhost:9000. The fastcgi_param directive sets the FastCGI parameterSCRIPT_FILENAME
to “/data/www/index.php
”, and the FastCGI server executes the file. The variable$document_root
is equal to the value of the root directive and the variable$fastcgi_script_name
is equal to the request URI, i.e. “/index.php
”. - A request “
/about.html
” is matched by the prefix location “/
” only, therefore, it is handled in this location. Using the directive “root /data/www
” the request is mapped to the file/data/www/about.html
, and the file is sent to the client. - Handling a request “
/
” is more complex. It is matched by the prefix location “/
” only, therefore, it is handled by this location. Then the index directive tests for the existence of index files according to its parameters and the “root /data/www
” directive. If the file/data/www/index.html
does not exist, and the file/data/www/index.php
exists, then the directive does an internal redirect to “/index.php
”, and nginx searches the locations again as if the request had been sent by a client. As we saw before, the redirected request will eventually be handled by the FastCGI server.
written by Igor Sysoev edited by Brian Mercer |
多进程端口监听 How nginx processes a request Server names的更多相关文章
- nodejs 80端口监听失败及NODE_PATH不起作用的问题
nodejs做web服务器,打开80时报错:Error: listen EACCES 0.0.0.0:80 80端口监听失败,是因为1024以下的端口需要root权限,需要sudo或su之后执行.但这 ...
- asp.net core 多端口监听&日志服务
1 配置多个端口监听 HostingAbstractionsWebHostBuilderExtensions. public static IWebHostBuilder UseUrls(this I ...
- swoole多端口监听
今天测试swoole写webserver实现多端口监听.记录下爬过的坑:关于tcp协议监听触发不到receive!!!!! 首先上服务端代码 class Http { /** * 服务实例 * @va ...
- netty同端口监听tcp和websocket协议
前言: 软件通信七层结构(osi模型)中由协议套协议最终组成最高级应用层协议(http等等),下三层结构偏向与数据通信,上三层更偏向于数据处理,中间的传输层则是连接上三层与下三层之间的桥梁,每一层都做 ...
- 获取运行端口监听的用户身份auth-owner
获取运行端口监听的用户身份auth-owner Windows系统提供工作在TCP 113端口的授权服务(Authentication Service),用来判断TCP连接的用户.Nmap的aut ...
- 利用 netsh 给 mysql 开启多端口监听
利用 netsh 给 mysql 开启多端口监听 标题党,实际并不是真的多端口监听,只是端口转发而已. 由于某种特殊原因需要 mysql 服务器多个端口监听. mysql 服务器本身是不支持的,但可以 ...
- ZooKeeper(二):多个端口监听的建立逻辑解析
ZooKeeper 作为优秀的分布系统协调组件,值得一探究竟.它的启动类主要为: 1. 单机版的zk 使用 ZooKeeperServerMain 2. 集群版的zk 使用 QuorumPeerMai ...
- Nginx配置IPv6端口监听及务器设置IPV6及Https支持并通过AppStore审核
一.监听端口 从Nginx 1.3的某个版本起,默认ipv6only是打开的,所以,我们只需要在监听中加入ipv6监听即可,不过推荐都手动加上比较好,代码如下: listen [::]: ipv6on ...
- node多项目同时运行,nginx端口监听转发
在服务器端安装pm2 npm install npm2 -g --save 之后再项目目录下运行 pm2 start app.js 在查看进程,是否已经启动 pm2 list 多个项目,我们只要监听端 ...
随机推荐
- Keep-Alive简介及在Tomcat中配置
Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接.市场上 的大部分Web服务器,包括iPlanet.IIS和 ...
- 树莓派之OLED12864视频播放—BadApple
代码地址如下:http://www.demodashi.com/demo/13218.html 概述 本篇教程讲述了使用树莓派驱动OLED12864液晶屏,并在液晶屏上播放动画和视频. 硬件平台 树莓 ...
- C语言-编译
编译的时候只是需要知道函数原型(即只需要 xxx.h 文件即可), 不需要知道函数定义, 在链接阶段可以把 xxx.c 生成的 xxx.o 链接进去, 以知道函数定义 编译时,编译器需要的是语法的正确 ...
- oracle 创建一个用户,并且设定只能访问指定的对象
出处:http://www.cnblogs.com/BetterWF/archive/2012/07/03/2574416.html 今天在开发接口时候,需要给接口开发公司提供一个ORACLE 用户, ...
- <转>程序员的心理疾病
注:本文转自大神王垠的博客 原文出处 http://www.yinwang.org/blog-cn/2014/02/09/programmer-mental/ 说实话,虽然似乎为之奋斗了十多年,在真正 ...
- netstat命令初探
Proto :网络传输协议,主要为tcp和udp Local Address :本地的ip:port Foreign Address:远程主机的ip:port State :连线状态,主要有监听( L ...
- Webpack 的 HtmlWebpackPlugin 如何控制某个 chunks 的 inject 位置?
https://segmentfault.com/q/1010000006591131 通过修改 HtmlWebpackPlugin 源码实现了 修改后的配置: new HtmlWebpackPlug ...
- UML类图详解_关联关系_多对多
在关联关系中,很多情况下我们的多重性并不是多对一或者一对多的,而是多对多的. 不过因为我们要考虑里面的导航性,如果直接搞的话就是需要去维护两群对象之间多对多的互指链接,这就十分繁杂且易错.那么我们怎么 ...
- Spring @Transactional
在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例外(RunTimeExcep ...
- Vim使用技巧(3) -- 可视化模式技巧 【持续更新】
快捷键 Esc / Ctrl + [ / v //切换到普通模式 o //切换高亮选区的光标活动端 y //将光标选中的内容复制到寄存器中 u //将光标选中的字母全部改成小写字母 U //将光标选中 ...