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