Nginx
+ Node
+ Vue
部署初試知乎javascript
我的博客css
Githubhtml
平常學習筆記vue
Nginx
異步框架的 Web服務器,也能夠用做反向代理,負載平衡器 , HTTP緩存, 媒體流等的開源軟件。它最初是一個旨在實現最高性能和穩定性的Web
服務器。除了HTTP
服務器功能外,NGINX
還能夠用做電子郵件(IMAP
,POP3
和SMTP
)的代理服務器以及HTTP
,TCP
和UDP
服務器的反向代理和負載平衡器。java
特色node
Nginx
的模塊都是嵌入到二進制文件中執行master
管理進行與work
工做進程分離設計,所以具有熱部署功能BSD
許可協議功能mysql
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/nginx ll -al vim nginx.conf
homebrew
詳見linux
配置參數屬性 | 解釋說明 | 參數列表 | ||||
---|---|---|---|---|---|---|
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中全部處理鏈接的設置 | |||||
http | Nginx http處理的全部核心特性 |
Event
Nginx
是以event
(事件)處理模型爲基礎的模塊。它爲了支持跨平臺,抽象出了event
模塊。它支持的event
處理類型有:AIO
(異步IO
),/dev/poll
(Solaris
和Unix
特有),epoll
(Linux
特有),eventport
(Solaris
10特有),kqueue
(BSD
特有),poll
,rtsig
(實時信號),select
等。
它的做用是監聽accept
後創建的鏈接,對讀寫事件進行添加刪除。事件處理模型和Nginx
的非阻塞IO模型結合在一塊兒使用。當IO
可讀可寫的時候,相應的讀寫事件就會被喚醒,此時就會去處理事件的回調函數。ios
配置參數屬性 | 解釋說明 | 參數列表 | ||||||
---|---|---|---|---|---|---|---|---|
worker_connections | 定義每一個進程的最大鏈接數,受系統進程的最大打開文件數量限制 | 單個後臺worker process進程的最大併發連接數 (最大鏈接數= worker_processes worker_connections) 在反向代理環境下:<br/>最大鏈接數 = worker_processes worker_connections / 4 |
||||||
use | 選擇一個可用的事件的模型(能夠在編譯時指定),Nginx會自動選擇事件的模型 | [ epoll \ | /dev/poll \ | poll \ | eventport \ | kqueue \ | select \ | rtsig ] |
multi_accept | 一個新鏈接通知後接受盡量多的鏈接 | on / off | ||||||
accept_mutex | 開啓或者禁用使用互斥鎖來打開sockets | on / off |
Event Use
支持的事件模型nginx
HTTP
能夠嵌套多個server
,配置代理,緩存,日誌定義等絕大多數功能和第三方模塊的配置。
配置參數屬性 | 解釋說明 | 參數列表 |
---|---|---|
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 | 負載均衡 | |
server | Nginx的server虛擬主機配置 |
Upstream
它的做用是實如今輪詢和客戶端IP之間的後端服務器負荷平衡。
配置參數屬性 | 解釋說明 |
---|---|
輪詢(默認) | 當weight不指定時,各服務器weight相同,每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。 |
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
配置虛擬主機的相關參數,一個http
中能夠有多個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
以某個常規字符串開頭,不是正則匹配.~
: 開頭表示區分大小寫的正則匹配.~*
: 開頭表示不區分大小寫的正則匹配./
: 通用匹配, 若是沒有其它匹配,任何請求都會匹配到.匹配優先級(高到低)
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 / off |
proxy_buffers | 請求分配的緩衝區的大小和數量 | |
proxy_buffer_size | 代理服務器的響應的第一部分存儲在單獨的緩衝區大小 | 一般包含一個相對較小的響應頭,而且能夠比其他響應的緩衝區小。 |
proxy_bind | 接受來自特定IP網絡或IP地址範圍的鏈接 | 指定proxy_bind 必要網絡接口的指令和IP地址 |
Global Variable
變量名 | 變量含義 |
---|---|
$args | 請求中的參數 |
$content_length | HTTP 請求信息裏的Content-Length |
$content_type | 請求信息裏的Content-Type |
$host | 請求信息中的Host ,若是請求中沒有Host 行,則等於設置的服務器名 |
$http_cookie | cookie 信息 |
$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
中的配置
啓動Nginx
nginx ps -ef | grep nginx
從新加載修改後的Nginx
配置文件
nginx -s reload
多謝小夥伴給提出的問題(詳見評論區),reload
和resatrt
是兩個不一樣的概念。
reload
conf
文件,不中斷Nginx
服務,conf
文件有問題則加載上一次的conf
.restart
Nginx
服務,形成服務器中斷一段時間,固然會由於conf
文件問題報錯。關閉Nginx
nginx -s stop
由於我已經啓動了,因此就重啓一下Nginx
便可
Linux
安裝Nginx
使用pstree
查看當前服務器啓動的進程
pstree
查找Nginx
的位置
ps -aux | grep nginx
進入nginx
的目錄
而後配置nginx.conf
文件便可
http { upstream add-news { server 127.0.0.1:9527; } server { listen 8080; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; root /Users/rainy/Desktop/MyWork/Work/website/dist; index index.html index.htm; location / { # root html; try_files $uri $uri/ @router; index index.html index.htm; } location @router { rewrite ^.*$ /index.html last; } location ~ /api/ { proxy_pass http://127.0.0.1:9527; } # 個人圖片存放在本地服務器上的路徑👇 location /news-images/ { expires 24h; root /Users/rainy/Desktop/MyWork/Work/website/server/; autoindex on; } # 經過轉發某服務器上的圖片 -> https://localhost:9527/*/*.png location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 24h; proxy_pass https://localhost:9527; access_log /root/nginx/logs/images.log; proxy_store on; proxy_store_access user:rw group:rw all:rw; proxy_redirect off; proxy_set_header Host 127.0.0.1; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 1280k; proxy_connect_timeout 900; proxy_send_timeout 900; proxy_read_timeout 900; proxy_buffer_size 40k; proxy_buffers 40 320k; proxy_busy_buffers_size 640k; proxy_temp_file_write_size 640k; } } }
Docker
安裝Nginx
查找 Docker Hub 上的 nginx
鏡像
docker search nginx
拉取官方鏡像
docker pull nginx
查看當前鏡像
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
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}`) })
db.js
-> Mysql
配置
module.exports = { mysql: { host: 'localhost', user: 'root', password: 'xxxx', database: 'test', port: '3306' } }
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
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 = ?' }
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() }) } }) } let mkdirSync = dirname => { if (fs.existsSync(dirname)) { return true } else { if (mkdirSync(path.dirname(dirname))) { fs.mkdirSync(dirname) return true } } return false } let uploadImg = (req, res, next) => { const form = new formidable.IncomingForm() form.encoding = 'utf-8' form.keepExtensions = true form.parse(req, (err, fileds, files) => { if (err) { console.log(err) } let imgPath = fs.readFileSync(files.file.path) let filename = path.resolve(__dirname, `../${NEWS_IMAGES_PATH}/${files.file.name}`) if (mkdirSync(NEWS_IMAGES_PATH)) { fs.writeFile(filename, imgPath, (err) => { if (err) { console.log(err) } res.json({ code: '200', msg: 'success', files: files.file, }) }) }) } } module.exports = { queryAll, queryById, add, update, deleteNews, uploadImg }
Vue
配置代理以及使用api
config/index.js
修改proxyTable
module.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 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
此處我以前的命令執行錯誤,因此我須要kill
這個進程
nohup node website/server/app.js &
nohup
:能夠將程序以忽略掛起信號的方式運行起來,被運行的程序的輸出信息將不會顯示到終端。
不管是否將 nohup
命令的輸出重定向到終端,輸出都將附加到當前目錄的 nohup.out
文件中。若是當前目錄的 nohup.out
文件不可寫,輸出重定向到$HOME/nohup.out
文件中。若是沒有文件能建立或打開以用於追加,那麼 command
參數指定的命令不可調用。若是標準錯誤是一個終端,那麼把指定的命令寫給標準錯誤的全部輸出做爲標準輸出重定向到相同的文件描述符。
到這裏,咱們的Web
,Node Server
,Nginx
都已經配置並啓動好了,咱們只須要到瀏覽器輸入你的服務器IP:8080
便可.