网络编程( 六):端口那些事儿 - 知乎专栏  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_serverparameter  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 the defaultparameter 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 parameter SCRIPT_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.htmldoes 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的更多相关文章

  1. nodejs 80端口监听失败及NODE_PATH不起作用的问题

    nodejs做web服务器,打开80时报错:Error: listen EACCES 0.0.0.0:80 80端口监听失败,是因为1024以下的端口需要root权限,需要sudo或su之后执行.但这 ...

  2. asp.net core 多端口监听&日志服务

    1 配置多个端口监听 HostingAbstractionsWebHostBuilderExtensions. public static IWebHostBuilder UseUrls(this I ...

  3. swoole多端口监听

    今天测试swoole写webserver实现多端口监听.记录下爬过的坑:关于tcp协议监听触发不到receive!!!!! 首先上服务端代码 class Http { /** * 服务实例 * @va ...

  4. netty同端口监听tcp和websocket协议

    前言: 软件通信七层结构(osi模型)中由协议套协议最终组成最高级应用层协议(http等等),下三层结构偏向与数据通信,上三层更偏向于数据处理,中间的传输层则是连接上三层与下三层之间的桥梁,每一层都做 ...

  5. 获取运行端口监听的用户身份auth-owner

    获取运行端口监听的用户身份auth-owner   Windows系统提供工作在TCP 113端口的授权服务(Authentication Service),用来判断TCP连接的用户.Nmap的aut ...

  6. 利用 netsh 给 mysql 开启多端口监听

    利用 netsh 给 mysql 开启多端口监听 标题党,实际并不是真的多端口监听,只是端口转发而已. 由于某种特殊原因需要 mysql 服务器多个端口监听. mysql 服务器本身是不支持的,但可以 ...

  7. ZooKeeper(二):多个端口监听的建立逻辑解析

    ZooKeeper 作为优秀的分布系统协调组件,值得一探究竟.它的启动类主要为: 1. 单机版的zk 使用 ZooKeeperServerMain 2. 集群版的zk 使用 QuorumPeerMai ...

  8. Nginx配置IPv6端口监听及务器设置IPV6及Https支持并通过AppStore审核

    一.监听端口 从Nginx 1.3的某个版本起,默认ipv6only是打开的,所以,我们只需要在监听中加入ipv6监听即可,不过推荐都手动加上比较好,代码如下: listen [::]: ipv6on ...

  9. node多项目同时运行,nginx端口监听转发

    在服务器端安装pm2 npm install npm2 -g --save 之后再项目目录下运行 pm2 start app.js 在查看进程,是否已经启动 pm2 list 多个项目,我们只要监听端 ...

随机推荐

  1. 重新 java 对象的 equals 和 hashCode 方法的建议和示例代码

    equals 方法 equals 方法需要满足的规范: 自反性: 对于任意非空引用 x, x.equals(x) 应该返回 true; 对称性: 对于任意引用, 当且仅当 x.equals(y) == ...

  2. <转 >socket穿透代理代码(C++版)

    本文转自 http://blog.csdn.net/bodybo/article/details/7274865 写代码经常会遇到socket要通过代理连接服务器的情况,代理类型通畅有三种:HTTP. ...

  3. git 命令使用速查手册( 个人版)

    1. 克隆远程库 git clone   repository_address 通过 git clone 获取的git库只是远程库中的当前工作分支,如果想获取其它分支信息,可参考下面. 2. 查看远程 ...

  4. C#--I/O流操作文本文件之StreamWrite类和StreamReader类

    使用I/O流操作文本文件时主要用到StreamWrite类和StreamRead类. 1.StreamWrite类 (1)StreamWrite类专门用来处理文本文件的类.能够方便地想文本文件里写入字 ...

  5. 系统管理员应该知道的 20 条 Linux 命令

    如果您的应用程序不工作,或者您希望在寻找更多信息,这 20 个命令将派上用场. 在这个全新的工具和多样化的开发环境井喷的大环境下,任何开发者和工程师都有必要学习一些基本的系统管理命令.特定的命令和工具 ...

  6. Java平台调用.net开发的WebService报错处理

    1.报错:服务器未能识别 HTTP 头 SOAPAction 的值 : 解决办法:.net 开发的WebService文件中(.asmx)增加属性: [SoapDocumentService(Rout ...

  7. EFM8单片机与I2C外设通信

    近期帮同学做一个项目,开发板是EFM8单片机,支持SPI和I2C协议(SMBus).非常久没搞过单片机了,并且条件限制,为了使单片机和外设成功通信.花了一个星期时间.刚開始使用SPI.发现代码逻辑都没 ...

  8. Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

    keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...

  9. linux/Documentation/kobject.txt

    Everything you never wanted to know about kobjects, ksets, and ktypes Greg Kroah-Hartman <gregkh@ ...

  10. wp8页面导向

    一般打开的是MainPage.xaml需要打开另一个页面的时候,用NavigationService.Navigate(uri);当然uri要配置是相对路径还是绝对路径Uri uri = new Ur ...