- Created by 郭强, last modified on Aug 29, 2023
You are viewing an old version of this page. View the current version.
Compare with Current View Page History
Version 15 Next »
基本介绍
GoFrame
框架提供了服务注册发现组件,由gsvc
组件管理,该组件主要定义了注册发现的接口,具体的实现由社区组件提供: https://github.com/gogf/gf/tree/master/contrib/registry 。目前社区组件提供了多种注册发现的实现,如 etcd, zookeeper, polaris
等,开发者根据需要插拔使用,也可以根据gsvc
组件的接口定义实现自己的注册发现组件。
组件启用
注册发现组件只有在引入具体的接口实现时才会启用。例如,使用etcd
实现注册发现的使用方式:
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/v2/net/gsvc" ) func main() { gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`)) // ... }
常用组件
更多组件,请参考:https://github.com/gogf/gf/tree/master/contrib/registry
使用示例
HTTP
可以使用gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`))
来设置使用etcd
的注册发现。其中的etcd.New
表示通过社区组件创建一个gsvc.Registry
的接口实现对象,并通过gsvc.SetRegistry
方法设置全局默认的注册发现接口实现对象。
server.go
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/gsvc" ) func main() { gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`)) s := g.Server(`hello.svc`) s.BindHandler("/", func(r *ghttp.Request) { g.Log().Info(r.Context(), `request received`) r.Response.Write(`Hello world`) }) s.Run() }
client.go
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/gsvc" "github.com/gogf/gf/v2/os/gctx" ) func main() { gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`)) ctx := gctx.New() res := g.Client().GetContent(ctx, `http://hello.svc/`) g.Log().Info(ctx, res) }
执行后,服务端输出:
$ go run server.go 2023-03-15 20:55:56.256 [INFO] pid[3358]: http server started listening on [:60700] 2023-03-15 20:55:56.256 [INFO] openapi specification is disabled 2023-03-15 20:55:56.256 [DEBU] service register: &{Head: Deployment: Namespace: Name:hello.svc Version: Endpoints:10.35.12.81:60700 Metadata:map[insecure:true protocol:http]} 2023-03-15 20:55:56.297 [DEBU] etcd put success with key "/service/default/default/hello.svc/latest/10.35.12.81:60700", value "{"insecure":true,"protocol":"http"}", lease "7587869265945813002" SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- hello.svc | default | :60700 | ALL | / | main.main.func1 | ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- hello.svc | default | :60700 | ALL | /* | github.com/gogf/gf/v2/net/ghttp.internalMiddlewareServerTracing | GLOBAL MIDDLEWARE ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- 2023-03-15 20:56:45.739 [INFO] {880eaa8104994c17ffb384495cd4c613} request received
客户端输出:
$ go run client.go 2023-03-15 20:56:45.739 [INFO] {880eaa8104994c17ffb384495cd4c613} Hello world
GRPC
如果是GRPC
协议,必须使用grpcx.Resolver
的grpcx
模块来设置服务注册发现组件。Server
端未在 config.yaml
中设置 grpc.name
值时,默认值是 default
。
server.go
代码中的etcd.New
表示通过社区组件创建一个gsvc.Registry
的接口实现对象,并通过grpcx.Resolver.Register
设置全局的grpc
注册发现接口实现对象。
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/contrib/rpc/grpcx/v2" "github.com/gogf/gf/example/registry/etcd/grpc/controller" ) func main() { grpcx.Resolver.Register(etcd.New("127.0.0.1:2379")) s := grpcx.Server.New() controller.Register(s) s.Run() }
config.yaml
服务端默认的配置文件:
grpc: name: "demo" # 服务名称 address: ":8000" # 自定义服务监听地址 logPath: "./log" # 日志存储目录路径 logStdout: true # 日志是否输出到终端 errorLogEnabled: true # 是否开启错误日志记录 accessLogEnabled: true # 是否开启访问日志记录 errorStack: true # 当产生错误时,是否记录错误堆栈
client.go
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/contrib/rpc/grpcx/v2" "github.com/gogf/gf/example/registry/etcd/grpc/protobuf" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" ) func main() { grpcx.Resolver.Register(etcd.New("127.0.0.1:2379")) var ( ctx = gctx.New() conn = grpcx.Client.MustNewGrpcClientConn("demo") client = protobuf.NewGreeterClient(conn) ) res, err := client.SayHello(ctx, &protobuf.HelloRequest{Name: "World"}) if err != nil { g.Log().Error(ctx, err) return } g.Log().Debug(ctx, "Response:", res.Message) }
执行后,服务端输出:
$ go run server.go 2023-03-15 21:06:57.204 [DEBU] service register: &{Head: Deployment: Namespace: Name:demo Version: Endpoints:10.35.12.81:61978 Metadata:map[protocol:grpc]} 2023-03-15 21:06:57.257 [DEBU] etcd put success with key "/service/default/default/demo/latest/10.35.12.81:61978", value "{"protocol":"grpc"}", lease "7587869265945813015" 2023-03-15 21:06:57.257 [INFO] pid[5786]: grpc server started listening on [:61978] 2023-03-15 21:07:04.955 {08f0aead94994c1731591d2b653ddc18} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World"
客户端输出:
$ go run client.go 2023-03-15 21:07:04.950 [DEBU] Watch key "/service/default/default/demo/latest/" 2023-03-15 21:07:04.952 [DEBU] client conn updated with addresses [{"Addr":"10.35.12.81:61978","ServerName":"demo","Attributes":{},"BalancerAttributes":null,"Type":0,"Metadata":null}] 2023-03-15 21:07:04.953 [DEBU] client conn updated with addresses [{"Addr":"10.35.12.81:61978","ServerName":"demo","Attributes":{},"BalancerAttributes":null,"Type":0,"Metadata":null}] 2023-03-15 21:07:04.955 [DEBU] {08f0aead94994c1731591d2b653ddc18} Response: Hello World
常见问题
在全局启用服务注册发现时,如何关闭特定请求的发现特性
问题:在使用gclient
时,如果全局开启了服务注册发现特性,那么gclient
的所有请求都将走发现服务。但是针对不是在服务注册发现中维护的服务,例如一个IP:PORT
的地址请求或者一个外网请求服务,也会走发现服务,并且会引起服务找不到而报错。如何避免这样的问题?
回答:在全局启用服务发现特性时,gclient
请求默认会使用全局设置的发现服务,如果特定的请求不使用发现服务,那么可以通过gclient.Client
的Discovery(nil)
链式操作方法来关闭当前请求的发现服务,或者SetDiscovery(nil)
配置方法来关闭当前客户端的发现服务。这样请求就不会走发现服务啦。
例子:
// 通过链式操作方法来关闭当前请求的发现服务 g.Client().Discovery(nil).Get(ctx, "http://192.168.1.1/api/v1/user") // 通过配置方法来关闭当前客户端的发现服务 client := g.Client() client.SetDiscovery(nil) client.Get(ctx, "http://192.168.1.1/api/v1/user")
·
- No labels