zanePerfor監控系統在高流量項目下的架構配置建議實踐說明

HI!,你好,我是zane,zanePerfor是一款我開發的一個前端性能監控平臺,如今支持web瀏覽器端和微信小程序端。html

我定義爲一款完整,高性能,高可用的前端性能監控系統,這是將來會達到的目的,現今的架構也基本支持了高可用,高性能的部署。實際上還不夠,在不少地方還有優化的空間,我會持續的優化和升級。前端

開源不易,若是你也熱愛技術,擁抱開源,但願能小小的支持給個star。node

項目的github地址:github.com/wangweiange…nginx

項目開發文檔說明:blog.seosiwei.com/performance…git


zanePerfor應用理論上可以支持千萬級以上pv項目,但實際狀況須要依賴於服務器和數據庫的性能,如下項儘量的從各類配置來提高應用的性能。github

備註:如下內容以選擇redis消息隊列來闡述和說明。


一:相關項目配置項說明

config.default.js 配置說明複製代碼

一、servers集羣模式下服務器之間主要經過內網進行通訊,所以在這裏hostname咱們須要配置成內網IP,作以下更改便可
web

// 集羣配置(通常默認便可)
    config.cluster = {
        listen: {
            port: config.port,
            hostname: address.ip(),  // 此處替換127.0.0.1
            ip: address.ip(),
        },
    };複製代碼


二、實時統計任務在大流量項目下時間儘量的長一些,即能減輕數據庫的壓力也能提高實時統計的準確性 (定時任務時間間隔建議5-20分鐘之間)ajax

// 執行pvuvip定時任務的時間間隔 默認每分鐘定時執行一次 (可更改)
config.pvuvip_task_minute_time = '0 */1 * * * *';
// 更改成
config.pvuvip_task_minute_time = '0 */10 * * * *';複製代碼


三、上報和消費數據方式選擇redisredis

// 上報原始數據使用redis存儲、kafka儲存、仍是使用mongodb存儲
config.report_data_type = 'redis'; // redis  mongodb  kafka複製代碼


四、在數據庫性能足夠強悍的狀況下,每次定時任務的時間儘可能短,消費的數據儘可能多,消息隊列池儘可能不作限制mongodb

config.redis_consumption = {
    // 定時任務執行時間
    task_time: '*/10 * * * * *',
    // 每次定時任務消費線程數(web端)
    thread_web: 2000,
    // 每次定時任務消費線程數(wx端)
    thread_wx: 2000,
    // 消息隊列池限制數, 0:不限制 number: 限制條數,高併發時服務優雅降級方案
    total_limit_web: 0,
    total_limit_wx: 0,
};複製代碼
  • task_time 消費消息定時任務間隔

  • thread_wx 每次消費數據條數

  • total_limit_wx 限制消息隊列中總條數

以上配置表示:每10秒鐘消費2000條數據,不對上報數據條數作限制 (若是定時任務設置了type: 'all',消費數據會成倍數增長)。


五、解析用戶IP使用redis方式,並關閉文件緩存(備註:流量大時,本地文件存儲的數據會比較大,每次加載會比較耗時)

// 解析用戶ip地址爲城市是使用redis仍是使用mongodb
config.ip_redis_or_mongodb = 'redis'; // redus  mongodb

// 文件緩存ip對應地理位置(文件名)
config.ip_city_cache_file = {
    isuse: false, // 是否開啓本地文件緩存(數據量太大時建議不開啓)
    web: 'web_ip_city_cache_file.txt',
    wx: 'wx_ip_city_cache_file.txt',
};複製代碼


六、mongodb集羣模式下url連接須要更改成內網ip,鏈接池能夠稍微調大一些

// mongodb 服務
const dbclients = {
    db3: {
        // 集羣分片
        url: 'mongodb://192.168.1.10:30000/performance',
        options: {
            autoReconnect: true,
            poolSize: 50,
        },
    },
};複製代碼


二:HTTP層面說明(如下內容已在程序中實現)

一、設置Connection,關閉keep-alive

爲何要關閉?

  • 在高併發項目下,tcp保持鏈接時間不要太長,所以nginx的keepalive_timeout儘可能設置的更短
  • 同一域下請求頻率低、請求次數少的http連接儘可能減小tcp連接時間,所以keepalive_timeout儘可能設置低

而對於本應用來講,上面兩條都已知足,所以關閉keep-alive選項。

// node服務實現:
ctx.set('Connection', 'close');

// nginx服務實現:
http {
    keepalive_timeout: 0;
}複製代碼


二、返回空body信息

  • 上報接口接收到請求就儘快返回狀態碼,邏輯處理放到後面處理
  • body返回內容儘可能簡短或者爲空
// 代碼實現:
async wxReport() {
    const { ctx } = this;
    ctx.set('Access-Control-Allow-Origin', '*');
    ctx.set('Connection', 'close');
    ctx.status = 200;

    // 後續邏輯處理...
}複製代碼


三:node單機集羣

使用node.js的Cluster 模塊開啓多進程,儘量的榨乾服務器資源,利用上多核 CPU 的併發優點。同時也保證單機服務的穩定性。

egg.js提供多進程模型和進程間通信。

傳送門:eggjs.org/zh-cn/core/…

開啓方式:

// 應用package.json
// 案例中開啓兩個worker進程,默認會開啓服務器cpu核數個worker進程
"scripts": {
    "start": "egg-scripts start --daemon --workers=2 --title=performance",
}複製代碼


四:Mongodb集羣搭建

高流量,高併發項目少不了mongodb集羣的搭建,關於mongodb集羣搭建請參考如下兩篇文章:

zanePerfor前端性能監控平臺高可用之Mongodb集羣分片架構

zanePerfor前端性能監控平臺高可用之Mongodb副本集讀寫分離架構

案例:如今有3臺服務器,內網ip分別爲:(10.1.0.8六、10.1.0.9七、10.1.0.70),如今咱們來搭建由三臺服務器組建的集羣。

一、分別在每臺服務器上建立以下3個文件

kdir -p /data/mongod/s0
mkdir -p /data/mongod/log
mkdir -p /data/mongod/c0複製代碼

二、分別在每臺服務器上啓動Shard Server

mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --bind_ip 10.1.0.86 --shardsvr
mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --bind_ip 10.1.0.97 --shardsvr
mongod --dbpath /data/mongod/s0 --logpath /data/mongod/log/s0.log --fork --smallfiles --port 27020 --bind_ip 10.1.0.70 --shardsvr複製代碼

三、分別在每臺服務器上啓動Config Server

mongod --dbpath /data/mongod/c0 --logpath  /data/mongod/log/c0.log --fork --smallfiles --port 27100 --bind_ip 10.1.0.86 --replSet rs1 --configsvr
mongod --dbpath /data/mongod/c0 --logpath  /data/mongod/log/c0.log --fork --smallfiles --port 27100 --bind_ip 10.1.0.97 --replSet rs1 --configsvr
mongod --dbpath /data/mongod/c0 --logpath  /data/mongod/log/c0.log --fork --smallfiles --port 27100 --bind_ip 10.1.0.70 --replSet rs1 --configsvr複製代碼

四、配置副本集

// 進入97的mongo
mongo --port 27100 --host 10.1.0.97

// 使用admin帳戶
use admin

// 初始化副本集
rs.initiate({_id:"rs1",members:[{_id:0,host:"10.1.0.97:27100"},{_id:1,host:"10.1.0.86:27100"},{_id:2,host:"10.1.0.70:27100"}]})

// 查看副本集狀態
rs.status()複製代碼

五、啓動Route Process服務

mongos  --logpath /data/mongod/log/mongo.log --port 30000 --bind_ip 10.1.0.97 --fork --configdb rs1/10.1.0.97:27100,10.1.0.86:27100,10.1.0.70:27100複製代碼

六、配置Sharding分片

// 進入路由服務器
mongo --port 30000 --host 10.1.0.97

// 添加分片
sh.addShard("10.1.0.97:27020")
sh.addShard("10.1.0.86:27020")
sh.addShard("10.1.0.70:27020")

// 查看分片信息
sh.status();複製代碼

七、設置分片數據庫與片鍵

//指定須要分片的數據庫
sh.enableSharding("performance")

//建立索引(須要對片建建立索引)
db.wx_ajaxs_wx3feeea844b1d03ffs.ensureIndex({"path":1})

//設置分片(對performance數據庫的wx_ajaxs_wx3feeea844b1d03ffs表按照path字段以hashed的方式分片)
sh.shardCollection("performance.wx_ajaxs_wx3feeea844b1d03ffs", { "path": "hashed"})

//查看分片信息
sh.status()複製代碼

其餘表分片重複以上步驟便可, 至此一個簡單的3臺服務器集羣搭建完畢。

注意事項:對mongodb進行分片時須要綁定內網IP,否則請求沒法連通。

備註:應用中對瀏覽器端 | 微信小程序端 默認使用 _id字段 進行分片, 儘可能不要更改。



五:servers負載均衡

servers負載:即把全部上報的請求分發到不一樣的servers進行處理,減少單個servers服務的壓力,也減輕了單個服務器的壓力。

  • zanePerfor作到了一套代碼多服務部署的方案

  • 應用保證了多服務同時運行時,task任務不重複執行

此處servers負載均衡採用nginx方案,ng配置以下:

upstream ps-servers {
    server 10.1.0.86:7001 weight=1 max_fails=4 fail_timeout=5;
    server 10.1.0.97:7001 weight=1 max_fails=4 fail_timeout=5;
    server 10.1.0.70:7001 weight=2 max_fails=4 fail_timeout=5;
}複製代碼

參數說明:

weight=number:設置服務器的權重,默認狀況下爲1
max_conns=number:限制到代理服務器的同時活動鏈接的最大數量,默認爲0
max_fails=number:服務器通訊的失敗嘗試次數
fail_timeout=number:服務器通訊失敗超時時間,默認爲10
backup:將服務器標記爲備份服務器。它將在主服務器不可用時傳遞請求
down:將服務器標記爲永久不可用


六:redis集羣

應用中有不少功能都會依賴於redis的緩存能力,所以一臺高性能的redis或者redis集羣顯得頗有必要。

官方如此介紹redis的強勁性能:性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s ,理論上來講單臺redis就能知足絕大部分的應用。

至於redis是否須要集羣的支持,須要根據各個應用的狀況來決定,博主暫時用的單臺redis,500w PV內暫未碰見性能問題。

至於redis集羣的搭建此處暫不作介紹,暫時掛個官網參考連接:redis.io/topics/clus…


zanePerfor在高流量項目下的架構配置建議實踐說明(完)。

相關文章
相關標籤/搜索