nginx使用纪要

一、基本概念

1、nginx个人理解

nginx是一个web服务器,啥叫web服务器呢?我画个简图:
在这里插入图片描述
客户端各种请求,我们会让它们先去nginx(通过域名控制);nginx会根据请求的种类,安排对应的处理,比如请求是访问网站的、nginx就给他对应的页面,是请求接口的、nginx给它对接接口。这种接收各种客户端请求、并根据请求类别给予对应资源的服务器,就叫web服务器。

那这样的安排有什么作用?或者说使用web服务器有什么好处呢?
第一,可以做服务端负载均衡
在分布式系统中,用加机器扩展系统,是提升可用性的最有效方法。但扩展系统时,需要在应用服务前添加1个负载均衡服务,让它能将请求流量分发给后面的应用。
这一场景中,除了对负载均衡服务的性能有极高的要求外,它还必须能够处理应用层协议,而NGINX不仅性能极高、还非常擅长应用层的协议处理,完美胜任这个角色。
第二,指到静态资源
就是把http或者https请求指到对应的vue等前端项目,或具体的图片等。
有朋友就要问了,我直接访问服务器静态资源不行吗?
少了当然可以,但是多了的时候就不好找了;nginx找静态资源,优势在于它处理这种找静态资源的请求效率特别高,没别的、就是又快又准。
第三,反向代理
有的请求,是直接要访问动态资源的,就是想直接找接口要结果数据;nginx可以通过反向代理满足这一需求。
我直接访问接口好好的,为什么非要“多此一举”经nginx这么一手呢?
并不是多此一举,直接访问接口当然可以,但是很多时候,我们的接口不是谁想访问就访问的,需要对请求做有些筛选、增强、跳转等等,或者像后面要说的,限制只能接收https请求;这些额外的要求,写代码就费老鼻子事了,可以通过nginx配置实现上述功能,为了使用nginx的这项能力,有时候就需要配nginx反向代理。
配置外网可以访问的地址
nginx这个功能,就是它反向代理的一个应用实例。
工作中,有时候需要把某些只有内网可以访问的地址,设置成外网可以访问的;比如,我们要给商城测试环境的支付功能配置一个支付宝沙箱支付,支付宝要求回调地址要是外网可以访问的,但无论是我们本地(连的公司网,ip网外不可访问)还是测试服务器,都只有内网可以访问。这时,你就可以找运维申请把测试机改成外网可以访问的地址,你只需要告诉运维,你需要把
123.12:7001(开发电脑,端口为服务端口)
456.89:7002(测试服务器,端口为服务端口)
配置成外网可访问的地址。
运维会通过部署在外网可访问服务器的nginx(假设该服务器叫A、ip是202.103),使用反向代理把你的对服务器A特定端口的访问指向你的测试服务器
比如,设置用户访问202.103:5001,指向开发机123.12:7001;
设置用户访问202.103:5002,指向测试服务器456.89:7002。

二、实际应用

1、实例1:普通vue项目打包、部署、通过nginx访问

1)打包

不同项目有所区别,比较简单的如下

# 打包命令不同项目有略微差别,核心命令
npm run build

# 我们项目前端给配了测试、生产环境,测试环境打包命令是
npm run build:stage

# 建议先看一下项目的README文件

2)包上传到服务器

打包之后,得到一个文件夹,一般叫dist、也有其他名字的
在这里插入图片描述
提前再linux上、合适的位置建好放代码的文件夹,将dist中的内容传过去
在这里插入图片描述

3)配置nginx

我以自己遇到的情况为例说明,如果你的linux服务器还没有装nginx,那就先装一下。

a、找到nginx位置
# 先用命令找nginx进程pid
ps -aux | grep nginx

# 再用命令找位置
ll /proc/[写pid]/cwd

在这里插入图片描述

b、配置nginx.conf

在nginx下的conf中,配置文件nginx.conf
在这里插入图片描述
在文件中编辑 http{} 块 中的 server{} 块
新增(或者编辑已经不用的)server,主要是以下几个地方:

# server{}中的listen
listen :代理端口

# server{}中的server_name
server_name:服务名,比较简单的就写服务器ip;
# 注意,还可以写域名,但是需要额外的配置,后面示例会介绍,这个实例是简单的测试服务器的nginx配置、不过多说明

# location{}中的root和index
root :资源根目录
index :默认索引页面

在这里插入图片描述
附上配置文件示例,大家可以参照

server {
    listen       9001;
    server_name  192.168.191.52;
    location / {
      root   /webserver/nuohua2023/ui/admin;
      try_files $uri $uri/ /index.html $uri/ =404;
      index  index.html index.htm;
      add_header X-Content-Type-Options  'nosniff';#禁止嗅探文件类型
      add_header Content-Security-Policy "script-src 'self' 'unsafe-eval' 'unsafe-inline' oyxdwx.com:9443 *.aliyun.com unpkg.com g.alicdn.com *.alibaba.com *.aliapp.org *.csslcloud.net *.qq.com *.bokecc.com";#只允许同源下的js
      add_header X-XSS-Protection "1; mode=block";#开启XSS过滤器
    }
  }

4)重启nginx

# 重启:进入nginx的sbin中,执行
./nginx -s reload

# 或者在nginx下执行
./sbin/nginx -s reload

# 或者在任意目录执行(注意不同系统nginx安装位置可能不同,path指nginx安装位置)
path/sbin/nginx -s reload
# 例如
/usr/local/nginx/sbin/nginx -s reload

# 上面三个命令效果相同

# 补充:停止nginx服务
./sbin/nginx -s stop

4)访问
以我上面对admin的配置为例,访问首页地址应该是

http://192.168.191.52:9001

2、nginx主从配置(也可以叫父子配置、主子配置等)

1)场景说明

一台nginx服务器,往往不只为我们一个项目使用;尤其在测试环境,多个项目公用一个nginx的情况很多。
这个时候,如果多个项目的nginx配置都放在一个conf配置文件中,会特别混乱;有的同事习惯不好、加配置还不写备注,更有甚者配错了、导致所有项目都用不了…
这个种情况,怎么处理会更好呢?

2)优化方式

正常的nginx配置,结构如下图
在这里插入图片描述

a、主配置

在nginx.conf这个主配置中,我们保留所有公共配置,但是所有server不要写在主配置中。

b、子配置

在nginx/conf文件夹下新建一个文件夹,我这里叫www,在此文件夹下建多个.conf配置文件,具体建多少个看需要,一般是一个项目一个;这些子配置文件,最好以项目名简称.conf格式命名、做到见名知义,如下图:
在这里插入图片描述
每个子配置文件中,做各自的server{}模块配置,例如:

# xxx项目-后台
  server {
    listen       4101;
    server_name  192.168.191.52;
    location / {
      root   /webserver/nuohua/ui/admin;
      try_files $uri $uri/ /index.html $uri/ =404;
      index  index.html index.htm;
      add_header X-Content-Type-Options  'nosniff';#禁止嗅探文件类型
      add_header Content-Security-Policy "script-src 'self' 'unsafe-eval' 'unsafe-inline' oyxdwx.com:9443 *.aliyun.com unpkg.com g.alicdn.com *.alibaba.com *.aliapp.org *.csslcloud.net *.qq.com *.bokecc.com";#只允许同源下的js
      add_header X-XSS-Protection "1; mode=block";#开启XSS过滤器
    }
  }

  # xxx项目-用户端pc
  server {
    listen       4102;
    server_name  192.168.191.52;
    location / {
      root   /webserver/nuohua/ui/web;
      try_files $uri $uri/ /index.html $uri/ =404;
      index  index.html index.htm;
      add_header X-Content-Type-Options  'nosniff';#禁止嗅探文件类型
      add_header Content-Security-Policy "script-src 'self' 'unsafe-eval' 'unsafe-inline' *.bokecc.com class.csslcloud.net *.amap.com *.haoyisheng.com 192.168.191.52";#只允许同源下的js
      add_header X-XSS-Protection "1; mode=block";#开启XSS过滤器
    }
  }

  # xxx项目-用户端h5
  server {
    listen       4103;
    server_name  192.168.191.52;
    location / {
      root   /webserver/nuohua/ui/web_h5;
      try_files $uri $uri/ /index.html $uri/ =404;
      index  index.html index.htm;
      add_header X-Content-Type-Options  'nosniff';#禁止嗅探文件类型
      add_header Content-Security-Policy "script-src 'self' 'unsafe-eval' 'unsafe-inline' 192.168.191.51:7000 p.bokecc.com class.csslcloud.net";#只允许同源下的js
      add_header X-XSS-Protection "1; mode=block";#开启XSS过滤器
    }
  }
c、在主配置的http模块加include,引入子配置
# 在nginx.conf的http{}模块中,加入include配置
http {
	......
	include path/www/*.conf
}
# 其中path指子配置目录所在位置,可以用相对路径、也可以用绝对路径
# 相对路径,就是指相对于主配置文件的路径,比如我这里子配置文件都在主配置文件同级的www文件夹中
http {
	......
	include www/*.conf
}
# 绝对路径,就是从根目录开始的路径,示例如下
http {
	......
	include /usr/local/nginx/conf/www/*.conf
}
# *.conf就是说,把目录下所有conf文件引入到主配置的http{}模块中

配置完成后重启nginx即可生效。

ok,通过以上主从配置后,各个项目的nginx分开配置,开发们各改各的,清晰明了;而且出了问题,也好定位。
甚至可以为每个子配置单独配置访问日志,用的不多就不多说了;但是这个主从配置真的很好用,强烈建议采用。

3、nginx安装 SSL模块

Nginx的https功能是基于ngx_http_ssl_module模块来实现的,这个模块默认不安装,需要手动装以下。
第一步:查看nginx是否安装了ssl模块,在nginx目录执行(注意,如果报“未找到命令”,说明nginx没有配环境变量)

nginx -v

我的执行结果如下
在这里插入图片描述
configure arguments后面如果有值,如上图,就说明安好了;没有的话接着往下看。

依次执行以下命令安装ssl模块

./configure --with-http_ssl_module
make 
make install

4、实例2:配置nginx接收https请求

1)首先,要了解一点基础知识。

https协议是在http协议的基础上,出于数据安全的考虑、对传输数据进行加密传输的一种协议。
https是通过网景公司设计的SSL(Secure Sockets Layer)协议对数据进行加密的;换句话说,https协议由ssl+http协议构建而成。
所以,要发送https请求,需要通过ssl对数据进行加密;
要接收https请求,也需要通过ssl协议对数据进行解密。

另一个概念,CA(Certificate Authority,证书授权/授权证书),可以把它理解为电子证书;相当于生活中的“门禁卡”、“工卡”、“会员卡”。
在ssl协议下,只有使用相同的ca证书,才能对ssl加密数据进行解密。
通用的ca证书需要向GoDaddy或VeriSign等大机构申请,需要一定费用;如果是不知名或本土机构颁发的ca证书,需要专门安装这些ca证书才能和通用的证书一样解析对应的ssl加密数据。

2)使用正规的ca证书,配置nginx接收https请求

先说比较顺利的情况,先联系公司的运维,看看能不能提供可用的ca证书。
比如,运维提供,abc.com的ca证书(包括公钥abc.com.pem,私钥abc.com.key两个文件),把ca证书放到服务器专门的文件夹下,比如/usr/local/nginx/ssl_key,接着做如下配置

a、nginx做主从配置
b、针对前端

专门开几个子配置文件(有几个端开几个,比如有客户端、管理端,因为两个端域名不同,就新建两个子配置)。
举例,我这个系统有客户端,测试域名设置为buyertest.abc.com(二级域名、顶级域名要与ca证书匹配,三级域名自定义,尽量见名知义),那么对应的子配置文件需要这样配置

  server {
    listen       80;
    listen       443 ssl;
    server_name  buyertest.abc.com;
    
    ssl_certificate      /usr/local/nginx/ssl_key/abc.com.pem;
    ssl_certificate_key  /usr/local/nginx/ssl_key/abc.com.key;

    ssl_session_cache    shared:SSL:20m;
    ssl_session_timeout  10m;

    ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers  on;

    # 用户端
    location / {
      root   /webserver/javashop/ui/buyer;
      try_files $uri $uri/ /index.html $uri/ =404;
      index  index.html index.htm;
      add_header X-Content-Type-Options  'nosniff';#禁止嗅探文件类型
      add_header Content-Security-Policy "script-src 'self' 'unsafe-eval' 'unsafe-inline' 192.168.191.51:7000";#只允许同源下的js
      add_header X-XSS-Protection "1; mode=block";#开启XSS过滤器
    }
  }

配置说明:
https请求的默认端口是443,所以同时监听80和443端口;
如果是http请求(80端口),nginx会作正常的处理(不用解密),然后指到对应的静态文件;
如果是https请求(443端口),nginx会通过ssl、ca证书对数据先进行解密,然后指到静态文件;

listen       80;
listen       443 ssl;

监听域名,当然是我们设置的客户端域名

server_name  buyertest.abc.com;

给nginx的ssl模块配置ca证书,即配置公钥、私钥

ssl_certificate      /usr/local/nginx/ssl_key/abc.com.pem;
ssl_certificate_key  /usr/local/nginx/ssl_key/abc.com.key;

再往下ssl的配置,我都是采用查到的同一配置,大家也可以参照写一样

ssl_session_cache    shared:SSL:20m;
ssl_session_timeout  10m;
ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers  on;

最后的localhost配置,也和普通的前端项目nginx配置一样

配置完成后重启nginx,
至此,nginx接收https请求就以配置完毕!

注意,因为我们的域名是自己编的、公网解析不了,所以我们需要在测试的电脑上,配置一下host文件

buyer.abc.com	服务器ip

大功告成!

c、针对后端

一般来说,后端使用同一个域名,所以配一个nginx子配置文件即可。
与前端不同的地方在于,前端请求nginx最终将给它指到静态文件(页面),而后端请求nginx最终通过反向代理指到对应接口。
和上边一样,先给后端编一个测试域名apitest.abc.com(二级域名、顶级域名要与ca证书匹配,三级域名自定义,尽量见名知义),nginx子配置如下:

  
server {
	listen       80;
	server_name  apitest.abc.com;
	rewrite ^(.*)$ https://$host$1 permanent;
	access_log  /backup/logs/nginx/kmapitest.haoyisheng.com-access.log  main;
}

  
  
server {
	listen       443 ssl;
	server_name  apitest.abc.com;
	ssl_certificate      /usr/local/nginx/sslkey/abc.com.pem;
	ssl_certificate_key  /usr/local/nginx/sslkey/abc.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
    ssl_prefer_server_ciphers on;
    client_max_body_size 10M;

    	location /buyer {
                proxy_pass    http://xxx:7002;
                proxy_set_header Host $host:$server_port;
                proxy_pass_header User-Agent;
                }
                
        location /seller {
                proxy_pass   http://xxx:7003;
                proxy_set_header Host $host:$server_port;
                proxy_pass_header User-Agent;
                }

        location /admin {
                proxy_pass   http://xxx:7004;
                proxy_set_header Host $host:$server_port;
                proxy_pass_header User-Agent;
                }
        access_log  /backup/logs/nginx/apitest.abc.com-access.log  main;
}

配置说明:
我们这里要求,后端只能接受https请求,对于http请求就需要对其进行强转、也就是重定向:

server {
	listen       80;
	server_name  apitest.abc.com;
	rewrite ^(.*)$ https://$host$1 permanent;
	access_log  /backup/logs/nginx/kmapitest.haoyisheng.com-access.log  main;
}

对于nginx的ssl模块配置,与前端相同,这里就不赘述了。
最后,和前端不同,要把请求通过反向代理,指到对应接口(接口可以是装nginx的本服务器的、也可以是其他可访问服务器的)

		location /buyer {
                proxy_pass    http://xxx:7002;
                proxy_set_header Host $host:$server_port;
                proxy_pass_header User-Agent;
                }
                
        location /seller {
                proxy_pass   http://xxx:7003;
                proxy_set_header Host $host:$server_port;
                proxy_pass_header User-Agent;
                }

location后面要配置/模块名,要求后端必须配置springbootserver:servlet:context-path,location后模块名要与之对应,以客户端配置为例,yml配置如下:
在这里插入图片描述
nginx的location后就配置/buyer

3)使用自签的ca证书,配置nginx接收https请求

再说一下不顺利的情况,网上说、可用通过以下步骤,申请自签ca证书,再服务器依次执行以下命令(有的命令需要填配置,公司名啊、要申请的域名啊,等等),执行完成后,最终会获得两个文件:
xxx.crt文件
xxx.key文件
通过自签证书,也能实现接收https请求(测试环境);其中crt文件,和上面pem公钥文件一样。

我没有实操过,把命令记录在下边,大家需要可用去试试

# 使用openssl生产服务端、客户端私钥
openssl genrsa -out server.key 1024
openssl genrsa -out client.key 1024

# 使用openssl生产服务端、客户端公钥
openssl rsa  -in client.key -pubout -out client.pem
openssl rsa  -in server.key -pubout -out server.pem

# 生成ca私钥
openssl genrsa -out ca.key 1024
# 生成ca-csr请求文件
openssl req -new -key ca.key -out ca.csr
# 生成ca-crt证书
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

# 生成客户端、服务器csr请求文件
openssl req -new -key server.key -out server.csr
openssl req -new -key client.key -out client.csr

# 生成客户端、服务端crt证书
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt

# 生成nginx需要的私钥和crt证书
openssl rsa -in server.key -out server_nginx.key
openssl x509 -req -days 3650 -in server.csr -signkey server_nginx.key -out server_nginx.crt

最后使用server_nginx.crt 和 server_nginx.key 这两个文件。
之后配置如下:

 server {
        listen       8061 ssl;
        server_name  hlhk.com;

        ssl_certificate      /root/new_cert/server_nginx.crt;
        ssl_certificate_key  /root/new_cert/server_nginx.key;

		# 后面配置与前面2)一样,省略
   }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值