日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

gRPC之java语言的简单Demo

發布時間:2023/12/15 综合教程 27 生活家
生活随笔 收集整理的這篇文章主要介紹了 gRPC之java语言的简单Demo 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近由于項目需要,就簡單看了下gRPC入門,使用起來挺簡單的。這里就順便記錄一下,便于后面回顧。

RPC是什么

說到RPC(Remote Process Communication,遠程過程調用)就不得不說到進程間通信(Inter-process Communication,簡稱IPC),IPC是指多個進程之間傳送數據或信號的一些技術或方法。

而IPC又分為本地過程調用(LPC)和遠程過程調用(RPC),這兩者的區別就是 LPC的調用可以共享內存空間,比較方便;而RPC的調用雙方則不在同一個主機中,無法像LPC那樣方便。

說到底,RPC就是在本地來 調用遠程的方法。而RPC框架要做的就是 讓遠程調用 像本地調用一樣方便,而這個調用過程則是RPC框架需要做的工作。這個工作涉及到大概 兩個方面:序列化協議傳輸協議

1、常見的序列化協議有:
基于文本(text)的:XML、JSON
基于二進制(binary)的: Protocol Buffer、Thrift等

2、常見的傳輸協議有:
傳輸層的: TCP(基于Socket)、UDP
應用層的:HTTP1.1、HTTP2.0

而RPC框架中,通常使用的序列化協議包括Protocol Buffer、Thrift等,傳輸協議則常用TCP、HTTP2.0等。

更多的內容可以參考博客:【RPC簡介及框架選擇】

gRPC框架

上面簡單介紹了RPC機制的作用,現如今已經出現了許多優秀的RPC框架,比如:gRPC、Dubbo、Thrift等。這些框架在 序列化協議和傳輸協議兩部分都有不同的選擇,各有優劣。不過,沒必要全部都去學習一遍,可以簡單嘗試一種,大概了解運行機制即可。

下面是以gRPC的簡單使用為例,了解gRPC的運行過程和用法。

gRPC使用的序列化協議是 Protocol Buffer,使用的傳輸協議是 HTTP2.0協議。

需要清楚的是,
gRPC的通信方式需要先確定好proto文件,這個proto文件中定義了遠程api的具體服務接口、api方法的參數類型/返回值類型;
然后,將該proto文件編譯為 java類文件,這些類文件包含的就是 client端 和 server端都遵循的 遠程調用api的定義內容。
接著,client端 和 server端按照gRPC框架的方式來進行通信即可。

gRPC的java示例

具體步驟如下【參考源碼】:

1、創建一個maven項目,創建src/main/proto目錄,在其中添加定義好的遠程API接口hello.proto文件,如下:

// 使用該proto文件可以定義交互的服務接口,基于該文件編譯成的源文件可以分別復制到 client端和server端,便于兩者使用
?
syntax = "proto3"; // 定義語法類型
?
package hello; // 定義作用域
option java_multiple_files = false; // 表示下面的message不需要編譯成多個java文件
option java_outer_classname = "HelloMessage"; // 表示下面的message編譯成的java類文件的名字
option java_package = "grpc"; //指定該proto文件編譯成的java源文件的包名
?
service Hello {  // 定義服務
  rpc sayHello(HelloRequest) returns(HelloResponse) {}
}
?
message HelloRequest { // 定義請求的消息體
  string name = 1;
}
?
message HelloResponse { // 定義回復的消息體
  string message = 1;
}

2、在pom.xml文件中添加gRPC依賴與插件,參考grpc-java倉庫,如下:

依賴為:
    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.31.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.31.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.31.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>annotations-api</artifactId>
            <version>6.0.53</version>
            <scope>provided</scope>
        </dependency>
    </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.12.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.31.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
?
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
?
        </plugins>
    </build>

3、執行mvn clean compile命令,然后在生成的target/generated-sources/ptotobuf文件夾中找到服務接口對應的類文件接口參數/返回值對應的類文件

將這兩個文件分別復制到client端 和 server端的java源文件中。

4、編寫server端代碼,如下:

public class ServerDemo {
?
    // 定義一個Server對象,監聽端口來獲取rpc請求,以進行下面的處理
    private Server server;
?
    //使用main方法來測試server端
    public static void main(String[] args) throws IOException, InterruptedException {
?
        final ServerDemo serverDemo = new ServerDemo();
?
        //啟動server
        serverDemo.start();
?
        //block 一直到退出程序
        serverDemo.blockUntilShutdown();
    }
?
    /**
     * 啟動一個Server實例,監聽client端的請求并處理
     * @throws IOException
     */
    private void start() throws IOException {
?
        //server運行在的端口號
        int port = 50051;
?
        // 給server添加監聽端口號,添加 包含業務處理邏輯的類,然后啟動
        server = ServerBuilder.forPort(port)
                .addService(new HelloImpl())
                .build()
                .start();
?
    }
?
    /**
     * 阻塞server直到關閉程序
     * @throws InterruptedException
     */
    private void blockUntilShutdown() throws InterruptedException {
?
        if (server != null) {
            server.awaitTermination();
        }
?
    }
?
?
    /**
     * proto文件被編譯后,在生成的HelloGrpc的抽象內部類HelloImplBase中包含了 proto中定義的服務接口的簡單實現
     * 該HelloImpl類需要重寫這些方法,添加需要的處理邏輯
     */
    static class HelloImpl extends HelloGrpc.HelloImplBase {
?
        // proto文件中的sayHello服務接口被編譯后,在生成的HelloGrpc的抽象內部類HelloImplBase中有一個簡單的實現
        // 因此,在server端需要重寫這個方法,添加上相應的邏輯
        @Override
        public void sayHello(HelloMessage.HelloRequest req, StreamObserver<HelloMessage.HelloResponse> responseObserver) {
?
            HelloMessage.HelloResponse reply = HelloMessage.HelloResponse.newBuilder().setMessage("(server端的sayHello()方法處理結果) Hello," + req.getName()).build();
?
?
            // 調用onNext()方法來通知gRPC框架把reply 從server端 發送回 client端
            responseObserver.onNext(reply);
?
            // 表示完成調用
            responseObserver.onCompleted();
        }
    }
?
}

5、編寫client端代碼,如下:

public class ClientDemo {
?
    //使用main方法來測試client端
    public static void main(String[] args) throws Exception {
?
        ClientDemo clientDemo = new ClientDemo();
?
        try {
?
            //基于gRPC遠程調用對應的方法
            clientDemo.remoteCall("【zhongyuan】");
?
        } finally {
?
        }
    }
?
    /**
     * 基于gRPC框架的使用步驟,進行遠程調用
     * @param name
     */
    public void remoteCall(String name) {
?
        HelloMessage.HelloRequest request = HelloMessage.HelloRequest.newBuilder().setName(name).build();
        HelloMessage.HelloResponse response;
?
        try {
?
            // 基于訪問地址 創建通道
            Channel channel =  ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext().build();
?
            // 利用通道 創建一個樁(Stub)對象
            HelloGrpc.HelloBlockingStub blockingStub = HelloGrpc.newBlockingStub(channel);
?
            //通過樁對象來調用遠程方法
            response = blockingStub.sayHello(request);
?
        } catch (StatusRuntimeException e) {
            return;
        }
?
        System.out.println("client端遠程調用sayHello()的結果為:

" + response.getMessage());
    }
?
}

6、接下來,先運行server端main()函數,再運行client端的main()函數,即可測試rpc遠程調用結果,如下:

源碼詳見:https://github.com/zhongyuanzhao000/gRPC-demo

參考:

grpc官網:https://grpc.io/docs/languages/java/quickstart/

grpc官方文檔中文版:http://doc.oschina.net/grpc?t=60134

grpc-java倉庫:https://github.com/grpc/grpc-java

博客:

https://blog.csdn.net/sunsun314/article/details/73780169

https://blog.csdn.net/m0_38001814/article/details/108229637

總結

以上是生活随笔為你收集整理的gRPC之java语言的简单Demo的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。