1. Genel Bakış
gRPC Google'da geliştirilen, dilden bağımsız, platform açısından bağımsız bir uzak prosedür çağrısı (RPC) çerçevesi ve araç setidir. Özellikle güçlü bir ikili program serileştirme araç seti ve dili olan Protokol Arabelleklerini kullanarak hizmet tanımlamanızı sağlar. Daha sonra çeşitli dillerde hizmet tanımınızdan deyimsel istemci ve sunucu kökleri oluşturmanıza olanak tanır.
Bu codelab'de, gRPC çerçevesini kullanarak API ortaya çıkaran Java tabanlı bir hizmet derlemeyi ve oluşturulan gRPC istemci taraflı saplama kısmını kullanmak için bir istemci yazmayı öğreneceksiniz.
Neler öğreneceksiniz?
- Protokol Arabellek Dili
- Java kullanarak gRPC hizmeti uygulama
- Java kullanarak gRPC istemcisini uygulama
Bu eğiticiden nasıl yararlanacaksınız?
Node.js uygulamaları oluşturma deneyiminizi nasıl değerlendirirsiniz?
Go uygulamaları oluşturma deneyiminizi nasıl değerlendirirsiniz?
2. Kurulum ve Gereksinimler
Kendi hızınızda ortam kurulumu
- Cloud Console'da oturum açıp yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.
Tüm Google Cloud projelerinde benzersiz bir ad olan proje kimliğini unutmayın (yukarıdaki ad zaten alınmış ve size uygun olmayacaktır!). Bu kod laboratuvarın ilerleyen bölümlerinde PROJECT_ID
olarak adlandırılacaktır.
- Sonraki adımda, Google Cloud kaynaklarını kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir.
Bu codelab'i çalıştırmanın maliyeti, yüksek değildir. "Temizleme" bölümündeki talimatları izlediğinizden emin olun. bölümünde, bu eğiticinin dışında faturalandırmayla karşılaşmamanız için kaynakları nasıl kapatacağınız konusunda tavsiyelerde bulunuyoruz. Yeni Google Cloud kullanıcıları, 300 ABD doları değerindeki ücretsiz denemeden yararlanabilir.
Google Cloud Shell
Bu codelab, bilgisayarınızdan çalıştırılabilse de bu codelab'de, Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacağız.
Bu Debian tabanlı sanal makine, ihtiyacınız olan tüm geliştirme araçlarıyla yüklüdür. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud'da çalışarak ağ performansını ve kimlik doğrulamasını büyük ölçüde iyileştirir. Yani bu codelab'de ihtiyacınız olan tek şey bir tarayıcıdır (Evet, Chromebook'ta çalışır).
- Cloud Shell'i Cloud Console'dan etkinleştirmek için Cloud Shell'i etkinleştir simgesini tıklamanız yeterlidir (sağlanması ve ortama bağlanması yalnızca birkaç dakika sürer).
Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin PROJECT_ID
olarak ayarlanmış olduğunu göreceksiniz.
gcloud auth list
Komut çıkışı
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Komut çıkışı
[core] project = <PROJECT_ID>
Herhangi bir nedenle proje ayarlanmamışsa şu komutu vermeniz yeterlidir:
gcloud config set project <PROJECT_ID>
PROJECT_ID
cihazınızı mı arıyorsunuz? Kurulum adımlarında kullandığınız kimliği kontrol edin veya Cloud Console kontrol panelinden arayın:
Cloud Shell bazı ortam değişkenlerini de varsayılan olarak ayarlar. Bu değişkenler, gelecekte komut çalıştırdığınızda işinize yarayabilir.
echo $GOOGLE_CLOUD_PROJECT
Komut çıkışı
<PROJECT_ID>
- Son olarak, varsayılan alt bölgeyi ve proje yapılandırmasını ayarlayın.
gcloud config set compute/zone us-central1-f
Çeşitli farklı alt bölgeler seçebilirsiniz. Daha fazla bilgi için Bölgeler ve Bölgeler.
3. gRPC Hizmeti Oluşturma
Maven ile yeni bir Java projesi oluşturun:
$ mvn archetype:generate -DgroupId=com.example.grpc \ -DartifactId=grpc-hello-server \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false $ cd grpc-hello-server
gRPC Tanım Dosyası Ekleme
gRPC'de hizmet yüklerinin (istek ve yanıt) ve hizmet işlemlerinin IDL (Arayüz Tanımlama Dili) olarak yakalanması gerekir. gRPC, mesaj yüklerini ve işlemlerini tanımlamak için Protobuffer 3 söz dizimini kullanır. Basit bir Karşılama Hizmeti için Hello İsteği ve Hello yanıtı ile birlikte bir proto dosyası oluşturalım.
İlk olarak, yeni proto dosyasını içerecek yeni bir proto dizini oluşturun:
$ mkdir -p src/main/proto
Sonra src/main/proto/GreetingService.proto
adlı yeni bir proto dosyası oluşturun.
Dosyayı düzenlemek için vim,nano,
veya emacs
aracını kullanabilirsiniz:
src/main/proto/GreetingService.proto
syntax = "proto3"; package com.example.grpc; // Request payload message HelloRequest { // Each message attribute is strongly typed. // You also must assign a "tag" number. // Each tag number is unique within the message. string name = 1; // This defines a strongly typed list of String repeated string hobbies = 2; // There are many more basics types, like Enum, Map // See https://developers.google.com/protocol-buffers/docs/proto3 // for more information. } message HelloResponse { string greeting = 1; } // Defining a Service, a Service can have multiple RPC operations service GreetingService { // Define a RPC operation rpc greeting(HelloRequest) returns (HelloResponse); }
gRPC Bağımlılıkları ve Eklentisi Ekleme
Tanımı belirledikten sonra, bu dosyadan hem sunucu tarafı saplama hem de istemci tarafı saplamayı oluşturabiliriz. gRPC bağımlılarını ve eklentilerini eklemeniz gerekir.
İlk olarak gRPC bağımlılıklarını pom.xml
öğesine ekleyin:
pom.xml
<project> ... <dependencies> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.24.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.24.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.24.0</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> ... </dependencies> ... </project>
Ardından eklentiyi ekleyin:
pom.xml
<project> ... <dependencies> ... </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.2</version> </extension> </extensions> <plugins> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Saplamaları Oluştur
Uygulamayı derlediğinizde, eklenti proto tanımlarını Java koduna dönüştürür.
$ mvn -DskipTests package
Oluşturulan dosyaları görmek için:
$ find target/generated-sources
Hizmeti Uygulama
Öncelikle, greeting
işlemini uygulayacak yeni bir GreetingServiceImpl
sınıfı oluşturun:
src/main/java/com/example/grpc/GreetingServiceImpl.java
package com.example.grpc; import io.grpc.stub.StreamObserver; public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { @Override public void greeting(GreetingServiceOuterClass.HelloRequest request, StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) { // HelloRequest has toString auto-generated. System.out.println(request); // You must use a builder to construct a new Protobuffer object GreetingServiceOuterClass.HelloResponse response = GreetingServiceOuterClass.HelloResponse.newBuilder() .setGreeting("Hello there, " + request.getName()) .build(); // Use responseObserver to send a single response back responseObserver.onNext(response); // When you are done, you must call onCompleted. responseObserver.onCompleted(); } }
Sunucuyu uygulama
Son olarak, bağlantı noktasını dinlemek ve bu hizmet uygulamasını kaydetmek için bir sunucu başlatmanız gerekir. App
sınıfını ve ana yöntemini düzenleyin:
src/main/java/com/example/grpc/App.java
package com.example.grpc; import io.grpc.*; public class App { public static void main( String[] args ) throws Exception { // Create a new server to listen on port 8080 Server server = ServerBuilder.forPort(8080) .addService(new GreetingServiceImpl()) .build(); // Start the server server.start(); // Server threads are running in the background. System.out.println("Server started"); // Don't exit the main thread. Wait until server is terminated. server.awaitTermination(); } }
Son olarak, sunucuyu çalıştırın:
$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.App ... Server Started
4. Hizmeti Kullanma
Oluşturma aracı, istemci taraflı saplamaların tümünü zaten oluşturdu. Laboratuvarda kolaylık sağlamak için aynı Maven projesini kullanacağız ancak yeni bir ana yöntemle yeni bir Client
sınıfı ekleyeceğiz.
Öncelikle + simgesini tıklayarak yeni bir Cloud Shell oturumu açın. Böylece sunucuyu sonlandırmanıza gerek kalmaz:
Yeni oturumda grpc-hello-server
dizinine geçin:
$ cd grpc-hello-server
Ardından, yeni Client
sınıfını ekleyin:
src/main/java/com/example/grpc/Client.java
package com.example.grpc; import io.grpc.*; public class Client { public static void main( String[] args ) throws Exception { // Channel is the abstraction to connect to a service endpoint // Let's use plaintext communication because we don't have certs final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080") .usePlaintext(true) .build(); // It is up to the client to determine whether to block the call // Here we create a blocking stub, but an async stub, // or an async stub with Future are always possible. GreetingServiceGrpc.GreetingServiceBlockingStub stub = GreetingServiceGrpc.newBlockingStub(channel); GreetingServiceOuterClass.HelloRequest request = GreetingServiceOuterClass.HelloRequest.newBuilder() .setName("Ray") .build(); // Finally, make the call using the stub GreetingServiceOuterClass.HelloResponse response = stub.greeting(request); System.out.println(response); // A Channel should be shutdown before stopping the process. channel.shutdownNow(); } }
Son olarak, istemciyi çalıştırın:
$ mvn -DskipTests package exec:java -Dexec.mainClass=com.example.grpc.Client ... greeting: "Hello there, Ray"
İşte bu kadar. Çok basit, değil mi?
5. Akış Hizmeti
Deneyebileceğiniz çok daha fazla şey var. Örneğin, proto dosyasındaki stream
anahtar kelimesini isteğe veya yanıt parametresine (ör.
src/main/proto/GreetingService.proto
syntax = "proto3"; package com.example.grpc; ... // Defining a Service, a Service can have multiple RPC operations service GreetingService { // MODIFY HERE: Update the return to streaming return. rpc greeting(HelloRequest) returns (stream HelloResponse); }
Sunucunuzu tek bir yanıt yerine birden çok yanıt gönderecek şekilde güncelleyin. Bunu, birden fazla responseObserver.onNext(...)
çağrısı yaparak yapabilirsiniz:
src/main/java/com/example/grpc/GreetingServiceImpl.java
package com.example.grpc; import io.grpc.stub.StreamObserver; public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { @Override public void greeting(GreetingServiceOuterClass.HelloRequest request, StreamObserver<GreetingServiceOuterClass.HelloResponse> responseObserver) { ... // Feel free to construct different responses if you'd like. responseObserver.onNext(response); responseObserver.onNext(response); responseObserver.onNext(response); // When you are done, you must call onCompleted. responseObserver.onCompleted(); } }
İstemci, engelleme koçanı yerine eşzamansız bir saplama kullanmalıdır. stub
türünü GreetingServiceStub
olarak güncellediğinizden emin olarak istemci kodunu güncelleyin:
src/main/java/com/example/grpc/Client.java
package com.example.grpc; import io.grpc.*; // New import import io.grpc.stub.*; public class Client { public static void main( String[] args ) throws Exception { final ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080") .usePlaintext(true) .build(); // Replace the previous synchronous code with asynchronous code. // This time use an async stub: GreetingServiceGrpc.GreetingServiceStub stub = GreetingServiceGrpc.newStub(channel); // Construct a request GreetingServiceOuterClass.HelloRequest request = GreetingServiceOuterClass.HelloRequest.newBuilder() .setName("Ray") .build(); // Make an Asynchronous call. Listen to responses w/ StreamObserver stub.greeting(request, new StreamObserver<GreetingServiceOuterClass.HelloResponse>() { public void onNext(GreetingServiceOuterClass.HelloResponse response) { System.out.println(response); } public void onError(Throwable t) { } public void onCompleted() { // Typically you'll shutdown the channel somewhere else. // But for the purpose of the lab, we are only making a single // request. We'll shutdown as soon as this request is done. channel.shutdownNow(); } }); } }
Uygulamayı yeniden derleyin:
$ mvn -DskipTests package
Hem sunucuyu hem de istemciyi kendi Cloud Shell oturumunda yeniden başlatın.
Sunucuyu başlatmak için:
$ mvn exec:java -Dexec.mainClass=com.example.grpc.App ... Server Started
Müşteriyi başlatmak için:
$ mvn exec:java -Dexec.mainClass=com.example.grpc.Client ... greeting: "Hello there, Ray" greeting: "Hello there, Ray" greeting: "Hello there, Ray"
6. Tebrikler!
İşlediğimiz konular:
- Protokol Arabellek Dili
- Java kullanarak gRPC sunucusu uygulama
- Java kullanarak gRPC istemcisini uygulama
Sonraki Adımlar:
- gRPC Java hakkında daha fazla bilgi
- GitHub'da daha fazla gRPC Java örneklerine bakın
- gRPC'de akış hakkında bilgi edinin
- gRPC'den REST'e kod dönüştürme hakkında daha fazla bilgi
Geri bildiriminizi paylaşın
- Lütfen çok kısa bir süre ayırarak anketimizi doldurun.