3.2 gRPC

3.2.1 gRPC介绍

Jupiter微服务目前支持gRPCJupitergRPC服务提供了很多可观察性的手段。

内置了多个中间件,可以采集请求日志、采集trace、采集监控、采集慢日志,更加方便我们对gRPC服务的可观测。

通过govern的治理端口,能够查看监控、HTTP实时信息

3.2.2 配置规范

配置说明3.2 gRPC - 图1

3.2.3 直连的gRPC

参考gRPC直连示例3.2 gRPC - 图2

3.2.3.1 启动gRPC服务

配置项

  1. [jupiter.server.grpc]
  2. port = 9091

代码

  1. func main() {
  2. eng := NewEngine()
  3. eng.SetGovernor("127.0.0.1:9092")
  4. if err := eng.Run(); err != nil {
  5. xlog.Panic(err.Error())
  6. }
  7. }
  8. type Engine struct {
  9. jupiter.Application
  10. }
  11. func NewEngine() *Engine {
  12. eng := &Engine{}
  13. if err := eng.Startup(
  14. eng.serveGRPC,
  15. ); err != nil {
  16. xlog.Panic("startup", xlog.Any("err", err))
  17. }
  18. return eng
  19. }
  20. func (eng *Engine) serveGRPC() error {
  21. server := xgrpc.StdConfig("grpc").Build()
  22. helloworld.RegisterGreeterServer(server.Server, new(Greeter))
  23. return eng.Serve(server)
  24. }
  25. type Greeter struct{}
  26. func (g Greeter) SayHello(context context.Context, request *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
  27. return &helloworld.HelloReply{
  28. Message: "Hello Jupiter",
  29. }, nil
  30. }

运行指令go run main.go --config=config.toml,可以看到以下运行结果 image 从图中可以看到,我们启动了一个gRPC服务运行在9091端口,接下来我们启动客户端

3.2.3.2 启动gRPC客户端

配置项

  1. [jupiter.client.directserver]
  2. address = "127.0.0.1:9091"
  3. balancerName = "round_robin" # 默认值
  4. block = false # 默认值
  5. dialTimeout = "0s" # 默认值

代码

  1. func main() {
  2. eng := NewEngine()
  3. if err := eng.Run(); err != nil {
  4. xlog.Error(err.Error())
  5. }
  6. }
  7. type Engine struct {
  8. jupiter.Application
  9. }
  10. func NewEngine() *Engine {
  11. eng := &Engine{}
  12. if err := eng.Startup(
  13. eng.consumer,
  14. ); err != nil {
  15. xlog.Panic("startup", xlog.Any("err", err))
  16. }
  17. return eng
  18. }
  19. func (eng *Engine) consumer() error {
  20. conn := grpc.StdConfig("directserver").Build()
  21. client := helloworld.NewGreeterClient(conn)
  22. for {
  23. resp, err := client.SayHello(context.Background(), &helloworld.HelloRequest{
  24. Name: "jupiter",
  25. })
  26. if err != nil {
  27. xlog.Error(err.Error())
  28. } else {
  29. xlog.Info("receive response", xlog.String("resp", resp.Message))
  30. }
  31. time.Sleep(1 * time.Second)
  32. }
  33. return nil
  34. }

我们的gRPC客户端通过配置里的地址和负载均衡算法,可以请求刚才我们启动的gRPC服务端。运行指令go run main.go --config=config.toml,可以看到以下运行结果 image 我们定时1s,发送hellogRPC服务端,可以收到服务端响应的Hello Jupiter

3.2.4 注册ETCD的gRPC服务

参考gRPC注册ETCD示例3.2 gRPC - 图5

3.2.4.2 启动gRPC服务

配置项

  1. [jupiter.server.grpc]
  2. port = 9091
  3. [jupiter.registry.wh]
  4. connectTimeout = "1s"
  5. endpoints=["127.0.0.1:2379"]
  6. secure = false

代码

  1. func main() {
  2. eng := NewEngine()
  3. eng.SetRegistry(
  4. compound_registry.New(
  5. etcdv3_registry.StdConfig("wh").BuildRegistry(),
  6. ),
  7. )
  8. eng.SetGovernor("127.0.0.1:9092")
  9. if err := eng.Run(); err != nil {
  10. xlog.Error(err.Error())
  11. }
  12. }
  13. type Engine struct {
  14. jupiter.Application
  15. }
  16. func NewEngine() *Engine {
  17. eng := &Engine{}
  18. if err := eng.Startup(
  19. eng.serveGRPC,
  20. ); err != nil {
  21. xlog.Panic("startup", xlog.Any("err", err))
  22. }
  23. return eng
  24. }
  25. func (eng *Engine) serveGRPC() error {
  26. server := xgrpc.StdConfig("grpc").Build()
  27. helloworld.RegisterGreeterServer(server.Server, new(Greeter))
  28. return eng.Serve(server)
  29. }
  30. type Greeter struct{}
  31. func (g Greeter) SayHello(context context.Context, request *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
  32. return &helloworld.HelloReply{
  33. Message: "Hello Jupiter",
  34. }, nil
  35. }

运行指令go run main.go --config=config.toml,可以看到以下运行结果 image 从图中可以看到,我们启动了一个gRPC服务运行在9091端口,在命令行的第四行,展示了我们注册的keyvalue信息。接下来我们在启动客户端。

3.2.4.2 启动gRPC客户端

配置项

  1. [jupiter.registry.wh]
  2. connectTimeout = "1s"
  3. endpoints=["127.0.0.1:2379"]
  4. secure = false
  5. [jupiter.client.etcdserver]
  6. address = "etcd:///main"
  7. balancerName = "round_robin" # 默认值
  8. block = false # 默认值
  9. dialTimeout = "0s" # 默认值

代码

  1. func main() {
  2. eng := NewEngine()
  3. if err := eng.Run(); err != nil {
  4. xlog.Error(err.Error())
  5. }
  6. }
  7. type Engine struct {
  8. jupiter.Application
  9. }
  10. func NewEngine() *Engine {
  11. eng := &Engine{}
  12. if err := eng.Startup(
  13. eng.initResolver,
  14. eng.consumer,
  15. ); err != nil {
  16. xlog.Panic("startup", xlog.Any("err", err))
  17. }
  18. return eng
  19. }
  20. func (eng *Engine) initResolver() error {
  21. resolver.Register(etcdv3_registry.StdConfig("wh").BuildResolver())
  22. return nil
  23. }
  24. func (eng *Engine) consumer() error {
  25. conn := grpc.StdConfig("etcdserver").Build()
  26. client := helloworld.NewGreeterClient(conn)
  27. for {
  28. resp, err := client.SayHello(context.Background(), &helloworld.HelloRequest{
  29. Name: "jupiter",
  30. })
  31. if err != nil {
  32. xlog.Error(err.Error())
  33. } else {
  34. xlog.Info("receive response", xlog.String("resp", resp.Message))
  35. }
  36. time.Sleep(1 * time.Second)
  37. }
  38. return nil
  39. }

运行指令go run main.go --config=config.toml,可以看到以下运行结果 image 我们的gRPC客户端通过应用名称mainETCD中获取到服务地址,并监听了/jupiter/main,用于后续更新服务地址。

客户端会定时1s,发送hellogRPC服务端,可以收到服务端响应的Hello Jupiter