diff --git a/redis/common.go b/redis/common.go index 8f4fd6f..c019e39 100644 --- a/redis/common.go +++ b/redis/common.go @@ -16,71 +16,26 @@ package redis import ( "context" - "crypto/tls" "fmt" - "net" "time" "github.com/bytedance/sonic" "github.com/cloudwego/hertz/pkg/app/server/registry" - "github.com/go-redis/redis/v8" ) const ( - Redis = "redis" - register = "register" - deregister = "deregister" - hertz = "hertz" - server = "server" - tcp = "tcp" + Redis = "redis" + hertz = "hertz" + server = "server" + tcp = "tcp" ) const ( - defaultExpireTime = 60 - defaultTickerTime = time.Second * 30 - defaultKeepAliveTime = time.Second * 60 - defaultMonitorTime = time.Second * 30 - defaultWeight = 10 + defaultExpireTime = 60 + defaultRefreshInterval = 30 + defaultWeight = 10 ) -type Option func(opts *redis.Options) - -func WithPassword(password string) Option { - return func(opts *redis.Options) { - opts.Password = password - } -} - -func WithDB(db int) Option { - return func(opts *redis.Options) { - opts.DB = db - } -} - -func WithTLSConfig(t *tls.Config) Option { - return func(opts *redis.Options) { - opts.TLSConfig = t - } -} - -func WithDialer(dialer func(ctx context.Context, network, addr string) (net.Conn, error)) Option { - return func(opts *redis.Options) { - opts.Dialer = dialer - } -} - -func WithReadTimeout(t time.Duration) Option { - return func(opts *redis.Options) { - opts.ReadTimeout = t - } -} - -func WithWriteTimeout(t time.Duration) Option { - return func(opts *redis.Options) { - opts.WriteTimeout = t - } -} - type registryHash struct { key string field string @@ -111,10 +66,6 @@ func generateKey(serviceName, serviceType string) string { return fmt.Sprintf("/%s/%s/%s", hertz, serviceName, serviceType) } -func generateMsg(msgType, serviceName, serviceAddr string) string { - return fmt.Sprintf("%s-%s-%s", msgType, serviceName, serviceAddr) -} - func prepareRegistryHash(info *registry.Info) (*registryHash, error) { meta, err := sonic.Marshal(convertInfo(info)) if err != nil { @@ -137,12 +88,12 @@ func convertInfo(info *registry.Info) *registryInfo { } func keepAlive(ctx context.Context, hash *registryHash, r *redisRegistry) { - ticker := time.NewTicker(defaultTickerTime) + ticker := time.NewTicker(time.Duration(r.options.refreshInterval) * time.Second) defer ticker.Stop() for { select { case <-ticker.C: - r.client.Expire(ctx, hash.key, defaultKeepAliveTime) + r.client.Expire(ctx, hash.key, time.Duration(r.options.expireTime)*time.Second) case <-ctx.Done(): break } diff --git a/redis/go.mod b/redis/go.mod index b820f30..c9bff16 100644 --- a/redis/go.mod +++ b/redis/go.mod @@ -3,8 +3,10 @@ module github.com/hertz-contrib/registry/redis go 1.16 require ( - github.com/bytedance/sonic v1.8.3 - github.com/cloudwego/hertz v0.6.0 + github.com/bytedance/gopkg v0.0.0-20231219111115-a5eedbe96960 // indirect + github.com/bytedance/sonic v1.10.2 + github.com/cloudwego/hertz v0.8.0 github.com/go-redis/redis/v8 v8.11.5 + github.com/redis/go-redis/v9 v9.4.0 github.com/stretchr/testify v1.8.2 ) diff --git a/redis/go.sum b/redis/go.sum index af8d485..febea70 100644 --- a/redis/go.sum +++ b/redis/go.sum @@ -1,23 +1,36 @@ +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bytedance/go-tagexpr/v2 v2.9.2 h1:QySJaAIQgOEDQBLS3x9BxOWrnhqu5sQ+f6HaZIxD39I= github.com/bytedance/go-tagexpr/v2 v2.9.2/go.mod h1:5qsx05dYOiUXOUgnQ7w3Oz8BYs2qtM/bJokdLb79wRM= github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 h1:PtwsQyQJGxf8iaPptPNaduEIu9BnrNms+pcRdHAxZaM= github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7/go.mod h1:2ZlV9BaUH4+NXIBF0aMdKKAnHTzqH+iMU4KUjAbL23Q= +github.com/bytedance/gopkg v0.0.0-20231219111115-a5eedbe96960 h1:t2xAuIlnhWJDIpcHZEbpoVsQH1hOk9eGGaKU2dXl1PE= +github.com/bytedance/gopkg v0.0.0-20231219111115-a5eedbe96960/go.mod h1:FtQG3YbQG9L/91pbKSw787yBQPutC+457AvDW77fgUQ= +github.com/bytedance/mockey v1.2.1 h1:g84ngI88hz1DR4wZTL3yOuqlEcq67MretBfQUdXwrmw= +github.com/bytedance/mockey v1.2.1/go.mod h1:+Jm/fzWZAuhEDrPXVjDf/jLM2BlLXJkwk94zf2JZ3X4= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.8.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/bytedance/sonic v1.8.3 h1:pf6fGl5eqWYKkx1RcD4qpuX+BIUaduv/wTm5ekWJ80M= -github.com/bytedance/sonic v1.8.3/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= +github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cloudwego/hertz v0.6.0 h1:yxRfc1BbuVilhV73VKvB80jkqKzfedj/LLXH1fQWDIg= -github.com/cloudwego/hertz v0.6.0/go.mod h1:83EedHQvCXpveYh2r9us8YlQ1C28vPg93wPdB/QpJiA= -github.com/cloudwego/netpoll v0.3.1 h1:xByoORmCLIyKZ8gS+da06WDo3j+jvmhaqS2KeKejtBk= -github.com/cloudwego/netpoll v0.3.1/go.mod h1:1T2WVuQ+MQw6h6DpE45MohSvDTKdy2DlzCx2KsnPI4E= +github.com/cloudwego/hertz v0.8.0 h1:rjALfbD/E3IkaNDksQ4oF0nA5d03FfSEx3yc2PkJklo= +github.com/cloudwego/hertz v0.8.0/go.mod h1:WliNtVbwihWHHgAaIQEbVXl0O3aWj0ks1eoPrcEAnjs= +github.com/cloudwego/netpoll v0.5.0 h1:oRrOp58cPCvK2QbMozZNDESvrxQaEHW2dCimmwH1lcU= +github.com/cloudwego/netpoll v0.5.0/go.mod h1:xVefXptcyheopwNDZjDPcfU6kIjZXZ4nY550k1yH9eQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -47,6 +60,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/henrylee2cn/ameda v1.4.8/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= github.com/henrylee2cn/ameda v1.4.10 h1:JdvI2Ekq7tapdPsuhrc4CaFiqw6QXFvZIULWJgQyCAk= github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= @@ -54,8 +69,11 @@ github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 h1:yE9ULgp02BhY github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8/go.mod h1:Nhe/DM3671a5udlv2AdV2ni/MZzgfv2qrPL5nIi3EGQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -74,6 +92,12 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwyKk= +github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -86,8 +110,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M= -github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= @@ -95,6 +119,7 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -102,12 +127,15 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -125,16 +153,22 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -165,4 +199,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/redis/mentor.go b/redis/mentor.go deleted file mode 100644 index b207c3f..0000000 --- a/redis/mentor.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2022 CloudWeGo Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package redis - -import ( - "context" - "strings" - "sync" - "time" - - "github.com/cloudwego/hertz/pkg/app/server/registry" - "github.com/cloudwego/hertz/pkg/common/hlog" -) - -var gm *mentor - -var form = make(map[string]addrs) - -type addrs []string - -type mentor struct { - mform map[string]addrs - mu sync.Mutex -} - -// newMentor use singleton -func newMentor() *mentor { - if gm != nil { - return gm - } - m := &mentor{mform: form} - gm = m - return gm -} - -func (m *mentor) subscribe(ctx context.Context, info *registry.Info, r *redisRegistry) { - sub := r.client.Subscribe(ctx, generateKey(info.ServiceName, server)) - defer sub.Close() - r.wg.Done() - select { - case <-ctx.Done(): - return - default: - ch := sub.Channel() - for msg := range ch { - split := strings.Split(msg.Payload, "-") - if split[0] == register { - m.mu.Lock() - m.insertForm(split[1], split[2]) - hlog.Infof("HERTZ: service info %v", m.mform) - m.mu.Unlock() - } else if split[0] == deregister { - m.mu.Lock() - m.removeAddr(split[1], split[2]) - hlog.Infof("HERTZ: service info %v", m.mform) - m.mu.Unlock() - } else { - hlog.Warnf("HERTZ: invalid message %v", msg) - } - } - } -} - -func (m *mentor) monitorTTL(ctx context.Context, hash *registryHash, info *registry.Info, r *redisRegistry) { - ticker := time.NewTicker(defaultMonitorTime) - defer ticker.Stop() - for { - select { - case <-ticker.C: - if r.client.TTL(ctx, hash.key).Val() == -2 { - m.mu.Lock() - m.removeService(info.ServiceName) - m.mu.Unlock() - } - case <-ctx.Done(): - break - } - } -} - -func (m *mentor) insertForm(serviceName, addr string) { - m.mform[serviceName] = append(m.mform[serviceName], addr) -} - -func (m *mentor) removeService(serviceName string) { - delete(m.mform, serviceName) -} - -func (m *mentor) removeAddr(serviceName, addr string) { - for i, v := range m.mform[serviceName] { - if v == addr { - m.mform[serviceName] = append(m.mform[serviceName][:i], m.mform[serviceName][i+1:]...) - } - } -} diff --git a/redis/option.go b/redis/option.go new file mode 100644 index 0000000..af7063d --- /dev/null +++ b/redis/option.go @@ -0,0 +1,86 @@ +// Copyright 2023 CloudWeGo Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package redis + +import ( + "context" + "crypto/tls" + "net" + "time" + + "github.com/redis/go-redis/v9" +) + +type Option func(opts *Options) + +type Options struct { + *redis.Options + expireTime int + refreshInterval int +} + +// WithExpireTime redis key expiration time in seconds +// NOTE: expiration time must be greater than refresh interval +// Default: 60s +func WithExpireTime(time int) Option { + return func(opts *Options) { + opts.expireTime = time + } +} + +// WithRefreshInterval redis key refresh interval in seconds +// NOTE: refresh interval must be less than expiration time +// Default: 30s +func WithRefreshInterval(interval int) Option { + return func(opts *Options) { + opts.refreshInterval = interval + } +} + +func WithPassword(password string) Option { + return func(opts *Options) { + opts.Password = password + } +} + +func WithDB(db int) Option { + return func(opts *Options) { + opts.DB = db + } +} + +func WithTLSConfig(t *tls.Config) Option { + return func(opts *Options) { + opts.TLSConfig = t + } +} + +func WithDialer(dialer func(ctx context.Context, network, addr string) (net.Conn, error)) Option { + return func(opts *Options) { + opts.Dialer = dialer + } +} + +func WithReadTimeout(t time.Duration) Option { + return func(opts *Options) { + opts.ReadTimeout = t + } +} + +func WithWriteTimeout(t time.Duration) Option { + return func(opts *Options) { + opts.WriteTimeout = t + } +} diff --git a/redis/redis_test.go b/redis/redis_test.go index 3e28f9a..9d9baac 100644 --- a/redis/redis_test.go +++ b/redis/redis_test.go @@ -193,13 +193,6 @@ func TestResolve(t *testing.T) { } } -// TestNewMentor test singleton -func TestNewMentor(t *testing.T) { - m1 := newMentor() - m2 := newMentor() - assert.Equal(t, m1, m2) -} - // TestRedisRegistryWithHertz Test redis registry complete workflow (service registry|service de-registry|service resolver) with hertz. func TestRedisRegistryWithHertz(t *testing.T) { addr := "127.0.0.1:8080" diff --git a/redis/registry.go b/redis/registry.go index 521fdfd..00d69fa 100644 --- a/redis/registry.go +++ b/redis/registry.go @@ -16,19 +16,21 @@ package redis import ( "context" + "errors" "sync" + "github.com/bytedance/gopkg/util/gopool" "github.com/cloudwego/hertz/pkg/app/server/registry" - "github.com/go-redis/redis/v8" + "github.com/redis/go-redis/v9" ) var _ registry.Registry = (*redisRegistry)(nil) type redisRegistry struct { - client *redis.Client - rctx *registryContext - mu sync.Mutex - wg sync.WaitGroup + mu sync.Mutex + options *Options + client *redis.Client + rctx *registryContext } type registryContext struct { @@ -38,17 +40,22 @@ type registryContext struct { // NewRedisRegistry creates a redis registry func NewRedisRegistry(addr string, opts ...Option) registry.Registry { - redisOpts := &redis.Options{ - Addr: addr, - Password: "", - DB: 0, + options := &Options{ + Options: &redis.Options{ + Addr: addr, + Password: "", + DB: 0, + }, + expireTime: defaultExpireTime, + refreshInterval: defaultRefreshInterval, } for _, opt := range opts { - opt(redisOpts) + opt(options) } - rdb := redis.NewClient(redisOpts) + rdb := redis.NewClient(options.Options) return &redisRegistry{ - client: rdb, + options: options, + client: rdb, } } @@ -56,35 +63,37 @@ func (r *redisRegistry) Register(info *registry.Info) error { if err := validateRegistryInfo(info); err != nil { return err } + rctx := registryContext{} rctx.ctx, rctx.cancel = context.WithCancel(context.Background()) - m := newMentor() - r.wg.Add(1) - go m.subscribe(rctx.ctx, info, r) - r.wg.Wait() rdb := r.client + hash, err := prepareRegistryHash(info) if err != nil { return err } + r.mu.Lock() r.rctx = &rctx r.mu.Unlock() + keys := []string{ hash.key, } args := []interface{}{ hash.field, hash.value, - defaultExpireTime, - generateMsg(register, info.ServiceName, info.Addr.String()), + r.options.expireTime, } + err = registerScript.Run(rctx.ctx, rdb, keys, args).Err() - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return err } - go m.monitorTTL(rctx.ctx, hash, info, r) - go keepAlive(rctx.ctx, hash, r) + + gopool.Go(func() { + keepAlive(rctx.ctx, hash, r) + }) return nil } @@ -92,23 +101,27 @@ func (r *redisRegistry) Deregister(info *registry.Info) error { if err := validateRegistryInfo(info); err != nil { return err } + rctx := r.rctx rdb := r.client + hash, err := prepareRegistryHash(info) if err != nil { return err } + keys := []string{ hash.key, } args := []interface{}{ hash.field, - generateMsg(deregister, info.ServiceName, info.Addr.String()), } + err = deregisterScript.Run(rctx.ctx, rdb, keys, args).Err() - if err != nil && err != redis.Nil { + if err != nil && !errors.Is(err, redis.Nil) { return err } + rctx.cancel() return nil } @@ -118,18 +131,14 @@ local key = KEYS[1] local field = ARGV[1] local value = ARGV[2] local expireTime = tonumber(ARGV[3]) -local message = ARGV[4] redis.call('HSET', key, field, value) redis.call('EXPIRE', key, expireTime) -redis.call('PUBLISH', key, message) `) var deregisterScript = redis.NewScript(` local key = KEYS[1] local field = ARGV[1] -local message = ARGV[2] redis.call('HDEL', key, field) -redis.call('PUBLISH', key, message) `) diff --git a/redis/resolver.go b/redis/resolver.go index cc61148..60f504e 100644 --- a/redis/resolver.go +++ b/redis/resolver.go @@ -20,7 +20,7 @@ import ( "github.com/bytedance/sonic" "github.com/cloudwego/hertz/pkg/app/client/discovery" "github.com/cloudwego/hertz/pkg/common/hlog" - "github.com/go-redis/redis/v8" + "github.com/redis/go-redis/v9" ) var _ discovery.Resolver = (*redisResolver)(nil) @@ -31,11 +31,15 @@ type redisResolver struct { // NewRedisResolver creates a redis resolver func NewRedisResolver(addr string, opts ...Option) discovery.Resolver { - redisOpts := &redis.Options{Addr: addr} + options := &Options{ + Options: &redis.Options{ + Addr: addr, + }, + } for _, opt := range opts { - opt(redisOpts) + opt(options) } - rdb := redis.NewClient(redisOpts) + rdb := redis.NewClient(options.Options) return &redisResolver{ client: rdb, }