项目打包上线不知道怎么弄?教你用nginx最简单配置

406 阅读8分钟

安装

这个就不扯了,可以直接上网搜索

启动

进入安装好的目录 /usr/local/nginx/sbin

./nginx 启动
./nginx -s stop 快速停止
./nginx -s quit 优雅关闭,退出前完成已经接受的连接请求
./nginx -s reload 重新加载配置

启动完如果更改conf文件
直接可以 systemctl restart nginx

配置

虚拟主机配置

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html; 
            index  index.html index.htm;	 #访问80端口,找到nginx目录下的html目录下的index.html
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  • worker_processes

worker_processes 1; 默认为1,表示开启一个业务进程

  • worker_connections

worker_connections 1024; 单个业务进程可接受连接数

  • include mime.types;

include mime.types; 引入http mime类型

  • default_type application/octet-stream;

default_type application/octet-stream; 如果mime类型没匹配上,默认使用二进制流的方式传输。

  • sendfile on;

sendfile on; 使用linux的 sendfile(socket, file, len) 高效网络传输,也就是数据0拷贝。

  • keepalive_timeout 65;

keepalive_timeout 65; ,保持连接,超时时间。

  • server

虚拟主机配置 vhost

将前端应用上传到服务器,然后直接在服务器上打包,nginx路径配置到项目打包之后生成的dist文件即可

server {
    listen 80; 监听端口号
    server_name localhost; #域名、主机名
    location / { 匹配路径 (www.baidu.com/xxx/index.html, xxx/index.html就是
    location匹配的部分)
        root html; 
        // root指的是nginx的根目录,这里有相对路径和绝对路径的区别啊,因为是直接写的
        // html,所以是绝对路径,就是nginx的根目录,如果是/html,就是在服务器的根目录
        (记住是根路径)
        // 比如说你的项目在/root/workspace/webpack/dist, 这里就
        // 是/root//workspace/webpack/dist下
        // 了,下面有个例子
        index index.html index.htm; 默认页名称
    }
    error_page 500 502 503 504 /50x.html; 报错编码对应页面
    location = /50x.html {
        root html;
    }
}

原本一台服务器只能对应一个站点,通过虚拟主机技术可以虚拟化成多个站点同时对外提供服务

server {
    listen 80; 监听端口号
    server_name www.mmban.com; #域名、主机名
    location / { 匹配路径 (www.baidu.com/xxx/index.html, xxx/index.html就是
    location匹配的部分)
        root /www/www; 
        // 这里就是相对路径了,指的是服务器的根路径(根目录就是根目录,不是root文件下面)
        index index.html index.htm; 默认页名称
    }
    error_page 500 502 503 504 /50x.html; 报错编码对应页面
    location = /50x.html {
        root html;
    }
}

server {
    listen 80; #端口号和上面的相同,但是下面的server_name必须不同,不然会报错
    #listen 88 这里如果端口号是88,那就必须是vod.mmban.com:88(或者是s1.com:88(用本
    地host配置)才能匹配到这条)
    server_name vod.mmban.com vod1.mmban.com; #可以写多个域名
    location / { 匹配路径 (www.baidu.com/xxx/index.html, xxx/index.html就是
    location匹配的部分)
        root /www/vod; 
        // 这里就是相对路径了,指的是服务器的根路径
        index index.html index.htm; 默认页名称
    }
    error_page 500 502 503 504 /50x.html; 报错编码对应页面
    location = /50x.html {
        root html;
    }
}

如果用了泛解析,即*.mmban.com都指向服务器的ip,那也会跑到nginx的虚拟主机配置里,比如输入vod2.mmban.com,则会匹配第一个规则,进到/www/www/index.html里面,(这里就算是s1.com指向是服务器的ip(用本地host配置),也会匹配第一个规则,进到/www/www/index.html里面,太神奇了),如果需要到第二个规则,可以在server_name里配置多个域名,这里匹配规则不细讲了,精准匹配不到就走模糊匹配。

同一个端口号可以代理到不同的资源,太牛逼了

baidu.com 主域名(一级域名) www.baidu.com 子域名(二级域名)

域名解析相关企业项目实现技术构架

  • 多用户二级域名;
  • 短网址 淘宝拼多多那种分享链接;
  • httpdns 不适用于浏览器,适用于app/ cs架构;

反向代理和正向代理

正向代理代理客户端,反向代理代理服务器 客户端为了能够去访问外网,主动搞了个代理服务器去访问外网,就是正向代理 反向代理是服务器端搞的,客户端就是访问了服务器端,客户端是被动的

正向代理(看不到客户端真正的地址)主动 image.png

反向代理(看不到服务端真正的地址)被动 image.png

这里提一嘴restful风格api,大概就是这么个过程

  1. 获取用户列表
GET /users

2. 创建新用户

POST /users
{"name": "John", "age": 30}

3. 获取指定用户信息

GET /users/{userId}

4. 更新指定用户信息

PUT /users/{userId}
{"name": "John", "age": 31}

5. 删除指定用户

DELETE /users/{userId}

6. 获取指定用户的地址信息

GET /users/{userId}/addresses

7. 创建新地址

POST /users/{userId}/addresses
{"street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "12345"}

8. 获取指定地址信息

GET /users/{userId}/addresses/{addressId}

9. 更新指定地址信息

PUT /users/{userId}/addresses/{addressId}
{"street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "54321"}

10. 删除指定地址

DELETE /users/{userId}/addresses/{addressId}

使用proxy_pass进行代理配置

浏览器访问localhost或者ip或者某个域名命中了这个ip,就会跳转到 www.atguigu.com,同时域名没有变化(不支持https)

可以有多个server。然后根据策略、调度。

server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://www.atguigu.com;
            # proxy_pass http://atguigu.com; 不输入www的话,这个
            网址会自动帮你redirect,可以看到页面响应是302,然后连url上
            的网址都会改
            掉!有输www的是直接200,且url不会被改。其实要看你反向代理的
            这个网址是什么,如果http://www.qq.com,他甚至会帮你
            redirect到https://www.qq.com上面,协议都直接变了
            
            # 配了proxy_pass下面两个都会失效,直接注视
            #root   html; 
            #index  index.html index.htm;	 #访问80端口,找
            到nginx目录下的html目录下的index.html
            
            proxy_set_header X-real-ip $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 是代理服务器的地址
            proxy_set_header Host $host  # 域名
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

proxy_set_header X-real-ip 通过转发之后服务器是拿不到真正的ip地址的,只能拿到中间转发服务器的ip地址,可以通过设置这个请求头然后服务器通过request.header(X-real-ip)拿到真正的ip地址

image.png

image.png

负载均衡基本配置(轮询案例)

搞多两台虚拟机,三台虚拟机

  • 192.168.44.101
  • 192.168.44.102
  • 192.168.44.103

upstream httpds{
       server 192.168.44.102:80 weight=8 down; 
       #weight 权重,访问次数的比例,down 不用了
       #backup 预留的备份服务器; 其它所有的非backup机器down或者忙的时候,请求backup机
       器。
       server 192.168.44.103:80 weight=2 backup;  #backup 备胎
}

server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://httpds; #对应上面的upstream
            # 配了proxy_pass下面两个都会失效,直接注视
            #root   html; 
            #index  index.html index.htm;	 #访问80端口,找到nginx目录下的html目录下的index.html
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

访问192.168.44.101就能看到雨露均沾的效果,轮流访问192.168.44.102和192.168.44.103

负载均衡策略

其实下面这几种都不会在生产上用,问题太多了

  • 轮询:默认算法按时间顺序逐一分配到不同的后端服务器;
  • 加权轮询:Weight值越大,分配到访问几率越高;
  • ip_hash:为每一个请求访问的IP的hash结果分配,可以将来自一个IP的固定访问一个后端服务器;
  • url_hash:需要安装模块安装访问的URL的hash结果来分配,这样每个URL定向到同一个后端服务器
  • least_conn:按照某台机器最少连接数的进行分配访问;
  • fair

ip_hash 会话粘连, 上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。但是移动端会有问题,ip是动态的,那也炸开

或者服务器用springSession,在redis服务器上存session,不管访问到哪台服务器(因为只有之前的那台服务器上才有session),只要去redis服务器上就可以找到之前的session,但是不适应于高并发的形式,所以轮询+JWT(token)才是终极解决方案

轮询+JWT(token)好像是可以的喔,好像确实可以

服务器上下线的问题,服务器上下线需要nginx --reload 有状态连接会导致中断,开辟的new conf PID无法获取有状态链接,导致session会话失效

upstream test {
    ip_hash;
    server weiyigeek.top:8080;
    server weiyigeek.top:8081;
}

url_hash(第三方):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。使用场景就是当有些文件在固定的某个服务器上,比如a文件只有1服务器才有,那就可以用url_hash定位到1服务器上

在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

upstream backend {
  hash $request_uri;
  hash_method crc32;
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
} 

least_conn

描述: 将请求分配到连接数最少的服务上。

upstream  dalaoyang-server {
  least_conn;
  server    weiyigeek.top:10001;
  server    weiyigeek.top:10002;
} 

以上6种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过fair和url_hash需要安装第三方模块才能使用

动静分离

首先这里先理解一下前后端分离和不是前后端分离的情况,现在的前后端分离,就是前端负责html,js,css,比如一个react项目,直接扔上服务器上面,然后打包生成文件在dist文件下,然后前端直接nginx配置一下主机,就可以访问到对应的资源,后端只负责请求的接口,接口部署在tomcat上?

以前的不是前后端分离的情况就是js和css都是写在jsp上面,后端将jsp和接口一起部署在tomcat服务器上面

动静分离就是用在这种前后端不分离的情况,将jsp里的js和css搬到nginx上,就不用跑到tomcat上去加载了

随便看看就行了,现在谁还用jsp

upstream test{
  server weiyigeek.top:8080;
  server weiyigeek.top:8081;
}

server {
  listen       80;
  server_name  weiyigeek.top;
  location / {
      root   e:wwwroot;//文件夹路径
      index  index.html;
  }

  # 所有静态请求都由nginx处理,存放目录为nginx中的html
  location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
      root    e:wwwroot;
  }
  # 例子,比如
  #location /css{
  	#root html;
    #index index.html index.htm;
  #}
  

  # 所有动态请求都转发给tomcat处理
  location ~ .(jsp|do)$ {
      proxy_pass  http://test;
  }
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
      root   e:wwwroot;
  }
} 

URLRewrite

超级叼的功能哈,能重写url

server {
        listen       80;
        server_name  localhost;

        location / {
            rewrite ^/2.html$  /index.jsp?pageNum=2  break;  #这个flao有几个选项
            # 可以写成正则,这个你会的啦
            rewrite ^/([0-9]+).html$  /index.jsp?pageNum=$1  break;
            proxy_pass http://192.168.44.104:8080;
            #root   html; 
            #index  index.html index.htm;	 #访问80端口,找到nginx目录下的html目录下的index.html
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

上面这个写的本来是做了个反向代理,就是访问 http://192.168.44.101/index.jsp?pageNum=2 能方向代理到 http://192.168.44.104:8080/index.jsp?pageNum=2, 当然url上面还是显示的http://192.168.44.101/index.jsp?pageNum=2, 然后这里又做了一个重写url的功能,直接访问 http://192.168.44.101/2.html 就能访问到http://192.168.44.101/index.jsp?pageNum=2, 当然url也不会变,相当于转发了两遍, 转发是不会改变url的,只有重定向才会,如果flag设置成 redirect或者permanent url就改变,相当于又多跳转了一次

flag

ast #本条规则匹配完成后,继续向下匹配新的location URI规则

break #本条规则匹配完成即终止,不再匹配后面的任何规则

redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址 (防爬虫)

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

Gzip压缩

配置之后能在浏览器response_header里看到Content-Encoding: gzip和Transfer-Encoding: chunked,本来的Content-Length没了

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;
        gzip off;   // 是否开启压缩
        gzip_buffers 4 16k;  // 根据系统 32的 4 16k,64的 16 8k
        gzip_comp_level 5;  // 压缩等级 1~6
        gzip_http_version 1.1;  // 支持的最低http版本,不配默认1.1
        gzip_min_length 1k;  // 低于这个大小的文件不压缩
        gzip_proxyed any;  // 只有反向代理时这个选项才会生效
        gzip_types text/plain text/css application/javascript 
        application/x-javascript text/xml application/xml 
        application/xml+rss text/javascript image/x-icon 
        image/bmp; 
        gzip_vary on; // 增加一个header,适配老的浏览器

        location / {
            root   html; 
            index  index.html index.htm;	 #访问80端口,找到nginx目录下的html目录下的index.html
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

一些比较基础的知识

端口号

默认端口号是指在计算机系统中,某个网络服务所使用的默认端口号。一般来说,不同的网络服务都会使用不同的默认端口号,例如:

  • HTTP服务默认使用80端口。
  • HTTPS服务默认使用443端口。
  • FTP服务默认使用21端口。
  • SSH服务默认使用22端口。
  • SMTP服务默认使用25端口。
  • POP3服务默认使用110端口。
  • IMAP服务默认使用143端口。