Thursday, June 27, 2019
Saturday, June 22, 2019
Nginx 初探 基於 反向代理 負載平衡 實現 無痛升級 ?
嘖嘖,公司架構,大部分可能要換成新的一些架構,被我抓到這個機會可以參與研發與設計比較底層的架構這樣,希望可以參與設計到結束這樣,廢話說完爽 今天來使用新的東西 反向代理!
Nginx
來看一下比較客觀的大眾比較, 最終 技術經理 是說 apache 越來越肥,所以叫我先來研究一下 nginx ,網頁伺服器 如何 做到無痛更新之類的,痾vue webpack 的預設 服務器是 nodejs 的 express , 經過打包過後 可以生成 一個靜態檔案
1、nginx相對於apache的優點: 輕量級,同樣起web 服務,比apache佔用更少的記憶體及資源
抗併發,nginx 處理請求是非同步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能
高度模組化的設計,編寫模組相對簡單
社群活躍,各種高效能模組出品迅速啊
apache 相對於nginx 的優點: rewrite ,比nginx 的rewrite 強大 動態頁面
抗併發,nginx 處理請求是非同步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能
高度模組化的設計,編寫模組相對簡單
社群活躍,各種高效能模組出品迅速啊
apache 相對於nginx 的優點: rewrite ,比nginx 的rewrite 強大 動態頁面
模組超多,基本想到的都可以找到
少bug ,nginx 的bug 相對較多
少bug ,nginx 的bug 相對較多
超穩定 存在就是理由,一般來說,需要效能的web 服務,用nginx 。如果不需要效能只求穩定,那就apache 吧。後者的各種功能模組實現得比前者,例如ssl 的模組就比前者好,可配置項多。這裡要注意一點,epoll(freebsd 上是 kqueue )網路 IO 模型是nginx 處理效能高的根本理由,但並不是所有的情況下都是epoll 大獲全勝的,如果本身提供靜態服務的就只有寥寥幾個檔案,apache 的select 模型或許比epoll 更高效能。當然,這只是根據網路IO 模型的原理作的一個假設,真正的應用還是需要實測了再說的。
2、作為 Web 伺服器:相比 Apache,Nginx 使用更少的資源,支援更多的併發連線,體現更高的效率,這點使 Nginx 尤其受到虛擬主機提供商的歡迎。在高連線併發的情況下,Nginx是Apache伺服器不錯的替代品: Nginx在美國是做虛擬主機生意的老闆們經常選擇的軟體平臺之一. 能夠支援高達 50,000 個併發連線數的響應, 感謝Nginx為我們選擇了 epoll and kqueue 作為開發模型.
Nginx 作為負載均衡伺服器: Nginx 既可以在內部直接支援 Rails 和 PHP 程式對外進行服務, 也可以支援作為 HTTP代理 伺服器對外進行服務. Nginx採用C進行編寫, 不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多.
作為郵件代理伺服器: Nginx 同時也是一個非常優秀的郵件代理伺服器(最早開發這個產品的目的之一也是作為郵件代理伺服器), Last.fm 描述了成功並且美妙的使用經驗.
Nginx 是一個安裝非常的簡單 , 配置檔案非常簡潔(還能夠支援perl語法), Bugs 非常少的伺服器: Nginx 啟動特別容易, 並且幾乎可以做到 7*24不間斷執行,即使執行數個月也不需要重新啟動. 你還能夠不間斷服務的情況下進行軟體版本的升級 .
Nginx 作為負載均衡伺服器: Nginx 既可以在內部直接支援 Rails 和 PHP 程式對外進行服務, 也可以支援作為 HTTP代理 伺服器對外進行服務. Nginx採用C進行編寫, 不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多.
作為郵件代理伺服器: Nginx 同時也是一個非常優秀的郵件代理伺服器(最早開發這個產品的目的之一也是作為郵件代理伺服器), Last.fm 描述了成功並且美妙的使用經驗.
Nginx 是一個安裝非常的簡單 , 配置檔案非常簡潔(還能夠支援perl語法), Bugs 非常少的伺服器: Nginx 啟動特別容易, 並且幾乎可以做到 7*24不間斷執行,即使執行數個月也不需要重新啟動. 你還能夠不間斷服務的情況下進行軟體版本的升級 .
3、Nginx 配置簡潔, Apache 複雜 Nginx 靜態處理效能比 Apache 高 3倍以上
Apache 對 PHP 支援比較簡單,Nginx 需要配合其他後端用
Apache 的元件比 Nginx 多
現在 Nginx 才是 Web 伺服器的首選
4、最核心的區別在於apache是同步多程序模型,一個連線對應一個程序;nginx是非同步的,多個連線(萬級別)可以對應一個程序
Apache 對 PHP 支援比較簡單,Nginx 需要配合其他後端用
Apache 的元件比 Nginx 多
現在 Nginx 才是 Web 伺服器的首選
4、最核心的區別在於apache是同步多程序模型,一個連線對應一個程序;nginx是非同步的,多個連線(萬級別)可以對應一個程序
5、nginx處理靜態檔案好,耗費記憶體少.但無疑apache仍然是目前的主流,有很多豐富的特性.所以還需要搭配著來.當然如果能確定nginx就適合需求,那麼使用nginx會是更經濟的方式.
apache有先天不支援多核心處理負載雞肋的缺點,建議使用nginx做前端,後端用apache。大型網站建議用nginx自代的叢集功能
6、從個人過往的使用情況來看,nginx的負載能力比apache高很多。最新的伺服器也改用nginx了。而且nginx改完配置能-t測試一下配置有沒有問題,apache重啟的時候發現配置出錯了,會很崩潰,改的時候都會非常小心翼翼現在看有好多叢集站,前端nginx抗併發,後端 apache叢集,配合的也不錯。
7、nginx處理動態請求是雞肋,一般動態請求要apache去做,nginx只適合靜態和反向。
8、從我個人的經驗來看,nginx是很不錯的前端伺服器,負載效能很好,在老奔上開nginx,用webbench模擬10000個靜態檔案請求毫不吃力。apache對php等語言的支援很好,此外apache有強大的支援網路,發展時間相對nginx更久,
9、 Nginx優於apache的主要兩點:1.Nginx本身就是一個反向代理伺服器 2.Nginx支援7層負載均衡;其他的當然,Nginx可能會比 apache支援更高的併發,但是根據NetCraft的統計,2011年4月的統計資料,Apache依然佔有62.71%,而Nginx是 7.35%,因此總得來說,Aapche依然是大部分公司的首先,因為其成熟的技術和開發社群已經也是非常不錯的效能。
10、你對web server的需求決定你的選擇。大部分情況下nginx都優於APACHE,比如說靜態檔案處理、PHP-CGI的支援、反向代理功能、前端Cache、維持連線等等。在 Apache PHP(prefork)模式下,如果PHP處理慢或者前端壓力很大的情況下,很容易出現Apache程序數飆升,從而拒絕服務的現象。
11、可以看一下nginx lua模組:https://github.com/chaoslaw…apache比nginx多的模組,可直接用lua實現apache是最流行的,why?大多數人懶得更新到nginx或者學新事物
12、對於nginx,我喜歡它配置檔案寫的很簡潔,正則配置讓很多事情變得簡單執行效率高,佔用資源少,代理功能強大,很適合做前端響應伺服器
13、Apache在處理動態有優勢,Nginx併發性比較好,CPU記憶體佔用低,如果rewrite頻繁,那還是Apache吧
Nginx LoadBlance
一開始的時候,呵呵被要求開發 遠端手術醫療的東西使用串流,那個時候有提到
Load Blance 負載平衡,比較那時候經理有提到 負載平衡 可以透過硬體或者 軟體 來設置
那麼大概 除了國外的 f5 硬負載 和 nginx 去做的軟負載,那時候沒有選用 Nginx 來做 影音串流平台單純想要試一下 新東西xd
那麼那時候有研究一下,大致是怎麼弄呢
像是這樣哈哈,痾 Nginx 會透過 反向代理 去自動根據 流量 分配到 負擔比較沒有那麼重的 伺服器上安內這個時候就一定要來提一下 正向代理 和反向代理 這樣我們來看下去。Load Blance 負載平衡,比較那時候經理有提到 負載平衡 可以透過硬體或者 軟體 來設置
那麼大概 除了國外的 f5 硬負載 和 nginx 去做的軟負載,那時候沒有選用 Nginx 來做 影音串流平台單純想要試一下 新東西xd
那麼那時候有研究一下,大致是怎麼弄呢
正向代理
正向代理发生在 client 端,用户能感知到的,并且是用户主动发起的代理。
比如:翻墙。
我们不能访问外网,但是可以访问代理服务器,然后代理服务器帮我们从外网中获取数据。但是在使用之前,用户往往需要
我们不能访问外网,但是可以访问代理服务器,然后代理服务器帮我们从外网中获取数据。但是在使用之前,用户往往需要
主动
在client端配置代理。
黑客为了隐藏身份,用的就是正向代理。
|客户端+代理服务器|-->|目标服务器|
反向代理
反向代理发生在 server端,从用户角度看是不知道发生了代理的(这个只有服务器工程师才知道)。
比如:
用户访问
但是
这个过程是在 server 端发生的,用户并不知道(只有服务器运维人员才知道)。
用户访问
服务器A
,服务器A
就给用户返回了数据。但是
服务器A
上其实并没有数据,它是偷偷从服务器B
上获取数据,然后再返回给用户的。这个过程是在 server 端发生的,用户并不知道(只有服务器运维人员才知道)。
|客户端|-->|代理服务器+目标服务器|
Nginx 如何做到無痛更新?
一開始我注意到了負載平衡的這個東西,是否可以套用到無痛更新思考了一會,不過現在倒是有找到類似的東西 https://blog.51cto.com/favccxx/1622091
如果我們的伺服器設計為這樣呢?雙層 Nginx 或者其他 伺服器 web service 等等 都可以這樣安全替換掉 來看看如何實現吧,其實也有很多基於負載平衡的伺服器,來做到無痛換版本。
Nginx 實現 無痛升級
我不最終不確定這個方案,因為在切換不同的伺服器的話,chorme 或者 其他的瀏覽器,除非發生url 的跳轉 等等之類的相關因素 ,是無法 即時更新伺服器的,目前有待深入研究不過初始架構就是 基於 負載平衡這樣,好想趕快學寫伺服器腳本等等之類的喔,
在這張圖 初步規畫與實現 非常簡單,
1. 在http节点下,添加upstream节点。
upstream favtomcat {
server 192.168.1.1:8080 weight = 1;
server 10.0.6.108:7080
weight = 4;
server 10.0.6.108:7080 backup
;
}
2. 将server节点下的location节点中的proxy_pass配置为:http:// + upstream名称,即“
location / {
root html;
index index.html index.htm;
proxy_pass http://favtomcat;
}
當我們在切換伺服器的時候,都開啟的時候來給各位看幾張圖
當一般的情況下 ,在dev 1 和 dev2 沒有狀態的時候 ,除非 發生異常否則中間負載平衡的會根據權重去配對伺服器 ,主要 loding 主 dev2 副 dev1 這樣,當 dev1 和 dev2 伺服器 掛掉 (關閉 將會 啟用 預備伺服器。
發生異常狀況
當發生異常狀態的時候 。 我們把 伺服器 處理好 當 dev 1 或者 dev2 某台伺服器 啟用後,把 backup 伺服器 關掉 又會 nginx 負載平衡的伺服器 又會根據 權重 重新引導 client 繼續分配伺服器 給使用者使用
同學!!你猜怎麼回事 ,這時候 我們把 伺服器掛掉(關掉 想成更新 ! 那麼我們就可以實現無痛 更新伺服器了! ,不過這邊 如上所說 , 像一般的打包過後的程式將會在 本地端 留下緩存 , 這邊還需 多研究不過, 每次的 request 模組 , 呼叫 ajax 預先 緩存? 確保醫療端 資料不會無故消失,我想又是一個 奇特的問題...。
Vue 建構一個 simple login/menu
建構一個 simple login/menu
安裝各個套件
章節需用到 vuex , vue-router , vuei18n ,axios , element ui , vue-context
如要安裝各個套件 可以透過 下載下面github 訪問
17LearnVue.js
下載完專案 使用 vscode 並 run 起專案
安裝完章節
npm install
啟動伺服器
npm run dev
自訂一個額外 api cookies.js
/api/cookies.js
import Cookies from 'js-cookie'
const TokenKey = 'token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
/main.js
import { getToken } from './api/cookiesex'
getToken() 可以取得 cookie 資料
///也可以 ,,,,
import testmod from './api/cookiesex'
testmod.getToken() //一樣效果
客製化表格 改為分次傳送
代碼為上述專案裡面 home 裡面 由於過於攏長
寫下實現方式
網頁表格 需要使用 虛擬渲染,以防頁面元素 dom 呼叫過多 事件
導致記憶體過多
寫下實現方式
網頁表格 需要使用 虛擬渲染,以防頁面元素 dom 呼叫過多 事件
導致記憶體過多
- 取得相對應 data
- 自定義變數 紀錄目前資料length 送至後端 目前筆數
- data 重新顯示範圍 20 ~ 40
- currentIndex…
- 透過ajax 像伺服器端請求下一份 data ,不斷累加到 資料沒有
- 判斷table scroll 是否到底 是的話 +20 否則 -20 回到步驟2
欄位篩選功能
新增右鍵選單
main.js 入口點 篇
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
///ui插件ㄐ
import { Message, Table } from 'element-ui'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import VueRouter from 'vue-router'
import { gettest } from './routes' //路由規則
//import routers from './routes' //路由規則
import axios from 'axios' // ajax 相對應模組
import i18n from './assets/i18n/i18n' //多國語言模組
import { getRequest } from './api/request' // 封裝 axios 為另一個模組
import { postRequest } from './api/request'
import { deleteRequest } from './api/request'
import { putRequest } from './api/request'
import { getToken } from './api/cookiesex'
Vue.config.productionTip = false
///這邊弄好完的xd 透過其他模組 而引用外部 js 變數
///請仔細 觀察 它們之間的關係 後面有關於個模組引用 有很大的關係
const routes2 = gettest()
///////////router
const router = new VueRouter({
routes: routes2,
//routers
mode: 'history'
})
// router
// 當有人沒有相對應 權限而進入
// 非法路徑 則 直接透過 router 導向 正常 login 畫面
router.beforeEach((to, from, next) => {
const isLogin = getToken() == 'ImLogin'
if (isLogin) {
next()
} else {
if (to.path !== '/login') next('/login')
else next()
}
})
Vue.use(VueRouter)
//引用 ui
Vue.use(ElementUI)
/////////// 全局引用 這邊引用過後可以透過讓底下各個模塊食用
Vue.prototype.getRequest = getRequest
Vue.prototype.postRequest = postRequest
Vue.prototype.deleteRequest = deleteRequest
Vue.prototype.putRequest = putRequest
Vue.prototype.$message = Message
///////////
/* eslint-disable no-new */
new Vue({
el: '#app',
router, //根據路由決定 components 位置
i18n, //多國語系
components: { App },
template: '<App/>'
})
router.js 路由篇
這邊仔細觀察 我們在 main.js new router 那一段 有呼叫一個
js函數 我們可以知道 我們額外呼叫了 gettest()
這個函數,透過引用 外部 JS 一個小範例,也讓 我們的主 VUE 比較乾淨一點
當然也可以 直接傳入 像 routes 那邊可以直接引用 js 變數
可以 參考 VueRouter 的建構元 內部 所需傳遞的參數
main 內部引用 額外 js 內部 變數 讓 main.js 乾淨
router 對應相對應 components
import Login from './components/login.vue'
import Header from './components/header.vue'
import Home from './components/table.vue'
import UserInfo from './components/userInfo.vue'
export const routes = [
{
path: '/login',
component: Login
},
{
path: '/',
components: {
default: Home,
nav: Header
}
},
{
path: '/userInfo',
components: {
default: UserInfo,
nav: Header
}
},
{
path: '*',
redirect: '/'
}
]
export function gettest() {
console.log(routes)
return routes
}
攔截訪問非法路徑
Vue-router 基礎
vue-router 基礎
router 基本參數
this.$router.go(-1)//跳转到上一次浏览的页面
this.$router.replace('/menu')//指定跳转的地址
this.$router.replace({name:'menuLink'})//指定跳转路由的名字下
this.$router.push('/menu')//通过push进行跳转
this.$router.push({name:'menuLink'})//通过push进行跳转路由的名字下
router.js 應用
單頁 one router-view
app.vue
<template>
<div id="app">
<p>{{$t('message.i1')}}</p>
<img src="./assets/logo.png">
//對應router.js 原本為default
<router-view name="nav"></router-view>
//對應router.js 此處為導覽 的上方條列
<router-view/>
</div>
</template>
router.js
import Login from './components/login.vue'
import Header from './components/header.vue'
import Home from './components/home.vue'
export const routes = [
{
path: '/login', //路由路徑
component: Login, //相對應comopnent
name: 'login' // 可以透過路由url 跳轉直接導向該相對應名稱
},
{
path: '/',
components: {
default: Home,
nav: Header
},
name: 'home'
}
herader.vue
<template>
<div>
//對印到 相對應 name路由
<router-link :to="{name:'home'}">Home</router-link>
<router-link :to="{name:'userinfo'}">User Info</router-link>
<router-link :to="{name:'test'}">test</router-link>
</template>
單頁 multi router-view
app.vue 照第一步走 往後新增下列程式碼
router.js
import test from './components/test.vue'
import test2 from './components/h1.vue'
import test3 from './components/h2.vue'
{
path: '/test',
components: {
default: test,
nav: Header
},
name: 'test',
children: [
{
path: '/h1',
components: {
nav2: test
},
name: 'h1'
},
{
path: '/h2',
components: { nav2: test3 },
name: 'h2'
}
]
},
test.vue
<template>
<div>
<router-link :to="{name:'h1'}">h1</router-link>
<router-link :to="{name:'h2'}">h2</router-link>
<h1>test</h1>
<router-view name="nav2" style="float:left;width:50%;background-color:#ccc;height:300px;"></router-view>
</div>
</template>
h1.vue
<template>
<h1>test2</h1>
</template>