目前,我開發 HTTP 服務, 用的是 beego框架, 方便了很多。
但是, 有時候,還是會遇到一些 特殊的場景。
比如: 過濾日志。
這應該是一種典型的stream,同時數據量也適中, 不會有人,為了這個, 就用一些很重的框架。
可以這樣直觀的描述這個 邏輯
其他組件 產生 log
||
\ /
我的組件,業務處理
||
\ /
用戶, http client
這種情景下, 有幾個特殊點:
1. 難以用 string,或者 byte 數組 收集數據
2. 數據Source 端,不斷的有數據產生
3. 數據緩沖,如果占有的 內存太多, 可能導致 服務崩潰
通常情況下,我們準備好數據, 然后調用Beego框架的方法,將數據發送到客戶端,就不管了。
而如果,我們需要根據處理的情況,多次寫數據到客戶端,該怎么辦呢?
首先,對于 這種簡單的 流數據, golang 提供了一個 結構。
pipeReader, pipeWriter := io.Pipe()
這個方法的原型是這樣的
func Pipe() (*PipeReader, *PipeWriter)
它返回緊密相連的一對 Reader 和 Writer。 他們的“生命周期”相同。
任何 寫到 Writer中的數據, 直接流到了Reader中。這個 和 Linux 命令行中 “管道 |” 很像。
我們先開個goroutine 接收 日志數據
go func () {
for {
var log []byte
//log =
pipeWriter.Write(log)
//break;
}
pipeWriter.CloseWithError(io.EOF)
}
主邏輯中, 處理日志
defer pipeReader.Close()
rr := bufio.NewReader(io.Reader(pipeReader))
for {
line, err := rr.ReadBytes('\n')
if io.EOF == err {
break
}
........
}
最后, 輸出到客戶端
var out []byte
ctl.Ctx.ResponseWriter.Write(out)
ctl.Ctx.ResponseWriter.Flush()
總結:
iopipe 直接 對接了 日志輸出, 緩沖很小,
處理后的結果, 直接輸出到 http 客戶端。
尤其是第二點,很重要,我在處理這個邏輯的時候, 發現服務器,有幾次意外崩潰,后來,才意識到,beego的controller 如果緩沖 處理后的數據,有可能仍然占有大量內存。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- golang DNS服務器的簡單實現操作
- golang-gin-mgo高并發服務器搭建教程
- golang項目如何上線部署到Linu服務器(方法詳解)
- golang文件服務器的兩種方式(可以訪問任何目錄)
- golang搭建靜態web服務器的實現方法
- 詳解如何熱重啟golang服務器
- 淺談Golang中創建一個簡單的服務器的方法
- 基于 HLS 創建 Golang 視頻流服務器的優缺點