Nginx
一、Nginx基础配置常用参数说明
nginx配置有3部分组成:
- 全局块
从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配
置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以
及配置文件的引入等。
- events设置块
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process
下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word
process 可以同时支持的最大连接数等。
- http设置块
这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
需要注意的是:http 块也可以包括 http 全局块、server 块。
①http全局块
http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。
②server块
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了
节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块
全局server块
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置
location 块
一个 server 块可以配置多个 location 块。
这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称
(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓
存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
#启动Nginx工作进程的用户和组,比如"user nginx nginx"
#user nobody;
#启动nginx工作进程的数量,默认是一个,这个参数取决于你服务器CPU的核心数,一般情况下该值要小于等于你服务器的核心数哟。在nginx1.8版本之后咱们可以直接写"auto",即无需手写几个core数量,而是交给nginx自动取判断服务器拥有的core数量。
worker_processes 4;
#将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
worker_cpu_affinity 00000001 00000010 00000100 00001000;
#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit |alert | emerg]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid文件保存路径
#pid logs/nginx.pid;
#工作进程优先级,-20~19
worker_priority 0;
#这个数字包括Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.
worker_rlimit_nofile 65536;
#前台运行Nginx服务用于测试、docker等环境。 是否以守护进程方式运行nginx
daemon on|off;
#是否开启Nginx的master-woker工作模式。
master_process off|on;
#-------全局块--------
#events设置快,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等。
events {
#设置单个nginx工作进程可以接受的最大并发,作为web服务器的时候最大并发数为"worker_connections * worker_processes",作为反向代理的时候为"(worker_connections * worker_processes)/2"(因为反向代理服务器是响应一个客户端请求连接需要消耗两个文件描述符,即接收客户端请求需要消耗一个文件描述符,将请求转发给后端的rip服务器处理又消费了一个文件描述符)
worker_connections 100000;
#使用epoll事件驱动,Nginx支持众多的事件驱动,比如select、poll、epoll,只能设置在events模块中设置。
use epoll;
#优化同一时刻只有一个请求而避免多个睡眠进程被唤醒的设置,on为防止被同时唤醒默认为off,全部唤醒的过程也成为"惊群",因此nginx刚安装完以后要进行适当的优化。
accept_mutex on;
#Nginx服务器的每个工作进程可以同时接受多个新的网络连接,但是需要在配置文件中配置,此指令默认为关闭,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个,配置语法如下:
multi_accept on;
}
#http块是Nginx服务器配置中的重要部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都可以在这设置,http块可以包含多个server块,而一个server块中又可以包含多个location块,server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和单个链接的请求上限等。
http {
#导入支持的文件类型,mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
include 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 logs/access.log main;
#指定是否使用sendfile系统调用来传输文件,sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈。作为web服务器的时候我推荐大家打开sendfile加快文件传输
sendfile on;
#在开启了sendfile的情况下,合并请求后统一发送给客户端。
#tcp_nopush on;
#在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户相应报文。
#tcp_nodelay off;
#长连接超时时间,单位是秒,即设置会话保持时间
#keepalive_timeout 0;
#设置会话保持时间时,我们也可以指定2个参数,第一个参数表示会话的保存时间,第二个参数是nginx通过response报文告诉客户端会话的保持时间,比如咱们配置的了服务端主动告诉客户端设置的连接超时时间是60秒,而实际上是65秒会话才会断开哟~
keepalive_timeout 65 60;
#通常情况下咱们都会开启压缩功能的哟~
#gzip on;
#设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个locating模块。比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server 可以使用一个端口,比如都使用80端口提供web服务、一个server相当于一个代理服务器,可以配置多个server。
server {
#配置server监听的端口
listen 80;
#本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配,以空格方式隔开多个FQDN,当然也支持正则表达式的方式匹配主机名。
server_name localhost;
#指定编码格式,推荐修改为UTF-8字符编码
#charset koi8-r;
#access_log logs/host.access.log main;
#location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令,都是在location中体现的,主要是基于nginx接受到的请求字符串,对用户请求的UIL进行匹配,并对特定的指令进行处理,包括地址重定向、数据缓存和应答控制等功能都是在这部分实现,另外很多第三方模块的配置也是在location模块中配置。
location / {
#相当于默认页面的目录名称,默认是相对路径(如果是基于yum方式安装则是"/usr/share/nginx/html/",如果是基于源码方式安装,则在安装目录的下,如"/yinzhengjie/softwares/nginx/html/"),当然咱们也可以使用绝对路径配置。
root html;
#默认的页面文件名称
index index.html index.htm;
}
#错误页面的文件名称
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
#location处理对应的不同错误码的页面定义到/50x.html,这个跟对应其server中定义的目录下。
location = /50x.html {
#定义默认页面所在的目录
root html;
}
#以http的方式转发php请求到指定web服务器
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
#以fastcgi的方式转发php请求到php处理
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
#拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件来改变自己的重定向等功能。
# deny all;
#}
}
#自定义虚拟server
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
#指定默认网页文件,此指令由ngx_http_index_module模块提供
# index index.html index.htm;
# }
#}
#https服务器配置
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
#和邮件相关的配置
#mail {
# ... #mail 协议相关配置段
# }
#tcp代理配置,1.9版本以上支持
#stream {
# ... #stream 服务器相关配置段
# }
#导入其他路径的配置文件
#include /yinzhengjie/softwares/nginx/conf.d/*.conf;
}
- 执行的命令行参数
nginx -t # 执行配置文件检测
nginx -t -q # 执行配置文件检测,且只输出错误信息
nginx -s stop # 快速停止Nginx
nginx -s quit # 正常关闭Nginx
nginx -s reopen # 重新打开日志文件
nginx -s reload # 重新加载配置文件
nginx -p /usr/local/newnginx # 指定Nginx的执行目录
nginx -c /etc/nginx/nginx.conf # 指定nginx.conf文件的位置
# 外部指定pid和worker_processes配置指令参数
nginx -g "pid /var/run/nginx.pid; worker_processes 'sysctl -n hw.ncpu';"
二、构建Nginx镜像并且推送到Harbor仓库中
- 1、编写Dockerfile文件
# 基础镜像
FROM centos
# 下载必要的安装和编译的工具
RUN yum -y install gcc make pcre-devel zlib-devel tar zlib
#RUN wget https://nginx.org/download/nginx-1.20.1.tar.gz 我先把Nginx下载到本地了
#复制
copy nginx-1.20.1.tar.gz /usr/local/
RUN cd /usr/local/ && tar xvf nginx-1.20.1.tar.gz
# 工作目录 编译安装
WORKDIR /usr/local/nginx-1.20.1/
# 编译
RUN ./configure --prefix=/usr/local/nginx && make && make install
# 开启 80 和443端口
EXPOSE 80
EXPOSE 443
# 修改配置文件,以非 deamon方式启动
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
# 复制服务脚本并设置权限
ADD run.sh /run.sh
RUN chmod 755 /run.sh
# 启动容器时执行脚本
CMD ["/run.sh"]
- 编辑启动脚本
vi run.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx
- 查看当前目录文件
[root@ecs-431f-0002 nginx]# ls -ll
total 21428
-rw-r--r-- 1 root root 714 Sep 3 15:06 Dockerfile
-rw-r--r-- 1 root root 40 Sep 3 14:46 run.sh
-rw-r--r-- 1 root root 1061461 Sep 3 10:44 nginx-1.20.1.tar.gz
- 构建镜像
sudo docker build -t nginx:v1
- 查看镜像
root@ecs-431f-0002 opt]# sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 db02b8751752 2 hours ago 416MB
- 以后台的方式启动镜像
sudo docker run -d -p 9000:80 --name nginxs nginx:v1
- 访问测试
[root@ecs-431f-0002 opt]# curl localhost:9000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 访问成功
- 2、推送到harbor仓库中
- 给镜像打标签
sudo docker tag nginx:v1 xx.106.254.42/harbor/nginx:1.0
- 登录harbor仓库
sudo docker login http://xx.106.254.42 -u admin -p 12345
- 推送到远程harbor
sudo docker push xx.106.254.42/harbor/nginx:1.0
- 查看镜像仓库
- 3、错误总结
- received unexpected HTTP status: 500 Internal Server Error
[root@ecs-431f-0002 opt]# docker push xx.106.254.42/nginx:1.0
The push refers to repository [xx.106.254.42/nginx]
de05fb081d65: Retrying in 1 second
b499e6e2b1fc: Retrying in 1 second
d60e4df6f74c: Retrying in 2 seconds
290b0e2b22e6: Retrying in 2 seconds
4ac8eeb9ccda: Retrying in 2 seconds
20a8b37d5f98: Waiting
524435504f09: Waiting
2653d992f4ef: Waiting
received unexpected HTTP status: 500 Internal Server Error
查看错误日志 tail -f /var/log/messages
...
Sep 3 17:54:41 ecs-431f-0002 dockerd[2593526]: time="2021-09-03T17:54:41.625981159+08:00" level=error msg="Upload failed: received unexpected HTTP status: 500 Internal Server Error"
Sep 3 17:54:41 ecs-431f-0002 dockerd[2593526]: time="2021-09-03T17:54:41.626061564+08:00" level=info msg="Attempting next endpoint for push after error: received unexpected HTTP status: 500 Internal Server Error"
...
大致意思就是上传的时候失败了,然后经过自己的分析,原来是自己的马虎在docker push
的过程中提交到仓库中的代码出问题了,就是像上面那样,xx.106.254.42/nginx/nginx:1.0就解决了这个问题,harbor后面需要跟的是仓库的名称,然后是版本信息。在docker pull
的过程中 一定要加版本号,否则也会出现这个问题的哟。
三、配置nginx中遇到的问题解决
1、解决进程占用的问题
nginx -s stop #关闭nginx服务
#如果关闭不了的使用下面两种方式:
netstat -anp|grep 80 #查看下 80 端口的使用情况
netstat -aux|grep 3016179 #查看80端口被被占用的PID,根据这个pid来查看那个程序在使用
kill -9 进程id #然后 使用 kill -9 命令即可杀掉该进程
----------------------------------------------------------
fuser -k 80/tcp #杀掉所有80进程(这个比较直接)
2、解决node节点使用不了kubectl的相关命令
[root@ecs-431f-0002 ~]# kubectl get pod
error: no configuration has been provided, try setting KUBERNETES_MASTER environment variable
将master中的admin.conf复制到需要的工作节点中即可。
修改配置文件,并使用source
命令使其生效
[root@ecs-431f-0002 kubernetes]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
[root@ecs-431f-0002 kubernetes]# source ~/.bash_profile
3.解决Nginx通过路径转发tomcat服务资源404的解决办法
问题描述: localhost /{}
可以访问到tomcat的服务,但是通过tomcat二级目录来访问tomcat后端服务提示404的错误。
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#内部使用nginx访问k8s的svc的服务
upstream myapp{
##start##
server myapp:8080;
##end##
}
server {
listen 80;
server_name 121.36.93.234;
#root /usr/local/apache-tomcat-9.0.1/webapps/ROOT/;
#index index.html index.htm index.jsp index.php;
if ( $query_string ~* ".*[\;'\<\>].*" ){
return 404;
}
location ^~ /tomcat { #^~ 加上这个匹配原则,在路由匹配成功之后还会继续向下寻找匹配规则。
proxy_pass http://myapp/; #后面的斜杠是一个关键,没有斜杠的话就会传递tomcat到后端节点导致404
root html;
index index.html index.htm index.jsp index.php;
}
}
}
四、正向代理,反向代理,负载均衡,动静分离
1、正向代理
正向代理:如果把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访问 Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。要访问谷歌的话,因为谷歌在美国,访问的话中间有一道墙,所有这时需要一个代理服务器解析谷歌的地址,然后我们供我们使用。
2、反向代理
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器
地址,隐藏了真实服务器 IP 地址。反向代理代理的是服务端,正向代理的是客户端。
- 请求转发(根据路径进行转发)
3、负载均衡
负载均衡:单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器中,将原先请求服务器到单个服务器上的情况改为请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。
- 服务器配置指令
upstream backend {
server backend1.example.com weight=5; # 被代理服务器端口号为80,权重为5
server backend2.example.com:8080; # 被代理服务器端口号为8080,默认权重为1
server unix:/tmp/backend3;
server backup1.example.com:8080 backup; # 该被代理服务器为备份状态
server backup2.example.com:8080 backup; # 该被代理服务器为备份状态
}
server {
location / {
proxy_pass http://backend; # 将客户端请求反向代理到上游服务器组backend
}
}
- nginx分配服务的策略
- 轮询
- weight
- ip_hash
4、动静分离
- 为什么要做动静分离?
- Nginx是当下最热的Web容器,网站优化的重要点在于静态化网站,网站静态化的关键点则是是动
静分离,动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开
来,动静资源做好了拆分以后,我们则根据静态资源的特点将其做缓存操作。 - 让静态的资源只走静态资源服务器,动态的走动态的服务器。Nginx的静态处理能力很强,但是动态处理能力不足,因此,在企业中常用动静分离技术。
- 对于静态资源比如图片,js,css等文件,我们则在反向代理服务器nginx中进行缓存。这样浏览器在请求一个静态资源时,代理服务器nginx就可以直接处理,无需将请求转发给后端服务器tomcat。
- 若用户请求的动态文件,比如servlet,jsp则转发给Tomcat服务器处理,从而实现动静分离。这也是
反向代理服务器的一个重要的作用。
五、nginx配置高可用集群
六、注册系统服务
- 1、注册系统服务
vim /usr/lib/systemd/system/nginx.service
,在Linux中是没有这个文件的,需要自己创建
[Unit]
Description=The Nginx HTTP and reverse proxy server # Nginx服务描述信息
After=network.target # Nginx服务启动依赖,在指定服务之后启动
[Service] # 记录service文件的service信息
Type=forking # 标准UNIX Daemon使用的启动方式
PIDFile=/cust1/nginx-1.18.0/logs/nginx.pid # Nginx服务的pid文件位置
ExecStartPre=/cust1/nginx-1.18.0/sbin/nginx -t -c /cust1/nginx-1.18.0/conf/nginx.conf #Nginx服务启动前执行配置文件检测
ExecStart=/cust1/nginx-1.18.0/sbin/nginx #启动nginx
ExecReload=/cust1/nginx-1.18.0/sbin/nginx -s reload #Nginx服务重启前执行配置文件检测
ExecStop=/cust1/nginx-1.18.0/sbin/nginx -s stop #停止nginx
PrivateTmp=true
[Install]
WantedBy=default.target #多用户环境下启用
如果遇到下面的问题,就按照他的提示执行命令即可。
执行的命令
systemctl start nginx.service 启动nginx服务
systemctl stop nginx.service 停止服务
systemctl restart nginx.service 重新启动服务
systemctl list-units --type=service 查看所有已启动的服务
systemctl status nginx.service 查看服务当前状态
systemctl enable nginx.service 设置开机自启动
systemctl disable nginx.service 停止开机自启动
- 2.配置nginx命令到系统环境
[root@ecs-431f-0002 logs]# vim /etc/profile
export PATH=$PATH:/cust1/nginx-1.18.0/sbin #在文件末尾添加你的nginx的执行目录,入下图
[root@ecs-431f-0002 logs]# source /etc/profile #将配置文件进行生效
[root@ecs-431f-0002 logs]# nginx -v
nginx version: nginx/1.18.0
[root@ecs-431f-0002 logs]# ps -ef|grep nginx
root 2870143 1 0 15:54 ? 00:00:00 nginx: master process /cust1/nginx-1.18.0/sbin/nginx
nobody 2870144 2870143 0 15:54 ? 00:00:00 nginx: worker process
nobody 2870145 2870143 0 15:54 ? 00:00:00 nginx: worker process
root 2872306 2846004 0 15:59 pts/0 00:00:00 grep --color=auto nginx
[root@ecs-431f-0002 logs]# nginx -s reload #同样可以实现nginx的热加载,前后的pid发生了变化,master不变,worker进程发生了变化。
[root@ecs-431f-0002 logs]# ps -ef|grep nginx
root 2870143 1 0 15:54 ? 00:00:00 nginx: master process /cust1/nginx-1.18.0/sbin/nginx
nobody 2872382 2870143 0 16:00 ? 00:00:00 nginx: worker process
nobody 2872383 2870143 0 16:00 ? 00:00:00 nginx: worker process
root 2872385 2846004 0 16:00 pts/0 00:00:00 grep --color=auto nginx