Showing posts with label golang. Show all posts
Showing posts with label golang. Show all posts
Monday, February 14, 2022
Sunday, February 13, 2022
Saturday, February 12, 2022
Friday, February 11, 2022
Tuesday, February 8, 2022
Monday, February 7, 2022
Sunday, February 6, 2022
Saturday, February 5, 2022
Saturday, July 11, 2020
Monday, August 12, 2019
websocket 達到百萬連接?
在跟技術經理討論過一次,我們的推送 server,將會面臨到有沒有可能斷線
或者資料遺失的可能性,
假設一最多只能有 65536 個port 扣掉 端口後,剩下
可用端口可能兩三萬,那麼有沒有可能單台 server 就突破 65536 個 port呢 ?
emmmm…
在經過一番查詢是有的,那麼就是差實做囉, 我們來架設一波
首先呢我們要對 linux 進行 一些額外的設定
至於伺服器方面呢,我們把移到golang 的 websocket 伺服器
或者資料遺失的可能性,
假設一最多只能有 65536 個port 扣掉 端口後,剩下
可用端口可能兩三萬,那麼有沒有可能單台 server 就突破 65536 個 port呢 ?
emmmm…
在經過一番查詢是有的,那麼就是差實做囉, 我們來架設一波
首先呢我們要對 linux 進行 一些額外的設定
至於伺服器方面呢,我們把移到golang 的 websocket 伺服器
client 和 server 是run 在 同一台 虛擬機
client 端
docker搭建
產生 n個 docker 映像檔並執行 client.go 編譯出來的 client 使用 docker 映射到 docker 容器裡 再讓容器 發起 m個連接到 指定 ip 上
#!/bin/bash
## This script helps regenerating multiple client instances in different network namespaces using Docker
## This helps to overcome the ephemeral source port limitation
## Usage: ./connect <connections> <number of clients> <server ip>
## Server IP is usually the Docker gateway IP address, which is 172.17.0.1 by default
## Number of clients helps to speed up connections establishment at large scale, in order to make the demo faster
CONNECTIONS=$1
REPLICAS=$2
IP=$3
#go build --tags "static netgo" -o client client.go
for (( c=0; c<${REPLICAS}; c++ ))
do
docker run -v $(pwd)/client:/client --name 1mclient_$c -d alpine /client -conn=${CONNECTIONS} -ip=${IP}
done
client 發起 10萬連接
sudo bash setup.sh 20000 5 192.168.109.129
刪除 迴圈產生出來的 docker 映像檔
sudo docker rm -f 1mclient_4
sudo docker rm -f 1mclient_3
sudo docker rm -f 1mclient_2
sudo docker rm -f 1mclient_1
sudo docker rm -f 1mclient_0
server 端
linux 調效篇
這篇講得不錯很容易懂
http://blog.udn.com/q928856957/25855941
http://blog.udn.com/q928856957/25855941
sudo sysctl -w fs.file-max=2000500
sudo sysctl -w fs.nr_open=2000500
sudo sysctl -w net.nf_conntrack_max=2000500
sudo ulimit -n 2000500
sudo sysctl -w net.ipv4.tcp_mem='131072 262144 524288'
sudo sysctl -w net.ipv4.tcp_rmem='8760 256960 4088000'
sudo sysctl -w net.ipv4.tcp_wmem='8760 256960 4088000'
sudo sysctl -w net.core.rmem_max=16384
sudo sysctl -w net.core.wmem_max=16384
sudo sysctl -w net.core.somaxconn=2048
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=2048
sudo sysctl -w /proc/sys/net/core/netdev_max_backlog=2048
sudo sysctl -w net.ipv4.tcp_tw_recycle=1
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
sudo echo 2000500 > /proc/sys/fs/nr_open
Run server!
組態檔,我們把onlyTestConnect 設為 false
{
"port": 8888,
"delay": "1m",
"interval": "1m",
"totalSize": 1,
"onlyTestConnect": false
}
server.go
package main
import (
"container/list"
"fmt"
"golang.org/x/net/websocket"
"net/http"
"strconv"
"time"
"encoding/json"
"os"
"sync"
"goserver"
"math/rand"
//"unsafe"
)
var Config goserver.Configuration
const n = 10
var wsList = [n]*list.List {list.New(),list.New(),list.New(),list.New(),list.New(),list.New(),list.New(),list.New(),list.New(),list.New()}
var locks = [n]sync.RWMutex {}
func wsHandler(ws *websocket.Conn) {
//p := unsafe.Pointer(&ws)
//index := ((int)(uintptr(p))) % n
index := rand.Intn(n)
lock := locks[index]
lock.Lock()
wsList[index].PushBack(ws)
lock.Unlock()
for {
var reply string
if err := websocket.Message.Receive(ws, &reply); err != nil {
fmt.Println("Can't receive because of " + err.Error())
break
}
}
lock.Lock()
for e := wsList[index].Front(); e != nil; e = e.Next() {
if e.Value.(*websocket.Conn) == ws {
wsList[index].Remove(e)
break
}
}
lock.Unlock()
}
func load(configfile string) goserver.Configuration {
config := goserver.Configuration{}
file, _ := os.Open(configfile)
decoder := json.NewDecoder(file)
err := decoder.Decode(&config)
if err != nil {
panic(err.Error())
}
return config
}
func main() {
seed := time.Now().UTC().UnixNano()
rand.Seed(seed)
Config = load("config.json")
//http.Handle("/", websocket.Handler(wsHandler))
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
s := websocket.Server{Handler: websocket.Handler(wsHandler)}
s.ServeHTTP(w, req)
})
delay, _ := time.ParseDuration(Config.Delay)
interval, _ := time.ParseDuration(Config.Interval)
timer := time.NewTimer(delay)
if !Config.OnlyTestConnect {
go func() {
for {
<-timer.C
timer.Reset(interval)
totalLen := 0
for i :=0; i < n; i++ {
totalLen += wsList[i].Len()
}
if totalLen >= Config.TotalSize {
fmt.Println("send timestamp to all")
for i :=0; i < n; i++ {
i := i
go func() {
for e := wsList[i].Front(); e != nil; e = e.Next() {
var ws = e.Value.(*websocket.Conn)
now := time.Now().UnixNano() / int64(time.Millisecond)
err := websocket.Message.Send(ws, strconv.FormatInt(now, 10))
if err != nil {
panic("Error: " + err.Error())
}
}
}()
}
} else {
fmt.Println("current websockets: " + strconv.Itoa(totalLen))
}
}
}()
}
err := http.ListenAndServe(":"+strconv.Itoa(Config.Port), nil)
if err != nil {
panic("Error: " + err.Error())
}
}

emm… emmemm. 看起來差不多調校好了??
記憶體吃滿了先開 10w client 玩玩看 ,不過單台 確實突破 65536 的迷思 (?


中間能不能再夾一層 nginx 呢進行更多變化呢或優化呢… 看來要在 買一些洋垃圾組一台 server
端口重複使用? 假象?
https://colobu.com/2019/02/23/1m-go-tcp-connection/
在看了下數據後 最下面貼文 發現了是不是只是 本地端 的假象?
在看了下數據後 最下面貼文 發現了是不是只是 本地端 的假象?
來實驗一下
在使用docker 虛擬連接發現docker 創建的連線數是正常的嗎
開了兩台 client 模擬客戶端 每台上限65536 ,可以看到 server 確實達到
接近12萬連線數 所以 這個就取決的server的硬件是否強大囉

後面 其中一docker 可能掛了還是怎樣,連線數掉到剩一台client
數據 大概 滿仔數據 記憶體大概是 快接近 6g cpu除了每個一分鐘回傳滿載
幾乎 接近10%左右,頻寬 回傳 1.4m
在使用docker 虛擬連接發現docker 創建的連線數是正常的嗎
開了兩台 client 模擬客戶端 每台上限65536 ,可以看到 server 確實達到
接近12萬連線數 所以 這個就取決的server的硬件是否強大囉

後面 其中一docker 可能掛了還是怎樣,連線數掉到剩一台client
數據 大概 滿仔數據 記憶體大概是 快接近 6g cpu除了每個一分鐘回傳滿載
幾乎 接近10%左右,頻寬 回傳 1.4m
接近 剛才的 部落格實測數據
參考
Sunday, February 24, 2019
https nodejs rtmp publisher use openssl
https nodejs rtmp publisher use openssl
新增https 功能
由於呢在chrome 呢 如果調用getUserMedia api 則必需要https 代理來小改造一下
Saturday, September 29, 2018
Golang Json的回傳與畫出股市蠟燭圖
打造股票回測
Debug時間
這樣跳來跳去進度會不會超太快xd
剛剛的教學已經大致上完成一部分了,大家比較有問題的在
要改直接改源碼的話,就注意資料庫的ip和密碼和table表,
還有在route的網址所對應的網址基本上應該是沒什麼難度
golang的時間轉timestamp
還有
golang回傳json的格式在有些網站的時候json格式並不會照你的方式走,
不是你配合它就是它配合你(應該不可能xd
那麼接著早上繼續坐下去
- 架設伺服器回傳json
- 畫折線圖
Highcharts
highcharts這次是我們主要用來顯示股票的插件
這邊是改裝後的程式碼
回傳Json
這邊的話還是依樣用查詢方式來做
整體程式碼
看著我你CSV你才能動->>>>CSV檔案下載
golang學習
Golang 數據處理與 Mysql 基礎語法
打造股票回測/盯盤網頁
我們今天就對數據做一個處理吧首先我們先來直上代碼
這邊代碼我們把檔案讀進去了接下來看要怎樣對上傳CSV檔案到SQL資料庫吧
每一檔股票都它其編號,所以呢我們可以create一個table名稱對應股票的代號這邊先做個簡易版
先來讀一下檔
綜合下
在資料的insert速度超快跟python比差一大截
目標
昨天有說到要打造一個用redis資料庫,後來想一想這是用在有快取場合的方面,那麼
我們能做到什麼呢,我打算用golang mongodb jquery來實現我們的框架初步回測的框架
那麼我們可能需要完成下列清單不過我們先用mysql搭起來熟悉一下環境吧~
整個流程跑完苦
- 數據的導入
- 架設伺服器回傳json
- 畫折線圖
- 新增回測按鈕與篩選條件
- 打造一個盯盤軟體
數據的處理
看著我你CSV你才能動->>>>CSV檔案下載
就是說這一次的話沒想過要弄爬蟲,相信大家可以在很多地方找到股票的歷史資料,我們今天就對數據做一個處理吧首先我們先來直上代碼
這邊代碼我們把檔案讀進去了接下來看要怎樣對上傳CSV檔案到SQL資料庫吧
Mysql 的 常用函數
我大致上把它整理一下
讀csv檔與上傳到數據庫
先來讀一下檔
綜合下
在資料的insert速度超快跟python比差一大截
Wednesday, September 26, 2018
Golang 搭建一個簡單Http Server
上一次我們講到安裝Golang那麼今天我們來看如何架設一個跟網頁溝通的伺服器
安裝套件的過程它不會講話xd,套一句老師說的沒消息就是好消息
Setting
go get -u github.com/gorilla/mux
go get -u github.com/gorilla/mux
安裝套件的過程它不會講話xd,套一句老師說的沒消息就是好消息
放置檔案路徑,沒什麼難度,放到資料夾而已。
上述相關文件安裝完後,沒想到的是,只要設定好route,仔細看整組搬過來就可以了這是比較正規的作法,當然網路上也有其他更暴力的方法(牛逼稍微進行一下小改裝
後續
整組搬來用是不錯啦,這樣的話我們做處理的時候可以在golange做處理了
之前在python寫的交易系統,在前段時間呢看到了一個 影片
遺傳演算法最佳化高頻交易策略 沒錯很喜歡模擬的我們呢已經搭建好這框架了
Golang Install On Ubutun
接觸原因
想試一下也可以來這邊看看
那麼我們開始吧
Install
我們把環境裝在linxu吧,以後還要紀錄一下Ducker安裝過程等等。
在Windows子系統下我們可以直接複製到/mnt/c掛載區直接把我們的壓縮檔解壓縮並安裝。
sudo tar -C /usr/local -xzf go1.x.x.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
存成hello.go,之後執行看看吧!go build hello.go./hello
環境參數
go env
學習資源
golangpkg























