forked from free-lancers/electricity_bill_calc_service
合并分支
This commit is contained in:
84
tools/serial/algorithm.go
Normal file
84
tools/serial/algorithm.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package serial
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/config"
|
||||
"electricity_bill_calc/logger"
|
||||
"electricity_bill_calc/types"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
log = logger.Named("Algorithm", "Unique Serial")
|
||||
SerialRequestChan = make(chan int64, 500)
|
||||
StringSerialRequestChan = make(chan int64, 500)
|
||||
SerialResponseChan = make(chan int64, 500)
|
||||
StringSerialResponseChan = make(chan string, 500)
|
||||
)
|
||||
|
||||
func init() {
|
||||
go func() {
|
||||
var (
|
||||
lastTimestamp int64 = 0
|
||||
lastSerial int64 = 0
|
||||
)
|
||||
log.Info("唯一序列号生成服务已经启动。")
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-SerialRequestChan:
|
||||
log.Info("收到生成数字型唯一序列号的请求。")
|
||||
timestamp := generateTimestamp(lastTimestamp)
|
||||
if timestamp != lastTimestamp {
|
||||
lastSerial = 0
|
||||
}
|
||||
lastSerial = lastSerial + 1
|
||||
uniqueId := generateSerial(timestamp, lastSerial)
|
||||
SerialResponseChan <- uniqueId
|
||||
lastTimestamp = timestamp
|
||||
case <-StringSerialRequestChan:
|
||||
log.Info("收到生成字符串型唯一序列号的请求。")
|
||||
timestamp := generateTimestamp(lastTimestamp)
|
||||
if timestamp != lastTimestamp {
|
||||
lastSerial = 0
|
||||
}
|
||||
lastSerial = lastSerial + 1
|
||||
uniqueId := generateStringSerial(timestamp, lastSerial)
|
||||
StringSerialResponseChan <- uniqueId
|
||||
lastTimestamp = timestamp
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 生成一个能够对抗服务器时间回拨的时间戳
|
||||
func generateTimestamp(base int64) int64 {
|
||||
for {
|
||||
timestamp := types.Timestamp()
|
||||
if timestamp >= base {
|
||||
return timestamp
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// 生成一个唯一的数字型序列号
|
||||
func generateSerial(timestamp, serial int64) int64 {
|
||||
return (timestamp << 20) | ((config.ServiceSettings.HostSerial & 0xffff) << 16) | (serial & 0xffff_ffff)
|
||||
}
|
||||
|
||||
// 生成一个唯一的字符串型序列号
|
||||
func generateStringSerial(timestamp, serial int64) string {
|
||||
return fmt.Sprintf("%017d", generateSerial(timestamp, serial))
|
||||
}
|
||||
|
||||
// 生成一个带前缀字符串的唯一字符串型序列号
|
||||
func Prefix(prefix string, serial interface{}) string {
|
||||
switch serial := serial.(type) {
|
||||
case int64:
|
||||
return fmt.Sprintf("%s%017d", prefix, serial)
|
||||
case string:
|
||||
return fmt.Sprintf("%s%s", prefix, serial)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user