[Dry goods] springcloud-nacos-grpc framework combat

1. Environment preparation

Java version: jdk16

Linux virtual machine (deploy nacos)

Nacos version: 2.0.3

Development tools: idea

2. New parent project

pom file:

<?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>

It can be seen that the distributed project is mainly divided into three modules

1.grpc-api provides grpc capability, which is mainly used to generate corresponding java code from proto

2. user-server module The user module mainly provides grpc-server capabilities

3. The client module provides an http interface to the outside world, calls grpc-server, and this module acts as grpc-client

Note: The version of lombok must be above 1.18.20, otherwise the compilation error will be reported (stepping on the pit)

3. Create a new grpc-api project

pom file:

<?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>

Write the 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;
}

Specifies that the output path for compiling proto into java code is the same as the package in proto

The next step is to install the proto idea plugin:

 

After executing the compile command, the file can be generated

 

 

 

Note: If the compilation reports the following error (the m1 chip of the mac computer is stepping on the pit again):

insert image description here

 Need to do the following configuration in 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>

4. Create a new user-server project

structure:

 

pom file:

<?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


5. New client project

structure:

 pom file:

<?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();
    }
}

Note: It is best not to write business code in the controller, this is lazy

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


6. Debugging

Start user-server and client services

You can see that these two services are registered on nacos

Next call the interface: http://localhost:8089/greet?str=1

 

The server prints the log:

 

 

Confusion: I don’t know why the negotiation-type: plaintext configuration does not take effect with GLOBAL, and the service name must be specified

Guess you like

Origin blog.csdn.net/babing18258840900/article/details/125519885