github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/metrics/meter.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:40</date> 10 //</624450099384160256> 11 12 package metrics 13 14 import ( 15 "sync" 16 "time" 17 ) 18 19 //米数事件以产生指数加权移动平均速率 20 //以1分钟、5分钟和15分钟的平均速率。 21 type Meter interface { 22 Count() int64 23 Mark(int64) 24 Rate1() float64 25 Rate5() float64 26 Rate15() float64 27 RateMean() float64 28 Snapshot() Meter 29 Stop() 30 } 31 32 //GetOrRegisterMeter返回现有的仪表或构造并注册 33 //新标准仪表。 34 //一旦没有必要从注册表中注销仪表 35 //允许垃圾收集。 36 func GetOrRegisterMeter(name string, r Registry) Meter { 37 if nil == r { 38 r = DefaultRegistry 39 } 40 return r.GetOrRegister(name, NewMeter).(Meter) 41 } 42 43 //GetOrRegisterMeterForced返回现有的仪表或构造并注册 44 //新标准仪表,无论是否启用全局开关。 45 //一旦没有必要从注册表中注销仪表 46 //允许垃圾收集。 47 func GetOrRegisterMeterForced(name string, r Registry) Meter { 48 if nil == r { 49 r = DefaultRegistry 50 } 51 return r.GetOrRegister(name, NewMeterForced).(Meter) 52 } 53 54 //NewMeter构建了一个新的StandardMeter并启动了一个Goroutine。 55 //当计量器不允许垃圾收集时,一定要调用stop()。 56 func NewMeter() Meter { 57 if !Enabled { 58 return NilMeter{} 59 } 60 m := newStandardMeter() 61 arbiter.Lock() 62 defer arbiter.Unlock() 63 arbiter.meters[m] = struct{}{} 64 if !arbiter.started { 65 arbiter.started = true 66 go arbiter.tick() 67 } 68 return m 69 } 70 71 //newmeterforced构建了一个新的StandardMeter并启动Goroutine 72 //全局开关是否启用。 73 //当计量器不允许垃圾收集时,一定要调用stop()。 74 func NewMeterForced() Meter { 75 m := newStandardMeter() 76 arbiter.Lock() 77 defer arbiter.Unlock() 78 arbiter.meters[m] = struct{}{} 79 if !arbiter.started { 80 arbiter.started = true 81 go arbiter.tick() 82 } 83 return m 84 } 85 86 //NewRegisteredMeter构造并注册一个新的StandardMeter 87 //启动Goroutine。 88 //一旦没有必要从注册表中注销仪表 89 //允许垃圾收集。 90 func NewRegisteredMeter(name string, r Registry) Meter { 91 c := NewMeter() 92 if nil == r { 93 r = DefaultRegistry 94 } 95 r.Register(name, c) 96 return c 97 } 98 99 //newregisteredmeterforced构造并注册新的标准仪表 100 //并启动Goroutine,无论全局开关是否启用。 101 //一旦没有必要从注册表中注销仪表 102 //允许垃圾收集。 103 func NewRegisteredMeterForced(name string, r Registry) Meter { 104 c := NewMeterForced() 105 if nil == r { 106 r = DefaultRegistry 107 } 108 r.Register(name, c) 109 return c 110 } 111 112 //metersnapshot是另一个meter的只读副本。 113 type MeterSnapshot struct { 114 count int64 115 rate1, rate5, rate15, rateMean float64 116 } 117 118 //Count返回拍摄快照时的事件计数。 119 func (m *MeterSnapshot) Count() int64 { return m.count } 120 121 //马克恐慌。 122 func (*MeterSnapshot) Mark(n int64) { 123 panic("Mark called on a MeterSnapshot") 124 } 125 126 //RATE1返回在 127 //拍摄快照的时间。 128 func (m *MeterSnapshot) Rate1() float64 { return m.rate1 } 129 130 //RATE5返回每秒5分钟的移动平均事件速率 131 //拍摄快照的时间。 132 func (m *MeterSnapshot) Rate5() float64 { return m.rate5 } 133 134 //Rate15返回每秒15分钟的事件移动平均速率 135 //拍摄快照时。 136 func (m *MeterSnapshot) Rate15() float64 { return m.rate15 } 137 138 //RateMean返回在 139 //已拍摄快照。 140 func (m *MeterSnapshot) RateMean() float64 { return m.rateMean } 141 142 //快照返回快照。 143 func (m *MeterSnapshot) Snapshot() Meter { return m } 144 145 //停止是不允许的。 146 func (m *MeterSnapshot) Stop() {} 147 148 //nilmeter是一个无运算表。 149 type NilMeter struct{} 150 151 //计数是不允许的。 152 func (NilMeter) Count() int64 { return 0 } 153 154 //马克是个无赖。 155 func (NilMeter) Mark(n int64) {} 156 157 //RATE1是不可操作的。 158 func (NilMeter) Rate1() float64 { return 0.0 } 159 160 //RATE5是不允许的。 161 func (NilMeter) Rate5() float64 { return 0.0 } 162 163 //RATE15是不允许的。 164 func (NilMeter) Rate15() float64 { return 0.0 } 165 166 //RateMean是一个不允许的人。 167 func (NilMeter) RateMean() float64 { return 0.0 } 168 169 //快照是不可操作的。 170 func (NilMeter) Snapshot() Meter { return NilMeter{} } 171 172 //停止是不允许的。 173 func (NilMeter) Stop() {} 174 175 //标准仪表是仪表的标准实现。 176 type StandardMeter struct { 177 lock sync.RWMutex 178 snapshot *MeterSnapshot 179 a1, a5, a15 EWMA 180 startTime time.Time 181 stopped bool 182 } 183 184 func newStandardMeter() *StandardMeter { 185 return &StandardMeter{ 186 snapshot: &MeterSnapshot{}, 187 a1: NewEWMA1(), 188 a5: NewEWMA5(), 189 a15: NewEWMA15(), 190 startTime: time.Now(), 191 } 192 } 193 194 //停止停止计时表,如果您在停止后使用它,mark()将是一个no op。 195 func (m *StandardMeter) Stop() { 196 m.lock.Lock() 197 stopped := m.stopped 198 m.stopped = true 199 m.lock.Unlock() 200 if !stopped { 201 arbiter.Lock() 202 delete(arbiter.meters, m) 203 arbiter.Unlock() 204 } 205 } 206 207 //count返回记录的事件数。 208 func (m *StandardMeter) Count() int64 { 209 m.lock.RLock() 210 count := m.snapshot.count 211 m.lock.RUnlock() 212 return count 213 } 214 215 //标记记录n个事件的发生。 216 func (m *StandardMeter) Mark(n int64) { 217 m.lock.Lock() 218 defer m.lock.Unlock() 219 if m.stopped { 220 return 221 } 222 m.snapshot.count += n 223 m.a1.Update(n) 224 m.a5.Update(n) 225 m.a15.Update(n) 226 m.updateSnapshot() 227 } 228 229 //Rate1返回每秒事件的一分钟移动平均速率。 230 func (m *StandardMeter) Rate1() float64 { 231 m.lock.RLock() 232 rate1 := m.snapshot.rate1 233 m.lock.RUnlock() 234 return rate1 235 } 236 237 //Rate5返回每秒事件的5分钟移动平均速率。 238 func (m *StandardMeter) Rate5() float64 { 239 m.lock.RLock() 240 rate5 := m.snapshot.rate5 241 m.lock.RUnlock() 242 return rate5 243 } 244 245 //Rate15返回每秒事件的15分钟移动平均速率。 246 func (m *StandardMeter) Rate15() float64 { 247 m.lock.RLock() 248 rate15 := m.snapshot.rate15 249 m.lock.RUnlock() 250 return rate15 251 } 252 253 //RateMean返回仪表每秒事件的平均速率。 254 func (m *StandardMeter) RateMean() float64 { 255 m.lock.RLock() 256 rateMean := m.snapshot.rateMean 257 m.lock.RUnlock() 258 return rateMean 259 } 260 261 //快照返回仪表的只读副本。 262 func (m *StandardMeter) Snapshot() Meter { 263 m.lock.RLock() 264 snapshot := *m.snapshot 265 m.lock.RUnlock() 266 return &snapshot 267 } 268 269 func (m *StandardMeter) updateSnapshot() { 270 //应在m.lock上保持写锁的情况下运行 271 snapshot := m.snapshot 272 snapshot.rate1 = m.a1.Rate() 273 snapshot.rate5 = m.a5.Rate() 274 snapshot.rate15 = m.a15.Rate() 275 snapshot.rateMean = float64(snapshot.count) / time.Since(m.startTime).Seconds() 276 } 277 278 func (m *StandardMeter) tick() { 279 m.lock.Lock() 280 defer m.lock.Unlock() 281 m.a1.Tick() 282 m.a5.Tick() 283 m.a15.Tick() 284 m.updateSnapshot() 285 } 286 287 //计量员每5秒从一个Goroutine数米。 288 //仪表是一套用于将来停车的参考。 289 type meterArbiter struct { 290 sync.RWMutex 291 started bool 292 meters map[*StandardMeter]struct{} 293 ticker *time.Ticker 294 } 295 296 var arbiter = meterArbiter{ticker: time.NewTicker(5e9), meters: make(map[*StandardMeter]struct{})} 297 298 //按计划间隔计时米 299 func (ma *meterArbiter) tick() { 300 for range ma.ticker.C { 301 ma.tickMeters() 302 } 303 } 304 305 func (ma *meterArbiter) tickMeters() { 306 ma.RLock() 307 defer ma.RUnlock() 308 for meter := range ma.meters { 309 meter.tick() 310 } 311 } 312