Nginx学习随笔

一、Nginx介绍

引言

一个项目搭建

Nginx学习随笔插图

但在高并发的环境下,服务器接受不了太多的请求,就会导致宕机。所以会部署多个服务器来处理请求,但是又会遇到如下问题:

问题1:客户端到底要将请求发送给哪台服务器?

问题2:如果所有客户端都将请求发送给了服务器1,怎么办?

问题3:客户端可能会请求动态资源 或者 静态资源,如果只请求静态资源,那么还让服务器处理是否占用资源了?

服务器搭建集群后

服务器搭建集群后

Nginx学习随笔插图1

为什么要学习Nginx?它有效的解决了上面3个问题。

问题1:Nginx会接受用户的请求,再做转发,所以客户端只需要向Nginx发起请求。

问题2:Nginx通过算法指定将请求发送到哪个服务器上,比如:轮循算法 就是按顺序1 2 1 2。

问题3:Nginx可以实现动静分离,动态资源请求交给服务器,静态资源自身就可以处理。

服务器搭建集群,并用Nginx做反向代理

Nginx学习随笔插图2

Nginx介绍

Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

特点:

  • 能够支持 50,000 个并发连接数的响应。(tomcat默认支持150个并发量)
  • 稳定性极强,可以 24小时不间断的工作。
  • 占用内存小
  • Nginx提供了非常丰富的配置实例,学习成本低。

二、Nginx的安装

安装Nginx

# 创建维护 nginx服务的目录 [root@zxh opt]# mkdir docker_nginx [root@zxh opt]# cd docker_nginx/ [root@zxh docker_nginx]# vim docker-compose.yml # 编写 docker-compose.yml 编排文件 version: "3" services: nginx: restart: always image: daocloud.io/library/nginx:latest container_name: nginx ports: - 80:80 [root@zxh docker_nginx]# docker-compose up -d # 访问测试

Nginx学习随笔插图3

Nginx的配置文件

cat /etc/nginx/conf.d

user nginx; worker_processes 1; ​ error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; ​ # 以上统称为全局块 # worker_processes 的数值越大,Nginx的并发能力就越强,需要根据服务器的性能进行配置,默认即可 # error_log 代表Nginx的错误日志存在的位置 # pid 保存着nginx的进程id ​ ​ # events块,需要根据服务器的性能进行配置,默认即可 # worker_connections 的数值越大,Nginx并发能力越强 events { worker_connections 1024; } ​ # http块 http { # include代表引入一个外部的文件 -> mime.types中放着大量的媒体类型 include /etc/nginx/mime.types; default_type application/octet-stream; ​ log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; ​ access_log /var/log/nginx/access.log main; ​ sendfile on; #tcp_nopush on; ​ keepalive_timeout 65; ​ #gzip on; # include代表引入一个外部的文件 -> *.conf 是配置文件,之后的配置主要是对给目录下的文件进行修改 include /etc/nginx/conf.d/*.conf; }

include /etc/nginx/conf.d/*.conf 引入的配置文件

root@c7206ced66dc:/etc/nginx/conf.d# ls default.conf root@c7206ced66dc:/etc/nginx/conf.d# cat default.conf  server { listen 80; # Nginx监听的端口 listen [::]:80; server_name localhost; # Nginx接收请求的ip,只要访问到该地址就会被nginx处理 # location块 location / { root /usr/share/nginx/html; # 接收到请求后,去该目录下查找静态资源 index index.html index.htm; # 默认去上述的路径中找 index.html 或 index.html  } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }

修改docker-compose文件

之后需要修改的就是这个文件,所以做好挂载

# 先停掉服务 docker-compose down # 修改配置文件为 [root@zxh docker_nginx]# vim docker-compose.yml version: "3" services: nginx: restart: always image: daocloud.io/library/nginx:latest container_name: nginx ports: - 80:80 volumes: - /opt/docker_nginx/conf.d:/etc/nginx/conf.d # 重新构建 [root@zxh conf.d]# docker-compose build # 再次启动 [root@zxh conf.d]# docker-compose up -d # 进入挂载目录,编写配置文件 [root@zxh conf.d]# pwd /opt/docker_nginx/conf.d [root@zxh conf.d]# vim default.conf ################## server{ listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } } ################## # 这样就挂在好了配置文件,方便之后修改

Nginx学习随笔插图4

三、Nginx的反向代理

正向代理和反向代理的介绍

正向代理

  1. 正向代理服务器是由客户端设立的

  2. 客户端要了解代理服务器和目标服务器都是谁

  3. 帮助我们实现突破访问权限,提高访问的速度,对目标服务器隐藏客户端的 IP 地址

Nginx学习随笔插图5

反向代理 

  1. 反向代理服务器是配置服务端的。

  2. 客户端不知道访问的到底是那一台服务器。

  3. 可以实现负载均衡,能够隐藏服务器真正的 IP 地址。

Nginx学习随笔插图6

基于Nginx实现反向代理

举例:通过Nginx访问tomcat

1)创建目标服务器,我们就创建一个tomcat容器

[root@zxh opt]# mkdir docker_mysql_tomcat [root@zxh opt]# cd docker_mysql_tomcat/ [root@zxh docker_mysql_tomcat]# vim docker-compose.yml [root@zxh docker_mysql_tomcat]# cat docker-compose.yml version: '3' services: mysql: # 服务的名称 restart: always # 代表只要docker启动,那么这个容器就跟着一起启动 image: daocloud.io/library/mysql:5.7.4 # 指定镜像路径 container_name: mysql # 指定容器的名称  ports: - 3306:3306 # 指定端口号的映射  environment: MYSQL_ROOT_PASSWORD: 123456 # 指定MySQL的ROOT用户登录密码 TZ: Asia/Shanghai # 指定时区  volumes: - /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql # 映射数据卷  tomcat: restart: always image: daocloud.io/library/tomcat:8.5.15-jre8 container_name: tomcat ports: - 8080:8080 environment: TZ: Asia/Shanghai volumes: - /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps - /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs # 后台运行 [root@zxh docker_mysql_tomcat]# docker-compose up -d # 编写首页 [root@zxh docker_mysql_tomcat]# cd tomcat_webapps/ [root@zxh tomcat_webapps]# mkdir ROOT [root@zxh tomcat_webapps]# cd ROOT/ [root@zxh ROOT]# vim index.html  [root@zxh ROOT]# cat index.html  <h1>hello,lanmu!!<h1>

访问测试,http://47.95.37.17:8080

Nginx学习随笔插图7

2)配置Nginx的反向代理

# 配置Nginx的反向代理,监听localhost:80,当接收到请求后,将其转发到 http://47.95.37.172:8080 [root@zxh docker_nginx]# cd conf.d/ [root@zxh conf.d]# vim default.conf  [root@zxh conf.d]# cat default.conf server{ listen 80; server_name localhost; location / { proxy_pass http://47.69.37.172:8080; # 配置请求转发  } #location / { # root /usr/share/nginx/html; # index index.html index.htm; #} } # 重启 nginx 容器 [root@zxh conf.d]# cd .. [root@zxh docker_nginx]# docker-compose restart Restarting nginx ... done

测试通过Nginx访问:http://47.69.37.172

 Nginx学习随笔插图8

关于Nginx的location路径映射

# 1. 等号'='匹配 location = / { # 精准匹配,主机名后面不能带任何的字符串 } # 举例:访问www.baidu.com时,nginx可以匹配,因为它是根目录 /,而访问www.baidu.com/hello时,则不能匹配,因为它的路径为 /hello,所有的匹配方式都是如此。 # 2. 通用匹配 location /xxx { # 匹配所有以/xxx开头的路径 } # 3. 正则匹配 location ~ /xxx { # 匹配所有以/xxx开头的路径 } # 4. 匹配开头的路径 location ^~ /images { # 匹配所有以/images开头的路径 } # 5. 匹配结尾的路径 location ~* \.(gif|jpg|png)$ { # 匹配以gif、jpg、png结尾的路径 } # 6. 匹配所有路径,也就是所有路径都会拦截 location / { }

优先级从大到小(location / 是匹配所有的路径,但会继续往优先级高的去匹配):

精准匹配(location =)> 完整路径匹配(location /xxx/yyy/zzz)> 匹配开头(location ^~)> 正则匹配和匹配结尾(location ^~, ~*)> 通用匹配(location /xxx)> 匹配所有(location /)

推荐按照优先级书写

实例

1)我们将之前在docker中写过的SpringBoot+redis实现访问自增的项目也启动,方便做多条路径映射

Nginx学习随笔插图9

2)启动后有两个页面,一个是首页,一个自增的功能

Nginx学习随笔插图10

Nginx学习随笔插图11

3)现在我们用Nginx做路径映射,修改default.conf配置文件

server{ listen 80; server_name localhost; location = /msg/send/index { proxy_pass http://47.95.37.172:8081/look; } location /msg/send { proxy_pass http://47.95.37.172:8081/; # 这里URL的结尾需要有 /,否则会404  } location ^~ /msg { proxy_pass http://47.95.37.172:8080/; # 这里URL的结尾需要有 /,否则会404  } location / { root /usr/share/nginx/html; index index.html index.htm; } }

4)重启容器

[root@zxh docker_nginx]# docker-compose restart Restarting nginx ... done

测试访问,映射成功!

Nginx学习随笔插图12

Nginx学习随笔插图13

Nginx学习随笔插图14

Nginx学习随笔插图15

四、Nginx负载均衡

Nginx为我们提供了三种负载均衡的策略:

  1. 轮询(默认的方式)

将客户端发起请求,平均的分配给每一台服务器,也就是每台服务器处理一次请求,但是也不是0101非常有规律的,这不用去纠结。

  1. 权重(用于服务器性能不一致)

会将客户端的请求,根据服务器的权重值不同,分配不同的数量。

  1. ip_hash

基于发起请求的客户端的IP地址不同,他始终会将请求发送到指定的服务器上。

轮询

  • 这里使用 8080 和 8081 端口进行模拟多台服务器的情况。
# 1、修改nginx配置文件 [root@zxh docker_nginx]# vim conf.d/default.conf  # 2、配置完成重新启动容器 [root@zxh docker_nginx]# docker-compose restart Restarting nginx ... done [root@zxh docker_nginx]# cat conf.d/default.conf  upstream my-server { server 47.95.37.172:8080; server 47.95.37.172:8081; } server{ listen 80; server_name localhost; location / { proxy_pass http://my-server/; } } # 格式: =================default.conf ========================= # 自定义名称不要出现下划线 # upstream 自定义名称 { # server ip:port; # server ip:port: # ... # } upstream my-server { server 47.95.37.172:8080; server 47.95.37.172:8081; ... } server { listen 80; server_name localhost; # 格式:proxy_pass http://服务的名称/; location / { proxy_pass http://my-server/; # 注意路径最后的 /,端口号之后需要加上/  } } ================default.conf ==========================

运行测试。

Nginx学习随笔插图16

权重

[root@zxh docker_nginx]# vim conf.d/default.conf  [root@zxh docker_nginx]# docker-compose restart Restarting nginx ... done [root@zxh docker_nginx]# cat conf.d/default.conf  # 只需要添加 weight=权重比例 即可,权重比例只能使用数字 upstream my-server { server 47.95.37.172:8080 weight=10; server 47.95.37.172:8081 weight=90; } server{ listen 80; server_name localhost; location / { proxy_pass http://my-server/; } }

 

ip_hash

[root@zxh docker_nginx]# vim conf.d/default.conf  [root@zxh docker_nginx]# docker-compose restart Restarting nginx ... done [root@zxh docker_nginx]# cat conf.d/default.conf  upstream my-server { ip_hash; # 只需要添加 ip_hash; 即可 server 47.95.37.172:8080; server 47.95.37.172:8081; } server{ listen 80; server_name localhost; location / { proxy_pass http://my-server/; } }

五、Nginx动静分离

Nginx 的并发能力公式

  • worker_processes * worker_connections / (4 | 2) = Nginx最终的并发能力

worker_processes 和 worker_connections 这两个属性在 nginx 的配置文件里看到了

为什么要除以 4或者2 呢?

如下图所示:

  • 客户端请求动态资源要向服务器获取资源,那么就需要4个连接数。
  • 客户端请求Nginx服务里的静态资源,只需要从自身获取资源,那么就需要2个连接数。

Nginx学习随笔插图17

Nginx通过动静分离,来提升Nginx的并发能力,更快的给用户响应。

动态资源代理

# 配置如下 location / { proxy_pass 路径; }

静态资源代理

# 配置如下 location / { root 静态资源所在的父目录路径; index 默认访问root路径下的什么资源; autoindex on; # 以列表的形式展示root目录下的所有资源 }

举例

  • 因为静态资源代理,指的是Nginx服务自带的静态资源。
  • 所以需要在 Nginx服务 中创建静态资源,然后进行代理配置即可。

1、创建静态资源

# 1、修改docker配置文件,挂在Nginx容器的数据卷 [root@zxh docker_nginx]# ls conf.d docker-compose.yml [root@zxh docker_nginx]# vim docker-compose.yml  [root@zxh docker_nginx]# cat docker-compose.yml  version: "3" services: nginx: restart: always image: daocloud.io/library/nginx:latest container_name: nginx ports: - 80:80 volumes: - /opt/docker_nginx/conf.d/:/etc/nginx/conf.d - /opt/docker_nginx/img/:/data/img # 指定根目录下的 /data/img 目录 - /opt/docker_nginx/html/:/data/html # 指定根目录下的 /data/html 目录 # 2、先停止容器 [root@zxh docker_nginx]# docker-compose down Stopping nginx ... done Removing nginx ... done Removing network docker_nginx_default # 再重新启动,这样可以自动创建数据卷对应的目录 [root@zxh docker_nginx]# docker-compose up -d Creating network "docker_nginx_default" with the default driver Creating nginx ... done # 3、任意图片当作静态资源 [root@zxh docker_nginx]# ls conf.d docker-compose.yml html img [root@zxh docker_nginx]# mv /home/zxh/file/123\ 005.GIF img/123.GIF [root@zxh docker_nginx]# ls img 123.GIF [root@zxh docker_nginx]# vim html/index.html [root@zxh docker_nginx]# ls html index.html [root@zxh docker_nginx]# cat html/index.html  <h1>hello,lanmu!</h1>

配置Nginx静态资源代理

server{ listen 80; server_name localhost; # 代理html静态资源,当请求 /html/xx 时,自动去 Nginx 容器中的 /data/html 目录中获取资源,获取不到404 location /html { root /data; # 会自动拼接为/data/html index index.html; # 请求为 /html,则默认访问 /html/index.html  } # 代理到img静态资源,当请求 /img/xx 时,自动去 Nginx 容器中的 /data/img 目录中获取资源 location /img { root /data; # 会自动拼接为/data/img autoindex on; # 以目录的形式展示所有的资源  } }

访问测试

Nginx学习随笔插图18

Nginx学习随笔插图19

Nginx学习随笔插图20

 Nginx学习随笔插图21

六、Nginx集群

引言

为什么要搭建集群呢?

一个应用有多个模块,也成为多个服务,这些服务分别搭建在不同的服务器上,这样可以保证某个服务宕掉了,其他的服务可以照常使用。

而 Nginx 集群亦是如此,如果只有一台Nginx服务,那么Nginx服务宕掉了,那么所有服务就都访问不到了,所以才需要搭建集群。

也就是解决单点故障问题。

1、怎么知道 Nginx 可用?

准备 keepalived,监听nginx的健康情况。

2、多个 Nginx服务,到底要访问哪个?

准备haproxy,提供一个虚拟的路径,统一去接收用户的请求。

Nginx学习随笔插图22

 

搭建Nginx集群

注意ps:所有的配置文件最好是通过 vim 命令创建出来。

Nginx学习随笔插图23

其中的 favicon.ico 是网页的图标,随便上传一张ico图片即可。

创建镜像文件 Dockerfile

FROM nginx: 1.13.5-alpine # 指定nginx镜像版本 RUN apk update && apk upgrade # apk 类似 yaml,该镜像版本不是centos,所以用的是apk命,更新仓库 RUN apk add --no-cache bash curl ipvsadm iproute2 openrc keepalived # 下载软件,可以看到包含了 keepalived COPY entrypoint.sh /entrypoint.sh # 复制当前目录下的一个脚本文件 RUN chmod +x /entrypoint.sh # 给脚本文件添加执行权限 CMD ["/entrypoint.sh"] # 执行脚本

entrypoint.sh

#!/bin/sh #/usr/sbin/keepalived -n -l -D -f /etc/keepalived/keepalived.conf --dont-fork --log-console & /usr/sbin/ keepalived -D -f /etc/keepalived/keepalived.conf nginx -g "daemon off;"

 

容器编排 docker-compose.yml

version: "3" services: # 主服务  nginx_master: build: context: ./ # 指定当前目录下的dockerfile dockerfile: ./Dockerfile ports: - 8081:80 # 端口映射  volumes: # 关联首页 - ./index-master.html:/usr/share/nginx/html/index.html # 关联页面图标 - ./favicon.ico:/usr/share/ngin/html/favicon.ico # 关联keepalived配置文件 - ./keepalived-master.conf:/etc/keepalived/keepalived.conf networks: static-network: # 将ip写死,保证keepalived可以正确识别 ipv4_address: 172.20.128.2 cap_add: - NET_ADMIN # 从服务  nginx_slave: build: context: ./ # 指定当前目录下的dockerfile dockerfile: ./Dockerfile ports: - 8082:80 # 端口映射  volumes: # 关联首页 - ./index-slave.html:/usr/share/nginx/html/index.html # 关联页面图标 - ./favicon.ico:/usr/share/ngin/html/favicon.ico # 关联keepalived配置文件 - ./keepalived-slave.conf:/etc/keepalived/keepalived.conf networks: static-network: ipv4_address: 172.20.128.3 cap_add: - NET_ADMIN # haproxy  proxy: image: haproxy:1.7-alpine ports: # 80端口映射到haproxy的端口 - 80:6301 volumes: - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg networks: - static-network networks: static-networks: ipam: config: - subnet: 172.20.0.0/16

index-master.html

<h1>Master!!</h1>

index-slave.html

<h1>Slave!!</h1>

keepalived 主从配置

keepalived-master.conf

# 指定多久检测一次nginx的健康状态 vrrp_script cnk_nginx { script "pidof nginx" interval 2 } vrrp_instance VI_1 { state MASTER # master负责接收用户的请求,当master宕掉后才会有slave接收 interface eth0 # 容器内部的网卡名称 virtual_router_id 33 # 虚拟路由id priority 200 # 优先级 advert_int 1 authentication { auth_type PASS auth_pass letmein } virtual_ipaddress { 172.20.128.50 # 指定maste主服务的虚拟ip地址  } track_script { chk_nginx } }

keepalived-slave.conf

# 指定多久检测一次nginx的健康状态 vrrp_script cnk_nginx { script "pidof nginx" interval 2 } vrrp_instance VI_1 { state BACKUP # master负责接收用户的请求,当master宕掉后才会有slave接收 interface eth0 # 容器内部的网卡名称 virtual_router_id 33 # 虚拟路由id priority 100 # 优先级比master低 advert_int 1 authentication { auth_type PASS auth_pass letmein } virtual_ipaddress { 172.20.128.50 # 指定maste主服务的虚拟ip地址  } track_script { chk_nginx } }

haproxy.conf

g1oba1 log 127.0.0.1 local0 maxconn 4096 daemon nbproc 4 defaults log 127.0.0.1 local3 mode http option dontlognull option redispatch retries 2 maxconn 2000 balance roundrobin timeout connect 5000ms timeout client 5000ms timeout server 5000ms frontend main bind *:6301 default_backend webserver # 172.20.128.50:80 对应 keepalived-master/slave.conf 配置的虚拟路径 # 当用户访问 80端口 时,会映射到haproxy,haproxy通过下面的虚拟路径将请求交给keepalived,有keepalived 决定选择 主/从nginx。 backend webserver server ngxin_master 172.20.128.50:80 check inter 2000 rise 2 fall 5

测试

# 1、构建镜像 [root@zxh docker_nginx_cluster]# docker-compose build # 2、后台启动容器 [root@zxh docker_nginx_cluster]# docker-compose up -d Creating docker_nginx_cluster_nginx_slave_1 ... done Creating docker_nginx_cluster_proxy_1 ... done Creating docker_nginx_cluster_nginx_master_1 ... done

Nginx学习随笔插图24

Nginx学习随笔插图25

Nginx学习随笔插图26

[root@zxh docker_nginx_cluster]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES da30c781d9b8 docker_nginx_cluster_nginx_slave "/entrypoint.sh" About a minute ago Up About a minute 0.0.0.0:8082->80/tcp docker_nginx_cluster_nginx_slave_1 c2a931441c08 haproxy:1.7-alpine "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:80->6301/tcp docker_nginx_cluster_proxy_1 adc693524c73 docker_nginx_cluster_nginx_master "/entrypoint.sh" About a minute ago Up About a minute 0.0.0.0:8081->80/tcp docker_nginx_cluster_nginx_master_1 # 停掉master节点的nginx容器 [root@zxh docker_nginx_cluster]# docker stop adc693524c73 adc69352473

再次访问 80端口,发现切换到了slave从节点。

Nginx学习随笔插图27

# 重新启动容器,再次访问80端口,可以看到又切换回了 master节点 [root@zxh docker_nginx_cluster]# docker start adc693524c73 adc69352473

 

引用:https://www.bilibili.com/video/BV1PV411C7bc?p=14

 

 

 

原文链接:https://www.cnblogs.com/zxhbk/p/14298957.html

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享