update at 2020-07-20 10:06:17 by ehlxr

master
ehlxr 2020-07-20 10:06:17 +08:00
parent cc3dec7cf5
commit e6c62d0bda
8 changed files with 305 additions and 43 deletions

4
clog-err.log Normal file
View File

@ -0,0 +1,4 @@
2019/11/13 11:40:11 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!
2019/11/13 11:40:52 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!
2019/11/13 11:40:58 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!
2019/11/13 13:46:57 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!

9
clog.log Normal file
View File

@ -0,0 +1,9 @@
2019/11/13 11:40:52 [ INFO] Hello World!
2019/11/13 11:40:52 [ WARN] Hello World!
2019/11/13 11:40:52 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!
2019/11/13 11:40:58 [ INFO] Hello World!
2019/11/13 11:40:58 [ WARN] Hello World!
2019/11/13 11:40:58 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!
2019/11/13 13:46:57 [ INFO] Hello World!
2019/11/13 13:46:57 [ WARN] Hello World!
2019/11/13 13:46:57 [ERROR] [...ithub.com/ehlxr/go-utils/main.go:49 main()] Hello World!

5
go.mod
View File

@ -5,12 +5,12 @@ go 1.13
require (
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/dgrijalva/jwt-go v3.1.0+incompatible
github.com/jessevdk/go-flags v1.4.1-0.20181221193153-c0795c8afcf4
github.com/manifoldco/promptui v0.3.2
github.com/mattn/go-colorable v0.0.10-0.20180115155639-6cc8b475d468 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/onsi/ginkgo v1.10.2 // indirect
github.com/onsi/gomega v1.7.0 // indirect
github.com/sirupsen/logrus v1.0.4
github.com/sirupsen/logrus v1.4.2
github.com/x-cray/logrus-prefixed-formatter v0.5.2
github.com/xwb1989/sqlparser v0.0.0-20171128062118-da747e0c62c4
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
@ -18,4 +18,5 @@ require (
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c // indirect
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
unknwon.dev/clog/v2 v2.0.0-beta.5
)

21
go.sum
View File

@ -15,6 +15,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.1.0+incompatible h1:FFziAwDQQ2dz1XClWMkwvukur3evtZx7x/wMHKM1i20=
github.com/dgrijalva/jwt-go v3.1.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/lint v0.0.0-20181026193005-c67002cb31c3 h1:I4BOK3PBMjhWfQM2zPJKK7lOBGsrsvOB7kBELP33hiE=
@ -27,8 +29,14 @@ github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.1-0.20181221193153-c0795c8afcf4 h1:xKkUL6QBojwguhKKetf1SocCAKqc6W7S/mGm9xEGllo=
github.com/jessevdk/go-flags v1.4.1-0.20181221193153-c0795c8afcf4/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -41,8 +49,13 @@ github.com/manifoldco/promptui v0.3.2/go.mod h1:8JU+igZ+eeiiRku4T5BjtKh2ms8sziGp
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.0.10-0.20180115155639-6cc8b475d468 h1:eRzQAWHiwqwFMdapAkX6t2tJMqN//3e1L+qel9k3BGI=
github.com/mattn/go-colorable v0.0.10-0.20180115155639-6cc8b475d468/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/nicksnyder/go-i18n v2.0.2+incompatible h1:Xt6dluut3s2zBUha8/3sj6atWMQbFioi9OMqUGH9khg=
@ -55,7 +68,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.0.4 h1:gzbtLsZC3Ic5PptoRG+kQj4L60qjK7H7XszrU163JNQ=
github.com/sirupsen/logrus v1.0.4/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -78,7 +94,10 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
@ -101,3 +120,5 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
unknwon.dev/clog/v2 v2.0.0-beta.5 h1:A0F7S8765S965KXyba4l1tQBW9908/lcFfkCkHmYRb4=
unknwon.dev/clog/v2 v2.0.0-beta.5/go.mod h1:zvUlyibDHI4mykYdWyWje2G9nF/nBzfDOqRo2my4mWc=

156
main.go
View File

@ -1,50 +1,128 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"io"
"os"
"strings"
jwtgo "github.com/dgrijalva/jwt-go"
"github.com/ehlxr/go-utils/utils/log"
)
func main() {
type jwtAuthenticator struct {
keyFunc jwtgo.Keyfunc
// type jwtAuthenticator struct {
// keyFunc jwtgo.Keyfunc
// }
// var claims = &jwtgo.StandardClaims{}
// tokenStr := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjZXJlcy5lbm5jbG91ZC5jbjphcHA6eTdnSU9hemlSIiwiY2VyZXMuZW5uY2xvdWQuY24vYXBwLmlkIjoieTdnSU9hemlSIiwiY2VyZXMuZW5uY2xvdWQuY24vbmFtZXNwYWNlIjoiZy1jZXJlcyJ9.JhSzDnUcCfenDFQkTudaAzLO2JJKaghTOPnHNT9bz4nysVFzSAD-wP4mIiQKTKGPYP4442QGbRtxocTZx-VTK7YkdEKh-QZDkpyyfNi7loTCdCDrcMUQHwK4w8zhZ8KzKOXQrmsYkMSO_kJ8FNKCpOpOeUS5zu-BN39MrgqwE5evFsE-9C-MhrsKzOxuLv5I_cF5AqNnfhHcdCdF7PhHEmXsWC8S_9ep21MxaPhXTspeZa56eZHylV5ddm-bj8WR4r_2OsBI0k1QRN_SZNh8j35eB-Ht3sReVBvYnAHyvGptB8kFTuN6fF-Lkxi-OhkxncAGpl0UpdA5gJ9U0zHaHEM18eE7yr2wQKZIPEWAvtP4xOVPK3GfCx6UAX5HU1Vp5OwSkIW-L6TIUfuGpTAfa36UyDpybXlQ6sU6kGbT5jTetffAjf3FLN4HbS61Mgj1QSjii2dUd2L3lT-jv1d2jSQJGtozL-sapRQ7o6F-IlIaRGmYV0AP7lhN7Pu-22SWseRBVYlkvdgcPXODm_WDmpxBVq77hAyJI2_ARAmbXRGfBDKmwD6kYD2YAvG8wAMiZApFazamwAIQKHmy0Y4tv8I2-r9YlOF5ri4vaZ36Uv65C9YaSL6ctbb25TwMHDVzwSaIYv-HhLMYxGxNBJxnOnIG-SHIE0f1rgYynJbL1sg"
// token, err := jwtgo.ParseWithClaims(tokenStr, claims, func(*jwtgo.Token) (interface{}, error) {
// f, err := os.Open("api-token-public.pem")
// if err != nil {
// panic(err)
// }
// defer f.Close()
// fd, err := ioutil.ReadAll(f)
// if err != nil {
// panic(err)
// }
// return jwtgo.ParseRSAPublicKeyFromPEM(fd)
// })
// if err != nil {
// fmt.Print(err)
// }
// if !token.Valid {
// return
// }
// log.Debugf("jwt token received: %v", claims)
// // appKey@namespace
// temp := strings.Split(claims.Subject, "@")
// fmt.Println(temp[0])
// sf, _ := util.NewWorker(1)
// fmt.Println(uint64(sf.GetId()))
//log.Trace("Hello %s!", "World") // YYYY/MM/DD 12:34:56 [TRACE] Hello World!
//log.Info("Hello %s!", "World") // YYYY/MM/DD 12:34:56 [ INFO] Hello World!
//log.Warn("Hello %s!", "World") // YYYY/MM/DD 12:34:56 [ WARN] Hello World!
//log.Error("Hello %s!", "World")
//// Graceful stopping all loggers before exiting the program.
//log.Stop()
// user := User{"root", "root@ddd.com", 1, false}
var user User = User{
username: "root",
email: "root@ddd.com",
signInCount: 1,
active: false,
}
var claims = &jwtgo.StandardClaims{}
tokenStr := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjZXJlcy5lbm5jbG91ZC5jbjphcHA6eTdnSU9hemlSIiwiY2VyZXMuZW5uY2xvdWQuY24vYXBwLmlkIjoieTdnSU9hemlSIiwiY2VyZXMuZW5uY2xvdWQuY24vbmFtZXNwYWNlIjoiZy1jZXJlcyJ9.JhSzDnUcCfenDFQkTudaAzLO2JJKaghTOPnHNT9bz4nysVFzSAD-wP4mIiQKTKGPYP4442QGbRtxocTZx-VTK7YkdEKh-QZDkpyyfNi7loTCdCDrcMUQHwK4w8zhZ8KzKOXQrmsYkMSO_kJ8FNKCpOpOeUS5zu-BN39MrgqwE5evFsE-9C-MhrsKzOxuLv5I_cF5AqNnfhHcdCdF7PhHEmXsWC8S_9ep21MxaPhXTspeZa56eZHylV5ddm-bj8WR4r_2OsBI0k1QRN_SZNh8j35eB-Ht3sReVBvYnAHyvGptB8kFTuN6fF-Lkxi-OhkxncAGpl0UpdA5gJ9U0zHaHEM18eE7yr2wQKZIPEWAvtP4xOVPK3GfCx6UAX5HU1Vp5OwSkIW-L6TIUfuGpTAfa36UyDpybXlQ6sU6kGbT5jTetffAjf3FLN4HbS61Mgj1QSjii2dUd2L3lT-jv1d2jSQJGtozL-sapRQ7o6F-IlIaRGmYV0AP7lhN7Pu-22SWseRBVYlkvdgcPXODm_WDmpxBVq77hAyJI2_ARAmbXRGfBDKmwD6kYD2YAvG8wAMiZApFazamwAIQKHmy0Y4tv8I2-r9YlOF5ri4vaZ36Uv65C9YaSL6ctbb25TwMHDVzwSaIYv-HhLMYxGxNBJxnOnIG-SHIE0f1rgYynJbL1sg"
token, err := jwtgo.ParseWithClaims(tokenStr, claims, func(*jwtgo.Token) (interface{}, error) {
f, err := os.Open("api-token-public.pem")
if err != nil {
panic(err)
}
defer f.Close()
fd, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
return jwtgo.ParseRSAPublicKeyFromPEM(fd)
})
if err != nil {
fmt.Print(err)
}
if !token.Valid {
return
}
log.Debugf("jwt token received: %v", claims)
// appKey@namespace
temp := strings.Split(claims.Subject, "@")
fmt.Println(temp[0])
fmt.Println(user)
}
type User struct {
username string
email string
signInCount uint64
active bool
}
func revertFileByLine() {
file, err := os.Open("/Users/ehlxr/Desktop/o")
if err != nil {
println(err)
}
defer file.Close()
var strs []string
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n')
if err != nil {
println(err)
}
if err == io.EOF {
break
}
strs = append(strs, line)
}
f, err := os.Create("/Users/ehlxr/Desktop/n.txt")
if err != nil {
println(err)
}
defer f.Close()
w := bufio.NewWriter(f)
for i := len(strs) - 1; i >= 0; i-- {
_, _ = fmt.Fprint(w, strs[i])
}
_ = w.Flush()
}
//func init() {
// err := log.NewConsole()
// if err != nil {
// panic("unable to create new logger: " + err.Error())
// }
//
// err = log.NewFileWithName("base", log.FileConfig{
// Level: log.LevelInfo,
// Filename: "clog.log",
// })
// if err != nil {
// panic("unable to create new logger: " + err.Error())
// }
//
// err = log.NewFileWithName("err", log.FileConfig{
// Level: log.LevelError,
// Filename: "clog-err.log",
// })
// if err != nil {
// panic("unable to create new logger: " + err.Error())
// }
//}

76
utils/SnowFlake.go Normal file
View File

@ -0,0 +1,76 @@
package util
import (
"errors"
"sync"
"time"
)
// 因为snowFlake目的是解决分布式下生成唯一id 所以ID中是包含集群和节点编号在内的
const (
workerBits uint8 = 10 // 每台机器(节点)的ID位数 10位最大可以有2^10=1024个节点
numberBits uint8 = 12 // 表示每个集群下的每个节点1毫秒内可生成的id序号的二进制位数 即每毫秒可生成 2^12-1=4096个唯一ID
// 这里求最大值使用了位运算,-1 的二进制表示为 1 的补码,感兴趣的同学可以自己算算试试 -1 ^ (-1 << nodeBits) 这里是不是等于 1023
workerMax int64 = -1 ^ (-1 << workerBits) // 节点ID的最大值用于防止溢出
numberMax int64 = -1 ^ (-1 << numberBits) // 同上用来表示生成id序号的最大值
timeShift uint8 = workerBits + numberBits // 时间戳向左的偏移量
workerShift uint8 = numberBits // 节点ID向左的偏移量
// 41位字节作为时间戳数值的话 大约68年就会用完
// 假如你2010年1月1日开始开发系统 如果不减去2010年1月1日的时间戳 那么白白浪费40年的时间戳啊
// 这个一旦定义且开始生成ID后千万不要改了 不然可能会生成相同的ID
epoch int64 = 1525705533000 // 这个是我在写epoch这个变量时的时间戳(毫秒)
)
// 定义一个woker工作节点所需要的基本参数
type Worker struct {
mu sync.Mutex // 添加互斥锁 确保并发安全
timestamp int64 // 记录时间戳
workerId int64 // 该节点的ID
number int64 // 当前毫秒已经生成的id序列号(从0开始累加) 1毫秒内最多生成4096个ID
}
// 实例化一个工作节点
func NewWorker(workerId int64) (*Worker, error) {
// 要先检测workerId是否在上面定义的范围内
if workerId < 0 || workerId > workerMax {
return nil, errors.New("Worker ID excess of quantity")
}
// 生成一个新节点
return &Worker{
timestamp: 0,
workerId: workerId,
number: 0,
}, nil
}
// 接下来我们开始生成id
// 生成方法一定要挂载在某个woker下这样逻辑会比较清晰 指定某个节点生成id
func (w *Worker) GetId() int64 {
// 获取id最关键的一点 加锁 加锁 加锁
w.mu.Lock()
defer w.mu.Unlock() // 生成完成后记得 解锁 解锁 解锁
// 获取生成时的时间戳
now := time.Now().UnixNano() / 1e6 // 纳秒转毫秒
if w.timestamp == now {
w.number++
// 这里要判断当前工作节点是否在1毫秒内已经生成numberMax个ID
if w.number > numberMax {
// 如果当前工作节点在1毫秒内生成的ID已经超过上限 需要等待1毫秒再继续生成
for now <= w.timestamp {
now = time.Now().UnixNano() / 1e6
}
}
} else {
// 如果当前时间与工作节点上一次生成ID的时间不一致 则需要重置工作节点生成ID的序号
w.number = 0
w.timestamp = now // 将机器上一次生成ID的时间更新为当前时间
}
// 第一段 now - epoch 为该算法目前已经奔跑了xxx毫秒
// 如果在程序跑了一段时间修改了epoch这个值 可能会导致生成相同的ID
ID := int64((now-epoch)<<timeShift | (w.workerId << workerShift) | (w.number))
return ID
}

74
utils/go-flags/main.go Normal file
View File

@ -0,0 +1,74 @@
package main
import (
"fmt"
"github.com/jessevdk/go-flags"
)
func main() {
// Callback which will invoke callto:<argument> to call a number.
// Note that this works just on OS X (and probably only with
// Skype) but it shows the idea.
// opts.Call = func(num string) {
// cmd := exec.Command("open", "callto:"+num)
// cmd.Start()
// cmd.Process.Release()
// }
// Make some fake arguments to parse.
// args := []string{
// "-vv",
// "--offset=5",
// "-n", "Me",
// "-p", "3",
// "-s", "hello",
// "-s", "world",
// "--ptrslice", "hello",
// "--ptrslice", "world",
// "--intmap", "a:1",
// "--intmap", "b:5",
// "--filename", "hello.go",
// "id",
// "10",
// "remaining1",
// "remaining2",
// }
// Parse flags from `args'. Note that here we use flags.ParseArgs for
// the sake of making a working example. Normally, you would simply use
// flags.Parse(&opts) which uses os.Args
// _, err := flags.ParseArgs(&opts, args)
_, err := flags.Parse(&opts)
if err != nil {
panic(err)
}
fmt.Printf("Verbosity: %v\n", opts.Verbose)
fmt.Printf("Offset: %d\n", opts.Offset)
fmt.Printf("Name: %s\n", opts.Name)
// fmt.Printf("Ptr: %d\n", *opts.Ptr)
// fmt.Printf("StringSlice: %v\n", opts.StringSlice)
// fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1])
// fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"])
// fmt.Printf("Filename: %v\n", opts.Filename)
// fmt.Printf("Args.ID: %s\n", opts.Args.ID)
// fmt.Printf("Args.Num: %d\n", opts.Args.Num)
// fmt.Printf("Args.Rest: %v\n", opts.Args.Rest)
}
var opts struct {
// Slice of bool will append 'true' each time the option
// is encountered (can be set multiple times, like -vvv)
Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
// Example of automatic marshalling to desired type (uint)
Offset uint `long:"offset" description:"Offset"`
// Example of a callback, called each time the option is found.
// Call func(string) `short:"c" description:"Call phone number"`
// Example of a required flag
Name string `short:"n" long:"name" description:"A name" required:"true" env:"ENV_NAME"`
}

View File

@ -2,9 +2,8 @@ package log
import (
"fmt"
"testing"
"github.com/sirupsen/logrus"
"testing"
)
func TestSetting(t *testing.T) {