1. 程式人生 > >Spring Boot 2+gRPC 學習系列2:搭建Spring Cloud +gRPC叢集專案

Spring Boot 2+gRPC 學習系列2:搭建Spring Cloud +gRPC叢集專案

本專案基於Spring Boot 2.0.5+yidongnan/grpc-spring-boot-starter 2.0.1.RELEASE+SpringCloud Finchley.SR1,通過2個grpc-eureka-server模擬Eureka叢集,多個可橫向彈性擴容的grpc-spring-cloud-provider負責提供gRPC服務,再用grpc-spring-cloud-consumer作為服務消費者來呼叫gRPC服務,服務提供者和消費者通過grpc-springboot-cloud-lib模組來完成介面約定。

一 專案結構

1 專案結構

根專案(com.linshen:grpc-springboot-cloud:1.0-SNAPSHOT)下有4個子模組:

  • grpc-eureka-server:Eureka伺服器
  • grpc-springboot-cloud-lib:gRPC介面,包含原始proto檔案,並負責將其轉換為java程式碼
  • grpc-spring-cloud-provider:Eureka客戶端,同時也是gRPC服務提供者
  • grpc-spring-cloud-consumer:Eureka客戶端,同時也是gRPC服務消費者

2 模組功能

  • 相互關係
    根專案負責依賴版本管理,通過grpc-eureka-server實現Eureka叢集,通過grpc-spring-cloud-provider負責提供gRPC服務,再用grpc-spring-cloud-consumer作為服務消費者來呼叫gRPC服務,服務提供者和消費者都作為Eureka客戶端註冊在Eureka叢集中,消費者通過服務名發現提供者並通過grpc-springboot-cloud-lib模組來完成介面約定實現RPC。
  • 對應MVC關係
    • grpc-springboot-cloud-lib就是service(介面,為提供實現)
    • grpc-spring-cloud-provider就相當於serviceImpl(service的實現類)
    • grpc-spring-cloud-consumer就相當於controller
  • 框架依賴
    • grpc-eureka-server:除了必要的eureka-server依賴外再依賴actuator方便監控
    • grpc-springboot-cloud-lib需要將proto檔案轉換成java類,故需依賴於protobuf-maven-plugin外掛,另外還需要io.grpc下的grpc-all,否則生成的java類會提示缺少依賴
    • grpc-spring-cloud-provider 要註冊到eureka服務中心,需要web依賴,否則會報錯
    • grpc-spring-cloud-consumer 基本和provider一樣

二 專案搭建

0 編寫根專案pom檔案

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.linshen</groupId>
    <artifactId>grpc-springboot-cloud</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>

    <modules>
        <module>grpc-springboot-cloud-lib</module>
        <module>grpc-eureka-server</module>
        <module>grpc-spring-cloud-provider</module>
        <module>grpc-spring-cloud-consumer</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-boot.version>${parent.version}</spring-boot.version>
        <net-devh-grpc.version>2.0.1.RELEASE</net-devh-grpc.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--公共grpc模組-->
            <dependency>
                <groupId>com.linshen</groupId>
                <artifactId>grpc-springboot-cloud-lib</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!--核心grpc-spring-boot依賴-->
            <dependency>
                <groupId>net.devh</groupId>
                <artifactId>grpc-client-spring-boot-starter</artifactId>
                <version>${net-devh-grpc.version}</version>
            </dependency>
            <dependency>
                <groupId>net.devh</groupId>
                <artifactId>grpc-server-spring-boot-starter</artifactId>
                <version>${net-devh-grpc.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

1 建立grpc-springboot-cloud-lib模組

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>grpc-springboot-cloud</artifactId>
        <groupId>com.linshen</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>grpc-springboot-cloud-lib</artifactId>
    <packaging>jar</packaging>

    <properties>
        <os.plugin.version>1.6.0</os.plugin.version>
        <grpc.version>1.15.1</grpc.version>
        <protoc.version>3.6.1</protoc.version>
        <protobuf.plugin.version>0.6.1</protobuf.plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>${grpc.version}</version>
        </dependency>
    </dependencies>

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>${os.plugin.version}</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>${protobuf.plugin.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                    <!--預設值-->
                    <protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
                    <!--預設值-->
                    <!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
                    <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                    <!--設定是否在生成java檔案之前清空outputDirectory的檔案,預設值為true,設定為false時也會覆蓋同名檔案-->
                    <clearOutputDirectory>false</clearOutputDirectory>
                    <!--更多配置資訊可以檢視https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html-->
                </configuration>
                <executions>
                    <execution>
                        <!--在執行mvn compile的時候會執行以下操作-->
                        <phase>compile</phase>
                        <goals>
                            <!--生成OuterClass類-->
                            <goal>compile</goal>
                            <!--生成Grpc類-->
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2 建立grpc-eureka-server模組

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>grpc-eureka-server</artifactId>
    <packaging>jar</packaging>

    <name>grpc-eureka-server</name>

    <parent>
        <artifactId>grpc-springboot-cloud</artifactId>
        <groupId>com.linshen</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3 建立grpc-spring-cloud-provider模組

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>grpc-spring-cloud-provider</artifactId>
    <packaging>jar</packaging>

    <name>grpc-spring-cloud-provider</name>

    <parent>
        <artifactId>grpc-springboot-cloud</artifactId>
        <groupId>com.linshen</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>com.linshen</groupId>
            <artifactId>grpc-springboot-cloud-lib</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3 建立grpc-spring-cloud-consumer模組

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>grpc-spring-cloud-consumer</artifactId>
    <packaging>jar</packaging>

    <name>grpc-spring-cloud-consumer</name>

    <parent>
        <artifactId>grpc-springboot-cloud</artifactId>
        <groupId>com.linshen</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>com.linshen</groupId>
            <artifactId>grpc-springboot-cloud-lib</artifactId>
        </dependency