导图社区 nginx
nginx 新手入门,包括基本配置,常用配置,使用 keepalived 实现 nginx 高可用。
编辑于2020-12-12 16:41:52nginx
安装
1. http://nginx.org/en/download.html 下载 nginx 安装包并上传到服务器 2. tar -zxvf nginx-1.18.0.tar.gz 解压 3. 进入解压后的目录,执行 .configure,如提示缺失组件则按要求添加: yum -y install pcre pcre-devel; yum install -y zlib zlib-devel; 4. make && make install 5. 进入 /usr/local/nginx/sbin (nginx 默认安装路径),执行 ./nginx 启动 nginx 6. 检查防火墙状态 firewall-cmd --list-ports 开放 80 端口 firewall-cmd --permanent --zone=public --add-port=80/tcp 重启防火墙 systemctl restart firewalld 7. 浏览器输入 服务器ip:80 看到 nginx 主页,安装完成。
nginx 启动关闭/设置成系统服务
进入 /usr/local/nginx/sbin 即 nginx 的安装路径, ./nginx 启动nginx ./nginx -t 校验 nginx.conf 文件是否合法 ./nginx -v 查看 nginx 版本 ./nginx -s reload 重新加载配置 ./nginx -s stop 关闭 nginx,不推荐 ./nginx -s quit 关闭 nginx,推荐 ./nginx -h 帮助文档
将 nginx 配置成系统服务并设置开机自启: 1. cd /usr/lib/systemd/system 2. touch nginx.service 3. vim nginx.service 4. 写入 [Unit] Description=nginx After=network.target [Service] Type=forking ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target 5. 设置开机自启 systemctl enable nginx 6. 重启服务器 reboot 7. 查看 nginx 是否已启动 systemctl status nginx
nginx.conf 文件解析
文件结构 main # 全局配置,对全局生效 ├── events # 配置影响 Nginx 服务器或与用户的网络连接 ├── http # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置 │ ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分 │ ├── server # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块 │ ├── server │ │ ├── location # server 块可以包含多个 location 块,location 指令用于匹配 uri │ │ ├── location │ │ └── ... │ └── ... └── ... 配置文件由指令与指令块构成; 每条指令以 ; 分号结尾,指令与参数间以空格符号分隔; 指令块以 {} 大括号将多条指令组织在一起; include 语句允许组合多个配置文件以提升可维护性; 使用 # 符号添加注释,提高可读性; 使用 $ 符号使用变量; 部分指令的参数支持正则表达式。
配置示例 user nginx; # 运行用户,默认即是nginx,可以不进行设置 worker_processes 1; # Nginx 进程数,一般设置为和 CPU 核数一样 error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录 pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置 events { accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off use epoll; # 使用epoll的I/O模型 worker_connections 1024; # 每个进程允许最大连接数 } http { # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置 include mime.types; #文件扩展名与文件类型映射表 default_type application/octet-stream; #默认文件类型,默认为text/plain # 设置日志模式 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; # Nginx访问日志存放位置 sendfile on; # 开启高效传输模式,提升文件传输性能 tcp_nopush on; # 减少网络报文段的数量 tcp_nodelay on; keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒 types_hash_max_size 2048; include /xx/xx/*.conf; # 加载子配置项,自定义路径,相当于 java 的 import server { # 代表一个虚拟服务器 listen 80; # 配置监听的端口 server_name localhost; # 配置的域名 location / { root /usr/share/nginx/html; # 网站根目录 index index.html index.htm; # 默认首页文件 deny 172.168.22.11; # 禁止访问的ip地址,可以为all allow 172.168.33.44; # 允许访问的ip地址,可以为all } error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面 error_page 400 404 error.html; # 同上 } upstream mysvr { server 127.0.0.1:7878; server 192.168.10.121:3333 backup; #热备 } server { keepalive_requests 120; #单连接请求上限次数。 listen 4545; #监听端口 server_name 127.0.0.1; #监听地址 location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。 #root path; #根目录 #index vv.txt; #设置默认页 proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表 deny 127.0.0.1; #拒绝的ip allow 172.18.5.54; #允许的ip } } }
配置反向代理
正向代理:一般的访问流程是客户端直接向目标服务器发送请求并获取内容,使用正向代理后,客户端改为向代理服务器发送请求,并指定目标服务器(原始服务器),然后由代理服务器和原始服务器通信,转交请求并获得的内容,再返回给客户端。正向代理隐藏了真实的客户端,为客户端收发请求,使真实客户端对服务器不可见。
反向代理:与一般访问流程相比,使用反向代理后,直接收到请求的服务器是代理服务器,然后将请求转发给内部网络上真正进行处理的服务器,得到的结果返回给客户端。反向代理隐藏了真实的服务器,为服务器收发请求,使真实服务器对客户端不可见。
server { listen 9090; server_name www.test-nginx.com; location / { proxy_pass http://www.baidu.com; } } 添加 "服务器ip www.test-nginx.com" 到本地 host; 修改服务器防火墙,开放 9090 端口; 浏览器访问 www.test-nginx.com:9090/ 即可访问到百度。
配置动静分离
方式:1. 使用 CND;2. 使用 nginx
server { listen 9091; server_name localhost; location /picture { root html; index index.html; } } 访问 服务器ip:9091/picture 时,可以访问到 /usr/local/nginx/html/picture 中的 index.html 页面。 server { listen 9090; server_name www.mynginx.com; location /abc { alias html/picture; } } 路径别名 alias,当键入 www.mynginx.com(或者服务器ip):9090/abc/1.jpg 时可以访问到 /usr/local/nginx/html/picture/1.jpg。
跨域处理
示例: 1 创建 web 工程,见注释 2 浏览器输入 localhost:8080/index 发生跨域问题 3 找到 nginx 中相关的 server 配置,加入 # 允许跨域请求的域, * 代表所有 add_header 'Access-Control-Allow-Origin' *; # 是否允许带上 cookie 请求 add_header 'Access-Control-Allow-Credentials' 'true' # 允许请求方法 add_header 'Access-Control-Allow-Methods' *; # 允许请求的 header add_header 'Access-Control-Allow-Headers' *; 4 重启 nginx,浏览器再次访问 localhost:8080/index 不再出现跨域问题
@SpringBootApplication @Controller public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @RequestMapping("/index") public String index(Model model){ model.addAttribute("welcome","Hello world!"); return "index"; } } <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>First page</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script> <script type="text/javascript" th:inline="javascript"> /*<![CDATA[*/ $(document).ready(function () { $.ajax({ type: 'get', url: 'http://www.test-nginx.com:9091/abc', data: {}, async: true, success: function (data) { console.log(data) } }); }); /*]]>*/ </script> </head> <body> <p th:text="${welcome}">Welcome to thymeleaf world!a</p> </body> </html> -------------- nginx -------------- server { listen 9091; server_name www.test-nginx.com; # 允许跨域请求的域, * 代表所有 add_header 'Access-Control-Allow-Origin' *; # 是否允许带上 cookie 请求 add_header 'Access-Control-Allow-Credentials' 'true'; # 允许请求方法 add_header 'Access-Control-Allow-Methods' *; # 允许请求的 header add_header 'Access-Control-Allow-Headers' *; location /abc { root html; index a.html; } location /efg { alias html/abc/; } }
配置负载均衡
示例: upstream guys { server 192.168.137.128:9099; server 192.168.137.135:9099; } server { listen 9090; server_name www.test-jq.com; location / { proxy_pass http://guys; } } upstream 的其他配置项查阅: http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html 记得将开放上游服务器的 9099 端口。 上游服务器中各自运行着一个 springboot 项目(监听 9099 端口),里边各自写着一个 /user_info 的接口,浏览器访问 http://www.test-jq.com:9090/user_info,请求被 nginx 转发到上游服务器集群中,因此访问到各个服务器中的 /user_info 接口。
负载均衡方式: 轮询 权重 iphash: 需注意用户 ip 动态变化问题,同一 ip 发起大量请求导致服务器负载过高问题,集群服务器数量变更导致重 hash 问题(替换方案:使用一致性 hash 算法) urlhash least_conn
配置防盗链
示例: server { # 对请求来自的域名进行校验,如果与下方配置好的域名匹配上则可以访问,否则返回 404 valid_referers 域名(例如 xx.xx.com); if ($invalid_referer) { return 404; } location /xx { } }
日志切割
日志切割(手动) 1 创建脚本 cut_log.sh #!/bin/bash LOG_PATH="/usr/local/nginx/logs/" RECORD_TIME=$(date -d 'yesterday' +%Y-%m-%d+%H:%M) PID=/usr/local/nginx/nginx.pid # 重命名 mv $LOG_PATH/access.log $LOG_PATH/access.$RECORD_TIME.log mv $LOG_PATH/error.log $LOG_PATH/error.$RECORD_TIME.log # 向 nginx 主进程发送信号,用于重新打开日志文件 kill -USR1 `cat $PID` 2 chmod +x cut_log.sh 3 ./cut_log.sh 日志切割(定时),即使用 crontab 来执行定时任务 1 crontab -e, 输入 */1 * * * * /usr/local/nginx/sbin/cut_log.sh 2 systemctl restart crond 重启定时任务
keepalived 双主配置
128 机器上修改 keepalived.conf ## 添加以下配置 vrrp_instance VI_2 { state BACKUP interface ens33 # virtual_router_id 主备需保持一致 virtual_router_id 52 priority 80 unicast_src_ip 192.168.137.128 #本地ip unicast_peer { 192.168.137.129 #对端ip地址 } # 主备心跳检查间隔,默认1s advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.137.17 } track_script { checknginx # 追踪 nginx 脚本 } }
129 机器上修改 keepalived.conf ## 添加以下配置 vrrp_instance VI_2 { state MASTER interface ens33 virtual_router_id 52 priority 100 unicast_src_ip 192.168.137.129 #本地ip unicast_peer { 192.168.137.128 #对端ip地址 } advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.137.17 } track_script { checknginx # 追踪 nginx 脚本 } }
浏览器上分别访问 192.168.137.16 和 192.168.137.17(如果是云服务器的话,可以用同一域名绑定不同的 ip 进行试验) 128 服务器执行 ip addr 出现 192.168.137.16 这个 vip;129 服务器执行 ip addr 出现 192.168.137.17 这个 vip; 停掉 128 服务器上的 keepalived,128 服务器 16 这个 vip 消失, 129 服务器 执行 ip addr 出现 16,17 两个 vip,页面访问正常,说明双主配置成功。
当 keepalived 正常而 nginx 故障时,同样会访问异常,因此需要将 keepalived 配置成 nginx 自动重启 1 在 keepalived.conf 中加入配置: vrrp_script checknginx { script "/etc/keepalived/checknginx.sh" interval 2 # 每隔2秒运行上一行脚本 } 2 在 vrrp_instance 中新增监控的脚本 track_script { check_nginx_alive # 追踪 nginx 脚本 } 3 checknginx.sh 脚本内容 #!/bin/bash A=`ps -C nginx --no-header | wc -l` if [ $A -eq 0 ]; then #/usr/local/nginx/sbin/nginx systemctl restart nginx sleep 3 if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then killall keepalived fi fi 4 重启 keepalived,关闭 nginx 浏览器访问 192.168.137.16 可以正常访问; 关闭 nginx 后修改 nginx 的配置为不能正常启动,浏览器访问 192.168.137.16 发现正常切换到另一个节点,说明 keepalived 配置 nginx 自动重启完成。
keepalived 主备配置
主节点(192.168.137.128)配置 1 进入 /etc/keepalived 目录,编辑 keepalived.conf 2 修改 keepalived.conf 内容为: global_defs { # 路由id,是当前安装 keepalived 的服务器的全局唯一的标识符 router_id keep_128 } vrrp_instance VI_1 { state MASTER interface ens33 # virtual_router_id 主备需保持一致 virtual_router_id 51 priority 100 # 以下两行通过配置来指定 ip 的两台服务器间进行通讯 unicast_src_ip 192.168.137.128 # 本地 ip unicast_peer { 192.168.137.129 #对端ip地址 } # 主备心跳检查间隔,默认1s advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.137.16 # 设置虚拟 ip,即 vip } } 3 ip addr 查看 ens33 网卡下仅有一个 ip 4 进入 /usr/local/keepalived/sbin 目录,执行 ./keepalived 5 ip addr 查看 ens33 网卡下多了一个 192.168.137.16,则配置完成 关闭 keepalived 要用 kill 指令
备份节点(192.168.137.129)配置 1 进入 /etc/keepalived 目录,编辑 keepalived.conf 2 修改 keepalived.conf 内容为: global_defs { # 路由id,是当前安装 keepalived 的服务器的全局唯一的标识符 router_id keep_129 } vrrp_instance VI_1 { state BACKUP interface ens33 # virtual_router_id 主备需保持一致 virtual_router_id 51 priority 80 # 以下两行通过配置来指定 ip 的两台服务器间进行通讯 unicast_src_ip 192.168.137.129 # 本地 ip unicast_peer { 192.168.137.128 #对端ip地址 } # 主备心跳检查间隔,默认1s advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.137.16 # 设置虚拟 ip,即 vip } } 3 ip addr 查看 ens33 网卡下仅有一个 ip 4 进入 /usr/local/keepalived/sbin 目录,执行 ./keepalived 5 ip addr 查看 ens33 网卡下还是仅有一个 ip,等待测试
主备节点上的 nginx server 配置 server { listen 9091; server_name www.test-nginx.com; location /abc { root html; index a.html; } }
测试: 浏览器访问 192.168.137.16:9091/abc,出现 128 服务器上 nginx 的 html/abc 目录下的 a.html 页面(因为 128 是主节点,所以会先请求到 128 服务器); 停掉 192.168.137.128 上的 keepalived 服务,在 128 上执行 ip addr 发现 192.168.137.16 已经不存在,在 129 上执行 ip addr 发现多了 192.168.137.16; 重新访问 192.168.137.16:9091/abc,若此时访问到 129 服务器上 nginx 的 html/abc 目录下的 a.html 页面,则 keepalived 主备配置成功。
将 keepalived 配置为系统服务 1 进入 keepalived 解压后的目录,例:/root/keepalived-2.0.20/keepalived/etc 2 cp init.d/keepalived /etc/init.d/ 3 cp sysconfig/keepalived /etc/sysconfig/ 4 systemctl daemon-reload 5 systemctl start keepalived 启动 keepalived
keepalived 安装 1 https://www.keepalived.org/download.html 下载 tar.gz 包并上传至服务器 2 解压,进入解压后的目录,运行 ./configure --prefix=/usr/local/keepalived --sysconf=/etc,prefix 指定软件安装目录,sysconf 指定 keepalived 核心文件所在位置,必须为 /etc,换成其他位置会导致 keeyalived 启动不了 3 若提示缺失组件则执行相应命令并重新执行第 2 步的命令 yum install openssl openssl-devel yum install libnl libnl-devel 4 make && make install