上报器
This commit is contained in:
parent
ef00111357
commit
f7db23d76b
|
@ -0,0 +1,17 @@
|
||||||
|
# Report
|
||||||
|
用于数据上报,其中数据埋点是线程安全的
|
||||||
|
|
||||||
|
# 全局埋点 GlobalBuried
|
||||||
|
全局埋点适用于活跃用户数、用户总量等全局的数据统计
|
||||||
|
|
||||||
|
# 数据埋点 DataBuried
|
||||||
|
数据埋点适合进行用户数据、交易数据等存在多id情况的数据统计
|
||||||
|
|
||||||
|
# 跨进程上报
|
||||||
|
通常数据埋点会占用一些系统资源而妨碍主进程的运行,这时候可以通过将上报工作独立出来减轻主进程负担
|
||||||
|
|
||||||
|
默认情况下的埋点数据是存储在执行进程的内存中的,可以通过可选项自定义存储位置,例如`Redis`
|
||||||
|
|
||||||
|
> 实现思路,以`Redis`为例:
|
||||||
|
> - 在主进程创建埋点,并将数据读写更改为`Redis`
|
||||||
|
> - 上报进程中创建上报器,按照特定策略从`Redis`读取数据进行上报
|
|
@ -0,0 +1,32 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import "github.com/kercylan98/minotaur/utils/timer"
|
||||||
|
|
||||||
|
func NewReporter(reportHandle func() error, options ...ReporterOption) *Reporter {
|
||||||
|
reporter := &Reporter{
|
||||||
|
reportHandle: reportHandle,
|
||||||
|
}
|
||||||
|
for _, option := range options {
|
||||||
|
option(reporter)
|
||||||
|
}
|
||||||
|
if reporter.ticker == nil {
|
||||||
|
reporter.ticker = timer.GetTicker(50)
|
||||||
|
}
|
||||||
|
for _, strategy := range reporter.strategies {
|
||||||
|
strategy(reporter)
|
||||||
|
}
|
||||||
|
return reporter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reporter 数据上报器
|
||||||
|
type Reporter struct {
|
||||||
|
ticker *timer.Ticker
|
||||||
|
strategies []ReporterStrategy
|
||||||
|
reportHandle func() error
|
||||||
|
errorHandle func(reporter *Reporter, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report 上报
|
||||||
|
func (slf *Reporter) Report() error {
|
||||||
|
return slf.reportHandle()
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import "github.com/kercylan98/minotaur/utils/timer"
|
||||||
|
|
||||||
|
type ReporterOption func(reporter *Reporter)
|
||||||
|
|
||||||
|
// WithReporterTicker 通过特定的定时器创建上报器
|
||||||
|
func WithReporterTicker(ticker *timer.Ticker) ReporterOption {
|
||||||
|
return func(reporter *Reporter) {
|
||||||
|
reporter.ticker = ticker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithReporterStrategies 通过特定上报策略进行创建
|
||||||
|
func WithReporterStrategies(strategies ...ReporterStrategy) ReporterOption {
|
||||||
|
return func(reporter *Reporter) {
|
||||||
|
reporter.strategies = append(reporter.strategies, strategies...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithReporterErrorHandle(errorHandle func(reporter *Reporter, err error)) ReporterOption {
|
||||||
|
return func(reporter *Reporter) {
|
||||||
|
reporter.errorHandle = errorHandle
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/kercylan98/minotaur/utils/timer"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReporterStrategy 上报器策略
|
||||||
|
type ReporterStrategy func(reporter *Reporter)
|
||||||
|
|
||||||
|
// ReportStrategyLoop 循环上报
|
||||||
|
// - 将在创建后上报一次,并且在每隔一段时间后继续上报
|
||||||
|
func ReportStrategyLoop(t time.Duration) ReporterStrategy {
|
||||||
|
return func(reporter *Reporter) {
|
||||||
|
reporter.ticker.Loop(fmt.Sprintf("ReportStrategyLoop_%d", t.Milliseconds()), timer.Instantly, t, timer.Forever, func() {
|
||||||
|
if err := reporter.Report(); err != nil && reporter.errorHandle != nil {
|
||||||
|
reporter.errorHandle(reporter, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportStrategyFixedTime 将在每天的固定时间上报
|
||||||
|
func ReportStrategyFixedTime(hour, min, sec int) ReporterStrategy {
|
||||||
|
return func(reporter *Reporter) {
|
||||||
|
now := time.Now()
|
||||||
|
current := now.Unix()
|
||||||
|
next := time.Date(now.Year(), now.Month(), now.Day(), hour, min, sec, 0, now.Location())
|
||||||
|
target := next.Unix()
|
||||||
|
if current >= target {
|
||||||
|
next = next.AddDate(0, 0, 1)
|
||||||
|
target = next.Unix()
|
||||||
|
}
|
||||||
|
reporter.ticker.Loop(fmt.Sprintf("ReportStrategyFixedTime_%d_%d_%d", hour, min, sec), time.Duration(target-current)*time.Second, 24*time.Hour, -1, func() {
|
||||||
|
if err := reporter.Report(); err != nil && reporter.errorHandle != nil {
|
||||||
|
reporter.errorHandle(reporter, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue