From e6c62d0bda962c8c8f43c139e7d0e54b702d6d39 Mon Sep 17 00:00:00 2001 From: ehlxr Date: Mon, 20 Jul 2020 10:06:17 +0800 Subject: [PATCH] update at 2020-07-20 10:06:17 by ehlxr --- clog-err.log | 4 ++ clog.log | 9 +++ go.mod | 5 +- go.sum | 21 ++++++ main.go | 156 ++++++++++++++++++++++++++++++----------- utils/SnowFlake.go | 76 ++++++++++++++++++++ utils/go-flags/main.go | 74 +++++++++++++++++++ utils/log/log_test.go | 3 +- 8 files changed, 305 insertions(+), 43 deletions(-) create mode 100644 clog-err.log create mode 100644 clog.log create mode 100644 utils/SnowFlake.go create mode 100644 utils/go-flags/main.go diff --git a/clog-err.log b/clog-err.log new file mode 100644 index 0000000..5b3f25c --- /dev/null +++ b/clog-err.log @@ -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! diff --git a/clog.log b/clog.log new file mode 100644 index 0000000..b001f6e --- /dev/null +++ b/clog.log @@ -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! diff --git a/go.mod b/go.mod index 614cdc6..74d1b5a 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index dac357f..f986112 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/main.go b/main.go index e460aad..722cc8c 100644 --- a/main.go +++ b/main.go @@ -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()) +// } +//} diff --git a/utils/SnowFlake.go b/utils/SnowFlake.go new file mode 100644 index 0000000..4b9cc97 --- /dev/null +++ b/utils/SnowFlake.go @@ -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)< 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"` +} diff --git a/utils/log/log_test.go b/utils/log/log_test.go index d544419..b1853ac 100644 --- a/utils/log/log_test.go +++ b/utils/log/log_test.go @@ -2,9 +2,8 @@ package log import ( "fmt" - "testing" - "github.com/sirupsen/logrus" + "testing" ) func TestSetting(t *testing.T) {