feat: registry.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package servicecomb
|
||||
|
||||
import (
|
||||
servicecombKratos "github.com/go-kratos/kratos/contrib/registry/servicecomb/v2"
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
|
||||
servicecombClient "github.com/go-chassis/sc-client"
|
||||
@@ -10,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
// NewRegistry 创建一个注册发现客户端 - Servicecomb
|
||||
func NewRegistry(c *conf.Registry) *servicecombKratos.Registry {
|
||||
func NewRegistry(c *conf.Registry) *Registry {
|
||||
if c == nil || c.Servicecomb == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -25,7 +24,7 @@ func NewRegistry(c *conf.Registry) *servicecombKratos.Registry {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
reg := servicecombKratos.NewRegistry(cli)
|
||||
reg := New(cli)
|
||||
|
||||
return reg
|
||||
}
|
||||
40
registry/servicecomb/go.mod
Normal file
40
registry/servicecomb/go.mod
Normal file
@@ -0,0 +1,40 @@
|
||||
module github.com/tx7do/kratos-bootstrap/registry/servicecomb
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.3
|
||||
|
||||
replace (
|
||||
github.com/armon/go-metrics => github.com/hashicorp/go-metrics v0.4.1
|
||||
|
||||
github.com/tx7do/kratos-bootstrap/api => ../../api
|
||||
github.com/tx7do/kratos-bootstrap/registry => ../registry
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-chassis/cari v0.9.0
|
||||
github.com/go-chassis/sc-client v0.7.0
|
||||
github.com/go-kratos/kratos/v2 v2.8.4
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tx7do/kratos-bootstrap/api v0.0.20
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||
github.com/go-chassis/foundation v0.4.0 // indirect
|
||||
github.com/go-chassis/openlog v1.1.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/karlseguin/ccache/v2 v2.0.8 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
100
registry/servicecomb/go.sum
Normal file
100
registry/servicecomb/go.sum
Normal file
@@ -0,0 +1,100 @@
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/go-chassis/cari v0.5.1-0.20210823023004-74041d1363c4/go.mod h1:av/19fqwEP4eOC8unL/z67AAbFDwXUCko6SKa4Avrd8=
|
||||
github.com/go-chassis/cari v0.9.0 h1:skvo2PX8nLyu26CCg7qUMv7yP2DY73GrBW9M5tWj63c=
|
||||
github.com/go-chassis/cari v0.9.0/go.mod h1:vM13BN0TT505ZKqeJ+hUfzZvfn4nN0vgE6IpBOTWcTc=
|
||||
github.com/go-chassis/foundation v0.3.0/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA=
|
||||
github.com/go-chassis/foundation v0.4.0 h1:z0xETnSxF+vRXWjoIhOdzt6rywjZ4sB++utEl4YgWEY=
|
||||
github.com/go-chassis/foundation v0.4.0/go.mod h1:6NsIUaHghTFRGfCBcZN011zl196F6OR5QvD9N+P4oWU=
|
||||
github.com/go-chassis/openlog v1.1.2/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCxvR2LrYZUaA=
|
||||
github.com/go-chassis/openlog v1.1.3 h1:XqIOvZ8YPJ9o9lLtLBskQNNWolK5kC6a4Sv7r4s9sZ4=
|
||||
github.com/go-chassis/openlog v1.1.3/go.mod h1:+eYCADVxWyJkwsFMUBrMxyQlNqW+UUsCxvR2LrYZUaA=
|
||||
github.com/go-chassis/sc-client v0.7.0 h1:c2LSdbFMuZ3RcbDu7So//kFCzjDCkzdQ0CNKhm8Dy7I=
|
||||
github.com/go-chassis/sc-client v0.7.0/go.mod h1:DmclCLMhyNpYN42ae0f5AgiF4lTrpG6NyJJgmyAgC+E=
|
||||
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
|
||||
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/karlseguin/ccache/v2 v2.0.8 h1:lT38cE//uyf6KcFok0rlgXtGFBWxkI6h/qg4tbFyDnA=
|
||||
github.com/karlseguin/ccache/v2 v2.0.8/go.mod h1:2BDThcfQMf/c0jnZowt16eW405XIqZPavt+HoYEtcxQ=
|
||||
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003 h1:vJ0Snvo+SLMY72r5J4sEfkuE7AFbixEP2qRbEcum/wA=
|
||||
github.com/karlseguin/expect v1.0.2-0.20190806010014-778a5f0c6003/go.mod h1:zNBxMY8P21owkeogJELCLeHIt+voOSduHYTFUbwRAV8=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
|
||||
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
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=
|
||||
175
registry/servicecomb/registry.go
Normal file
175
registry/servicecomb/registry.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package servicecomb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-chassis/cari/discovery"
|
||||
"github.com/go-chassis/cari/pkg/errsvc"
|
||||
"github.com/go-chassis/sc-client"
|
||||
"github.com/gofrs/uuid"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"github.com/go-kratos/kratos/v2/registry"
|
||||
)
|
||||
|
||||
func init() {
|
||||
appID = os.Getenv(appIDVar)
|
||||
if appID == "" {
|
||||
appID = "default"
|
||||
}
|
||||
env = os.Getenv(envVar)
|
||||
}
|
||||
|
||||
var (
|
||||
_ registry.Registrar = (*Registry)(nil)
|
||||
_ registry.Discovery = (*Registry)(nil)
|
||||
)
|
||||
|
||||
var (
|
||||
curServiceID string
|
||||
appID string
|
||||
env string
|
||||
)
|
||||
|
||||
const (
|
||||
appIDKey = "appId"
|
||||
envKey = "environment"
|
||||
envVar = "CAS_ENVIRONMENT_ID"
|
||||
appIDVar = "CAS_APPLICATION_NAME"
|
||||
frameWorkName = "kratos"
|
||||
frameWorkVersion = "v2"
|
||||
)
|
||||
|
||||
type RegistryClient interface {
|
||||
GetMicroServiceID(appID, microServiceName, version, env string, opts ...sc.CallOption) (string, error)
|
||||
FindMicroServiceInstances(consumerID, appID, microServiceName, versionRule string, opts ...sc.CallOption) ([]*discovery.MicroServiceInstance, error)
|
||||
RegisterService(microService *discovery.MicroService) (string, error)
|
||||
RegisterMicroServiceInstance(microServiceInstance *discovery.MicroServiceInstance) (string, error)
|
||||
Heartbeat(microServiceID, microServiceInstanceID string) (bool, error)
|
||||
UnregisterMicroServiceInstance(microServiceID, microServiceInstanceID string) (bool, error)
|
||||
WatchMicroService(microServiceID string, callback func(*sc.MicroServiceInstanceChangedEvent)) error
|
||||
}
|
||||
|
||||
// Registry is servicecomb registry.
|
||||
type Registry struct {
|
||||
cli RegistryClient
|
||||
}
|
||||
|
||||
func New(client RegistryClient) *Registry {
|
||||
r := &Registry{
|
||||
cli: client,
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Registry) GetService(_ context.Context, serviceName string) ([]*registry.ServiceInstance, error) {
|
||||
instances, err := r.cli.FindMicroServiceInstances("", appID, serviceName, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
svcInstances := make([]*registry.ServiceInstance, 0, len(instances))
|
||||
for _, instance := range instances {
|
||||
svcInstances = append(svcInstances, ®istry.ServiceInstance{
|
||||
ID: instance.InstanceId,
|
||||
Name: serviceName,
|
||||
Metadata: instance.Properties,
|
||||
Endpoints: instance.Endpoints,
|
||||
Version: instance.ServiceId,
|
||||
})
|
||||
}
|
||||
return svcInstances, nil
|
||||
}
|
||||
|
||||
func (r *Registry) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) {
|
||||
return newWatcher(ctx, r.cli, serviceName)
|
||||
}
|
||||
|
||||
func (r *Registry) Register(_ context.Context, svcIns *registry.ServiceInstance) error {
|
||||
fw := &discovery.FrameWork{
|
||||
Name: frameWorkName,
|
||||
Version: frameWorkVersion,
|
||||
}
|
||||
ms := &discovery.MicroService{
|
||||
ServiceName: svcIns.Name,
|
||||
AppId: appID,
|
||||
Version: svcIns.Version,
|
||||
Environment: env,
|
||||
Framework: fw,
|
||||
}
|
||||
// 先尝试创建微服务
|
||||
sid, err := r.cli.RegisterService(ms)
|
||||
// 若失败,说明服务可能已注册
|
||||
if err != nil {
|
||||
registryException, ok := err.(*sc.RegistryException)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
var svcErr errsvc.Error
|
||||
parseErr := json.Unmarshal([]byte(registryException.Message), &svcErr)
|
||||
if parseErr != nil {
|
||||
return parseErr
|
||||
}
|
||||
// 若错误码显示服务未注册,直接返回
|
||||
if svcErr.Code != discovery.ErrServiceAlreadyExists {
|
||||
return err
|
||||
}
|
||||
sid, err = r.cli.GetMicroServiceID(appID, ms.ServiceName, ms.Version, ms.Environment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// 保存当前版本微服务对应的sid
|
||||
curServiceID = sid
|
||||
}
|
||||
if svcIns.ID == "" {
|
||||
var id uuid.UUID
|
||||
id, err = uuid.NewV4()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
svcIns.ID = id.String()
|
||||
}
|
||||
props := map[string]string{
|
||||
appIDKey: appID,
|
||||
envKey: env,
|
||||
}
|
||||
_, err = r.cli.RegisterMicroServiceInstance(&discovery.MicroServiceInstance{
|
||||
InstanceId: svcIns.ID,
|
||||
ServiceId: sid,
|
||||
Endpoints: svcIns.Endpoints,
|
||||
HostName: svcIns.ID,
|
||||
Properties: props,
|
||||
Version: svcIns.Version,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
<-ticker.C
|
||||
_, err = r.cli.Heartbeat(sid, svcIns.ID)
|
||||
if err != nil {
|
||||
log.Errorf("failed to send heartbeat: %v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry) Deregister(_ context.Context, svcIns *registry.ServiceInstance) error {
|
||||
sid, err := r.cli.GetMicroServiceID(appID, svcIns.Name, svcIns.Version, env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = r.cli.UnregisterMicroServiceInstance(sid, svcIns.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
158
registry/servicecomb/registry_test.go
Normal file
158
registry/servicecomb/registry_test.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package servicecomb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
pb "github.com/go-chassis/cari/discovery"
|
||||
"github.com/go-chassis/sc-client"
|
||||
"github.com/gofrs/uuid"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/registry"
|
||||
)
|
||||
|
||||
var r *Registry
|
||||
|
||||
func init() {
|
||||
r = New(&mockClient{})
|
||||
}
|
||||
|
||||
type mockClient struct{}
|
||||
|
||||
func (receiver *mockClient) WatchMicroService(_ string, _ func(*sc.MicroServiceInstanceChangedEvent)) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (receiver *mockClient) FindMicroServiceInstances(_,
|
||||
_, microServiceName, _ string, _ ...sc.CallOption,
|
||||
) ([]*pb.MicroServiceInstance, error) {
|
||||
if microServiceName == "KratosServicecomb" {
|
||||
return []*pb.MicroServiceInstance{{}}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (receiver *mockClient) RegisterService(_ *pb.MicroService) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (receiver *mockClient) RegisterMicroServiceInstance(_ *pb.MicroServiceInstance) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (receiver *mockClient) Heartbeat(_, _ string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (receiver *mockClient) UnregisterMicroServiceInstance(_, _ string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (receiver *mockClient) GetMicroServiceID(_, _, _, _ string, _ ...sc.CallOption) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func TestRegistry(t *testing.T) {
|
||||
instanceID, err := uuid.NewV4()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
svc := ®istry.ServiceInstance{
|
||||
Name: "KratosServicecomb",
|
||||
Version: "0.0.1",
|
||||
Metadata: map[string]string{"app": "kratos"},
|
||||
Endpoints: []string{"tcp://127.0.0.1:9000?isSecure=false"},
|
||||
ID: instanceID.String(),
|
||||
}
|
||||
ctx := context.TODO()
|
||||
t.Run("Register test, expected: success.", func(t *testing.T) {
|
||||
err = r.Register(ctx, svc)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
})
|
||||
t.Run("GetService test, expected: success.", func(t *testing.T) {
|
||||
var insts []*registry.ServiceInstance
|
||||
insts, err = r.GetService(ctx, svc.Name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(insts) <= 0 {
|
||||
t.Errorf("inst len less than 0")
|
||||
}
|
||||
})
|
||||
t.Run("Deregister test, expected: success.", func(t *testing.T) {
|
||||
svc.ID = instanceID.String()
|
||||
err = r.Deregister(ctx, svc)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestWatcher(t *testing.T) {
|
||||
instanceID1, err := uuid.NewV4()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
svc1 := ®istry.ServiceInstance{
|
||||
Name: "WatcherTest",
|
||||
Version: "0.0.1",
|
||||
Metadata: map[string]string{"app": "kratos"},
|
||||
Endpoints: []string{"tcp://127.0.0.1:9000?isSecure=false"},
|
||||
ID: instanceID1.String(),
|
||||
}
|
||||
ctx := context.TODO()
|
||||
err = r.Register(ctx, svc1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w, err := r.Watch(ctx, "WatcherTest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if w == nil {
|
||||
t.Fatal("w is nil")
|
||||
}
|
||||
sbWatcher := w.(*Watcher)
|
||||
t.Run("Watch register event, expected: success", func(t *testing.T) {
|
||||
go sbWatcher.Put(svc1)
|
||||
var instances []*registry.ServiceInstance
|
||||
instances, err = w.Next()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(instances) == 0 {
|
||||
t.Errorf("instances is empty")
|
||||
}
|
||||
if instanceID1.String() != instances[0].ID {
|
||||
t.Errorf("expected %v, got %v", instanceID1.String(), instances[0].ID)
|
||||
}
|
||||
})
|
||||
t.Run("Watch deregister event, expected: success", func(t *testing.T) {
|
||||
// Deregister instance1.
|
||||
err = r.Deregister(ctx, svc1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
go sbWatcher.Put(svc1)
|
||||
var instances []*registry.ServiceInstance
|
||||
instances, err = w.Next()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(instances) == 0 {
|
||||
t.Errorf("instances is empty")
|
||||
}
|
||||
if instanceID1.String() != instances[0].ID {
|
||||
t.Errorf("expected %v, got %v", instanceID1.String(), instances[0].ID)
|
||||
}
|
||||
})
|
||||
t.Run("Stop test, expected: success", func(t *testing.T) {
|
||||
err = w.Stop()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
64
registry/servicecomb/watcher.go
Normal file
64
registry/servicecomb/watcher.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package servicecomb
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-chassis/sc-client"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/registry"
|
||||
)
|
||||
|
||||
var _ registry.Watcher = (*Watcher)(nil)
|
||||
|
||||
type Watcher struct {
|
||||
cli RegistryClient
|
||||
ch chan *registry.ServiceInstance
|
||||
}
|
||||
|
||||
func newWatcher(_ context.Context, cli RegistryClient, serviceName string) (*Watcher, error) {
|
||||
// 构建当前服务与目标服务之间的依赖关系,完成discovery
|
||||
_, err := cli.FindMicroServiceInstances(curServiceID, appID, serviceName, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w := &Watcher{
|
||||
cli: cli,
|
||||
ch: make(chan *registry.ServiceInstance),
|
||||
}
|
||||
go func() {
|
||||
watchErr := w.cli.WatchMicroService(curServiceID, func(event *sc.MicroServiceInstanceChangedEvent) {
|
||||
if event.Key.ServiceName != serviceName {
|
||||
return
|
||||
}
|
||||
svcIns := ®istry.ServiceInstance{
|
||||
ID: event.Instance.InstanceId,
|
||||
Name: event.Key.ServiceName,
|
||||
Version: event.Key.Version,
|
||||
Metadata: event.Instance.Properties,
|
||||
Endpoints: event.Instance.Endpoints,
|
||||
}
|
||||
w.Put(svcIns)
|
||||
})
|
||||
if watchErr != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// Put only for UT
|
||||
func (w *Watcher) Put(svcIns *registry.ServiceInstance) {
|
||||
w.ch <- svcIns
|
||||
}
|
||||
|
||||
func (w *Watcher) Next() ([]*registry.ServiceInstance, error) {
|
||||
var svcInstances []*registry.ServiceInstance
|
||||
svcIns := <-w.ch
|
||||
svcInstances = append(svcInstances, svcIns)
|
||||
return svcInstances, nil
|
||||
}
|
||||
|
||||
func (w *Watcher) Stop() error {
|
||||
close(w.ch)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user