Linux架构之nginx
目录
Linux架构之nginx
nginx概述与安装:
Nginx 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,处理高并发能力强,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。
nginx应用场景:
- Nginx作为web服务器
Nginx 可以作为静态页面的 web 服务器,同时还支持 CGI 协议的动态语言,比如 perl、php等,但是不支持 java
- Nginx作为正向代理服务器
正向代理:也就是传说中的代理,他的工作原理就像一个跳板。简单地说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录。结论就是,正向代理,是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
- Nginx作为反向代理服务器
反向代理,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址
- Nginx作为负载均衡服务器
客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。
这种架构模式对于早期的系统相对单一,并发请求相对较少的情况下是比较适合的,成本也低。但是随着信息数量的不断增长,访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器相应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃。很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?
我们首先想到的可能是升级服务器的配置,比如提高 CPU 执行频率,加大内存等提高机器的物理性能来解决此问题,但是我们知道摩尔定律的日益失效,硬件的性能提升已经不能满足日益提升的需求了。最明显的一个例子,天猫双十一当天,某个热销商品的瞬时访问量是极其庞大的,那么类似上面的系统架构,将机器都增加到现有的顶级物理配置,都是不能够满足需求的。那么怎么办呢?
上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法行不通了,那么横向增加服务器的数量呢?这时候集群的概念产生了,单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡
- Nginx作为静态资源访问服务器
把静态html页面,css样式,js脚本,图片等静态资源放到服务器上,然后使用Nginx作为静态资源访问服务器,对外访问地址。
Nginx快速安装:
- rpm安装
- epel仓库(阿里云)
- 官方仓库
- 源码安装
使用官方源安装:nginx
# 1.添加nginx官方源
[root@web01 ~]# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
# 2.安装nginx
[root@web01 ~]# yum install -y nginx
# 3.启动nginx并加入开机自启
[root@web01 ~]# systemctl start nginx
[root@web01 ~]# systemctl enable nginx
# 4.查看nginx的版本
[root@web01 ~]# nginx -v
nginx version: nginx/1.22.0
# 5.查看nginx的版本和源码安装生成步骤的参数有哪些
[root@web01 ~]# nginx -V
-v 打印版本号
-V 显示版本号和配置选项
-t 测试(检查)配置文件并退出
-T 测试配置文件,并且运行
-q 打印错误日志
-s 操作进程(发送信号到主进程)
stop 停止,停止但不是立即停止
quit 退出,马上停止退出
reopen 重启
reload 重新加载
-p 指定nginx的工作目录默认/etc/nginx
-e 指定错误日志路径
-c 指定配置文件的路径
-g 设置一个全局的nginx参数(配置项)
Nginx的启停
# 1.启动
systemctl start nginx
nginx
/app/nginx/sbin/nginx
# 2.停止
systemctl stop nginx
nginx -s stop
/app/nginx/sbin/nginx -s stop
# 3.重新加载
systemctl reload nginx
nginx -s reload
/app/nginx/sbin/nginx -s reload
## nginx启动脚本systemd管理
[root@web01 ~]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)"
[Install]
WantedBy=multi-user.target
###如果是源码安装,使用fpm打包,脚本内容:
# 先写脚本
[root@web01 ~]# vim post_install_nginx.sh
ln -s /application/nginx-1.20.2 /opt/nginx
echo 'PATH="/usr/local/nginx/sbin:$PATH"' > /etc/profile.d/nginx.sh
cat >> /usr/lib/systemd/system/nginx.service <<EOF
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/application/nginx/nginx.pid
ExecStart=/application/nginx/sbin/nginx -c /application/nginx/conf/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /application/nginx/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /application/nginx/nginx.pid)"
[Install]
WantedBy=multi-user.target
EOF
Nginx配置文件及详解:
1.Nginx主配置文件
路径 | 类型 | 作用 |
---|---|---|
/etc/nginx/nginx.conf | 配置文件 | nginx主配置文件 |
/etc/nginx/conf.d/default.conf | 配置文件 | nginx网站示例配置文件 |
2.Nginx代理相关参数文件
路径 | 类型 | 作用 |
---|---|---|
/etc/nginx/fastcgi_params | 配置文件 | Fastcgi代理配置文件 |
/etc/nginx/scgi_params | 配置文件 | scgi代理配置文件 |
/etc/nginx/uwsgi_params | 配置文件 | uwsgi代理配置文件 |
3.Nginx编码相关配置文件
路径 | 类型 | 作用 |
---|---|---|
/etc/nginx/win-utf | 配置文件 | Nginx编码转换映射文件 |
/etc/nginx/koi-utf | 配置文件 | Nginx编码转换映射文件 |
/etc/nginx/koi-win | 配置文件 | Nginx编码转换映射文件 |
/etc/nginx/mime.types | 配置文件 | Content-Type与扩展名 |
4.Nginx管理相关命令
路径 | 类型 | 作用 |
---|---|---|
/usr/sbin/nginx | 命令 | Nginx命令行管理终端工具 |
/usr/sbin/nginx-debug | 命令 | Nginx命令行与终端调试工具 |
5.Nginx日志相关目录与文件
路径 | 类型 | 作用 |
---|---|---|
/var/log/nginx | 目录 | Nginx默认存放日志目录 |
/etc/logrotate.d/ngin | 配置文件 | Nginx默认的日志切割 |
Nginx配置文件详解
## nginx主配置文件
[root@web02 nginx]# grep -Ev '^$|#' /etc/nginx/nginx.conf
## 注意:nginx配置文件,每一行,都';'结尾
[root@web01 nginx]# vim /etc/nginx/nginx.conf
## 核心层(核心模块)、全局配置
# nginx启动用户配置
user nginx;
# nginx工作线程数量(cpu亲和)
worker_processes auto;(auto 自动根据cpu的核心数来启动对应的工作进程数)
# 错误日志 日志路径 日志级别
error_log /var/log/nginx/error.log notice;
# 程序启动进程号(pid号)存放的路径
pid /var/run/nginx.pid;
## 事件层(事件模块)
events {
# 一个worker进程的最大连接数
worker_connections 1024;
}
## http层,http模块、网站配置
http {
## 浏览器中,默认可以解析的格式(不需要下载的格式)
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;
## 长链接,超时时间 65s
keepalive_timeout 65;
## 数据传输过程中,使用gzip压缩
#gzip on;
## 包含 nginx其他子配置文件(网站虚拟主机配置文件server)
include /etc/nginx/conf.d/*.conf;
}
#日志级别
none:不记录日志
debug:调试信息,系统进行调试时产生的日志,不属于错误日志,不需要过多关注。
info:一般的通知信息,用来反馈系统的当前状态给当前用户。
notice:提醒信息,需要检查一下程序了,不理会可能会出现错误。
warning:警告信息,当出现警告时,你的程序可能已经出现了问题,但不影响程序正常运行,尽快进行处理,以免导致服务宕掉。
error:错误信息,出现这一项时,已经挑明服务出现了问题,服务都无法确认是否能正常运行。
critical:比较严重的错误信息,服务已经宕了,可能已经无法修复。
alert:警报信息,需要立即采取行动,不仅是服务宕了,还会影响系统的正常启动。
emerg:紧急信息,系统可能已经不能使用了,如果不能解决,就重新装机吧。
#日志格式
$remote_addr:远端的IP(上一个节点的IP)
$remote_user # 记录客户端用户名
$time_local # 记录通用的本地时间
$time_iso8601 # 记录ISO8601标准格式下的本地时间
$request # 记录请求的方法以及请求的http协议 'GET /index.html HTTP 1.1'
$status # 记录请求状态码(用于定位错误信息)
$body_bytes_sent # 发送给客户端的资源字节数,不包括响应头的大小
$bytes_sent # 发送给客户端的总字节数
$msec # 日志写入时间。单位为秒,精度是毫秒。
$http_referer # 记录从哪个页面链接访问过来的
$http_user_agent # 记录客户端浏览器相关信息
$http_x_forwarded_for #记录客户端IP地址
$request_length # 请求的长度(包括请求行, 请求头和请求正文)。
$request_time # 请求花费的时间,单位为秒,精度毫秒
# 注:如果Nginx位于负载均衡器,nginx反向代理之后, web服务器无法直接获取到客户端真实的IP地址。
# $remote_addr获取的是反向代理的IP地址。 反向代理服务器在转发请求的http头信息中,
# 增加X-Forwarded-For信息,用来记录客户端IP地址和客户端请求的服务器地址。
#日志切割
[root@nginx conf.d]# cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily # 每天切割日志
missingok # 日志丢失忽略
rotate 52 # 日志保留52天
compress # 日志文件压缩
delaycompress # 延迟压缩日志
notifempty # 不切割空文件
create 640 nginx adm # 日志文件权限
sharedscripts
postrotate # 切割日志执行的命令
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
虚拟主机配置文件
## 虚拟主机配置文件
server {
## 该网站的监听端口
listen 80;
## 该网站的主机IP或域名
server_name localhost;
## 该网站的日志路径及日志格式
#access_log /var/log/nginx/host.access.log main;
## uri跳转
location / {
## 站点目录
root /usr/share/nginx/html;
## 默认首页,索引页面
index index.html index.htm;
}
}
server层是网站配置层,包含在http层中多虚拟主机
root和alias区别
alias实现虚拟⽬录 alias与root的⽤法区别
最基本的区别:alias指定的⽬录是准确的,root是指定⽬录的上级⽬录,并且该上级⽬录要含有location指定名称的同名⽬录。另外,根据
前⽂所述,使⽤alias标签的⽬录块中不能使⽤rewrite的break。
(1) . alias虚拟⽬录配置中,location匹配的path⽬录如果后⾯不带"/",那么访问的url地址中这个path⽬录后⾯加不加"/"不影响访问,访问时
它会⾃动加上"/";
但是如果location匹配的path⽬录后⾯加上"/",那么访问的url地址中这个path⽬录必须要加上"/",访问时它不会⾃动加上"/"。如果不加
上"/",访问就会失败!
(2) . root⽬录配置中,location匹配的path⽬录后⾯带不带"/",都不会影响访问。
所以,⼀般情况下,在nginx配置中的良好习惯是:
1)在location /中配置root⽬录;
2)在location /path中配置alias虚拟⽬录。
#结论:
1 alias是一个目录别名的定义,root则是最上层目录的定义。使用root时,会到root + location 寻找资源;使用alias时,会到alias后定义的目录中找资源;
2 alias后面必须要用“/”结束,否则会找不到文件的。而root则可有可无;
Nginx如何配置虚拟主机
基于多虚拟主机(多web网站配置)
在企业中,是不可能用一个nginx对应一套业务,多个网站都在一个nginx中配置
基于IP的多虚拟主机
#创建虚拟IP
[root@web01 conf.d]# ifconfig eth0:0 10.0.0.10
[root@web01 conf.d]# ifconfig eth0:1 10.0.0.11
[root@web01 conf.d]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.7 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::a319:8c13:9238:5bb6 prefixlen 64 scopeid 0x20<link>
inet6 fe80::3077:9382:f10c:ae23 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:9a:b0:68 txqueuelen 1000 (Ethernet)
RX packets 80416 bytes 76841088 (73.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 47140 bytes 15283547 (14.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.10 netmask 255.0.0.0 broadcast 10.255.255.255
ether 00:0c:29:9a:b0:68 txqueuelen 1000 (Ethernet)
[root@web01 conf.d]# cat 1_game.conf
server{
listen 80;
server_name 10.0.0.10;
location /{
root /game/h5_games;
index index.html;
}
}
[root@web01 conf.d]# cat 1_lw.conf
server{
listen 80;
server_name 10.0.0.7;
root /code;
location /{
index index.html;
}
location /zls{
index index_1.html huanglong.html;
}
}
基于多端口的虚拟主机
[root@web01 conf.d]# cat game.conf
server{
listen 8081;
server_name 10.0.0.7;
location /{
root /game/h5_games;
index index.html;
}
}
[root@web01 conf.d]# cat lw.conf
server{
listen 8082;
server_name 10.0.0.7;
root /code;
location /{
index index.html;
}
}
基于多域名的虚拟主机
[root@web01 conf.d]# cat blog.lw.com.conf
server{
listen 80;
server_name blog.lw.com;
root /lw1;
index index.html;
}
[root@web01 conf.d]# cat www.lw.com.conf
server{
listen 80;
server_name www.lw.com;
root /lw;
index index.html;
}
如何在windows系统中,配置本地的DNS
1.按win+r打开运行
2.输入drivers
3.进入etc目录
4.使用notepad++打开hosts文件
5.添加域名解析
Nginx常用模块
Nginx目录索引模块
ngx_http_autoindex_module
模块处理以斜杠字符('/')结尾的请求,并生成目录列表。 当 ngx_http_index_module
模块找不到索引文件时,通常会将请求传递给 ngx_http_autoindex_module
模块。
Syntax: autoindex on | off; #可以选择开或关
Default: #默认是关闭
autoindex off;
Context: http, server, location #适用模块
server{
## 监听端口
listen 80;
## 域名(ip,localhost,_,域名)
server_name _;
## uri
location /{
## 站点目录(代码存放目录)
root /test;
## 目录索引模块 开启;
autoindex on;
## 显示带单位的大小
autoindex_exact_size off;
## 目录索引页面显示格式(默认html)
#autoindex_format json;
## 显示本地时间
autoindex_localtime on;
}
}
Nginx状态模块
[root@web01 conf.d]# cat xxx.conf
server{
listen 80;
server_name _;
location /{
root /test;
autoindex on;
autoindex_exact_size off;
#autoindex_format json;
autoindex_localtime on;
}
location /lw{
stub_status;
}
}
Nginx访问控制模块
基于用户密码(auth_basic)
## 安装htpasswd命令
[root@web01 conf.d]# yum install -y httpd
## 创建存放认证文件的目录
[root@web01 nginx]# mkdir /etc/nginx/auth
## 创建认证文件
[root@web01 nginx]# htpasswd -b -c /etc/nginx/auth/lw_auth lw 123
## 查看认证文件内容
[root@web01 nginx]# cat /etc/nginx/auth/lw_auth
lw:$apr1$cS1Q1N2x$XXW/MODdxtFVnhWhgFV1m1
## 修改nginx配置文件,添加认证
[root@web01 nginx]# vim /etc/nginx/conf.d/xxx.conf
server{
listen 80;
server_name _;
auth_basic "password is 123";
auth_basic_user_file /etc/nginx/auth/lw_auth;
location /{
root /test;
autoindex on;
autoindex_exact_size off;
#autoindex_format json;
autoindex_localtime on;
}
location /lw{
stub_status;
}
}
-b:允许命令行中输入密码
-c:创建一个新文件,将用户名和密码保存到指定文件中
[root@web01 ~]# htpasswd -b /etc/nginx/auth/lw_auth lw1 123
Adding password for user lw1
[root@web01 ~]# cat /etc/nginx/auth/lw_auth
lw:$apr1$cS1Q1N2x$XXW/MODdxtFVnhWhgFV1m1
abc:$apr1$TRSviTnR$yzTB40uDeoizPhKivTX6c.
lw1:$apr1$1.D1EWsB$NsmYuBMi/CVtm3BGBpbzz0
nginx默认路径:/etc/nginx
基于IP访问控制(access)
[root@web01 ~]# vim /etc/nginx/conf.d/xxx.conf
server{
listen 80;
server_name _;
auth_basic "password is 123";
auth_basic_user_file auth/zls_auth;
location /{
root /test;
autoindex on;
autoindex_exact_size off;
#autoindex_format json;
autoindex_localtime on;
allow 10.0.0.8;
deny all;
}
location /lw{
stub_status;
}
}
## 注意:默认nginx是allow all;如果只允许某一个IP需要配合deny all使用,deny all;要放在最下面
curl http://用户名:密码@10.0.0.7
访问频率限制
连接频率限制(limit_conn)
http{
limit_conn_zone $remote_addr zone=随便起内存空间的名字:10m;
server {
limit_conn 随便起内存空间的名字 1;
}
}
conn_zone:内存空间的名字
1:连接次数
请求频率限制(limit_req)
# http标签段定义请求限制, rate限制速率,限制一秒钟最多一个IP请求
http {
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
}
server {
listen 80;
server_name module.oldboy.com;
# 1r/s只接收一个请求,其余请求拒绝处理并返回错误码给客户端
#limit_req zone=req_zone;
# 请求超过1r/s,剩下的将被延迟处理,请求数超过burst定义的数量, 多余的请求返回503
limit_req zone=req_zone burst=3 nodelay;
location / {
root /code;
index index.html;
}
}
#请求频率限制错误页面优化
[root@web01 test]# cat /etc/nginx/conf.d/xxx.conf
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server{
listen 80;
server_name _;
auth_basic "password is 123";
auth_basic_user_file auth/zls_auth;
limit_req zone=req_zone burst=3 nodelay;
limit_req_status 508; #(400 - 599之间)
error_page 508 /508.html;
location /{
root /test;
autoindex on;
autoindex_exact_size off;
#autoindex_format json;
autoindex_localtime on;
#allow 10.0.0.8;
#deny all;
}
location /lw{
stub_status;
}
}