感谢尚硅谷

  • https://www.bilibili.com/video/bv1zJ411w7SV/

nginx简介

nginx是什么

nginx:高性能的HTTP和反向代理的web服务器,是一个俄罗斯人研发的软件。

nginx在中国有着很多的使用:百度,京东,新浪,网易,腾讯,淘宝,…

nginx体型小,但是性能高,十分注重效率,最大能承受高达五万个并发数

反向代理

1、正向代理

正向代理:假如我们想要访问google,我们是直接访问不了的,我们应该访问一个能访问google的代理服务器,然后代理服务器去访问google

也就是说依赖于代理服务器去访问另一个资源。这个过程就叫做正向代理

客户端自己手动做配置,这也是正向代理的一个特点。

nginx不仅可以做返现代理,还可以做正向代理


2、反向代理

反向代理,其实客户端不知道你有没有做反向代理,客户端并不需要去做配置。

许多客户端都访问一个网址,比如百度的服务器。

而我们首先不是访问的百度的服务器,而是反向代理服务器,然后由反向代理服务器分发到不同服务器上。

我们可以看到的是反向代理服务器的暴露,而不是最后到的服务器。

负载均衡

随着信息的不断增加,访问量不断增长,服务器就会出现一些问题,性能会出现瓶颈。我们有两种解决方式

1、提高服务器配置

2、多找几台服务器,一块进行承载访问

我们的第二种方法就是将请求分发到不同服务器,让原来访问量爆炸的一台服务器承受改为多台服务器承受,这样服务器的压力小了,客户的体验也好了

负载均衡的意思就是,将爆炸的数据分摊到这多台服务器上

动静分离

1、动态资源:不同用户访问,结果可能不同

2、静态资源:不同用户访问,结果一定相同

我们的动静分离,就是将动态资源和静态资源分开,用不同的服务器存放,然后通过nginx分发

nginx快速入门

安装

使用源码安装

1、安装环境

  • yum -y install make zlib zlib-devel gcc gcc-c++ libtool openssl openssl-devel

2、使用wget下载源码包

  • wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
  • wget http://nginx.org/download/nginx-1.12.2.tar.gz

3、安装pcre

1、解压pcre源码包

  • tar -xvf pcre-8.35.tar.gz

2、进入到pcre解压缩包 3、执行命令./configure 4、执行命令make && make install 5、查看版本,确认安装成功pcre-config --version

4、安装nginx

1、解压nginx压缩包 2、进入到nginx压缩包 3、执行./configure 4、执行make && make install 5、查看版本:/usr/local/webserver/nginx/sbin/nginx -v

使用yum安装

使用docker安装

  • 使用docker安装,至于docker怎么安装去看docker

Nginx - 图1 Nginx - 图2

不使用docker的话,可以使用源码安装,或者yum安装

优缺点 1、源码安装

就像视频中的,先把包下载下来,然后进行手动安装 这样的好处是:因为是在自己系统上进行的编译,性能更好

2、yum安装

好处是:简单方便,不易出错 顺便说一句,docker官方的nginx镜像是使用的yum安装

安装路径 1、源码安装

会将文件都放在一个目录下,这个目录是/usr/local/nginx/ 想要卸载直接删除这个目录即可

2、yum安装

会将文件放在不同的目录下,可以使用rpm -ql nginx来查看安装路径 想要卸载只能通过命令来卸载:rpm -e nginx 假如没有rpm的命令 1、apt-get update 2、apt-get install rpm 此图来自:https://blog.csdn.net/u013705128/article/details/83655630 Nginx - 图3

常用命令

1、源码安装

执行/usr/local/nginx/sbin目录下的nginx可执行程序

  • /usr/local/nginx/sbin:启动
  • /usr/local/nginx/sbin -s stop:关闭
  • /usr/local/nginx/sbin -s reload:更改配置文件之后的热部署

2、yum安装

使用系统服务命令来启动和停止

  • service nginx start:启动
  • service nginx stop:停止
  • service nginx restart:重启

配置文件

1、源码安装位置

/usr/local/nginx/conf/nginx.conf

2、yum安装位置

/etc/nginx/nginx.conf

3、即使不确定,也可以使用命令nginx -t来查看配置文件的位置


我们将这个配置文件拷贝到主机上

docker cp 3516d6423546:/etc/nginx /etc/nginx Nginx - 图4 我曾经想要使用容器数据卷来挂载,但是会出现docker闪退的情况 于是我使用交互方式进去,之后发现/etc/nginx什么文件都没有了 解决这问题也很简单,只需要先启动一个容器,将配置文件先拷贝到主机上,然后重启另一个容器挂载数据卷即可


  • nginx.conf
  1. # 全局块
  2. # 主要会设置一些影响nginx服务整体运行的配置指令
  3. # 主要包括:1、配置运行nginx服务器的用户(组);2、允许生成的worker processes数(处理并发的数量);3、进程pid存放路径;4、日志存放路径;5、类型和配置文件的引入
  4. user nginx;
  5. worker_processes 1;
  6. # error_log:错误日志的存放路径
  7. error_log /var/log/nginx/error.log warn;
  8. pid /var/run/nginx.pid;
  9. # ---------------------------------------------------------------------
  10. # events块
  11. # 主要配置nginx服务器与用户的网络连接
  12. # 常用包括:1、是否开启对多worker_processes下的网络连接进行序列化;2、是否允许同时接收多个网络连接;3、选取哪种事件驱动模型来处理连接请求;4、每个worker_processes可以同时支持的最大连接数
  13. # worker_connections 1024:这个意思就是nginx的worker_processes的最大连接数是1024
  14. events {
  15. worker_connections 1024;
  16. }
  17. # ---------------------------------------------------------------------
  18. # http块
  19. # nginx中配置最频繁的部分
  20. # http块又包括两个内容:http全局快和server块
  21. http {
  22. # include是个主模块指令,作用是包含路径中的文件
  23. include /etc/nginx/mime.types;
  24. # http块的核心指令
  25. default_type application/octet-stream;
  26. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  27. '$status $body_bytes_sent "$http_referer" '
  28. '"$http_user_agent" "$http_x_forwarded_for"';
  29. access_log /var/log/nginx/access.log main;
  30. sendfile on;
  31. #tcp_nopush on;
  32. keepalive_timeout 65;
  33. #gzip on;
  34. include /etc/nginx/conf.d/*.conf;
  35. }

我们可以看到,对于http块的server部分只有一个include语句,这是因为引入了这个路径下的文件,http块会拿出来讲


  • /etc.nginx/conf.d/default.conf:那个目录下只有这一个文件
  1. server {
  2. # 监听的端口号
  3. listen 80;
  4. # 监听的端口号的ipv6版本,如果需要改变端口号,这里也需要该
  5. listen [::]:80;
  6. # 主机名称,因为是本地所以是localhost
  7. server_name localhost;
  8. #charset koi8-r;
  9. #access_log /var/log/nginx/host.access.log main;
  10. # 路径中假如是个斜杠,那么进行请求的跳转
  11. location / {
  12. root /usr/share/nginx/html;
  13. index index.html index.htm;
  14. }
  15. #error_page 404 /404.html;
  16. # redirect server error pages to the static page /50x.html
  17. #
  18. error_page 500 502 503 504 /50x.html;
  19. location = /50x.html {
  20. root /usr/share/nginx/html;
  21. }
  22. # proxy the PHP scripts to Apache listening on 127.0.0.1:80
  23. #
  24. #location ~ \.php$ {
  25. # proxy_pass http://127.0.0.1;
  26. #}
  27. # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  28. #
  29. #location ~ \.php$ {
  30. # root html;
  31. # fastcgi_pass 127.0.0.1:9000;
  32. # fastcgi_index index.php;
  33. # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
  34. # include fastcgi_params;
  35. #}
  36. # deny access to .htaccess files, if Apache's document root
  37. # concurs with nginx's one
  38. #
  39. #location ~ /\.ht {
  40. # deny all;
  41. #}
  42. }

这里先看一下端口号,主机名,location的基本配置,等会有更详细的

nginx配置实例

实现反向代理

反向代理案例一

配置反向代理,只需要一句话

Nginx - 图5

我们可以看到,nginx监听的端口号是80,监听的主机是localhost 在这里,只要访问localhost:80端口,就会跳转到http://howling.top:8081 为了这个我又开了一个docker容器,是8081端口,这样的话,只要访问Nginx就会转发到http://howling.top:8081去 那么因为我是使用的docker部署的,在外部的端口是http://howling.top:80 所以在外界看来,就是访问howling.top会转发到howling.top:8081

Nginx - 图6

注意点是:格式一定要正确,协议://网址:端口号 不能缺少


反向代理案例二

以上是一个快速入门的例子,可以看到非常简单,下面我们来看一下访问不同的路径如何跳转到不同的页面

我们现在有两个tomcat,分别是howling.top:8080和howling.top:8081

现在我们要求的是:只要请求路径中有/edu则跳转到8081,有/vod则跳转到8080

我们只需要配置一下配置文件

  1. server {
  2. listen 80;
  3. listen [::]:80;
  4. server_name localhost;
  5. location / {
  6. root /usr/share/nginx/html;
  7. proxy_pass http://howling.top:8081;
  8. index index.html index.htm;
  9. }
  10. error_page 500 502 503 504 /50x.html;
  11. location = /50x.html {
  12. root /usr/share/nginx/html;
  13. }
  14. }
  15. server {
  16. listen 8088;
  17. server_name localhost;
  18. location ~ /edu/ {
  19. proxy_pass http://howling.top:8081;
  20. }
  21. location ~ /vod/ {
  22. proxy_pass http://howling.top:8080;
  23. }
  24. }

可以看到,我们又写了一个server,监听的是9001端口 其中有一个 ~ /edu/的形式,~表明了这是一个正则表达式,/edu/表示只要路径中包含edu就执行下面的命令 proxy_pass就是转发的路径 也就是说,假如你要请求howling.top:8088/edu/index.html,那么将会转发到howling.top:8081/edu/index.html 这样写可以,但是我忽略了一个严重的问题,就是:我是在docker下运行的,对外面没有开放8088端口,所以我又把下面的server删了,在80端口上填了两个location


接下来我们分别在两个webapps下新建文件夹edu和vod,然后新建index.html,然后分别访问

Nginx - 图7

location介绍

1、正则表达式介绍

location [= | ~ | ~ | ^~]: 1、=:表示uri不含正则表达式,要求请求字符和uri严格匹配,如果匹配成功,就停止继续向下搜索并立刻处理该请求 2、~:用于表示包含正则表达式,并且区分大小写 3、~:用于表示包含正则表达式,不区分大小写 4、^~:表示uri不含正则表达式,要求nginx找到和uri和字符串匹配度最高的location后,立刻用此location请求而不再使用location块中的正则uri和请求字符串做匹配 5、$表示正则表达式结尾,如果要表示特殊符号比如.之类的,要用\来进行转义

2、正则表达式例子

  1. location ~ /edu/ {} # 当路径中包含edu时,进行下面的操作
  2. location ~ /(edu|dev)/ {} # 当路径中包含edu或者dev时,进行下面的操作
  3. location ~ \.gif$ {}# 当路径以.gif结尾时,进行下面的操作

3、location中的参数列表

  1. location ~ /edu/{
  2. root /www/; # 表示包含edu的网址的资源全部都在linux根目录下的www文件夹下
  3. expires 30d; # 表示静态资源的过期时间,30天
  4. }

实现负载均衡

1、刚才我们已经有了8080和8081,并且分别在这两个有index.html

2、准备nginx的配置

  1. http{
  2. ...
  3. # upstream 名字,名字随便起
  4. upstream myserver{
  5. # server 负载均衡服务器1; server 负载均衡服务器2; ...
  6. server howling.top:8080 weight=1;
  7. server howling.top:8081 weight=1;
  8. }
  9. ...
  10. # server的listen和server_name看情况改变
  11. server{
  12. location / {
  13. ...
  14. # location里面的 proxy_pass 改为upstream的名字
  15. proxy_pass http://myserver;
  16. proxy_connect_timeout 10;
  17. }
  18. }
  19. }

注意了,http包含着upstream和server,如果是两个文件包含关系的话就需要注意了 Nginx - 图8 还需要注意,在myserver中不需要写协议,在location中写就行

根据以上我写的内容,只要访问的是80端口的index页面(不包括edu,因为edu没有配置负载均衡),那么就会在两个tomcat之间进行负载均衡

Nginx - 图9 这里需要注意,谷歌浏览器F5刷新是不能够负载均衡的,因为它会记录缓存 有三个方式可以解决: 1、换浏览器 2、谷歌浏览器需要手动点击url链接回车才会负载均衡 3、谷歌浏览器在控制台disable cache

3、Nginx的负载均衡策略

1、轮询(默认),按照时间顺序分配,假如有服务器down了,自动剔除,在编写服务器列表的时候没有weight=xxx

  1. upstream myserver{
  2. server howling.top:8080;
  3. server howling.top:8081;
  4. }

2、weight权重,默认为1,权重越高分配的客户端越多,也就是我们刚才的 `server howling.top:8080

  1. upstream myserver{
  2. server howling.top:8080 weight=1;
  3. server howling.top:8081 weight=1;
  4. }

3、ip_hash:直接在配置文件中添加ip_hash,每个请求按照访问ip的hash分配,固定访问一个服务器,可以解决session问题,当然现在很少用了,现在session都很少用了,都用jwt

  1. upstream myserver{
  2. ip_hash;
  3. server howling.top:8080;
  4. server howling.top:8081;
  5. }

4、fair:根据响应时间分配,看谁的时间短就给谁分配

  1. upstream myserver{
  2. server howling.top:8080;
  3. server howling.top:8081;
  4. fair;
  5. }

实现动静分离

严格来说不是把动态页面和静态页面分开,而是把动态请求和静态请求分开

动静分离的本质其实还是反向代理

动静分离现在的视线角度大致分两种

1、将静态页面和资源放到单独的服务器上,成立单独的域名,也是主流方案,这样得前后端真分离

2、将动态和静态混合发布,通过nginx分开

1、通过location制定不同的后缀名进行不同的请求转发 2、通过expires参数设置,设定浏览器缓存过期时间,减少与服务期之前的请求和流量。

通过Expires定义是无需去服务器验证,直接让浏览器确认是否过期,所以不会产生额外的流量。 但是还是会向服务器对比该文件最后的更新时间有没有变化,如果没有变化直接返回304代表浏览器缓存;假如有变化返回200从服务器重新下载。 这种方式不适合经常变动的资源

现在回过头来,再看location的讲解,是不是就清楚多了

我们配置动静分离,其实现在大部分做法就是让nginx去找静态资源,然后让tomcat去找动态资源

当然了,让tomcat去找静态资源和动态资源也无所谓。

3、配置动静分离

  1. location /www/{
  2. root /data/;
  3. index index.html index.htm;
  4. }

我们将所有的静态资源全部都放到了linux的/data/目录下,在网址上反映的是:只要访问的是www,就访问的是静态资源 静态资源就根据nginx的root去找


Nginx的Windows版

只需要去官网下载即可,但是nginx的windows版本有几个问题需要注意

1、下载下来是一个压缩包,随便解压即可,但是要注意,不要解压到中文目录下

2、启动nginx的时候进程上会有两个nginx的进程,这是nginx的一个特点:多路复用

3、关闭nginx需要在命令行中使用nginx.exe -s stop