github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/metrics/meter.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  package metrics
    10  
    11  import (
    12  	"sync"
    13  	"time"
    14  )
    15  
    16  //米数事件以产生指数加权移动平均速率
    17  //以1分钟、5分钟和15分钟的平均速率。
    18  type Meter interface {
    19  	Count() int64
    20  	Mark(int64)
    21  	Rate1() float64
    22  	Rate5() float64
    23  	Rate15() float64
    24  	RateMean() float64
    25  	Snapshot() Meter
    26  	Stop()
    27  }
    28  
    29  //GetOrRegisterMeter返回现有的仪表或构造并注册
    30  //新标准仪表。
    31  //一旦没有必要从注册表中注销仪表
    32  //允许垃圾收集。
    33  func GetOrRegisterMeter(name string, r Registry) Meter {
    34  	if nil == r {
    35  		r = DefaultRegistry
    36  	}
    37  	return r.GetOrRegister(name, NewMeter).(Meter)
    38  }
    39  
    40  //NewMeter构建了一个新的StandardMeter并启动了一个Goroutine。
    41  //当计量器不允许垃圾收集时,一定要调用stop()。
    42  func NewMeter() Meter {
    43  	if !Enabled {
    44  		return NilMeter{}
    45  	}
    46  	m := newStandardMeter()
    47  	arbiter.Lock()
    48  	defer arbiter.Unlock()
    49  	arbiter.meters[m] = struct{}{}
    50  	if !arbiter.started {
    51  		arbiter.started = true
    52  		go arbiter.tick()
    53  	}
    54  	return m
    55  }
    56  
    57  //NewMeter构造并注册新的StandardMeter并启动
    58  //高尔图
    59  //一旦没有必要从注册表中注销仪表
    60  //允许垃圾收集。
    61  func NewRegisteredMeter(name string, r Registry) Meter {
    62  	c := NewMeter()
    63  	if nil == r {
    64  		r = DefaultRegistry
    65  	}
    66  	r.Register(name, c)
    67  	return c
    68  }
    69  
    70  //metersnapshot是另一个meter的只读副本。
    71  type MeterSnapshot struct {
    72  	count                          int64
    73  	rate1, rate5, rate15, rateMean float64
    74  }
    75  
    76  //Count返回拍摄快照时的事件计数。
    77  func (m *MeterSnapshot) Count() int64 { return m.count }
    78  
    79  //马克恐慌。
    80  func (*MeterSnapshot) Mark(n int64) {
    81  	panic("Mark called on a MeterSnapshot")
    82  }
    83  
    84  //RATE1返回在
    85  //拍摄快照的时间。
    86  func (m *MeterSnapshot) Rate1() float64 { return m.rate1 }
    87  
    88  //RATE5返回每秒5分钟的移动平均事件速率
    89  //拍摄快照的时间。
    90  func (m *MeterSnapshot) Rate5() float64 { return m.rate5 }
    91  
    92  //Rate15返回每秒15分钟的事件移动平均速率
    93  //拍摄快照时。
    94  func (m *MeterSnapshot) Rate15() float64 { return m.rate15 }
    95  
    96  //RateMean返回在
    97  //已拍摄快照。
    98  func (m *MeterSnapshot) RateMean() float64 { return m.rateMean }
    99  
   100  //快照返回快照。
   101  func (m *MeterSnapshot) Snapshot() Meter { return m }
   102  
   103  //停止是不允许的。
   104  func (m *MeterSnapshot) Stop() {}
   105  
   106  //nilmeter是一个无运算表。
   107  type NilMeter struct{}
   108  
   109  //计数是不允许的。
   110  func (NilMeter) Count() int64 { return 0 }
   111  
   112  //马克是个无赖。
   113  func (NilMeter) Mark(n int64) {}
   114  
   115  //RATE1是不可操作的。
   116  func (NilMeter) Rate1() float64 { return 0.0 }
   117  
   118  //RATE5是不允许的。
   119  func (NilMeter) Rate5() float64 { return 0.0 }
   120  
   121  //RATE15是不允许的。
   122  func (NilMeter) Rate15() float64 { return 0.0 }
   123  
   124  //RateMean是一个不允许的人。
   125  func (NilMeter) RateMean() float64 { return 0.0 }
   126  
   127  //快照是不可操作的。
   128  func (NilMeter) Snapshot() Meter { return NilMeter{} }
   129  
   130  //停止是不允许的。
   131  func (NilMeter) Stop() {}
   132  
   133  //标准仪表是仪表的标准实现。
   134  type StandardMeter struct {
   135  	lock        sync.RWMutex
   136  	snapshot    *MeterSnapshot
   137  	a1, a5, a15 EWMA
   138  	startTime   time.Time
   139  	stopped     bool
   140  }
   141  
   142  func newStandardMeter() *StandardMeter {
   143  	return &StandardMeter{
   144  		snapshot:  &MeterSnapshot{},
   145  		a1:        NewEWMA1(),
   146  		a5:        NewEWMA5(),
   147  		a15:       NewEWMA15(),
   148  		startTime: time.Now(),
   149  	}
   150  }
   151  
   152  //停止停止计时表,如果您在停止后使用它,mark()将是一个no op。
   153  func (m *StandardMeter) Stop() {
   154  	m.lock.Lock()
   155  	stopped := m.stopped
   156  	m.stopped = true
   157  	m.lock.Unlock()
   158  	if !stopped {
   159  		arbiter.Lock()
   160  		delete(arbiter.meters, m)
   161  		arbiter.Unlock()
   162  	}
   163  }
   164  
   165  //count返回记录的事件数。
   166  func (m *StandardMeter) Count() int64 {
   167  	m.lock.RLock()
   168  	count := m.snapshot.count
   169  	m.lock.RUnlock()
   170  	return count
   171  }
   172  
   173  //标记记录n个事件的发生。
   174  func (m *StandardMeter) Mark(n int64) {
   175  	m.lock.Lock()
   176  	defer m.lock.Unlock()
   177  	if m.stopped {
   178  		return
   179  	}
   180  	m.snapshot.count += n
   181  	m.a1.Update(n)
   182  	m.a5.Update(n)
   183  	m.a15.Update(n)
   184  	m.updateSnapshot()
   185  }
   186  
   187  //Rate1返回每秒事件的一分钟移动平均速率。
   188  func (m *StandardMeter) Rate1() float64 {
   189  	m.lock.RLock()
   190  	rate1 := m.snapshot.rate1
   191  	m.lock.RUnlock()
   192  	return rate1
   193  }
   194  
   195  //Rate5返回每秒事件的5分钟移动平均速率。
   196  func (m *StandardMeter) Rate5() float64 {
   197  	m.lock.RLock()
   198  	rate5 := m.snapshot.rate5
   199  	m.lock.RUnlock()
   200  	return rate5
   201  }
   202  
   203  //Rate15返回每秒事件的15分钟移动平均速率。
   204  func (m *StandardMeter) Rate15() float64 {
   205  	m.lock.RLock()
   206  	rate15 := m.snapshot.rate15
   207  	m.lock.RUnlock()
   208  	return rate15
   209  }
   210  
   211  //RateMean返回仪表每秒事件的平均速率。
   212  func (m *StandardMeter) RateMean() float64 {
   213  	m.lock.RLock()
   214  	rateMean := m.snapshot.rateMean
   215  	m.lock.RUnlock()
   216  	return rateMean
   217  }
   218  
   219  //快照返回仪表的只读副本。
   220  func (m *StandardMeter) Snapshot() Meter {
   221  	m.lock.RLock()
   222  	snapshot := *m.snapshot
   223  	m.lock.RUnlock()
   224  	return &snapshot
   225  }
   226  
   227  func (m *StandardMeter) updateSnapshot() {
   228  //应在m.lock上保持写锁的情况下运行
   229  	snapshot := m.snapshot
   230  	snapshot.rate1 = m.a1.Rate()
   231  	snapshot.rate5 = m.a5.Rate()
   232  	snapshot.rate15 = m.a15.Rate()
   233  	snapshot.rateMean = float64(snapshot.count) / time.Since(m.startTime).Seconds()
   234  }
   235  
   236  func (m *StandardMeter) tick() {
   237  	m.lock.Lock()
   238  	defer m.lock.Unlock()
   239  	m.a1.Tick()
   240  	m.a5.Tick()
   241  	m.a15.Tick()
   242  	m.updateSnapshot()
   243  }
   244  
   245  //计量员每5秒从一个Goroutine数米。
   246  //仪表是一套用于将来停车的参考。
   247  type meterArbiter struct {
   248  	sync.RWMutex
   249  	started bool
   250  	meters  map[*StandardMeter]struct{}
   251  	ticker  *time.Ticker
   252  }
   253  
   254  var arbiter = meterArbiter{ticker: time.NewTicker(5e9), meters: make(map[*StandardMeter]struct{})}
   255  
   256  //按计划间隔计时米
   257  func (ma *meterArbiter) tick() {
   258  	for range ma.ticker.C {
   259  		ma.tickMeters()
   260  	}
   261  }
   262  
   263  func (ma *meterArbiter) tickMeters() {
   264  	ma.RLock()
   265  	defer ma.RUnlock()
   266  	for meter := range ma.meters {
   267  		meter.tick()
   268  	}
   269  }