目录
什么是nginx
使用nginx的命令
nginx的目录结构
nginx的基本请求流程
nginx的基础配置文件
虚拟主机
虚拟主机域名配置
正向代理
反向代理
负载均衡
负载均衡策略
轮询策略
权重策略
ip_hash策略
least_conn策略
url_hash策略
fair策略
nginx常见属性
down属性
backup属性
动静分离
静态页面
动态请求
关于静态资源location匹配
urlRewrite
flag标记说明
防盗链
防盗链与自定义错误文件
防盗链配置
使用curl测试防盗链
curl基本命令
nginx高可用
前言
keepalived的使用
测试
nginx是一款高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,因为其稳定、丰富的功能集,简单的配置文件和地系统的资源消耗而闻名
注意:
进入安装好nginx的sbin目录
访问时注意关闭防火墙
关闭防火墙:systemctl stop firewalld.service
禁止防火墙开机自启:systemctl disable firewalld.service
访问虚拟机:http://192.168.126.129
注意:默认会跳到nginx内html目录下的index.html页面
注意:
conf:存放nginx的主配置文件
注意:nginx.conf为nginx的核心配置文件,里面进行nginx的一些策略设置等,在该配置文件里面会引用到其他配置文件
html:存放默认情况下(成功、失败等)的网页和其他的一些静态资源
logs:用来记录访问日志(分别有成功访问日志以及失败访问日志)
sbin:存放nginx的主程序,用于nginx的启动与关闭等
理解:nginx服务开启(此时nginx已经通过sbin目录下的主程序开启),首先nginx的Master主进程会把nginx.conf配置文件的内容读取进来并校验,若配置文件没有错误,则他的会开启多个子进程,来等待客户端发起的请求,worker对请求进行响应与解析,找到html目录,并将对应的资源返回给用户。
注意:nginx的主进程不处理业务,他的主要作用就是协调这些子进程worker
#说明在启动nginx的时候要启动多少个子进程
worker_processes 1;
#事件驱动模块
events {
#每一个work进程能够创建多少个连接
worker_connections 1024;
}
#http协议(里面可有多个主机,客户端请求按照顺序进行)
http {
#include作用是把另外一个配置文件引入到我们当前的配置文件当中
#mime.types-请求头,头里面会表明当前给客户端发送的文件的类型
include mime.types;
#如果类型不包含在mime.types里,那么就会用下面的默认类型
default_type application/octet-stream;
#数据零拷贝,若为off则nginx应用程序会读取资源后复制给网络接口,若为on,则nginx不去加载资源,会向网络接口添加信号;网络接口来读取资源(网络接口读到文件后直接通过网路将数据发送给用户)
sendfile on;
#保持连接超时的时间
keepalive_timeout 65;
#一个server代表一个虚拟主机,可写多个server(每个虚拟主机之间互相不干扰)
server {
#可以通过端口号的方式来区分主机的不同(当前服务器主机在80端口运行)
listen 80;
#表示当前主机的主机名(域名/主机名)
server_name localhost;
#localion表示拦截root目录下的子目录路径名(可写多个location)
location / {
#root表示以nginx目录下的什么目录为根目录(这里用到了相对路径-nginx内的html)
root html;
#index表示响应给具体目录下的具体页面
index index.html index.htm;
}
#如果发生下面错误码的错误,那么就会转向/50x.html这个地址
error_page 500 502 503 504 /50x.html;
#一旦用户访问/50.html,那么就会在root目录下寻找50x.html
location = /50x.html {
root html;
}
}
}
理解:把一台主机虚拟出来更多的主机(实现了一个ip地址可以访问多个域名),由nginx里判断,该客户端到底要访问哪个域名,nginx找到资源后将其返回给客户端
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
#访问端口号为88,打破http默认端口
listen 88;
#配置的域名,对应的是本机ip(域名可以写多个)
server_name cjc.com;
#拦截uri为/app的请求
location /{
#响应根目录下的www/main内的资源
root /www/main;
#响应的资源名
index main.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#第二个虚拟主机(顺序执行)
server {
listen 80;
server_name localhost;
location /{
#这里用了相对路径,nginx下html内的static目录
root html/static;
index app.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 90;
server_name localhost;
location /{
#proxy_pass的作用:将拦截的请求响应到一个地址上
proxy_pass http://www.265.com/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
注意:
含义:客户端发送的请求会先经过代理服务器,然后代理服务器转发请求到目标服务器,代理服务器从目标服务器获得内容后响应给客户端,整个过程目标服务器不知道是哪个具体客户端发出的请求(客户端没法访问目标服务器,通过代理服务器进行转发)
含义:用户发送请求到目标服务器,由代理服务器决定访问哪个ip,整个后面的过程用户不清楚,也不清楚是哪个服务器为自己处理的请求,全是由反向代理服务器决定
理解:用户在访问系统时通过互联网到我们系统的网关路由上,网关会将请求转发到具体的nginx服务器上,此服务器为nginx反向代理服务器,他会把用户发来的所有请求转发到我们后端的应用服务器(用户不能够直接访问外网服务器,必须通过nginx将请求转发给服务器;然后服务器将结果返回给nginx,nginx再将数据传递给用户)
#虚拟主机
server {
listen 90;
server_name cjc.com;
location /{
#proxy_pass后面配置一个服务器地址(不支持https服务器)
proxy_pass http://192.168.18.16:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
经测试向nginx服务器发送参数时,nginx会向目标服务器实现请求转发功能,该请求会发送到目标服务器内
即访问:cjc.com:90?name=lili
等价于:http://192.168.18.16:8080?name=lili
含义:请求发送到系统时,通过某些方式把请求均匀分发到多个节点上,使系统中的每个节点都能够均匀的处理请求负载,则可以认为系统是负载均衡的
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#虚拟主机
server {
listen 88;
server_name cjc.com;
location /{
#proxy_pass后面配置一个服务器地址(不支持https服务器)
proxy_pass http://randomName/getPort;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#upstream定义一组服务器来使用,用来配置负载均衡
upstream randomName{
server 192.168.18.16:8080;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
}
在后端开启了3个端口(8080、8081、8082)的服务
@RestController
public class TestController {
@Value("${server.port}")
private String port;
@GetMapping("/getPort")
public String getPort(String user){
System.out.println(user);
return "当前端口号"+port;
}
}
注意:访问cjc.com:88?name=lili等价于向randomName服务器集群中/getPort?name=lili
含义:按照配置文件的顺序依次访问(默认为轮询)
upstream randomName{
server 192.168.18.16:8080;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
分别给每个服务适当的权重,若没有设置权重,那么默认权重为1
#upstream定义一组服务器来使用,用来配置负载均衡
upstream randomName{
#为该服务设置权重为6
server 192.168.18.16:8080 weight=6;
#为该服务设置权重为3
server 192.168.18.16:8081 weight=3;
#为该服务设置权重为1
server 192.168.18.16:8082 weight=1;
}
判断来源的ip地址,相同的ip指向相同的服务器
upstream randomName{
#与第一个服务进行绑定
ip_hash;
server 192.168.18.16:8080;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
注意:
最少连接访问:寻找连接数最少的服务器进行访问
upstream randomName{
least_conn;
server 192.168.18.16:8080 backup;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
注意:这里有一个问题,比如某个服务器由于性能原因,通过权重策略使得该服务器的流量变少,这时使用该最少连接访问那么就不合理
判断来源的url路径,相同的url指向相同的服务器-比如注册的时候被转发到某台服务器(少用)
注意:使用该策略时需要安装第三方插件
根据后端服务器响应速度来实现转发请求(有流量倾斜的风险)
注意:使用时还得安装插件很少用
理解:若down属性标识了该服务器,则nginx不会再次访问该服务器
upstream randomName{
#down掉第一个服务,ip_hash;自动绑定下一个服务
ip_hash;
server 192.168.18.16:8080 down;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
理解:设置备用机,正常情况下备用机不会被访问,但当主机遇忙或者down机后,备用机才会被访问
upstream randomName{
#将第一台机器设置为备用机
server 192.168.18.16:8080 backup;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
理解:将动态请求和静态请求分离开,将静态资源前置到nginx里,将动态请求打到后端的tomcat中
作用:动静分离的基础是它可以根据配置不同的请求做不同的转发,动静分离有利于提高整个服务器系统的性能
#访问cjc.com对应的ip地址:80
server {
listen 80;
server_name cjc.com;
#后接/static会返回nginx/html/static目录下的app.html页面
location /static{
root html;
index app.html;
}
#后接/fix会返回nginx/html/fix目录下的fix.html页面
location /fix{
root html;
index fix.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 80;
server_name cjc.com;
location /{
proxy_pass http://randomName/getPort;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
upstream randomName{
least_conn;
server 192.168.18.16:8080 backup;
server 192.168.18.16:8081;
server 192.168.18.16:8082;
}
后端开启8080端口
@RestController
public class TestController {
@RequestMapping("/first.html")
public String getFirst(String username){
return "第一名:"+username;
}
}
通过正则匹配实现用2.html代替后端first.html?username=lili这个请求
server {
listen 88;
server_name cjc.com;
location /{
rewrite ^/2.html$ /first.html?username=lili break; #break为flag标记
rewrite ^/1.html$ /first.html?username=lan break;
proxy_pass http://192.168.18.16:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
请求:http://192.168.18.16:8080/2.html
相当于请求:http://192.168.18.16:8080/first.html?username=lili
注意:urlRewrite规则可以写多个
含义:存在我们服务器上的那些资源只能由我们自己的服务器来进行访问,其他地方的服务器地址来引入该资源则访问失败
server {
listen 80;
server_name cjc.com;
location /static{
#设置可以访问该静态资源的地址(none标识防盗链的配置,最后面的域名可以设置多个,多个之间用空格隔开)
valid_referers none 192.168.18.16;
#如果不是白名单,则会报403错误
if ($invalid_referer) {
#这里也可以直接rewrite
#rewrite ^/ img/x.png break;
return 403;
}
root html;
index app.html;
}
#如果发生下面错误码的错误,那么就会转向/50x.html这个地址
error_page 500 502 503 504 /50x.html;
#一旦用户访问/50.html,那么就会在root目录下寻找50x.html
location = /50x.html {
root html;
}
error_page 403 /40x.html;
location = /40x.html {
root html;
}
}
注意:
格式:valid_referers none server_name
linux下安装curl:yum install -y curl
curl -I http://192.168.44.101/img/logo.png
解释:
curl -e "http://baidu.com" -I http://192.168.44.101/img/logo.png
解释:表示访问192.168.44.101引用http://baidu.com内img下的logo.png资源
我们知道后端的应用服务器通过nginx的负载均衡保证了后端服务的高可用(后端服务器冗余备份,以备不时之需);但是我们应该怎么保证nginx的高可用呢?
开两个nginx服务,通过keepalived通信机制,keepalived不需要nginx加一层机器,其跑在运行中的机器上;当keepalived跑起来以后两台keepalived的机器(nginx)上会互相通信,来检测对方是否挂掉;两台机器既然要同时提供服务,那么两台机器必然具有不同ip地址,那么前端的用户请求应该请求哪个ip地址呢?
keepalived会管理虚拟ip地址在两台服务器中切换,用户发的请求都会通过虚拟ip,当一台机器down后,那么虚拟ip地址就会在下一个机器中。
简单解释:就是一个两个nginx以及所在的机器和keepalived都运行着,一个nginx提供服务,另一个nginx当备胎,用户请求只请求那个虚拟ip地址;那么一个nginx机器down了,虚拟ip跑到下一个nginx机器上,备用机开始提供服务
安装keepalived:yum install -y keepalived
进入/etc/keepalived目录的keepalived.conf文件
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
#vrrp为keepalived在内网当中通信的协议,VI_1为实例名称,可以随机写
vrrp_instance VI_1 {
#state表示当前机器是master
state MASTER
#interface后面接网卡名称
interface ens33
virtual_router_id 51
#priority表示优先级,主备竞选来决定谁是master
priority 100
#间隔检测的时间
advert_int 1
#分组认证配置(同一组保持一致)
authentication {
auth_type PASS
auth_pass 1111
}
#虚拟ip地址,可以添写多个
virtual_ipaddress {
192.168.126.130
}
}
启动keepalived:systemctl start keepalived
查看keepalived状态:systemctl status keepalived
查看ip地址:ip addr
可以看出多了个vip
然后在第二个含有nginx的linux服务器内配置keepalived
在对应的keepalived.conf文件内配置
! Configuration File for keepalived
global_defs {
#改变router_id名称
router_id LVS_DEVEL1
}
vrrp_instance VI_1 {
#将状态设置为备用机
state BACKUP
interface ens33
virtual_router_id 51
#优先级相对于master设置的低一些,因为是备用机
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
#虚拟ip地址,可以添写多个
virtual_ipaddress {
192.168.126.130
}
}
注意:
将第二个keepalived也启动
通过外网ping 192.168.126.130会发现起初master主机可以给外网计算机发送数据,当把主机down掉,那么会发现备用机身上的ip突然多出了192.168.126.130,备用机开始给主机发送数据(实现了ip漂移)