【干货】springcloud-nacos-grpc框架 实战

一.环境准备

java版本:jdk16

linux虚拟机(部署nacos)

nacos版本:2.0.3

开发工具:idea

二.新建父项目

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.zjlab.grpc</groupId>
    <artifactId>grpcdemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    
    <modules>
        <module>grpc-api</module>
        <module>user-server</module>
        <module>client</module>
    </modules>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/>
    </parent>
    
    <properties>
        <alibaba.version>2021.1</alibaba.version>
        <cloud.version>2020.0.4</cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.4</version>
            </dependency
            <dependency>
                <groupId>net.devh</groupId>
                <artifactId>grpc-client-spring-boot-starter</artifactId>
                <version>2.10.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>net.devh</groupId>
                <artifactId>grpc-server-spring-boot-starter</artifactId>
                <version>2.10.1.RELEASE</version>
            </dependency>
        </dependencies>

    </dependencyManagement>


</project>

可以看到分布式项目中主要分为三个模块

1.grpc-api 提供grpc能力,主要用来将proto生成相应的java代码

2.user-server模块 用户模块,主要提供grpc-server能力

3.client模块 对外提供http接口,调用grpc-server,此模块作为grpc-client

注意:lombok的版本要在1.18.20以上,否则编译报错(踩了坑)

三.新建grpc-api项目

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">
    <parent>
        <groupId>com.zjlab.grpc</groupId>
        <artifactId>grpcdemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zjlab.grpc</groupId>
    <artifactId>grpc-api</artifactId>

    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
        </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.34.1:exe:${os.detected.classifier}</pluginArtifact>
                    <!--设置grpc生成代码到指定路径-->
                    <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                    <!--生成代码前是否清空目录-->
                    <clearOutputDirectory>false</clearOutputDirectory>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- 设置多个源文件夹 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <!-- 添加主源码目录 -->
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.basedir}/src/main/gen</source>
                                <source>${project.basedir}/src/main/java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
</project>

编写proto:

syntax = "proto3";

option java_multiple_files = true;


package com.zjlab.grpc.proto;

// 问好类
service Greeter {
  // 问候方法
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// 请求类
message HelloRequest {
  string name = 1;
}

// 回应类
message HelloReply {
  string message = 1;
}

指定了将proto编译成java代码的输出路径和proto中的package相同

接下来就是安装proto的idea插件:

执行完compile命令即可生成文件

 

 

注意:如果编译报以下错误(mac电脑m1芯片,又是踩坑):

在这里插入图片描述

 需要在maven里做如下配置

 <profile>
  <id>apple-silicon</id>
  <properties>
    <os.detected.classifier>osx-x86_64</os.detected.classifier>
  </properties>
</profile>
<activeProfiles>
      <activeProfile>apple-silicon</activeProfile>
    <!-- 与 上面的profile 中的id对应 -->
</activeProfiles>

四.新建user-server项目

结构:

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">
    <parent>
        <groupId>com.zjlab.grpc</groupId>
        <artifactId>grpcdemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>user-server</artifactId>
    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>com.zjlab.grpc</groupId>
            <artifactId>grpc-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

GreetImpl:
package com.zjlab.grpc.user.impl;

import com.zjlab.grpc.proto.GreeterGrpc;
import com.zjlab.grpc.proto.HelloReply;
import com.zjlab.grpc.proto.HelloRequest;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

/**
 * @author bing.bai
 * @create 2022/6/28
 */
@GrpcService
public class GreetImpl extends GreeterGrpc.GreeterImplBase {

    @Override
    public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
        HelloReply reply = HelloReply.newBuilder().setMessage(("Hello " + req.getName())).build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
        System.out.println("Message from gRPC-Client:" + req.getName());
    }


}

ServerApplication:
package com.zjlab.grpc.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author bing.bai
 * @create 2022/6/28
 */
@SpringBootApplication
public class ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerApplication.class, args);
    }

}

yml:

grpc:
  client:
    GLOBAL:
      negotiation-type: plaintext
      enable-keep-alive: true
      keep-alive-without-calls: true
  server:
    port: 7777
server:
  port: 8081
spring:
  application:
    name: springcloud-nacos-grpc-server
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: 10.101.116.3:8999
        enabled: true
        namespace: grpc
      config:
        enabled: false


五.新建client项目

结构:

 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">
    <parent>
        <artifactId>grpcdemo</artifactId>
        <groupId>com.zjlab.grpc</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>client</artifactId>

    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${alibaba.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${alibaba.version}</version>
        </dependency>
        <dependency>
            <groupId>com.zjlab.grpc</groupId>
            <artifactId>grpc-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>

controller:

package com.zjlab.client.controller;

import com.zjlab.grpc.proto.GreeterGrpc;
import com.zjlab.grpc.proto.HelloReply;
import com.zjlab.grpc.proto.HelloRequest;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author bing.bai
 * @create 2022/6/28
 */
@RestController
@Slf4j
public class GreetController {

    @GrpcClient("springcloud-nacos-grpc-server")
    GreeterGrpc.GreeterBlockingStub greeterStub;


    @GetMapping(value="greet")
    public String greet( String str)  {
        HelloReply helloReply = null;
        System.out.println(str);
        try {
            helloReply = greeterStub.sayHello(
                    HelloRequest.newBuilder().setName(str).build()
            );
            return helloReply.toString();
        } catch (Exception e) {
            log.info("ex{}",e);
        }
        return helloReply.toString();
    }
}

注意:最好不要在controller里写业务代码,这里是偷懒

ClientApplication:
package com.zjlab.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author bing.bai
 * @create 2022/6/28
 */
@SpringBootApplication
public class ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}

yml:

grpc:
  server:
    port: 7778
  client:
    springcloud-nacos-grpc-server:
      negotiation-type: plaintext
      enable-keep-alive: true
      keep-alive-without-calls: true

server:
  port: 8089
spring:
  application:
    name: springcloud-nacos-grpc-client
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: 10.101.116.3:8999
        namespace: grpc
      config:
        enabled: false


六.调试

启动user-server和client服务

可以看到nacos上注册了这两个服务

接下来调用接口:http://localhost:8089/greet?str=1

 

服务端打印日志:

 

困惑:不知道为什么 negotiation-type: plaintext 这个配置用GLOBAL不生效,一定要指定服务名

猜你喜欢

转载自blog.csdn.net/babing18258840900/article/details/125519885