nginx学习之web服务器(四)
1. 定义一个虚拟服务器
- http {
- server {
- # Server configuration
- }
- }
可以在http {}块里面添加多个server {}块,每一个server {}块代表一个虚拟服务器。
2. 配置虚拟服务器监听的地址
- server {
- listen 127.0.0.1:;
- # The rest of server configuration
- }
这个服务器专门处理从8080端口过来的请求。
如果listen后面没有写端口,而只写了127.0.0.1,那么就监听默认端口80;
如果listen后面没有写地址,而只写了8080,那么就监听所有网卡上的8080端口;
如果没有配置listen指令,那么启动nginx后,它监听的地址就是0.0.0.0:80,表示监听所有网卡的80端口。"80/tcp"这是标准的端口。
3. 配置虚拟服务器的server_name
如果有多个虚拟主机匹配请求中的IP地址和端口,那么nginx会去检查请求头字段Host的值,然后匹配虚拟主机的server_name信息,最后决定使用哪个虚拟主机。
- server {
- listen ;
- server_name example.org www.example.org;
- ...
- }
server_name指令的参数可以是全名,通配符和正则表达式。
通配符:以*号开头的字符串,或以*号结尾的字符串,或开头和结尾都有*号的字符串。
如果多个虚拟主机中的server_name都能匹配Host头,那么按照如下顺序来匹配:
- Exact name
- Longest wildcard starting with an asterisk, such as *.example.org
- Longest wildcard ending with an asterisk, such as mail.*
- First matching regular expression (in order of appearance in the configuration file)
假如Host的信息是www.nicpotato.com,那么会在所有虚拟主机的server_name指令中首先寻找:www.nicpotato.com,然后寻找类似*.nicpotato.com这样的通配符,
再然后寻找类似www.nicpotato.*这样的通配符,最后寻找类似[a-z]{3}.[a-zA-Z]{9}.[a-z]{3}这样的正则表达式。
最先在哪个虚拟主机上匹配上,就使用哪个。
如果Host的值不匹配所有的server_name,那么就选择一台默认的虚拟主机来处理:
一般情况下,写在配置文件最前面的虚拟主机就是默认虚拟主机;但如果显式地在某个虚拟主机的listen指令后加了default_server参数,那么这台虚拟主机就是最后服务的主机。
- server {
- listen default_server;
- ...
- }
4. 配置location
nginx是根据请求的URI来判断:是将请求转发到后端的proxy,还是由自己来提供文件。
定义三个location块:
- 1. send some requests to one proxied server
- 2. send other requests to a different proxied server
- 3. serve the rest of the requests by delivering files from the local file system.
在极少数的情况下,可以在location的里面再嵌套location。
location指令有2种类型的参数,第一种是:路径名形式的前缀字符串;第二种是:正则表达式。
- location /some/path/ {
- ...
- }
对于上面这种路径名形式的前缀字符串(/some/path/),它能匹配任何以/some/path/开头的URI,比如/some/path/document.html,但是无法匹配
/my-site/some/path/document.html,因为/some/path/没有出现在这个URI的前面。
如果是正则表达式的话,必须在前面加上波浪线(~):表示区分大小写;或者加上波浪线星号(~*):表示不区分大小写。
- location ~ \.html? {
- ...
- }
这个配置中,表示它可以匹配任何包含有(.html)和(.htm)字符串的URI。
那么如何寻找一个最匹配URI的location呢?按照两条线:首先是路径名,然后是正则表达式。但正则表达式的优先级要比路径名高,什么意思?
有一个URI是:/data/www/aa.png,我有2个location:
- location /data/www {
- ....
- }
- location ~ \.(png)$ {
- ...
- }
你说应该用哪个location?初看起来,应该用/data/www这个,但实际上要用\.(png)$这个location。因为正则的优先级高。
虽然/data/www作为前缀也能匹配,但我们没有提前下定论,而是先将它存储起来,然后继续往后匹配。看有没有更好的,再来决定使用它否。
以下是选择最佳location的逻辑顺序:
- . 首先让URI与所有的前缀字符串做匹配。--这是第一步
- . 然后是找(=)修饰符,如果匹配了,就立刻停止,不再往后匹配。
- 3.如果最长匹配的前缀字符串前面放置了一个(^~),那么就不再检查正则。也就是说如果前缀表达式匹配了,但后面还有正则表达式没有匹配,由于我的前缀表达式前面加了(^~),所以就
- 不用匹配后面的正则了。
- . 保存那个最长匹配的前缀字符串。
- . 让URI与正则表达式进行匹配。
- . 使用第一个匹配的正则表达式。
- . 如果没有正则匹配,就使用先前存储的那个前缀字符串对应的location。
- location = / {
- ...
- }
这里,location指令的值是:(= /),表示精准匹配URI(/),对于一般的网站,访问(/)的频率很高,所以使用=,这样可以立即停止后面的匹配。
- server {
- location /images/ {
- root /data;
- }
- location / {
- proxy_pass http://www.example.com;
- }
- }
5. 使用变量
系统自带:
$remote_addr
$uri
自定义:
使用set,map,geo指令定义。
6. 返回指定的状态码
- location /wrong/url {
- return ;
- }
- location /permanently/moved/url {
- return http://www.example.com/moved/here;
- }
7. 重写请求里的URI
- location /users/ {
- rewrite ^/users/(.*)$ /show?user=$ break;
- }
rewrite指令的第一个参数是一个正则,用于匹配那些需要重写的URI,第二个参数用于替换匹配到的URI,第三个参数是一个标记,表示后面是否还进行重写,或者重定向。
用()括起来的部分代表一个变量,上面的例子中,只有一个(.*),所以括号里的内容代表$1,如果有多个(),就有$2,$3,$4...
我在server里可以使用一次rewrite,然后继续在location使用rewrite,这个指令是否持续执行,取决于rewrite指令的第三个标记。
- server {
- rewrite ^/user/(.*)$ /show?user=$ break;
- location /show {
- rewrite ^/show?(.*)$ /show/add?$ break;
- }
- location /show/add {
- rewrite ^/show/add?(.*)$ /show/add/new?$ break;
- }
- location /show/add/new {
- ...
- }
- location ~ \.(png)$ {
- ...
- }
- }
上面的例子中,只是为了说明,rewrite指令可以在多个地方使用,上面重写的结果会继续在后面匹配,除非在rewrite指令的后面加上stop的标记。
重写的最后结果还是需要在多个location之间进行匹配。
下面的截图结合了rewrite指令和return指令:
- server {
- ...
- rewrite ^(/download/.*)/media/(.*)\..*$ $/mp3/$.mp3 last;
- rewrite ^(/download/.*)/audio/(.*)\..*$ $/mp3/$.ra last;
- return ;
- ...
- }
一个URI进来,先看第一条重写规则,如果能匹配,就进行重写;如果不能匹配就看第二条规则,如果这两条都不能匹配,就返回403错误。
last指令用于表示:执行完重写指令后,后面的指令都忽略,也就是不再执行。
但是收费版nginx却会继续执行后面的指令,且会将重写后的URI作为新的URI来处理。
有2个标记可以打断rewrite指令:
break:就跟程序中的break一样,表示:停止处理当前上下文中rewrite指令,并且取消对于新URI的匹配。
last:停止执行当前server块或location块中的rewrite指令。收费版的nginx可以对新URI进行匹配,进而可以执行后面location中的rewrite指令。(表示URI还可以再改变)
8. 重写HTTP响应
可以使用sub_filter指令可以替换响应中的内容。比如修改某个字符串为另一个。
这个命令支持变量、链式替换,可以使修改更加复杂。
可以修改为指向某个服务器的绝对链接,而不是指向某个proxy:
- location / {
- sub_filter /blog/ /blog-staging/;
- sub_filter_once off;
- }
修改相应中的协议和主机地址:
- location / {
- sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/';
- sub_filter 'img src="http://127.0.0.1:8080/' 'img src="https://$host/';
- sub_filter_once on;
- }
某个请求是由location /处理的,返回的请求中原先是http://127.0.0.1:8080,替换后变为:https://$host/,这样客户端就去找这个真实的地址https://$host/。
sub_filter_once指令用于表示:sub_filter指令执行的次数。off表示连续执行,on表示只执行一次。
注意:响应中已经被sub_filter指令修改的部分,不再匹配后面的sub_filter指令。
9. 处理错误
给某个状态码配置一个特定的错误页面返回给用户:
- error_page /.html;
如果服务器返回给客户端的状态码为404,就会返回这个404.html页面给用户。这些错误页面可以自定义。
注意:error_page指令不能让404错误立即返回,只有return指令才有这个功能。它只是定义了当错误发生时的处理方式。
错误码可能来自后端服务器,或者是因为服务器找不到用户请求的文件。
- location /old/path.html {
- error_page = http:/example.com/new/path.html;
- }
当用户访问旧路径时,肯定是会返回一个带404错误的响应,但是nginx的处理方式是用301状态码替代404状态码,然后再返回一个新地址,告诉用户去访问这个新地址。
由于用户保存了旧有的访问方式,为了不返回错误,就用这种方式柔性处理,达到很好的用户体验效果。
- server {
- ...
- location /images/ {
- # Set the root directory to search for the file
- root /data/www;
- # Disable logging of errors related to file existence
- open_file_cache_errors off; // 这里的设置表示如果文件没有找到,不记录这条日志信息,因为后面的location正确处理了,所以没有必要记录
- # Make an internal redirect if the file is not found
- error_page = /fetch$uri;
- }
- location /fetch/ {
- proxy_pass http://backend/;
- }
- }
当我们请求/images/aa.png时,它首先到/data/www/images/下去寻找aa.png,如果找不到,按照正常流程,肯定是要返回404错误的,但是这个location里还有一个
error_page指令,告诉nginx如何去处理404错误。
这个例子中,等号后面为空,表示nginx不知道用什么状态码来替换404,所以先保留这一块。然后做一个内部重定向,此时nginx再次去请求/fetch/images/aa.png,这个新的
URI能够匹配下面的location,也就是去请求后台服务器,后台服务器处理后,会返回一个响应,然后返回给用户。(响应中的状态码会替换前面的错误码404)。
注意:本节的重点在于location的匹配顺序以及rewrite指令,同时对于每个功能需要测试,以加深理解。同时这些东西得经常查看,否则很容易遗忘。
nginx学习之web服务器(四)的更多相关文章
- virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续)
virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续) 第一次接触到 linux,不知道linux的确很强大,然后用virtualbox ...
- 你真的了解如何将 Nginx 配置为Web服务器吗
阅读之前,建议先阅读初识 Nginx. 之后,我们来了解一下 Nginx 配置. 抽象来说,将 Nginx 配置为 Web 服务器就是定义处理哪些 URLS 和如何处理这些URLS 对应的请求.具体来 ...
- 详解 Nginx如何配置Web服务器
概述 在高层次上,将NGINX配置作为Web服务器有一些问题需要了解,定义它处理哪些URL以及如何处理这些URL上的资源的HTTP请求. 在较低层次上,配置定义了一组控制对特定域或IP地址的请求的处理 ...
- centos从头学习配置web服务器环境
为了学习linux下配置web服务器环境,于是安装了vmware,准备在虚拟机里面学习web服务器的搭建! 首先是在虚拟机里安装centos,我选择的是32位的centos6.6版本,因为新版本7据说 ...
- ubuntu 12.04 安装 nginx+php+mysql web服务器
Nginx 是一个轻量级,以占用系统资源少,运行效率而成为web服务器的后起之秀,国内现在很多大型网站都以使用nginx,包括腾讯.新浪等大型信息网站,还有淘宝网站使用的是nginx二次开发的web服 ...
- [转] ubuntu 12.04 安装 nginx+php+mysql web服务器
Nginx 是一个轻量级,以占用系统资源少,运行效率而成为web服务器的后起之秀,国内现在很多大型网站都以使用nginx,包括腾讯.新浪等大型信息网站,还有淘宝网站使用的是nginx二次开发的web服 ...
- Apache、Lighttpd、Nginx 三种web服务器对比
简介 1. Apache Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一.Apac ...
- Nginx+Keepalived实现web服务器高可用
1.Nginx 业务背景 现公司需求快速搭建web服务器,对外提供给用户web服务. 需求拆分 需要基于http协议的软件,搭建服务实现 介绍 常见用法: 1) web服务器软件 httpd http ...
- Servlet学习之web服务器Tomcat 详解
Web服务器是什么 Web服务器是指驻留于因特网上某种类型计算机的程序.当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处理该请求并将文件发送到该浏览器上,附带的信息会告诉浏览器如何查看该文 ...
随机推荐
- leetcode题解:Construct Binary Tree from Preorder and Inorder Traversal (根据前序和中序遍历构造二叉树)
题目: Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume t ...
- 配置php扩展redis
环境说明: 系统版本 CentOS 6.9 x86_64 软件版本 nginx-1.12.2 php-5.5.38 yum安装redis3.2.11 php扩展 ...
- Elasticsearch教程(七) elasticsearch Insert 插入数据(Java)
首先我不赞成再采用一些中间件(jar包)来解决和 Elasticsearch 之间的交互,比如 Spring-data-elasticsearch.jar 系列一样,用就得依赖它.而 Elastic ...
- MySQL的查询,子查询,联结查询,联合查询
MySQL的查询,子查询,联结查询,联合查询 一.mysql查询的五种子句where(条件查询).having(筛选).group by(分组).order by(排序).limit(限制结果数) 二 ...
- 标准库Allocator的使用(一)
上一篇我们提到了new运算符以及它的工作步骤,其实无非是把两项工作独立出来: 1.申请原始内存 2.执行构造函数 delete也涉及了两个工作: 1.执行析构函数 2.释放原始内存 其实标准库提供了另 ...
- HTML 5 音频Audio
在HTML5标准网页里面,我们能够运用audio标签来完毕我们对声音的调用及播放. 下面是最常常见到的运用HTML5三种基本格式: 1.最少的代码 <audio src="song.o ...
- Android 虚线切割线
drawable下新建一个虚线的xml.dash_line.xml <? xml version="1.0" encoding="utf-8"?> ...
- JS 导出Table为excel的三种可行方法
[html] view plain copy<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q ...
- ubuntu下设置静态ip
直接修改系统配置文件ubuntu的网络配置文件是:/etc/network/interfacesubuntu命令行修改网络配置方法前面auto eth?,让网卡开机自动挂载. 为网卡配置静态IP地址 ...
- 每日一招:如何才能在A股持续盈利?
证券市场介入门槛低,是众多普通投资者希望实现自己的“中国梦”的首选场所,无论牛市熊市,源源不断的参与者前赴后继.在沪深A股这样一个大众市场,每年都在上演着七亏两平一赚的悲喜剧,赚钱的永远是少数人,但众 ...