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