paint-brush
gRPC-Secret: Son Teslim Tarihleri, Zaman Aşımları ve Özel Bağlamlarda Uzmanlaşmaile@gultm
767 okumalar
767 okumalar

gRPC-Secret: Son Teslim Tarihleri, Zaman Aşımları ve Özel Bağlamlarda Uzmanlaşma

ile Tatyana9m2024/08/01
Read on Terminal Reader

Çok uzun; Okumak

gRPC, açık kaynaklı bir uzaktan prosedür çağrısı (RPC) çerçevesidir. Hizmetler arasında verimli ve ölçeklenebilir iletişim sağlar. Önemli yönlerden biri son teslim tarihlerinin, istek zaman aşımlarının ve bağlamın yayılmasıdır. Bu mekanizmaları anlamak, hizmetlerin anında yanıt vermesini sağlamaya yardımcı olur.
featured image - gRPC-Secret: Son Teslim Tarihleri, Zaman Aşımları ve Özel Bağlamlarda Uzmanlaşma
Tatyana HackerNoon profile picture

Açık kaynaklı bir uzaktan prosedür çağrısı (RPC) çerçevesi olan gRPC, hizmetler arasında verimli ve ölçeklenebilir iletişim sağlar. GRPC'nin önemli yönlerinden biri son tarihlerin, istek zaman aşımlarının ve özel yapılar da dahil olmak üzere bağlamın yayılmasının yönetimidir.


Bu mekanizmaları anlamak, hizmetlerin anında yanıt vermesini, kaynakların makul bir zaman dilimini aşan işlemlerde israf edilmemesini ve özel meta verilerin etkili bir şekilde iletilmesini sağlamaya yardımcı olur.

Son Teslim Tarihlerini ve İstek Zaman Aşımlarını Anlama

Son teslim tarihleri

GRPC'deki son tarih, bir işlemin tamamlanması gereken maksimum süreyi belirtir. İşlemin bu süre içerisinde tamamlanmaması durumunda otomatik olarak sonlandırılacaktır. Yanıt vermeyen veya yavaş hizmetler nedeniyle sistem kaynaklarının süresiz olarak bağlı kalmamasını sağlamak için son tarihler önemlidir.

Zaman Aşımlarını Talep Et

İstek zaman aşımı, istemcinin sunucudan yanıt beklemek istediği süredir. Sunucu bu süre içerisinde yanıt vermezse istek iptal edilir. Bu mekanizma, istemcinin süresiz olarak yanıt bekleyerek askıda kalmasını önler.

GRPC'de Son Tarihleri ve İstek Zaman Aşımlarını Ayarlama

gRPC, hem istemci hem de sunucu tarafında son tarihlerin belirlenmesi ve zaman aşımlarının talep edilmesi için esnek seçenekler sunar. Go'da bunu nasıl yapabileceğiniz aşağıda açıklanmıştır:

İstemci Tarafı Ayarlama Son Tarihleri


 import ( "context" "log" "time" "google.golang.org/grpc" pb "path/to/your/protobuf/package" ) func main() { conn, err := grpc.Dial("server_address", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := pb.NewYourServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err := client.YourMethod(ctx, &pb.YourRequest{}) if err != nil { log.Fatalf("could not call method: %v", err) } log.Printf("Response: %v", resp) }

Sunucu Tarafında İşleme

Sunucu tarafında gRPC, son tarihleri uygulamanıza ve istemci tarafından belirtilen son tarihin aşıldığı senaryoları yönetmenize olanak tanır:


 import ( "context" "log" "net" "time" "google.golang.org/grpc" pb "path/to/your/protobuf/package" ) type server struct { pb.UnimplementedYourServiceServer } func (s *server) YourMethod(ctx context.Context, req *pb.YourRequest) (*pb.YourResponse, error) { select { case <-time.After(10 * time.Second): return &pb.YourResponse{}, nil case <-ctx.Done(): return nil, ctx.Err() } } func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterYourServiceServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }


Özel Yapıların Bağlamda Yayılması

Özel yapıları gRPC'de bağlam yoluyla göndermek için, verileri bağlama eklemeden önce serileştirmeniz ve ardından alıcı tarafta seri durumdan çıkarmanız gerekir. Bu, özel yapılarınızı JSON veya Protokol Arabellekleri gibi ağ üzerinden aktarılabilecek bir formata dönüştürmeyi ve ardından bu serileştirilmiş verileri bağlam meta verilerine eklemeyi içerir.

Adım Adım Süreç

  1. Özel Yapınızı Tanımlayın : Göndermek istediğiniz özel yapıyı tanımlayın.
  2. Yapıyı Serileştirin : Özel yapıyı bir dizeye veya bayt dizisine dönüştürün.
  3. Bağlama Ekle : Serileştirilmiş verileri bağlam meta verilerine ekleyin.
  4. İlet : GRPC çağrısını bağlamla birlikte gönderin.
  5. Sunucuda Çıkarma ve Seri Durumdan Çıkarma : Meta verileri sunucu tarafındaki bağlamdan çıkarın ve seri durumdan çıkarıp özel yapıya geri döndürün.

1. Adım: Özel Yapınızı Tanımlayın


 type CustomStruct struct { Field1 string Field2 int }


Adım 2: Yapıyı Serileştirin


 import ( "context" "encoding/json" "fmt" "google.golang.org/grpc/metadata" ) func serializeCustomStruct(customStruct CustomStruct) (string, error) { data, err := json.Marshal(customStruct) if err != nil { return "", err } return string(data), nil }


3. Adım: Bağlama Ekle


 func attachCustomStructToContext(ctx context.Context, customStruct CustomStruct) (context.Context, error) { serializedData, err := serializeCustomStruct(customStruct) if err != nil { return nil, err } md := metadata.Pairs("custom-struct", serializedData) ctx = metadata.NewOutgoingContext(ctx, md) return ctx, nil }


Adım 4: İletim


 func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := pb.NewYourServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() customStruct := CustomStruct{Field1: "value1", Field2: 42} ctx, err = attachCustomStructToContext(ctx, customStruct) if err != nil { log.Fatalf("could not attach custom struct to context: %v", err) } resp, err := client.YourMethod(ctx, &pb.YourRequest{}) if err != nil { log.Fatalf("could not call method: %v", err) } log.Printf("Response: %v", resp) }


Adım 5: Sunucuda Çıkarma ve Seri Durumdan Çıkarma


 func deserializeCustomStruct(data string) (CustomStruct, error) { var customStruct CustomStruct err := json.Unmarshal([]byte(data), &customStruct) if err != nil { return CustomStruct{}, err } return customStruct, nil } func extractCustomStructFromContext(ctx context.Context) (CustomStruct, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return CustomStruct{}, fmt.Errorf("no metadata found in context") } serializedData := md["custom-struct"] if len(serializedData) == 0 { return CustomStruct{}, fmt.Errorf("no custom struct found in metadata") } return deserializeCustomStruct(serializedData[0]) } func (s *server) YourMethod(ctx context.Context, req *pb.YourRequest) (*pb.YourResponse, error) { customStruct, err := extractCustomStructFromContext(ctx) if err != nil { return nil, err } log.Printf("Received custom struct: %+v", customStruct) select { case <-time.After(10 * time.Second): return &pb.YourResponse{}, nil case <-ctx.Done(): return nil, ctx.Err() } }


Tüm gRPC Çağrıları için Ara Yazılım Uygulama

Tüm gRPC çağrılarında özel yapılar da dahil olmak üzere bağlam yayılımını tutarlı bir şekilde yönetmek için önleyicileri kullanabilirsiniz. Durdurucular, istekleri ve yanıtları işleyen, günlüğe kaydetme, izleme ve bağlam meta veri işleme gibi işlevler ekleyen ara yazılımlardır.

Tekli ve Akış Durdurucuları

Farklı türdeki RPC çağrılarını yönetmek için hem tekli hem de akış önleyicilere ihtiyacınız vardır:


  • Tekli Durdurucular : Tekli istek-yanıt döngülerini yönetin.


  • Akış Durdurucuları : İstemci tarafı akışı, sunucu tarafı akışı ve çift yönlü akış dahil olmak üzere istek ve yanıt akışlarını yönetir.

Tekli Durdurucu Uygulaması

İstemci Tarafı Tekli Durdurucu:


 func unaryClientInterceptor( ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption, ) error { customStruct, ok := ctx.Value("customStruct").(CustomStruct) if ok { ctx, err := attachCustomStructToContext(ctx, customStruct) if err != nil { return err } } return invoker(ctx, method, req, reply, cc, opts...) }


Sunucu Tarafı Tekli Durdurucu:


 func unaryServerInterceptor( ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (interface{}, error) { customStruct, err := extractCustomStructFromContext(ctx) if err != nil { return nil, err } ctx = context.WithValue(ctx, "customStruct", customStruct) return handler(ctx, req) }

Akış Durdurucu Uygulaması

İstemci Tarafı Akış Durdurucusu:


 func streamClientInterceptor( ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption, ) (grpc.ClientStream, error) { customStruct, ok := ctx.Value("customStruct").(CustomStruct) if ok { ctx, err := attachCustomStructToContext(ctx, customStruct) if err != nil { return nil, err } } return


Sunucu Tarafı Akış Durdurucusu:


 import ( "context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) // StreamServerInterceptor handles server-side streaming func streamServerInterceptor( srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler, ) error { ctx := ss.Context() customStruct, err := extractCustomStructFromContext(ctx) if err != nil { return err } // Add custom struct to context for server handling newCtx := context.WithValue(ctx, "customStruct", customStruct) wrapped := grpc_middleware.WrapServerStream(ss) wrapped.WrappedContext = newCtx // Handle the request return handler(srv, wrapped) } // Example of using the interceptor in a gRPC server setup func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } // Register the interceptors server := grpc.NewServer( grpc.UnaryInterceptor(unaryServerInterceptor), grpc.StreamInterceptor(streamServerInterceptor), ) // Register your gRPC service implementations here pb.RegisterYourServiceServer(server, &yourServiceServer{}) if err := server.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }


Tekli ve akış yakalayıcılar oluşturup kaydederek, özel yapılar da dahil olmak üzere bağlam yayılımının tüm gRPC çağrılarında tutarlı bir şekilde işlenmesini sağlayabilirsiniz. Bu yaklaşım, özel meta verilerinizin uygun şekilde yönetilmesini ve yayılmasını sağlayarak sağlam ve esnek gRPC hizmetleri oluşturmanıza olanak tanır.