All About That Base - Keeley Erhardt

Microservice architectures promise to deliver flexibility and scalability to the development and deployment of service-based applications. With these obvious benefits, however, comes the difficulty and operational complexity of managing a distributed system. In this presentation, we will cover why building production services is hard, and how Improbable has tackled the problem through a new project designed to unify services' common functionality in a single base server. We will discuss how developing microservices utilizing a common base server has reduced development time and led to more stable and reliable systems at Improbable, and how you can use the strategy to achieve similar benefits in your own systems.
展开查看详情

1. radicle Building debuggable, production-ready servers in Go Keeley Erhardt @KeeleyErhardt 25 JUN 2018, LinuxCon + ContainerCon + CloudOpen China (LC3), Beijing

2. @KeeleyErhardt github.com/keelerh/demo-radicle

3. @KeeleyErhardt service Greeter { rpc SayHello (HelloRequest) returns (HelloResponse) {} Service } message HelloRequest { ● A collection of actions the string name = 1; server can perform at the } client’s request message HelloResponse { string message = 1; } github.com/keelerh/demo-radicle

4. @KeeleyErhardt service Greeter { rpc SayHello (HelloRequest) returns (HelloResponse) {} Service } message HelloRequest { ● A collection of actions the string name = 1; server can perform at the } client’s request message HelloResponse { string message = 1; } github.com/keelerh/demo-radicle

5. @KeeleyErhardt service Greeter { rpc SayHello (HelloRequest) returns (HelloResponse) {} Service } message HelloRequest { ● A collection of actions the string name = 1; server can perform at the } client’s request message HelloResponse { string message = 1; } github.com/keelerh/demo-radicle

6. @KeeleyErhardt // $ protoc -I protos/ \ Service // -I${GOPATH}/src \ // --go_out=plugins=grpc:protos \ // protos/helloworld.proto ● A collection of actions the // // Code generated by protoc-gen-go. DO NOT EDIT. server can perform at the // source: helloworld.proto client’s request type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloResponse, error) } github.com/keelerh/demo-radicle

7. @KeeleyErhardt // $ protoc -I protos/ \ Service // -I${GOPATH}/src \ // --go_out=plugins=grpc:protos \ // protos/helloworld.proto ● A collection of actions the // // Code generated by protoc-gen-go. DO NOT EDIT. server can perform at the // source: helloworld.proto client’s request type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloResponse, error) } github.com/keelerh/demo-radicle

8. @KeeleyErhardt // $ protoc -I protos/ \ Service // -I${GOPATH}/src \ // --go_out=plugins=grpc:protos \ // protos/helloworld.proto ● A collection of actions the // // Code generated by protoc-gen-go. DO NOT EDIT. server can perform at the // source: helloworld.proto client’s request type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloResponse, error) } github.com/keelerh/demo-radicle

9. @KeeleyErhardt // $ protoc -I protos/ \ Service // -I${GOPATH}/src \ // --go_out=plugins=grpc:protos \ // protos/helloworld.proto ● A collection of actions the // // Code generated by protoc-gen-go. DO NOT EDIT. server can perform at the // source: helloworld.proto client’s request type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloResponse, error) } github.com/keelerh/demo-radicle

10. @KeeleyErhardt type GreeterService struct {} Service func (s *GreeterService) SayHello( ctx context.Context, req *pb.HelloRequest) ● A collection of actions the (*pb.HelloResponse, error) { server can perform at the return &pb.HelloResponse{ Message: fmt.Sprintf("Hello %s", req.Name), client’s request }, nil } github.com/keelerh/demo-radicle

11. @KeeleyErhardt gRPC + Protobufs ● gRPC: a high performance, open-source remote procedure call (RPC) framework ● Protobufs: the Interface Definition Language (IDL) and underlying message interchange format for gRPC Image Source: http://www.grpc.io

12. @KeeleyErhardt func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8081)) if err != nil { Server log.Fatalf("failed to listen: %v", err) } ● A computer program or device grpcServer := grpc.NewServer() svc := helloworld.GreeterService{} that processes requests and pb.RegisterGreeterServer(grpcServer, &svc) delivers data over the network if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } } github.com/keelerh/demo-radicle

13. @KeeleyErhardt func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8081)) if err != nil { Server log.Fatalf("failed to listen: %v", err) } ● A computer program or device grpcServer := grpc.NewServer() svc := helloworld.GreeterService{} that processes requests and pb.RegisterGreeterServer(grpcServer, &svc) delivers data over the network if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } } github.com/keelerh/demo-radicle

14. @KeeleyErhardt func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8081)) if err != nil { Server log.Fatalf("failed to listen: %v", err) } ● A computer program or device grpcServer := grpc.NewServer() svc := helloworld.GreeterService{} that processes requests and pb.RegisterGreeterServer(grpcServer, &svc) delivers data over the network if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } } github.com/keelerh/demo-radicle

15. @KeeleyErhardt func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8081)) if err != nil { Server log.Fatalf("failed to listen: %v", err) } ● A computer program or device grpcServer := grpc.NewServer() svc := helloworld.GreeterService{} that processes requests and pb.RegisterGreeterServer(grpcServer, &svc) delivers data over the network if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } } github.com/keelerh/demo-radicle

16. @KeeleyErhardt func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8081)) if err != nil { Server log.Fatalf("failed to listen: %v", err) } ● A computer program or device grpcServer := grpc.NewServer() svc := helloworld.GreeterService{} that processes requests and pb.RegisterGreeterServer(grpcServer, &svc) delivers data over the network if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } } github.com/keelerh/demo-radicle

17. @KeeleyErhardt func main() { lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8081)) if err != nil { Server log.Fatalf("failed to listen: %v", err) } ● A computer program or device grpcServer := grpc.NewServer() svc := helloworld.GreeterService{} that processes requests and pb.RegisterGreeterServer(grpcServer, &svc) delivers data over the network if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %s", err) } } github.com/keelerh/demo-radicle

18. @KeeleyErhardt Greeter service Service ✅ Naive implementation ❌ Production ready Server

19. @KeeleyErhardt Production service Service ● Metrics Metrics

20. @KeeleyErhardt type Service struct {} Production service func (s *Service) SayHello( ctx context.Context, req *pb.HelloRequest) ● Metrics (*pb.HelloResponse, error) { helloCount.WithLabelValues(req.Name).Add(1) return &pb.HelloResponse{ Message: fmt.Sprintf("Hello %s", req.Name) }, nil } github.com/keelerh/demo-radicle

21. @KeeleyErhardt Production service Service ● Metrics Metrics ● Logging Logging

22. @KeeleyErhardt type GreeterService struct{} Production service func (s *GreeterService) SayHello( ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) { ● Metrics helloCount.WithLabelValues(req.Name).Add(1) ● Logging log.Printf("%s: %s: %s", "grpc", "SayHello", req.Name) return &pb.HelloResponse{ Message: fmt.Sprintf("Hello %s", req.Name), }, nil } github.com/keelerh/demo-allium

23. @KeeleyErhardt Production service Service ● Metrics Metrics ● Logging Logging ● Tracing Tracing

24. @KeeleyErhardt Production service Service ● Metrics Metrics ● Logging Logging ● Tracing Tracing ● Rate limiting Rate limiting

25. @KeeleyErhardt Production service Service ● Metrics Metrics ● Logging Logging ● Tracing Tracing ● Rate limiting ● ... Rate limiting ...

26. @KeeleyErhardt Building production services is hard.

27. @KeeleyErhardt What should I get out of this talk? ● Building production services is hard ● Existing solutions Talk overview ● Intro to radicle ○ Overview ○ Example ○ Functionality ● Key takeaways

28. @KeeleyErhardt Transport Operational metrics Existing solutions Balancing and limiting Business analytics ● Go Kit Application logging Service metrics Business logic Image Source: https://gokit.io

29. @KeeleyErhardt Transport Operational metrics Existing solutions Balancing and limiting Business analytics Service ● Go Kit Application logging Service metrics Business logic Image Source: https://gokit.io