趁着爸妈做年夜饭之前,把之前做的笔记贴出来,新的一年到了,祝大家Nginx + Node + Vue 部署初试知乎个人博客Github日常学习笔记Nginx定义异步框架的 Web服务器,也可以用作反向代理,负载平衡器 , HTTP缓存, 媒体流等的开源软件。它最初是一个旨在实现最高性能和稳定性的Web服务器。除了HTTP服务器功能外,NGINX还可以用作电子邮件(IMAP,POP3和SMTP)的代理服务器以及HTTP,TCP和UDP服务器的反向代理和负载平衡器。特点更快高扩展性, Nginx的模块都是嵌入到二进制文件中执行高可靠性低内存消耗单机支持10万次的并发连接热部署, master管理进行与work工作进程分离设计,因此具备热部署功能最自由的BSD许可协议功能静态服务(css , js , html, images, videos)SSL 和 TLS SNI 支持HTTP/HTTPS, SMTP, IMAP/POP3 反向代理FastCGI反向代理负载均衡页面缓存(CDN)支持gzip、expirse支持 keep-alive 和管道连接基于 PCRE 的 rewrite 重写模块带宽限制基于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/nginxll -alvim nginx.confhomebrew详见Nginx 参数列表配置参数属性解释说明参数列表user设置nginx服务的系统使用用户nobody(注意:此处用户如果比启动Nginx的用户权限低,你需要使用当前用户重启Nginx)nginx -s stop 关闭nginx-> nginx 启动-> ps auxgrep 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)在反向代理环境下:<br/>最大连接数 = worker_processes worker_connections / 4use工作进程数[ epoll /dev/poll \poll \eventport \kqueue \select \rtsig ]multi_accept一个新连接通知后接受尽可能多的连接on / offaccept_mutex开启或者禁用使用互斥锁来打开socketson / offEvent Use支持的事件模型Events详见HTTP配置参数属性解释说明参数列表include主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度,DNS主配置文件中的zonerfc1912,acl基本上都是用include语句 default_type核心模块指令默认设置为二进制流,也就是当文件类型未定义时使用这种方式log_format日志格式的设定日志格式的名称,可自行设置,后面引用access_log引用日志引用log_format设置的名称keepalive_timeout设置客户端连接保存活动的超时时间0是无限制sendfile开启高效文件传输模式on / offtcp_nopush开启防止网络阻塞on / offtcp_nodelay开启防止网络阻塞on / offupstream负载均衡 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 -> 443server_name设置主机域名localhostcharset设置访问的语言编码 access_log设置虚拟主机访问日志的存放路径及日志的格式 location设置虚拟主机的基本信息 Location配置参数属性解释说明参数列表root设置虚拟主机的网站根目录Vue项目的根目录/Users/rainy/Desktop/MyWork/Work/cloudwiz-website/distindex设置虚拟主机默认访问的网页index.html index.htmproxy通过不同协议将请求从NGINX传递到代理服务器 =: 开头表示精确匹配,如 api 中只匹配根目录结尾的请求,后面不能带任何字符串.^~ :开头表示uri以某个常规字符串开头,不是正则匹配.: 开头表示区分大小写的正则匹配.: 开头表示不区分大小写的正则匹配./ : 通用匹配, 如果没有其它匹配,任何请求都会匹配到.匹配优先级(高到低)location =location 完整路径location ^~ 路径location , 正则顺序location 部分起始路径/详见Location配置Reverse Proxy当NGINX代理请求时,它会将请求发送到指定的代理服务器,获取响应并将其发送回客户端。可以使用指定的协议将请求代理到HTTP服务器(另一个NGINX服务器或任何其他服务器)或非HTTP服务器(可以运行使用特定框架(如PHP或Python)开发的应用程序)。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应使用相应的指令:fastcgi_pass 将请求传递给FastCGI服务器uwsgi_pass 将请求传递给uwsgi服务器scgi_pass 将请求传递给SCGI服务器memcached_pass 将请求传递给memcached服务器配置参数属性解释说明参数列proxy_pass将请求传递给HTTP代理服务器 proxy_set_header传递请求标头默认情况下,NGINX在代理请求中重新定义两个头字段“Host”和“Connection”,并删除其值为空字符串的头字段。“Host”设置为$proxy_host变量,“Connection”设置为close。proxy_buffering负责启用和禁用缓冲on / offproxy_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请求的方法,比如GET、POST等$request_uri完整的原始请求URI(带参数)$scheme请求方案,http或https$server_addr接受请求的服务器的地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);$server_protocol请求的协议版本,HTTP/1.0或HTTP/1.1$uri请求中的当前URI, $uri在请求处理期间 ,值可能会发生变化,例如在执行内部重定向或使用索引文件时全局变量详见Alphabetical index of variables修改 http server中的配置启动Nginxnginxps -ef | grep nginx重启Nginxnginx -s reload关闭Nginxnginx -s stop因为我已经启动了,所以就重启一下Nginx即可Linux安装NginxLinux安装常见的Linux命令使用pstree查看当前服务器启动的进程pstree查找Nginx的位置ps -aux | grep nginx进入nginx的目录然后配置nginx.conf文件即可Docker安装Nginx查找 Docker Hub 上的 nginx镜像docker search nginx拉取官方镜像docker pull nginx查看当前镜像docker images nginxServer Treetree -C -L 3 -I ‘node_modules’├── server│ ├── app.js│ ├── db│ │ ├── db.js│ │ └── newsSql.js│ ├── package-lock.json│ ├── package.json│ └── routers│ ├── news.js│ └── router.jsNode Servernpm initnpm install express mysql body-parser -Sapp.jsconst express = require(’express’)const bodyParser = require(‘body-parser’)const app = express()const router = require(’./routers/router’)const PORT = 9527app.use(bodyParser.json())app.use(bodyParser.urlencoded({ extended: true }))app.use(router)app.listen(PORT, () => { console.log(Listen port at ${PORT})})db.js -> Mysql配置module.exports = { mysql: { host: ’localhost’, user: ‘root’, password: ‘xxxx’, database: ’test’, port: ‘3306’ }}router.jsconst 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 = routernewSql.jsmodule.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 = ?’}news.jsconst 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配置代理以及使用apiconfig/index.js 修改proxyTablemodule.exports = { dev: { proxyTable: { ‘/api’: { target: ‘http://127.0.0.1:9527’, changeOrigin: true, pathRewrite: { ‘^/api’: ‘/api’ } } } }}使用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 Ubuntucurl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -sudo apt-get install -y nodejs# Using Debian, as rootcurl -sL https://deb.nodesource.com/setup_8.x | bash -apt-get install -y nodejs# Using Centoscurl -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 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。到这里,我们的Web,Node Server ,Nginx都已经配置并启动好了,我们只需要到浏览器输入你的服务器IP:8080即可.Nginx众多概念详见官方词汇表什么是应用交付?什么是应用交付控制器(ADC)?什么是应用程序服务器与Web服务器?什么是缓存?什么是云负载平衡?什么是聚类?什么是DevOps?什么是分布式拒绝服务(DDoS)?什么是DNS负载平衡?什么是全局服务器负载平衡?什么是高可用性?什么是HTTP?什么是HTTP / 2?什么是混合负载均衡?什么是第4层负载均衡?什么是第7层负载平衡?什么是负载平衡?什么是媒体服务器?什么是微服务?什么是网络负载均衡器?什么是NGINX?什么是渐进式下载?什么是反向代理服务器?什么是反向代理与负载均衡器?什么是循环负载平衡?什么是面向服务的体系结构(SOA)?什么是会话持久性?什么是SSL负载均衡器?什么是Web加速?什么是Web服务器?
...