C++文件服务器项目—Nginx—3(三)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
网络型负载均衡 NLB,每月750个小时 15LCU
简介: C++文件服务器项目—Nginx—3(三)


前言

  本文重点介绍nginx的安装与配置,实现反向代理和负载均衡。源码地址:gopherWxf git

  本专栏知识点是通过零声教育的线上课学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接 C/C++后台高级服务器课程介绍 详细查看课程的服务。

1. Nginx一些基本概念

1.1 Nginx初步认识

  Nginx介绍:又名engine x,是一个框架,作者是俄罗斯人,开源的框架,C语言编写,淘宝基于nginx开源出了Tengine。

  Nginx能干什么:1. 作为web服务器(-解析http协议)、2. 反向代理服务器(实现web服务器的负载均衡) 、3.邮件服务器(解析邮件相关的协议: pop3/smtp/imap)。

  Nginx的优势:

  • 更快
  • 高峰期(数以万计的并发时)nginx可以比其它web服务器更快的响应请求
  • 高扩展
  • 低耦合设计的模块组成,丰富的第三方模块支持
  • 高可靠
  • 经过大批网站检验
  • www.sina.com.cn
  • www.xunlei.com
  • www.163.com
  • 每个worker进程相对独立, 出错之后可以快速开启新的worker
  • worker进程是在后台干活的进程
  • worker进程的个数是可以控制的
  • 低内存消耗
  • 一般情况下,10000个非活跃的HTTP Keep-Alive连接在nginx中仅消耗 2.5M内存
  • 单机支持10万以上的并发连接
  • 取决于内存,10万远未封顶
  • 热部署
  • master和worker的分离设计,可实现7x24小时不间断服务的前提下升级nginx可执行文件
  • 最自由的BSD许可协议
  • BSD许可协议允许用户免费使用nginx, 修改nginx源码,然后再发布
  • 淘宝: tengine

1.2 正向代理概念理解

  正向代理是位于客户端和原始服务器之间的服务器,为了能够从原始服务器获取请求的内容,客户端需要将请求发送给代理服务器,然后再由代理服务器将请求转发给原始服务器,原始服务器接受到代理服务器的请求并处理,然后将处理好的数据转发给代理服务器,之后再由代理服务器转发发给客户端,完成整个请求过程。

  正向代理的典型用途就是为在防火墙内的局域网客户端提供访问Internet的途径,最具代表性的就是学校的校园网,通常需要账号密码登陆才能访问外网;挂vpn访问github,谷歌等。可以看到,正向代理是为用户服务的,比较偏向于客户端。

1.3 反向代理概念理解

  反向代理方式是指代理原始服务器来接受来自Internet的链接请求,然后将请求转发给内部网络上的原始服务器,并将从原始服务器上得到的结果转发给Internet上请求数据的客户端。那么顾名思义,反向代理就是位于Internet和原始服务器之间的服务器,对于客户端来说就表现为一台服务器,客户端所发送的请求都是直接发送给反向代理服务器,然后由反向代理服务器统一调配。

  举个例子:三个客户端想要同时访问服务器,会给服务器造成一定的压力。

  即使增加了服务器,但是我们也无法限制客户端去访问那一台服务器,这就操作了服务器的请求分配不均匀。

  这个时候,如果能有一个代理出现,客户端先走到代理,再由代理去分配具体走到哪个服务器上,这样,服务器接收到的请求就比较均匀了。

  

  这么中间这个代理就是反向代理服务器!

下面来总结一下反向代理服务器:

  1. 客户端给服务器发送请求, 连接服务器, 用户不知道服务器地址, 只有反向代理服务器的地址是公开的
  2. 那么客户端只能将请求直接发给反向代理服务器
  3. 反向代理服务器将请求转发给后边的web服务器
  4. web服务器 N 台,那么反向代理服务器转发请求会轮询分配请求(当然也可以设置权重,后续介绍)
  5. web服务器收到请求进行处理, 得到结果
  6. web服务器将处理结果发送给反向代理服务器
  7. 反向代理服务器将拿到的结果转发给客户端

2. Nginx的安装与配置

2.1 Nginx与相关依赖库的安装

  对应的安装包已经放在前言的源码链接中,需要的自取。

  Nginx依赖openssl,zlib,pcre这些库。所以首先我们要把这三个库给安装好

Nginx官方地址: http://nginx.org/

Nginx相关依赖:

  • 密码库
  • 使用https进行通信的时候使用
tar -zxvf openssl-1.1.1g.tar.gz 
cd openssl-1.1.1g
./config 
make
make install
ldconfig
  • 数据压缩
  • 安装:
tar -zxvf zlib-1.2.11.tar.gz 
cd zlib-1.2.11
./configure 
make
make install
ldconfig
  • 解析正则表达式
  • 安装
tar -zxvf pcre-8.44.tar.gz 
cd pcre-8.44
ls
./configure 
make
make install
ldconfig

  三个依赖库安装好之后,就可以进行nginx的安装了,这三个库对应的源码安装目录需要根据自己的电脑的库安装包的位置进行指定。

./configure --with-openssl=../openssl-1.1.1g --with-pcre=../pcre-8.44 --with-zlib=../zlib-1.2.11

make
make install
ldconfig

总结:

tar -zxvf nginx-1.16.1.tar.gz 
cd nginx-1.16.1
./configure --with-openssl=../openssl-1.1.1g --with-pcre=../pcre-8.44 --with-zlib=../zlib-1.2.11
make
make install
ldconfig

  来看一些make install 都做了哪些操作,如下图。这里最重要的是记住/usr/local/nginx是nginx安装的根目录,usr/local/nginx/config是nginx的一些配置文件,/usr/local/nginx/sbin是nginx的启动目录。

2.2 Nginx相关的指令

  • Nginx的默认安装目录
# /usr/local/nginx
conf -> 存储配置文件的目录
html -> 默认的存储网站(服务器)静态资源的目录 [图片, html, js, css]
logs -> 存储log日志
sbin -> 启动nginx的可执行程序
  • Nginx可执行程序的路径
# 麻烦的启动方式
root@wxf:/# cd /usr/local/nginx/sbin
root@wxf:/usr/local/nginx/sbin# pwd
/usr/local/nginx/sbin
root@wxf:/usr/local/nginx/sbin# ./nginx 
# 快速启动的方式
# 1. 将/usr/local/nginx/sbin/添加到环境变量PATH中
# 2. /usr/local/nginx/sbin/nginx创建软连接, 放到PATH对应的路径中, 比如: /usr/bin
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
root@wxf:/# nginx
  • 启动Nginx - 需要管理器权限
# 假设软连接已经创建完毕
sudo nginx # 启动
  • 关闭Nginx
# 第一种, 马上关闭
sudo nginx -s stop
# 第二种, 等nginx作为当前操作之后关闭
sudo nginx -s quit
  • 重新加载Nginx
sudo nginx -s reload  # 修改了nginx的配置文件之后, 需要执行该命令
  • 测试是否启动成功
# 1. 命令方式
ps -aux | grep nginx
# 2. 浏览器查看
curl localhost

2.3 Nginx的配置

  1. Nginx配置文件的位置
/usr/local/nginx/conf/
# 需要我们修改的只有
nginx.conf
vi /usr/local/nginx/conf/nginx.conf



  1. Nginx配置文件的组织格式
      
  • http模块->http相关的通信配置
  • server模块 ->每个server对应的是一台web服务器
  • location 模块
  • 处理的是客户端的请求
  • mail模块 ->处理邮件相关的动作
      
      
      
  1. 常用配置项介绍

  注意下面的配置项,是把nginx当作一台web服务器来使用,与后续介绍的反向代理不同。

# user  nobody; # 启动之后的worker进程属于谁,默认就是nobody
- 错误提示: nginx操作xxx文件时候失败, 原因: Permission denied  
- 将nobody -> root
- 
worker_processes  1; # 设置worker进程的个数, 最大 == cpu的核数 (推荐)
error_log  logs/error.log; # 错误日志, /usr/local/nginx目录,这里是相对路径。后面跟日志级别,不写则默认
pid        logs/nginx.pid; # pid文件, 里边是nginx的进程ID
# nginx的事件处理
events {
  use epoll;  # 多路IO复用使用epoll
  worker_connections  1024; # 每个工作的进程的最大连接数
}
# http模块->http相关的通信配置
http{
  # 每个server模块可以看做一台web服务器
  server{
    listen       80;  # web服务器监听的端口, http协议的默认端口
      server_name  localhost; # 对应一个域名, 客户端通过该域名访问该nginx web服务器
      charset utf8;   # 字符串编码
    // location 模块, 处理客户端的请求
      location {指令} {
        #...
    } 
    // location 模块, 处理客户端的请求
      location {指令} {
        #...
    } 
    // location 模块, 处理客户端的请求
      location {指令} {
        #...
    } 
  }
}

2.4 location指令的提取

  上面的配置文件中,location后面跟的都是一个指令,这个指令是什么呢?

  假设现在有一个客户端发送一个请求,http://192.168.10.100:80/login.html 。web服务器收到这个请求之后就需要处理客户端的请求,这个时候我们将协议,ip:端口,尾部的文件名都去掉。剩下的就是服务器要处理的location指令。

# 客户端 (浏览器), 请求:
  http://192.168.10.100:80/login.html
# 服务器处理客户端的请求
  服务器要处理的指令如何从url中提取?
  - 去掉协议: http
  - 去掉IP/域名+端口: 192.168.10.100:80
  - 最后如果是文件名, 去掉该名字: login.html
  - 剩下的: /
  服务器要处理的location指令: 
  location /
  {
        处理动作
  }

  上述说的是静态请求,那么动态请求呢?get带参数怎么办?其实直接把?以及?之后的全部去掉即可

  1. 静态请求:客户端访问服务器的静态网页, 不涉及任何数据的处理, 如下面的URL:
http://localhsot:80/login.html
- 去掉协议: http://
- 去掉IP/域名+端口: localhsot:80
- 最后如果是文件名, 去掉该名字: login.html
- 剩下的: /
- 服务器要处理的location指令: 
  location /
  {
        处理动作
  }
http://localhsot:80/hello/login.html
- 去掉协议: http://
- 去掉IP/域名+端口: localhsot:80
- 最后如果是文件名, 去掉该名字: login.html
- 剩下的: /hello/
- 服务器要处理的location指令: 
  location /hello/
  {
        处理动作
  }
  1. 动态请求:客户端会将数据提交给服务器
# 使用get方式提交数据得到的url
http://localhost/login?user=zhang3&passwd=123456&age=12&sex=man
- http: 协议
- localhost: 域名
- /login: 服务器端要处理的指令
- ? : 连接符, 后边的内容是客户端给服务器提交的数据
- & : 分隔符
- user/zhang3...等:键值对,数据
########################
- 去掉协议
- 去掉域名/IP
- 去掉端口
- 去掉末尾的文件(此处没有)
- 去掉?和它后边的内容
- 剩下的: /login
- 服务器要处理的location指令: 
  location /login
  {
        处理动作
  }
# 如果看到的是请求行, 如何找处理指令?
POST /upload/UploadAction HTTP/1.1
GET /?username=tom&phone=123&email=hello%40qq.com&date=2018-01-01&sex=male&class=3&rule=on HTTP/1.1
1. 找请求行的第二部分
- 如果是post, 处理指令就是请求行的第二部分(/upload/UploadAction)
- 服务器要处理的location指令: 
  location /upload/UploadAction
  {
        处理动作
  }
- 如果是get, 处理指令就是请求行的第二部分, ? 以前的内容(/)
- 服务器要处理的location指令: 
  location /
  {
        处理动作
  }

3. Nginx的使用

3.1 部署静态网页

nginx默认存放静态资源的目录是

/usr/local/nginx/html

自己创建新的目录应该与这个html同级别才行

# 应该在 /usr/local/nginx/
mkdir /usr/local/nginx/mydir

  将源码中写好的html网页yundisk目录放到/usr/local/nginx/目录下。那么这个yundisk目录和html目录现在是同级的。yundisk里面存储的是静态资源。

3.2 访问http://ip:port/login.html

  • login.html放到什么位置?
location的指令是 / 
/ -> 服务器的资源根目录, /usr/local/nginx/root/
root在下面location里面指定
我们现在不使用默认的html文件夹
login.htm-> 放到yundisk中
  • 服务器要处理的动作
# root@wxf:/usr/local/nginx/conf# vi nginx.conf
# 对应这个请求服务器要添加一个location
location 指令(/)
{
    # 找一个静态网页,root需要显示指定
    root yundisk;  # 相对于/usr/local/nginx/来找
    # 客户端的请求如果是一个目录, nginx需要找一默认显示的网页
    index index.html index.htm;
}
# 配置之后重启nginx
sudo nginx -s reload
  • 牢记指令和root的关系
文件存储的真实路径等于下面三个路径的拼接
- 默认路径/usr/local/nginx/
- root
- location 指令
 即 /usr/local/nginx/ + root(yundisk) + location 指令(/)
 -  /usr/local/nginx/yundisk/

3.3 访问http://ip:port/hello/reg.html

  • hello是什么?
  • 目录
  • reg.html放到哪儿?
  • hello目录中
  • 如何添加location
# root@wxf:/usr/local/nginx/conf# vi nginx.conf
- 根据上面的指令提取规则
- 很容易找出指令/hello/
location /hello/
{
    root yundisk;
    index xx.html;
}
  • 牢记指令和root的关系
文件存储的真实路径等于下面三个路径的拼接
- 默认路径/usr/local/nginx/
- root
- location 指令
 即 /usr/local/nginx/ + root(yundisk) + location 指令(/)
 -  /usr/local/nginx/yundisk/hello/

3.4 访问http://ip:port/upload/

  • 直接访问一个目录, 得到一默认网页
  • upload是一个目录, uplaod.html应该再upload目录中
# root@wxf:/usr/local/nginx/conf# vi nginx.conf
location /upload/
{
    root yundisk;
    index upload.html;
}

4. Nginx作为反向代理服务器

4.1 准备实验环境

  1. 需要客户端 - 1个
  • Window中的浏览器作为客户端
  1. 反向代理服务器 -> 1个
  • ubuntu192.168.109.101作为反向代理服务器
  1. web服务器 -> 2个
  • ubuntu192.168.109.102 - 默认主页修改为gopherwxf
  • ubuntu192.168.109.103 - 默认主页修改为wuxufei
  1. 因为反向代理没有绑定域名,所以修改windows的hosts文件,自己加域名
  • 192.168.109.101 ubuntu101to102.com
  • 192.168.109.101 ubuntu101to103.com

4.2 反向代理设置

找101机器上上对应的nginx的配置文件
- vi /usr/local/nginx/conf/nginx.conf
  # 代理几台服务器就需要几个server模块
    # 客户端访问的url: http://192.168.109.100/login.html
    server {
        listen       80;        # 客户端访问反向代理服务器, 代理服务器监听的端口
        server_name  ubuntu101to102.com; # 客户端访问反向代理服务器, 需要一个域名
        location / {
            # 反向代理服务器转发location指令(/), http:// 固定
            proxy_pass http://reverse.proxy1.com;
        }
    }
    # 添加一个代理模块
    upstream reverse.proxy1.com
    {
        server 192.168.109.102:80;
    }
    # 103
    server {
        listen       80;        # 客户端访问反向代理服务器, 代理服务器监听的端口
        # 因为没有配置负载均衡,所以需要不同的域名
        # 来手动指定转发给哪台服务器
        server_name  ubuntu101to103.com; # 客户端访问反向代理服务器, 需要一个域名
        location / {
            # 反向代理服务器转发指令, http:// 固定
            proxy_pass http://reverse.proxy2.com;
        }
    }
    # 添加一个代理模块
    upstream reverse.proxy2.com
    {
        server 192.168.109.103:80;
    }
}

4.3 反向代理总结与测试

5. Nginx实现负载均衡

5.1 分析反向代理的缺陷

  反向代理虽然能代理到不同的web服务器上,但是server_name必须要不同。那有100台呢?要取100个名字吗?而且如果这100台服务器干的都是相同的内容,这么这个server_name就是冗余了。

  负载均衡就是实现入口资源的平均分配,那么这个入口地址server_name就应该是一样的了,而不是一个web服务器对应一个地址,这样是指定了。100台服务器都用同一个server_name,至于最终转发到哪台服务器,交给负载均衡来处理,用户不去关心。

  负载均衡就直接把server_name换成一个唯一的域名即可(相同服务的web服务器用同一个域名,如果有别的服务器处理别的业务,则它们共用另一个)。

  不止server_name是冗余的,proxy_pass也是冗余的,再观察,其实server也是冗余的。我们只需要在upstream里面把web服务器的ip加上去就行了,不需要额外再写server模块。

5.2 负载均衡设置

server {
        listen       80;         # 客户端访问反向代理服务器, 代理服务器监听的端口
        server_name  reverse.proxy.com; # 客户端访问反向代理服务器, 需要一个域名
        location / {
            # 反向代理服务器转发指令, http:// 固定的头
            proxy_pass http://linux.com;
        }
        location /hello/ {
            # 反向代理服务器转发指令, http:// 固定的头
            proxy_pass http://linux.com;
        }
      location /upload/ {
            # 反向代理服务器转发指令, http:// 固定的头
            proxy_pass http://linux.com;
        }
    }
    # 添加一个代理模块
    upstream linux.com
    { # 可以配置权重
      # 1/4 概率 走102
      # 3/4 概率 走103
        #server 192.168.109.102:80 weight=1;
        #server 192.168.109.103:80 weight=3;
        server 192.168.109.102:80;
        server 192.168.109.103:80;
    }
## =====================================
web服务器需要做什么?
# 192.168.109.102
location /
{
    root xxx;
    index xxx;
}
# 如果反向代理配置了location /hello/ 
# 那么web服务器就需要写
location /hello/ 
{
    root xx;
    index xxx;
}
# 如果反向代理配置了location /upload/ 
# 那么web服务器就需要写
location /upload/ 
{
    root xxx;
    index xx;
}
# 192.168.109.103
location /
{
    root xxx;
    index xxx;
}
# 如果反向代理配置了location /hello/ 
# 那么web服务器就需要写
location /hello/ 
{
    root xx;
    index xxx;
}
# 如果反向代理配置了location /upload/ 
# 那么web服务器就需要写
location /upload/ 
{
    root xxx;
    index xx;
}

5.3 负载均衡总结与测试

6. 需要了解的知识

6.1 IP和域名的关系

  1. 什么是域名?
www.baidu.com
www.jd.com
www.taobao.com
  1. 什么是IP地址?
点分十进制的字符串
例如:
192.168.109.101
192.168.109.102
192.168.109.103
  1. 域名和IP地址的关系?
域名绑定IP
一个域名只能绑定一个IP
一个IP地址被多个域名绑定

6.2 URL和URI

  1. 概念:
  • URL(Uniform Resource Locator): 统一资源定位符
  • 表示资源位置的字符串
  • 基本格式: “协议://IP地址/路径和文件名
  • URN(Uniform Resource Name): 统一资源名称
  • P2P下载中使用的磁力链接
  • URI(Uniform Resource Identifier): 统一资源标识符
  • 是一个紧凑的字符串用来标示抽象或物理资源, URL是URI的一种
  • URI可以没有协议, 没有地址(IP/域名)
  • 让URI能成为URL就必须拥有”协议“,”ip or 域名“,e.g.http://orftp://

6.3 DNS解析过程

  1. DNS解析的过程
  1. 在浏览器中输入www.magedu.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
  2. 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
  • Windows和Linux系统都会在本地缓存dns解析的记录,提高速度。
  1. 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
  2. 如果要查询的域名,不由本地DNS服务器区域解析,但该DNS服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
  3. 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(没有设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责 .com域的这台服务器。这台负责 .com域的服务器收到请求后,如果自己无法解析,它就会找一个管理 .com域的下一级DNS服务器地址(magedu.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找magedu.com域服务器,重复上面的动作进行查询,直至找到www.magedu.com主机。
  4. 如果用的是转发模式(设置转发器),此DNS服务器就会把请求转发至上一级ISP DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
  1. 域名解析服务器
  • Pod DNS+:
  • 首选:119.29.29.29
  • 备选:182.254.116.116
  • 114DNS:
  • 首选:114.114.114.114
  • 备选:114.114.114.115
  • 阿里 AliDNS:
  • 首选:223.5.5.5
  • 备选:223.6.6.6
  1. hosts文件
# 存储的是域名和IP的对应关系
-windows目录: "C:\Windows\System32\drivers\etc\hosts"

6.4 http协议报文分析

  1. 请求消息(Request)- 客户端(浏览器)发送给服务器的数据格式

四部分: 请求行, 请求头, 空行, 请求数据

  • 请求行: 说明请求类型, 要访问的资源, 以及使用的http版本
  • 请求头: 说明服务器要使用的附加信息
  • 空行: 空行是必须要有的, 即使没有请求数据
  • 请求数据: 也叫主体, 可以添加任意的其他数据
  • Get方式提交数据

第一行: 请求行

第2-9行: 请求头(键值对)

第10行: 空行

get方式提交数据, 没有第四部分, 提交的数据在请求行的第二部分, 提交的数据会全部显示在地址栏中

GET /?username=tom&phone=123&email=hello%40qq.com&date=2018-01-01&sex=male&class=3&rule=on HTTP/1.1
Host: 192.168.26.52:6789
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh,zh-CN;q=0.9,en;q=0.8
  • Post方式提交数据

第一行: 请求行

第2 -12行: 请求头 (键值对)

第13行: 空行

第14行: 提交的数据

POST / HTTP/1.1
Host: 192.168.26.52:6789
Connection: keep-alive
Content-Length: 84
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh,zh-CN;q=0.9,en;q=0.8
username=tom&phone=123&email=hello%40qq.com&date=2018-01-01&sex=male&class=3&rule=on
  1. 响应消息(Response) -> 服务器给客户端发送的数据
  • 四部分:状态行, 消息报头, 空行, 响应正文
  • 状态行: 包括http协议版本号, 状态码, 状态信息
  • 消息报头: 说明客户端要使用的一些附加信息
  • 空行: 空行是必须要有的
  • 响应正文: 服务器返回给客户端的文本信息

第一行:状态行

第2 -11行: 响应头(消息报头)

第12行: 空行

第13-18行: 服务器给客户端回复的数据

HTTP/1.1 200 Ok
Server: micro_httpd
Date: Fri, 18 Jul 2014 14:34:26 GMT
/* 告诉浏览器发送的数据是什么类型 */
Content-Type: text/plain; charset=iso-8859-1 (必选项)
/* 发送的数据的长度 */
Content-Length: 32  
Location:url
Content-Language: zh-CN
Last-Modified: Fri, 18 Jul 2014 08:36:36 GMT
Connection: close
#include <stdio.h>
int main(void)
{
    printf("hello world!\n");
    return 0;
}
  1. http状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

  • 1xx:指示信息–表示请求已接收,继续处理
  • 2xx:成功–表示请求已被成功接收、理解、接受
  • 3xx:重定向–要完成请求必须进行更进一步的操作
  • 4xx:客户端错误–请求有语法错误或请求无法实现
  • 5xx:服务器端错误–服务器未能实现合法的请求

7. Location语法

  1. 语法规则
# [=|~|~*|^~] [...] 中括号是可选项
   location [=|~|~*|^~] /uri/ 
   { 
   }
   正则表达式中的特殊字符:
   - . () {} [] * + ?
  1. Location优先级说明
  • 在nginx的location和配置中location的顺序没有太大关系。
  • 与location表达式的类型有关。
  • 相同类型的表达式,字符串长的会优先匹配
  1. location表达式类型
  • ~ 表示执行一个正则匹配,区分大小写
  • ~* 表示执行一个正则匹配,区分大小写
  • ^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location。
  • = 进行普通字符精确匹配。也就是完全匹配。
  1. 匹配模式及优先级顺序(高 -> 低):
location = /uri =开头表示精确匹配,只有完全匹配上才能生效。 一旦匹配成功,则不再查找其他匹配项。
location ^~ /uri ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 一旦匹配成功,则不再查找其他匹配项。 需要考虑先后顺序, 如: http://localhost/helloworld/test/a.html
location ~ pattern location ~* pattern ~ 开头表示区分大小写的正则匹配。 ~*开头表示不区分大小写的正则匹配。
location /uri 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后。
location / 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default。

指令是:/ -> configuration A
指令是:/index.html -> configuration B
指令是:/documents/document.html -> configuration C
指令是:/images/1.gif -> configuration  D
指令是:/documents/1.jpg ->      configuration  E
目录
相关文章
|
22天前
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
24天前
|
存储 编解码 应用服务中间件
使用Nginx搭建流媒体服务器
本文介绍了流媒体服务器的特性及各种流媒体传输协议的适用场景,并详细阐述了使用 nginx-http-flv-module 扩展Nginx作为流媒体服务器的详细步骤,并提供了在VLC,flv.js,hls.js下的流媒体拉流播放示例。
110 1
|
1月前
|
负载均衡 监控 应用服务中间件
配置Nginx反向代理时如何指定后端服务器的权重?
配置Nginx反向代理时如何指定后端服务器的权重?
63 4
WK
|
1月前
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
86 1
|
2月前
|
关系型数据库 MySQL Linux
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
467 3
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
571 3
|
2月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
386 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
3月前
|
C++
【C++案例】一个项目掌握C++基础-通讯录管理系统
这篇文章通过一个通讯录管理系统的C++项目案例,详细介绍了如何使用C++实现添加、显示、删除、查找、修改和清空联系人等功能。
57 3
|
2月前
|
前端开发 Java Shell
后端项目打包上传服务器部署运行记录
后端项目打包上传服务器部署运行记录
55 0