nginx常用命令与相关理论

常用命令

进入安装目录的sbin文件夹下:

  • ./nginx 或 systemctl start nginx.service 启动
  • ./nginx -s stop 或systemctl stop nginx.service 或 kill -9/-15 pid 快速停止
  • ./nginx -s quit 处理完当前工作后停止
  • systemctl restart nginx.service 或 ./nginx -s reopen 重启
  • ./nginx -s reload 或 systemctl reload nginx 重新加载配置文件
  • ./nginx -v 查看版本信息
  • ps aux | grep nginx 查看启动后的记录
  • systemctl status nginx 状态
  • systemctl enable nginx.service 开启自启动
    docker 中
    docker run --name nginx -p 80:80 -d nginx 容器内文件
    docker exec -it nginx /bin/bash
docker run  -p 80:80 -p 443:443 --name nginx --restart=always \
-v /usr/local/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:rw \
-v /usr/local/nginx/conf.d:/etc/nginx/conf.d:rw \
-v /usr/local/nginx/html:/usr/share/nginx/html:rw \
-v /usr/local/nginx/logs:/var/log/nginx:rw \
-v /home/nginx/ssl:/etc/nginx/ssl/:rw \
-d  nginx
前面是主机地址,后面是docker中地址

docker logs nginx或者id 查看日志
docker save nginx > nginx.tar 查看未启动容器文件结构(将镜像打包,然后移出查看)
docker cp source container:target_path 将外部文件复制到容器内
docker cp container:source_path output_path 将容器内部文件复制到容器外

在这里插入图片描述
conf #配置文件
|-nginx.conf # 主配置文件
|-其他配置文件 # 可通过那个include关键字,引入到了nginx.conf生效

html #静态页面

logs
|-access.log #访问日志(每次访问都会记录)
|-error.log #错误日志
|-nginx.pid #进程号

sbin
|-nginx #主进程文件

*_temp #运行时,生成临时文件

业务流程

ngibx启动后会有两个进程(master负责协调,work负责处理用户请求响应)
在这里插入图片描述

nginx的基础配置:

简化版 nginx.conf

worker_processes  1; # 启动的worker进程数

events {
    worker_connections  1024; #每个worker进程的连接数
}

http {
    include       mime.types; #include是引入关键字,这里引入了mime.types这个配置文件(同在conf目录下,mime.types是用来定义,请求返回的content-type)
    default_type  application/octet-stream; #mime.types未定义的,使用默认格式application/octet-stream

    sendfile        on; #详情,见下文
    keepalive_timeout  65; #长链接超时时间
	
		#一个nginx可以启用多个server(虚拟服务器)
		#主机,通过端口区分
    server {
        listen       80;#监听端口80
        server_name  localhost;  #接收的域名

        location / { 
            root   html; #根目录指向html目录 
            index  index.html index.htm; #域名/index 指向 index.html index.htm文件
        }

        error_page   500 502 503 504  /50x.html; # 服务器错误码为500 502 503 504,转到"域名/50x.html"
        location = /50x.html {# 指定到html文件夹下找/50x.htm
            root   html;
        }
    }
}

server_name:匹配规则

  • 在配置server时:root后路径不以/开头是相对路径,从nginx根目录开始;以/开头是绝对路径, 从linux根开始
  • 书写配置文件server时,如果前面匹配了就不会去匹配后面了,如果都不匹配则会去第一个server
  • 一个server中可以书写多个域名,用空格隔开
  • 使用通配符:*.linsy.work
  • 正则表达式:`^www.linsy.work$

打开sendfile,用户请求的数据不再加载到nginx内存,而是直接发送
在这里插入图片描述
不打开sendfile
在这里插入图片描述

正/反向代理

正向代理服务器看不到真正的客户端,反向代理客户端看不到真正的业务服务器

正向代理

如使用梯子访问外络,我们的请求打到代理服务器,代理服务器再将请求打到国外的服务器,响应的数据依次返回至我们的客户端中。国外的服务器看不到真正的客户端。
在这里插入图片描述

反向代理

不需要你做任何设置,直接访问服务器真实ip或者域名,但是服务器内部会自动根据访问内容进行跳转及内容返回,你不知道它最终访问的是哪些机器。
用户访问资源,请求进互联网 => 网关 => nginx服务器 => 应用服务器
用户的请求不会直接打到应用服务器,与应用服务器不同。nginx作为一个中间商进行数据代理
在这里插入图片描述

内网反向代理

使用proxy_pass:+网址,这里使用了proxy_pass就不用root和index了。

  • 这里使用www和不使用www的区别就是不使用会请求重定向,之后就不j经过nginx服务器,这里使用请求转发时部分网站(如百度)会重定向两次至不再通过自己nginx服务器。
    在这里插入图片描述
    二级域名:
    *.weibo.com进入nginx被泛解析,反向代理交给Tomcat去数据库中查询 域名前缀信息,然后交给nginx返回用户
    在这里插入图片描述

负载均衡

轮询

在这里插入图片描述

weight(权重)

即按比例分发请求,如下16次请求分10次132,分4次133,分2次134,大约是按照这个比例。
在这里插入图片描述

down

表示当前主机不参与负载均衡,只剩133和134启用。
在这里插入图片描述

backup

备用服务器,正常情况下不会启用,只有当133宕机才会启用
在这里插入图片描述

保持会话的负载均衡(不常用)

生产上使用redis做session共享
都存在问题:无法动态更改:如下线一台服务器,上线两台服务器

场景:登录操作,客户端保存cookie,服务端保存session,若使用轮询或其它下一次请求打到另一台服务器,而找不到session。

ip_hash

当请求地址为同一个时将打到同一台服务器,不常用原因:如坐车使用手机,网络基站会切换导致切换到另一台服务器。

least_conn

最少连接数访问,不常用原因:1、由于权重造成的流量倾斜(性能好的流量多),不能违背初始设定,2、加入一台新的服务器,会使整体reload配置,造成服务短时间中断(停掉原来的工作进程,启动新的工作进程),重新启动可能会耗费较长时间。场景:用户请求打到服务器,服务器reload,保持和会话,2分钟后成功启动然后将响应返回给用户。

解决方式:异步,使用中间件处理慢服务。

url_hash

根据用户访问的url定向转发请求,不常用原因:如用户注册,网址:http://www.baidu.com/register,解析这个网址拿到对应的hash值去访问一台服务器,注册结束登录(本应该访问同一台服务器通过session免登录),网址:http://www.baidu.com/login ,在次解析网址对应的hash值与之前不同,可能造成访问的服务器不同,而无法实现免登录。

适用于固定资源不在同一服务器。

fair

根据后端服务器访问时间转发请求,不常用原因:如其中一台服务器由于交换机过热造成网络延迟瞬时比较高,请求倾斜到其它服务器,由于负载较高可能会被压垮。

动静分离

适用于中小型网站,因并发量不是特别高,且分离出来的资源也不是很多。
在这里插入图片描述

将一些静态资源放在nginx里(图片,css,js),使得动态请求仍然通过nginx访问服务器,而静态请求直接打到nginx就能拿到。

第一种方式:将资源放到nginx目录下,在location中书写资源地址,注意带有字符的斜杠放在单斜杠的后面。 因为 \ 的优先级低于 js\ ,就是带有字符的反斜杠优先级更高,如果放在前面则,但斜杠不会被解析。
在这里插入图片描述

第二种方式:正则表达式

location ~*/(js/img/css) { 
	root html;
	index  index.html index.htm;
}

URLRewrite

rewrite是URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。

rewrite    <regex>   <replacement>  [flag];
关键字		正则			替代后内容     flagt标记

正则:per1内容正则表达式语句进行规则匹配
替代后内容(即真实转发内容):将正则匹配的内容替换成replacement

flag标记说明:
last  #本条规则匹配完成后,继续向下匹配新的1ocation URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则

redirect #返回302临重定向,游览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,测览器地址栏会显示跳转后的URL地址

浏览器地址栏访问 xxx/123.html实际上是访问xxx/index.jsp?pageNum=123

server {
        listen       80;
        server_name  localhost;
				
				location / { 
						rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1  break;
        		proxy_pass http://xxx;
        }
      

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

网关

在这里插入图片描述
应用服务器不能直接被外网访问,只能被nginx服务器访问。nginx作为网关服务器转发请求与响应

在服务器的防火墙上添加规则:

这里是设置允许访问服务器的ip地址
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.52.129" port protocol="tcp" port="80" accept"

移除允许访问服务器的IP地址
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.52.129" port port="80" protocol="tcp" accept"

firewall-cmd --reload 重加载规则

查看已开启规则:firewall-cmd --list-all

防盗链

当我们请求得到一个页面后,往往会再次去请求获得一些静态资源。这个时候请求头中就有一个refer的字段,表示当前这个请求的来源,我们可以设定限制请求来源地址以达到节省资源的效果。
在这里插入图片描述

在这里插入图片描述
生产环境上上面的ip应是域名,上面配置如果检测到没有referer则报403
valid_referers none | blocked | server_name 将这行命令放在防盗链资源的location内

设置有效的refer值

  • none:检测地址没有referer可以访问,有但是错了不让访问
  • blocked:
  • server_name:设置一个或多个url,检测请求头中的referer是否来自这些url中的某一个,则有效(server_name必须是完整的http://xxxx)

注意:if ($invalid_referer)中if后有个空格,不写就会报错

curl 测试
在这里插入图片描述

curl -i http://192.168.52.129 查看响应头信息,不加参数 i 可看整个信息

curl -e “http://www.baidu.com” -i http://192.168.52.129 带referer引用访问

高可用

生产上只有一个nginx充当网关调用资源服务器,那么当这个nginx服务器宕机了,整个系统也就崩溃了。
解决方法就是添加多台nginx服务器,当其中的一台宕机后启用备用的nginx(多台nginx的ip不一样),但是客户端请求域名的ip地址是不能随意切换的,这里怎么样才能使请求打到备用nginx上呢?加一层又会陷入最开始的问题。

采用虚拟ip,映射到nginx上。使用keepalived,keepalived检测其它nginx是否存活,若当前含有虚拟ip的nginx宕机了,就会把虚拟IP交给备用的nginx,若备用nginx宕机了,则会反馈给维护人员,以此来达到nginx的高可用。
在这里插入图片描述

keepalived 是通过检查进程是否存活,然后互相发送信息包
yum install -y keepalived

修改keepalived配置
配置文件在/etc/keepalived/keepalived.conf
vrrp_instance、authentication、virtual_router_id、virtual_ipaddress这几个一样的机器,才算是同一个组里。这个组才会选出一个作为Master机器
这里我们设置两台机器,分别下载好keepalived,然后进行配置

! Configuration File for keepalived

global_defs {
   router_id lb1 # 名字与其他配置了keepalive的机器不重复就行
}

vrrp_instance heyingjie {#vrrp实例名可以随意取
    state MASTER #只能有一个默认的Master,其他写BACKUP
    interface ens33 # ip addr查看下网卡名,默认时ens33
    virtual_router_id 51
    priority 100 # 多台安装了keepalived的机器竞争成为Master的优先级
    advert_int 1 #通信时间
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16 #虚拟IP
    }
}
! Configuration File for keepalived

global_defs {
   router_id lb2 
}

vrrp_instance heyingjie {
    state BACKUP #只能有一个默认的Master,其他写BACKUP
    interface ens33 
    virtual_router_id 51
    priority 50
    advert_int 1 
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16 #虚拟IP
    }
}

不安全的协议、证书配置

https是先非对称加密,由服务器给用户发公钥,然后用户确定服务器是正常后,再对称加密,将消息加密发送(因为对称加密消耗低)

对称加密不安全:

在这里插入图片描述

非对称加密:

  1. 公钥加密,私钥解密
  2. 私钥加密,公钥解密
  3. 公钥加密,公钥解不开
  4. 要保证私钥的安全性,不在互联网传输
    在这里插入图片描述

也是不安全的:
消息经路由在传输过程中,若被拦截,其中某一个路由下发假的公钥给客户端,自己得到真正的服务器公钥。经假公钥信息在传输到这个路由时被被假私钥解码并响应假的数据可客户端,而这个路由拿着假公钥解密的真实信息去请求服务器从而盗取信息。
在这里插入图片描述

HTTPS(CA机构)

服务器将生成的公钥提交给CA机构进行公钥认证,然后生成证书。服务器端响应数据时携带证书,操作系统内嵌CA公钥,当操作系统利用CA公钥能解开证书说明信息没有被篡改过(证书在传递过程中能够被解开,但是由于CA私钥是不会公开的,所以不能再次对证书进行正确的加密 ),客户端解密证书后拿到服务器公钥然后对信息进行加密传输(当然这个公钥其它人也能得到,但是他用服务器公钥解不开公钥加密的信息),因此保证了数据的安全性。
在这里插入图片描述

nginx证书引入

下载证书,解压压缩包,可以看到两个文件,一个是 xxx.key(私钥)和xxx.pem(证书),将这两个文件上传到nginx.conf所在conf目录下,
在这里插入图片描述
然后配置nginx.conf文件,添加server

server {
	listen 443 ss1; #配置端口协议
	server_name localhost; #配置域名
	ss1 certificate  xxx.pem; #这里是证书路径
	ss1_ certificate_key  xxx.key  #这里是私钥路径
}