閱讀618 返回首頁    go 阿裏雲 go 技術社區[雲棲]


構建高性能的彈幕應用 - 小項目也能做性能提升

直播是雲棲社區的主要模塊之一,彈幕服務是在直播頻道上線之後,為了更多的互動,提出的。

我主要做了下麵的一些迭代:

  • 使用 netty 構建彈幕應用
  • 授權服務與彈幕服務的分離
  • 專題頁本地緩存
  • 使用 nginx lua 為 web 應用加速
  • 實時監控在線人數

使用 netty 構建彈幕應用

抽離出來的小demo https://github.com/zhoumengkang/netty-websocket

├── WebSocketServer.java                啟動服務器端口監聽
├── WebSocketServerInitializer.java     初始化服務
├── WebSocketServerHandler.java         接管WebSocket數據連接
├── dto
│   └── Response.java                   返回給客戶端數據對象
├── entity
│   └── Client.java                     每個連接到WebSocket服務的客戶端對象
└── service
    ├── MessageService.java             完成發送消息
    └── RequestService.java             WebSocket初始化連接握手時的數據處理

客戶端授權與彈幕服務的分離

客戶端請求 web 服務器 api 獲取彈幕服務請求的完整地址

https://yq.aliyun.com/yqapi/webinar/barrage/url?id={id}

然後返回類似於

wss://barrage.aliyun.com/websocket/?rid={id}&code=xxxxx

然後客戶端使用返回的websocket地址發起請求即可。
因為在獲取code的過程中,需要讀取集團 cookie,和賬號中心交互驗證用戶身份合法性。獲取用戶的基本信息

{
  uid: xxx,
  name: xxx,
  level: xxx,
  isAdmin: xxx
}

然後和時間戳對稱加密運算得到最終的code,這樣彈幕服務器隻需要驗證解密code驗證數據的合法性,就可以使用客戶端傳遞過來的用戶信息了,免去了彈幕服務身份認證,獲取用戶信息等操作的網絡I/O。

專題頁本地緩存

很多直播頁麵都是靜態的專題頁麵,我們原來的做法是在tms裏麵運營編輯好了,我們再抓取過來緩存在redis裏麵,然後最後通過後端框架呈現。這樣還是有一次web服務器到遠程的集中式的redis緩存的網絡I/O。

做了以下的修改,在nginx配置單文件來操作

rewrite ^/promotion/(.*)$  /promotion.php last;

promotion.php 需要做兩個個工作

  • 判斷客戶端是移動端還是PC端,然後讀取不一樣的數據
  • 本地緩存文件不存在則從遠程redis裏讀取,然後緩存到本地

同時後台在抓取頁麵到redis時的同時,我會推送緩存到各個web服務器的指定目錄

#!/bin/bash
# 更新同步 html 靜態緩存到各個服務器

servers=(xxx.xxx.xxx.200 xxx.xxx.xxx.201 xxx.xxx.xxx.202 xxx.xxx.xxx.203)
for server in ${servers[@]};do
    cd /path/to/cache/output/
    rsync -aR promotion/pc/$1.html username@$server:/path/to/cache/output/
    rsync -aR promotion/mobile/$1.html username@$server:/path/to/cache/output/
done

還需要驗證文件發布是否成功,對比最終的md5

使用 nginx lua 為 web 應用加速

有了上麵的緩存文件的推送之後,我想緩存的讀取直接在nginx 裏進行。需求也就是:
pc、mobile 一個地址有兩套頁麵,需要在後端根據瀏覽器的 user_agent 來顯示不同的頁麵。

具體參考:https://mengkang.net/998.html

我在我們自己私人的web服務器上做了性能測試的對比,性能提升了近1倍,穩定性也挺高了很多。

實時監控在線人數

我們自己使用Grafana+telegraf+InfluxDb搭建了一個簡單的監控係統,然後我編寫了一個腳本來每秒監控統計端口ip

壓測

websocket 壓測

腳本 https://github.com/zhoumengkang/netty-websocket/blob/master/benchmark.py

並測試為N個客戶端,每個客戶端發送10條消息,服務器配置2核4G內存,廣播給所有的客戶端,我們測試1000個並發的時候,負載在後期陡升。
實際情況下,不可能那麼多人同時說話廣播,而是說話的人少,接受廣播的人多。

實際線上之後,在不限製刷帖頻率大家狂轟濫炸的情況下,1500多人在線,半小時,負載一直都處於0.5以下。

web 服務的壓測

ab -n 8000 -c 800 https://mengkang.net/promotion/1
Complete requests:      8000
Failed requests:        0
Requests per second:    7046.66 [#/sec] (mean)
Time per request:       113.529 [ms] (mean

ab -n 10000 -c 1000 https://mengkang.net/promotion/1
Complete requests:      10000
Failed requests:        0
Requests per second:    5670.38 [#/sec] (mean)
Time per request:       176.355 [ms] (mean)

最後更新:2017-10-09 10:03:12

  上一篇:go  2017雲棲大會·杭州峰會:《在線用戶行為分析:基於流式計算的數據處理及應用》Workshop-入口
  下一篇:go  PHP7.2、PHP7.1 性能對比