Nginx + Node + Vue 部署初试(修改)

趁着爸妈做年夜饭之前,把之前做的笔记贴出来,新的一年到了,祝大家

Nginx + Node + Vue 部署初试

知乎

个人博客

Github

日常学习笔记

Nginx
  1. 定义

    异步框架的 Web服务器,也可以用作反向代理负载平衡器 , HTTP缓存, 媒体流等的开源软件。它最初是一个旨在实现最高性能和稳定性的Web服务器。除了HTTP服务器功能外,NGINX还可以用作电子邮件(IMAPPOP3SMTP)的代理服务器以及HTTPTCPUDP服务器的反向代理和负载平衡器。

  2. 特点

    • 更快
    • 高扩展性, Nginx的模块都是嵌入到二进制文件中执行
    • 高可靠性
    • 低内存消耗
    • 单机支持10万次的并发连接
    • 热部署, master管理进行与work工作进程分离设计,因此具备热部署功能
    • 最自由的BSD许可协议
  3. 功能

    • 静态服务(css , js , html, images, videos
    • SSLTLS SNI支持
    • HTTP/HTTPS, SMTP, IMAP/POP3 反向代理
    • FastCGI反向代理
    • 负载均衡
    • 页面缓存(CDN
    • 支持gzipexpirse
    • 支持 keep-alive 和管道连接
    • 基于 PCRErewrite 重写模块
    • 带宽限制
    • 基于IP 和名称的虚拟主机服务
    • 支持访问速率、并发限制
    • 反向代理(适用2000WPV、并发连接1W/秒),简单的负载均衡和容错
    • 基于客户端IP 地址和 HTTP 基本认证的访问控制
Mac 安装Nginx
// 推荐使用`brew`, 安装`homebrew`
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
// Homebrew 安装 Nginx 
brew install nginx
// Mac 下 Nginx的目录
cd /usr/local/etc/nginx
ll -al
vim nginx.conf
复制代码

homebrew详见

Nginx 参数列表
配置参数属性解释说明参数列表
user设置nginx服务的系统使用用户nobody(注意:此处用户如果比启动Nginx的用户权限低,你需要使用当前用户重启Nginx)
nginx -s stop 关闭nginx-> nginx 启动-> ps aux | grep nginx查看启动用户
worker_processes开启的线程数一般与服务器核数保持一致
error_log定位全局错误日志文件错误日志定义等级,[ debug | info notice | warn | error | crit ],debug输出最多,crir输出最少
pid指定进程id的存储文件位置
worker_rlimit_nofile指定一个nginx进程打开的最多文件描述符数目,受系统进程的最大打开文件数量限制
events包含Nginx中所有处理连接的设置
httpNginx http处理的所有核心特性
Event
配置参数属性解释说明参数列表
worker_connections定义每个进程的最大连接数,受系统进程的最大打开文件数量限制单个后台worker process进程的最大并发链接数 (最大连接数= worker_processes * worker_connections)
在反向代理环境下:
最大连接数 = worker_processes * worker_connections / 4
use工作进程数[ epoll | /dev/poll | poll | eventport | kqueue | select | rtsig ]
multi_accept一个新连接通知后接受尽可能多的连接on / off
accept_mutex开启或者禁用使用互斥锁来打开socketson / off

Event Use支持的事件模型

Events详见

HTTP
配置参数属性解释说明参数列表
include主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度,DNS主配置文件中的zonerfc1912,acl基本上都是用include语句
default_type核心模块指令默认设置为二进制流,也就是当文件类型未定义时使用这种方式
log_format日志格式的设定日志格式的名称,可自行设置,后面引用
access_log引用日志引用log_format设置的名称
keepalive_timeout设置客户端连接保存活动的超时时间0是无限制
sendfile开启高效文件传输模式on / off
tcp_nopush开启防止网络阻塞on / off
tcp_nodelay开启防止网络阻塞on / off
upstream负载均衡
serverNginx的server虚拟主机配置
Upstream
配置参数属性解释说明
轮询(默认)每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
weight指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
ip_hash每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。
url_hash(第三方)按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

weight 默认为1.weight越大,负载的权重就越大。

Nginx Upstream状态

例如:

upstream news {
    server 127.0.0.1:9527 backup;
    server 127.0.0.1:9527 weight=1 max_fails=2 fail_timeout=3;
    ...
}
复制代码
配置参数属性解释说明
backup预留的备份服务器
down当前的server暂时不参与负载均衡
fail_timeout经过max_fails 失败后,服务暂停的时间
max_conns限制最大的接收的连接数
max_fails允许请求失败的次数

use location:在server中添加

proxy_pass http://127.0.0.1:9527;
// 因为我的API接口是这个,such as /api/profile
// location 具体匹配规则详见后面
location ~ /api/ {
    proxy_pass http://127.0.0.1:9527;
}
复制代码
Server
配置参数属性解释说明参数列表
listen监听端口http -> 80 / https -> 443
server_name设置主机域名localhost
charset设置访问的语言编码
access_log设置虚拟主机访问日志的存放路径及日志的格式
location设置虚拟主机的基本信息
Location
配置参数属性解释说明参数列表
root设置虚拟主机的网站根目录Vue项目的根目录/Users/rainy/Desktop/MyWork/Work/cloudwiz-website/dist
index设置虚拟主机默认访问的网页index.html index.htm
proxy通过不同协议将请求从NGINX传递到代理服务器
  • =: 开头表示精确匹配,如 api 中只匹配根目录结尾的请求,后面不能带任何字符串.
  • ^~ :开头表示uri以某个常规字符串开头,不是正则匹配.
  • ~: 开头表示区分大小写的正则匹配.
  • ~*: 开头表示不区分大小写的正则匹配.
  • / : 通用匹配, 如果没有其它匹配,任何请求都会匹配到.

匹配优先级(高到低)

  1. location =
  2. location 完整路径
  3. location ^~ 路径
  4. location ~,~* 正则顺序
  5. location 部分起始路径
  6. /

详见Location配置

Reverse Proxy

NGINX代理请求时,它会将请求发送到指定的代理服务器,获取响应并将其发送回客户端。可以使用指定的协议将请求代理到HTTP服务器(另一个NGINX服务器或任何其他服务器)或非HTTP服务器(可以运行使用特定框架(如PHPPython)开发的应用程序)。

location  / some / path /  {
    proxy_pass  http://www.example.com:8080;
    
    proxy_set_header  Host  $ host ; 
    proxy_set_header  X-Real-IP  $ remote_addr ;
    
    // 禁用特定位置的缓冲
    proxy_buffering  off ;
    proxy_buffers  16  4k ; 
    proxy_buffer_size  2k ;
    
    proxy_bind  127.0.0.2 ; // IP地址也可以用变量指定
}
复制代码

将请求传递给非HTTP代理服务器,**_pass应使用相应的指令:

配置参数属性解释说明参数列
proxy_pass将请求传递给HTTP代理服务器
proxy_set_header传递请求标头默认情况下,NGINX在代理请求中重新定义两个头字段“Host”和“Connection”,并删除其值为空字符串的头字段。“Host”设置为$proxy_host变量,“Connection”设置为close
proxy_buffering负责启用和禁用缓冲on / off
proxy_buffers请求分配的缓冲区的大小和数量
proxy_buffer_size代理服务器的响应的第一部分存储在单独的缓冲区大小通常包含一个相对较小的响应头,并且可以比其余响应的缓冲区小。
proxy_bind接受来自特定IP网络或IP地址范围的连接指定proxy_bind必要网络接口的指令和IP地址

详见Proxy

全局变量Global Variable
变量名变量含义
$args请求中的参数
$content_lengthHTTP请求信息里的Content-Length
$content_type请求信息里的Content-Type
$host请求信息中的Host,如果请求中没有Host行,则等于设置的服务器名
$http_cookiecookie 信息
$http_referer引用地址
$http_user_agent客户端代理信息
$remote_addr客户端地址
$remote_port客户端端口号
$remote_user客户端用户名,认证用
$request_method请求的方法,比如GETPOST
$request_uri完整的原始请求URI(带参数)
$scheme请求方案,httphttps
$server_addr接受请求的服务器的地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_protocol请求的协议版本,HTTP/1.0HTTP/1.1
$uri请求中的当前URI, $uri在请求处理期间 ,值可能会发生变化,例如在执行内部重定向或使用索引文件时

全局变量详见Alphabetical index of variables

修改 http server中的配置

启动Nginx

nginx
ps -ef | grep nginx
复制代码

重新加载修改后的Nginx配置文件

nginx -s reload
复制代码

多谢小伙伴给提出的问题(详见评论区),reloadresatrt是两个不同的概念。

  1. reload 重新加载conf文件,不中断Nginx服务,conf文件有问题则加载上一次的conf.
  2. restart 会根据配置文件,重启整个Nginx服务,造成服务器中断一段时间,当然会因为conf文件问题报错。

关闭Nginx

nginx -s stop
复制代码

因为我已经启动了,所以就重启一下Nginx即可

Linux安装Nginx

Linux安装

常见的Linux命令

使用pstree查看当前服务器启动的进程

pstree
复制代码

查找Nginx的位置

ps -aux | grep nginx
复制代码

进入nginx的目录

然后配置nginx.conf文件即可

Docker安装Nginx
  1. 查找 Docker Hub 上的 nginx镜像

    docker search nginx
    复制代码

  2. 拉取官方镜像

    docker pull nginx
    复制代码
  3. 查看当前镜像

    docker images nginx
    复制代码

Server Tree
tree -C -L 3 -I '*node_modules*'

├── server
│   ├── app.js
│   ├── db
│   │   ├── db.js
│   │   └── newsSql.js
│   ├── package-lock.json
│   ├── package.json
│   └── routers
│       ├── news.js
│       └── router.js
复制代码

Node Server
npm init
npm install express mysql body-parser -S
复制代码
  1. app.js

    const express = require('express')
    const bodyParser = require('body-parser')
    const app = express()
    const router = require('./routers/router')
    
    const PORT = 9527
    
    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({ extended: true }))
    
    app.use(router)
    
    app.listen(PORT, () => {
      console.log(`Listen port at ${PORT}`)
    })
    
    复制代码
  2. db.js -> Mysql配置

    module.exports = {
      mysql: {
        host: 'localhost',
        user: 'root',
        password: 'xxxx',
        database: 'test',
        port: '3306'
      }
    }
    复制代码
  3. router.js

    const express = require('express')
    const router = express.Router()
    const news = require('./news')
    
    router.get('/api/news/queryAll', (req, res, next) => {
      news.queryAll(req, res, next)
    })
    
    router.get('/api/news/query', (req, res, next) => {
      news.queryById(req, res, next)
    })
    
    router.post('/api/news/add', (req, res, next) => {
      news.add(req, res, next)
    })
    
    router.post('/api/news/update', (req, res, next) => {
      news.update(req, res, next)
    })
    
    router.delete('/api/news/deleteNews', (req, res, next) => {
      news.deleteNews(req, res, next)
    })
    
    module.exports = router
    复制代码
  4. newSql.js

    module.exports = {
      createNews: `CREATE TABLE news (
        id int(255) NOT NULL AUTO_INCREMENT,
        type varchar(255) CHARACTER SET utf8 NOT NULL,
        title varchar(255) CHARACTER SET utf8 NOT NULL,
        description varchar(255) CHARACTER SET utf8 NOT NULL,
        occur_time varchar(255) CHARACTER SET utf8 NOT NULL,
        url varchar(255) NOT NULL,
        newsImg varchar(255) NOT NULL,
        PRIMARY KEY (id)
      )`,
      queryAll: 'SELECT * FROM news',
      queryById: 'SELECT * FROM news WHERE id = ?',
      add: 'INSERT INTO news (type, title, description, occur_time, url, newsImg) VALUES (?, ?, ?, ?, ?, ?)',
      update: 'UPDATE news SET type = ?, title = ?, description = ?, occur_time = ?, url = ?, newsImg = ? WHERE id = ?',
      delete: 'DELETE FROM news WHERE id = ?'
    }
    复制代码
  5. news.js

    const mysql = require('mysql')
    const db = require('../db/db')
    const $newsSql = require('../db/newsSql')
    
    let pool = mysql.createPool(db.mysql)
    
    let queryAll = (req, res, next) => {
      pool.getConnection((error, connect) => {
        if (error) {
          throw error
        } else {
          connect.query($newsSql.queryAll, (error, data) => {
            if (error) {
              throw error
            }
            res.json({
              code: '200',
              msg: 'success',
              data
            })
            connect.release()
          })
        }
      })
    }
    
    let queryById = (req, res, next) => {
      let id = +req.query.id
      pool.getConnection((error, connect) => {
        if (error) {
          throw error
        } else {
          connect.query($newsSql.queryById, id, (error, data) => {
            if (error) {
              throw error
            }
            res.json({
              code: '200',
              msg: 'success',
              data
            })
            connect.release()
          })
        }
      })
    }
    
    let add = (req, res, next) => {
      let rb = req.body
      let params = [rb.type, rb.title, rb.description, rb.occur_time, rb.url, rb.newsImg]
      pool.getConnection((error, connect) => {
        if (error) {
          throw error
        } else {
          connect.query($newsSql.add, params, (error, data) => {
            if (error) {
              throw error
            }
            res.json({
              code: '200',
              msg: 'success'
            })
            connect.release()
          })
        }
      })
    }
    
    let update = (req, res, next) => {
      let rb = req.body
      let params = [rb.type, rb.title, rb.description, rb.occur_time, rb.url, rb.newsImg, rb.id]
      pool.getConnection((error, connect) => {
        if (error) {
          throw error
        } else {
          connect.query($newsSql.update, [...params], (error, data) => {
            if (error) {
              throw error
            }
            res.json({
              code: '200',
              msg: 'success'
            })
            connect.release()
          })
        }
      })
    }
    
    let deleteNews = (req, res, next) => {
      let id = +req.query.id
      pool.getConnection((error, connect) => {
        if (error) {
          throw error
        } else {
          connect.query($newsSql.delete, id, (error, data) => {
            if (error) {
              throw error
            }
            res.json({
              code: '200',
              msg: 'success'
            })
            connect.release()
          })
        }
      })
    }
    
    module.exports = {
      queryAll,
      queryById,
      add,
      update,
      deleteNews
    }
    复制代码
Vue配置代理以及使用api
  1. config/index.js 修改proxyTable

    module.exports = {
      dev: {
        proxyTable: {
          '/api': {
            target: 'http://127.0.0.1:9527',
            changeOrigin: true,
            pathRewrite: {
              '^/api': '/api'
            }
          }
        }
      }
    }
    复制代码
  2. 使用axios调用接口

    import axios from 'axios'
    export default {
      created () {
        this._getAllNews()
      },
      methods: {
        _getAllNews () {
          axios.get('/api/news/queryAll').then(res => {
                if (+res.data.code === SCC_CODE) {
                  this.news = res.data.data
                }
              })
          }
        }
    }
    复制代码
Vue build打包
npm run build
复制代码

因为我的Server端是Express写的,启动Server需要使用Node,所以我们需要在服务器上安装Node.

Linux安装Node 8.x
# Using Ubuntu
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

# Using Debian, as root
curl -sL https://deb.nodesource.com/setup_8.x | bash -
apt-get install -y nodejs

# Using Centos
curl -sL https://rpm.nodesource.com/setup_8.x | bash -
yum install -y nodejs
复制代码

具体安装各版本的Node详见

启动Node

此处我之前的命令执行错误,所以我需要kill这个进程

nohup node website/server/app.js &
复制代码

nohup:可以将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端。

无论是否将 nohup命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到$HOME/nohup.out文件中。如果没有文件能创建或打开以用于追加,那么 command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。

到这里,我们的WebNode ServerNginx都已经配置并启动好了,我们只需要到浏览器输入你的服务器IP:8080即可.

Nginx众多概念详见官方词汇表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值