Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 28 additions & 39 deletions core/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ func init() {
ServerStartTime: time.Now(),
TotalRequestCount: 0,
TotalErrorCount: 0,
CurrentRequestCount: 0,
IntervalRequestData: NewItemMap(),
DetailRequestURLData: NewItemMap(),
IntervalErrorData: NewItemMap(),
DetailErrorPageData: NewItemMap(),
DetailErrorData: NewItemMap(),
DetailHTTPCodeData: NewItemMap(),
dataChan_Request: make(chan *RequestInfo, 1000),
dataChan_Request: make(chan *RequestInfo, 2000),
dataChan_Error: make(chan *ErrorInfo, 1000),
dataChan_HttpCode: make(chan *HttpCodeInfo, 1000),
infoPool: &pool{
requestInfo: sync.Pool{
New: func() interface{} {
Expand All @@ -44,11 +44,6 @@ func init() {
return &ErrorInfo{}
},
},
httpCodeInfo: sync.Pool{
New: func() interface{} {
return &HttpCodeInfo{}
},
},
},
}
go GlobalState.handleInfo()
Expand Down Expand Up @@ -76,12 +71,6 @@ type ErrorInfo struct {
Num uint64
}

//httpcode count info
type HttpCodeInfo struct {
URL string
Code int
Num uint64
}

//服务器状态信息
type ServerStateInfo struct {
Expand All @@ -91,6 +80,8 @@ type ServerStateInfo struct {
EnabledDetailRequestData bool
//该运行期间总访问次数
TotalRequestCount uint64
//当前活跃的请求数
CurrentRequestCount uint64
//单位时间内请求数据 - 按分钟为单位
IntervalRequestData *ItemMap
//明细请求页面数据 - 以不带参数的访问url为key
Expand All @@ -108,7 +99,6 @@ type ServerStateInfo struct {

dataChan_Request chan *RequestInfo
dataChan_Error chan *ErrorInfo
dataChan_HttpCode chan *HttpCodeInfo
//对象池
infoPool *pool
}
Expand All @@ -124,6 +114,8 @@ func (state *ServerStateInfo) ShowHtmlData(version string) string {
data += "<br>"
data += "TotalRequestCount : " + strconv.FormatUint(state.TotalRequestCount, 10)
data += "<br>"
data += "CurrentRequestCount : " + strconv.FormatUint(state.CurrentRequestCount, 10)
data += "<br>"
data += "TotalErrorCount : " + strconv.FormatUint(state.TotalErrorCount, 10)
data += "<br>"
state.IntervalRequestData.RLock()
Expand Down Expand Up @@ -164,13 +156,20 @@ func (state *ServerStateInfo) QueryIntervalErrorData(queryKey string) uint64 {
}

//AddRequestCount 增加请求数
func (state *ServerStateInfo) AddRequestCount(page string, code int, num uint64) uint64 {
if strings.Index(page, "/dotweb/") != 0 {
atomic.AddUint64(&state.TotalRequestCount, num)
state.addRequestData(page, code, num)
state.addHTTPCodeData(page, code, num)
}
return state.TotalRequestCount
func (state *ServerStateInfo) AddRequestCount(page string, code int, num uint64) {
state.addRequestData(page, code, num)
}

//AddCurrentRequest 增加请求数
func (state *ServerStateInfo) AddCurrentRequest(num uint64) uint64 {
atomic.AddUint64(&state.CurrentRequestCount, num)
return state.CurrentRequestCount
}

//SubCurrentRequest 消除请求数
func (state *ServerStateInfo) SubCurrentRequest(num uint64) uint64 {
atomic.AddUint64(&state.CurrentRequestCount, ^uint64(num-1))
return state.CurrentRequestCount
}

//AddErrorCount 增加错误数
Expand Down Expand Up @@ -198,21 +197,16 @@ func (state *ServerStateInfo) addErrorData(page string, err error, num uint64) {
state.dataChan_Error <- info
}

func (state *ServerStateInfo) addHTTPCodeData(page string, code int, num uint64) {
//get from pool
info := state.infoPool.httpCodeInfo.Get().(*HttpCodeInfo)
info.URL = page
info.Code = code
info.Num = num
state.dataChan_HttpCode <- info
}

//处理日志内部函数
func (state *ServerStateInfo) handleInfo() {
for {
select {
case info := <-state.dataChan_Request:
{
if strings.Index(info.URL, "/dotweb/") != 0 {
atomic.AddUint64(&state.TotalRequestCount, info.Num)
}
//fixed #63 状态数据,当url较多时,导致内存占用过大
if state.EnabledDetailRequestData {
//ignore 404 request
Expand All @@ -228,6 +222,11 @@ func (state *ServerStateInfo) handleInfo() {
val := state.IntervalRequestData.GetUInt64(key)
state.IntervalRequestData.Set(key, val+info.Num)

//set code data
key = strconv.Itoa(info.Code)
val = state.DetailHTTPCodeData.GetUInt64(key)
state.DetailHTTPCodeData.Set(key, val+info.Num)

//put info obj
state.infoPool.requestInfo.Put(info)
}
Expand All @@ -251,16 +250,6 @@ func (state *ServerStateInfo) handleInfo() {
//put info obj
state.infoPool.errorInfo.Put(info)
}
case info := <-state.dataChan_HttpCode:
{
//set detail error page data
key := strconv.Itoa(info.Code)
val := state.DetailHTTPCodeData.GetUInt64(key)
state.DetailHTTPCodeData.Set(key, val+info.Num)

//put info obj
state.infoPool.httpCodeInfo.Put(info)
}
}
}
}
Expand Down
28 changes: 22 additions & 6 deletions core/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,25 @@ func Test_AddRequestCount_1(t *testing.T) {

func addRequestCount(wg *sync.WaitGroup, count int) {
for i := 0; i < count; i++ {
GlobalState.AddRequestCount("test", 1)
GlobalState.AddRequestCount("test", 200, 1)
}
wg.Add(-1)
}

func Test_CurrentRequestCount(t *testing.T) {
//var num uint64 = 1
GlobalState.AddCurrentRequest(1000465)
t.Log(GlobalState.CurrentRequestCount)
GlobalState.SubCurrentRequest(2561)
t.Log(GlobalState.CurrentRequestCount)
}

func Test_AddRequestCount_2(t *testing.T) {
var num uint64 = 1
var count uint64
for i := 0; i < 100; i++ {
count = GlobalState.AddRequestCount("test", num)
GlobalState.AddRequestCount("test", 200, num)
num++
}
t.Log("TotalRequestCount:", count)
}

func Test_AddErrorCount_1(t *testing.T) {
Expand Down Expand Up @@ -92,16 +98,26 @@ func Benchmark_AddErrorCount_Parallel(b *testing.B) {
func Benchmark_AddRequestCount_1(b *testing.B) {
var num uint64 = 1
for i := 0; i < b.N; i++ {
GlobalState.AddRequestCount("test", num)
GlobalState.AddRequestCount("test", 200, num)
}
}


//基准测试
func Benchmark_AddCurrentRequestCount_1(b *testing.B) {
var num uint64 = 1
for i := 0; i < b.N; i++ {
GlobalState.AddCurrentRequest(num)
}
}


// 测试并发效率
func Benchmark_AddRequestCount_Parallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
var num uint64 = 1
for pb.Next() {
GlobalState.AddRequestCount("test", num)
GlobalState.AddRequestCount("test", 200, num)
}
})
}
3 changes: 3 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ func (server *HttpServer) ListenAndServeTLS(addr string, certFile, keyFile strin

// ServeHTTP make sure request can be handled correctly
func (server *HttpServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
core.GlobalState.AddCurrentRequest(1)
defer core.GlobalState.SubCurrentRequest(1)

//针对websocket与调试信息特殊处理
if checkIsWebSocketRequest(req) {
http.DefaultServeMux.ServeHTTP(w, req)
Expand Down
5 changes: 5 additions & 0 deletions version.MD
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## dotweb版本记录:

#### Version 1.5.5
* New feature: /dotweb/state add CurrentRequestCount data
* Update: improve 30% performance on app's metric
* 2018-08-09 15:00

#### Version 1.5.4
* New feature: Session.StoreConfig support CookieName, used to set custom cookie name which sessionid store, default is dotweb_sessionId
* Update: Config.SessionNode add CookieName, used to set custom cookie name which sessionid store
Expand Down