github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:42</date> 10 //</624342650182438912> 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 //NewMeter构建了一个新的StandardMeter并启动了一个Goroutine。 44 //当计量器不允许垃圾收集时,一定要调用stop()。 45 func NewMeter() Meter { 46 if !Enabled { 47 return NilMeter{} 48 } 49 m := newStandardMeter() 50 arbiter.Lock() 51 defer arbiter.Unlock() 52 arbiter.meters[m] = struct{}{} 53 if !arbiter.started { 54 arbiter.started = true 55 go arbiter.tick() 56 } 57 return m 58 } 59 60 //NewMeter构造并注册新的StandardMeter并启动 61 //高尔图 62 //一旦没有必要从注册表中注销仪表 63 //允许垃圾收集。 64 func NewRegisteredMeter(name string, r Registry) Meter { 65 c := NewMeter() 66 if nil == r { 67 r = DefaultRegistry 68 } 69 r.Register(name, c) 70 return c 71 } 72 73 //metersnapshot是另一个meter的只读副本。 74 type MeterSnapshot struct { 75 count int64 76 rate1, rate5, rate15, rateMean float64 77 } 78 79 //Count返回拍摄快照时的事件计数。 80 func (m *MeterSnapshot) Count() int64 { return m.count } 81 82 //马克恐慌。 83 func (*MeterSnapshot) Mark(n int64) { 84 panic("Mark called on a MeterSnapshot") 85 } 86 87 //RATE1返回在 88 //拍摄快照的时间。 89 func (m *MeterSnapshot) Rate1() float64 { return m.rate1 } 90 91 //RATE5返回每秒5分钟的移动平均事件速率 92 //拍摄快照的时间。 93 func (m *MeterSnapshot) Rate5() float64 { return m.rate5 } 94 95 //Rate15返回每秒15分钟的事件移动平均速率 96 //拍摄快照时。 97 func (m *MeterSnapshot) Rate15() float64 { return m.rate15 } 98 99 //RateMean返回在 100 //已拍摄快照。 101 func (m *MeterSnapshot) RateMean() float64 { return m.rateMean } 102 103 //快照返回快照。 104 func (m *MeterSnapshot) Snapshot() Meter { return m } 105 106 //停止是不允许的。 107 func (m *MeterSnapshot) Stop() {} 108 109 //nilmeter是一个无运算表。 110 type NilMeter struct{} 111 112 //计数是不允许的。 113 func (NilMeter) Count() int64 { return 0 } 114 115 //马克是个无赖。 116 func (NilMeter) Mark(n int64) {} 117 118 //RATE1是不可操作的。 119 func (NilMeter) Rate1() float64 { return 0.0 } 120 121 //RATE5是不允许的。 122 func (NilMeter) Rate5() float64 { return 0.0 } 123 124 //RATE15是不允许的。 125 func (NilMeter) Rate15() float64 { return 0.0 } 126 127 //RateMean是一个不允许的人。 128 func (NilMeter) RateMean() float64 { return 0.0 } 129 130 //快照是不可操作的。 131 func (NilMeter) Snapshot() Meter { return NilMeter{} } 132 133 //停止是不允许的。 134 func (NilMeter) Stop() {} 135 136 //标准仪表是仪表的标准实现。 137 type StandardMeter struct { 138 lock sync.RWMutex 139 snapshot *MeterSnapshot 140 a1, a5, a15 EWMA 141 startTime time.Time 142 stopped bool 143 } 144 145 func newStandardMeter() *StandardMeter { 146 return &StandardMeter{ 147 snapshot: &MeterSnapshot{}, 148 a1: NewEWMA1(), 149 a5: NewEWMA5(), 150 a15: NewEWMA15(), 151 startTime: time.Now(), 152 } 153 } 154 155 //停止停止计时表,如果您在停止后使用它,mark()将是一个no op。 156 func (m *StandardMeter) Stop() { 157 m.lock.Lock() 158 stopped := m.stopped 159 m.stopped = true 160 m.lock.Unlock() 161 if !stopped { 162 arbiter.Lock() 163 delete(arbiter.meters, m) 164 arbiter.Unlock() 165 } 166 } 167 168 //count返回记录的事件数。 169 func (m *StandardMeter) Count() int64 { 170 m.lock.RLock() 171 count := m.snapshot.count 172 m.lock.RUnlock() 173 return count 174 } 175 176 //标记记录n个事件的发生。 177 func (m *StandardMeter) Mark(n int64) { 178 m.lock.Lock() 179 defer m.lock.Unlock() 180 if m.stopped { 181 return 182 } 183 m.snapshot.count += n 184 m.a1.Update(n) 185 m.a5.Update(n) 186 m.a15.Update(n) 187 m.updateSnapshot() 188 } 189 190 //Rate1返回每秒事件的一分钟移动平均速率。 191 func (m *StandardMeter) Rate1() float64 { 192 m.lock.RLock() 193 rate1 := m.snapshot.rate1 194 m.lock.RUnlock() 195 return rate1 196 } 197 198 //Rate5返回每秒事件的5分钟移动平均速率。 199 func (m *StandardMeter) Rate5() float64 { 200 m.lock.RLock() 201 rate5 := m.snapshot.rate5 202 m.lock.RUnlock() 203 return rate5 204 } 205 206 //Rate15返回每秒事件的15分钟移动平均速率。 207 func (m *StandardMeter) Rate15() float64 { 208 m.lock.RLock() 209 rate15 := m.snapshot.rate15 210 m.lock.RUnlock() 211 return rate15 212 } 213 214 //RateMean返回仪表每秒事件的平均速率。 215 func (m *StandardMeter) RateMean() float64 { 216 m.lock.RLock() 217 rateMean := m.snapshot.rateMean 218 m.lock.RUnlock() 219 return rateMean 220 } 221 222 //快照返回仪表的只读副本。 223 func (m *StandardMeter) Snapshot() Meter { 224 m.lock.RLock() 225 snapshot := *m.snapshot 226 m.lock.RUnlock() 227 return &snapshot 228 } 229 230 func (m *StandardMeter) updateSnapshot() { 231 //应在m.lock上保持写锁的情况下运行 232 snapshot := m.snapshot 233 snapshot.rate1 = m.a1.Rate() 234 snapshot.rate5 = m.a5.Rate() 235 snapshot.rate15 = m.a15.Rate() 236 snapshot.rateMean = float64(snapshot.count) / time.Since(m.startTime).Seconds() 237 } 238 239 func (m *StandardMeter) tick() { 240 m.lock.Lock() 241 defer m.lock.Unlock() 242 m.a1.Tick() 243 m.a5.Tick() 244 m.a15.Tick() 245 m.updateSnapshot() 246 } 247 248 //计量员每5秒从一个Goroutine数米。 249 //仪表是一套用于将来停车的参考。 250 type meterArbiter struct { 251 sync.RWMutex 252 started bool 253 meters map[*StandardMeter]struct{} 254 ticker *time.Ticker 255 } 256 257 var arbiter = meterArbiter{ticker: time.NewTicker(5e9), meters: make(map[*StandardMeter]struct{})} 258 259 //按计划间隔计时米 260 func (ma *meterArbiter) tick() { 261 for range ma.ticker.C { 262 ma.tickMeters() 263 } 264 } 265 266 func (ma *meterArbiter) tickMeters() { 267 ma.RLock() 268 defer ma.RUnlock() 269 for meter := range ma.meters { 270 meter.tick() 271 } 272 } 273