gRPC服务

1 Example

项目地址gRPC服务 - 图1 (opens new window)

ego版本:ego@v1.0.0

2 使用方式

  1. go get github.com/ego-component/ego

3 gRPC配置

  1. type Config struct {
  2. Host string // IP地址,默认0.0.0.0
  3. Port int // Port端口,默认9002
  4. Deployment string // 部署区域
  5. Network string // 网络类型,默认tcp4
  6. EnableMetricInterceptor bool // 是否开启监控,默认开启
  7. EnableTraceInterceptor bool // 是否开启链路追踪,默认开启
  8. SlowLogThreshold time.Duration // 服务慢日志,默认500ms
  9. EnableAccessInterceptorReq bool // 是否开启记录请求参数,默认不开启
  10. EnableAccessInterceptorRes bool // 是否开启记录响应参数,默认不开启
  11. EnableLocalMainIP bool // 自动获取ip地址
  12. }

4 普通服务

4.1 用户配置

  1. [server.grpc]
  2. host = "127.0.0.1"
  3. port = 9002

4.2 用户代码

配置创建一个 grpc 的配置项,其中内容按照上文配置进行填写。以上这个示例里这个配置key是server.grpc

代码中创建一个 gRPC 服务, egrpc.Load(“”).Build(),代码中的 key 和配置中的 key 要保持一致。创建完 gRPC 服务后, 将他添加到 ego new 出来应用的 Serve 方法中,之后使用的方法和 gRPC 就完全一致。

  1. package main
  2. import (
  3. "context"
  4. "github.com/gotomicro/ego"
  5. "github.com/gotomicro/ego/core/elog"
  6. "github.com/gotomicro/ego/server"
  7. "github.com/gotomicro/ego/server/egrpc"
  8. "google.golang.org/grpc/examples/helloworld/helloworld"
  9. )
  10. // export EGO_DEBUG=true && go run main.go --config=config.toml
  11. func main() {
  12. if err := ego.New().Serve(func() server.Server {
  13. server := egrpc.Load("server.grpc").Build()
  14. helloworld.RegisterGreeterServer(server.Server, &Greeter{server: server})
  15. return server
  16. }()).Run(); err != nil {
  17. elog.Panic("startup", elog.Any("err", err))
  18. }
  19. }
  20. type Greeter struct {
  21. server *egrpc.Component
  22. helloworld.UnimplementedGreeterServer
  23. }
  24. func (g Greeter) SayHello(context context.Context, request *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
  25. return &helloworld.HelloReply{
  26. Message: "Hello EGO, I'm " + g.server.Address(),
  27. }, nil
  28. }

5 开启链路的服务

5.1 用户配置

  1. [trace.jaeger] # 启用链路的核心配置
  2. ServiceName = "server"
  3. [server.grpc]
  4. host = "127.0.0.1"
  5. port = 9002

5.2 测试代码

gRPC直连查看链路idgRPC服务 - 图2 (opens new window)

5.2.1 服务端链路信息

image

5.2.2 客户端链路信息

image

6 开启服务端详细日志信息

6.1 测试代码

gRPC查看详细信息gRPC服务 - 图5 (opens new window)

6.2 用户配置

  1. [server.grpc]
  2. host = "127.0.0.1"
  3. port = 9002
  4. enableAccessInterceptorReq=true # 是否开启记录请求参数,默认不开启
  5. enableAccessInterceptorRes=true # 是否开启记录响应参数,默认不开启

6.3 服务端详细信息

image

7 gRPC获取Header头信息

  • app
  • x-trace-id
  • client-ip
  • cpu

7.1 服务端获取对端应用名的header信息

前提

  • gRPC客户端使用了EGO设置app应用名中间件
  1. func getPeerName(ctx context.Context) string {
  2. md, ok := metadata.FromIncomingContext(ctx)
  3. if !ok {
  4. return ""
  5. }
  6. val, ok2 := md["app"]
  7. if !ok2 {
  8. return ""
  9. }
  10. return strings.Join(val, ";")
  11. }

7.2 服务端获取trace id的header信息

前提:

  • gRPC客户端使用了EGO设置trace id中间
  • gRPC客户端开启链路
  • gRPC服务端开启链路
  1. [trace.jaeger] # 开启链路
  1. // 如果开启了全局链路,可以获取链路id
  2. if opentracing.IsGlobalTracerRegistered() {
  3. etrace.ExtractTraceID(ctx)
  4. }

7.3 服务端获取client ip的header信息

  1. func getPeerIP(ctx context.Context) string {
  2. md, ok := metadata.FromIncomingContext(ctx)
  3. if !ok {
  4. return ""
  5. }
  6. // 从metadata里取对端ip
  7. if val, ok := md["client-ip"]; ok {
  8. return strings.Join(val, ";")
  9. }
  10. // 从grpc里取对端ip
  11. pr, ok2 := peer.FromContext(ctx)
  12. if !ok2 {
  13. return ""
  14. }
  15. if pr.Addr == net.Addr(nil) {
  16. return ""
  17. }
  18. addSlice := strings.Split(pr.Addr.String(), ":")
  19. if len(addSlice) > 1 {
  20. return addSlice[0]
  21. }
  22. return ""
  23. }

7.4 服务端获取cpu的header信息

未来用于p2c的负载均衡,未实现