Java-gRPC-Consul整合

Java-gRPC-Consul整合

一、整合consul

工程搭建

  1. 使用springboot自带的consul-starter
        <dependency> 
            <groupId>org.springframework.cloud</groupId> 
            <artifactId>spring-cloud-starter-consul-discovery</artifactId> 
        </dependency> 
        <dependency> 
            <groupId>org.springframework.cloud</groupId> 
            <artifactId>spring-cloud-starter-consul-config</artifactId> 
        </dependency>
  1. 在工程配置目录下创建bootstrap.yml
#这里是自定义的consul配置
consul:
  cluster: dc1
  index: 2
#spring的
spring:
  application:
    name: hall #项目名or服务名or应用名
  profiles:
    active: zwb #启用哪个配置文件
  cloud:
    consul:
      host: 127.0.0.1 #consul地址
      port: 2000
      discovery:
        tags: ${consul.cluster}, ${consul.index} #一些自定义的tag
        metadata:    #一些自定义的meta
          cluster: ${consul.cluster}
          index: ${consul.index}
        service-name: ${spring.application.name} #服务名
        prefer-ip-address: true #表示注册时使用ip而不是hostname
        instance-id:  ${consul.cluster}:${spring.application.name}:${consul.index} #实例id
        register: true #配置服务注册
        deregister: true #服务停止时取消注册
        health-check-critical-timeout: 30s  #健康检查失败多长时间取消注册
      config:
        enabled: true # 启用配置中心
        prefix: config #读取consul配置中心的哪个文件夹
        format: YAML # 表示consul上面文件的格式 有四种 YAML PROPERTIES KEY-VALUE FILES
        data-key: zwb #表示consul上面的KEY值(或者说文件的名字) 默认是data
        watch:
          delay: 60000 #watch间隔

注意:

这里springcould-consul默认的watch配置文件的时间间隔是1s,我改成的60s

springcould-consul默认的拉取更新健康服务列表的间隔是30s,要改自行修改配置

  1. 启动类上添加@EnableDiscoveryClient注解

工程到这里就算搭建完毕了

consul上的配置文件路径

在这里插入图片描述

更正一下:应该是对应spring.application.name

二、整合grpc

这里打算使用grpc-spring-boot-starter , 虽然不是springboot官方的,但是使用还是比较方便

父工程依赖管理

<properties>
    <protobuf.version>3.5.0</protobuf.version>
    <grpc.version>1.23.0</grpc.version>
    <guava.version>20.0</guava.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!--grpc-spring相关-->
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-spring-boot-starter</artifactId>
            <version>2.4.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-client-spring-boot-starter</artifactId>
            <version>2.4.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <version>2.4.0.RELEASE</version>
        </dependency>
        <!--grpc包-->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>${grpc.version}</version>
        </dependency>
        <!--proto包-->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>${protobuf.version}</version>
        </dependency>
        <!--guava包-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

这里注意:在比较新的guava版本里面已经移除掉了com.google.guava这个包,但是不知道在哪个jar依赖了这个东西,就会报找不到这个jar包的问题。

解决办法:这里选择grpc 的版本为1.23.0,guava的版本为20.0是没有问题的

message工程

导入依赖

msg工程需要导入io.grpc:grpc-all包,build下需要加入编译proto文件的插件。

<dependencies>
    <!--protobuf-->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
    </dependency>
    <!--grpc-->
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-all</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.5.0</version>
            <configuration>
                <protocArtifact>com.google.protobuf:protoc:3.6.0:exe:${os.detected.classifier}</protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.6.0:exe:${os.detected.classifier}</pluginArtifact>
                <outputDirectory>${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.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>6</source>
                <target>6</target>
            </configuration>
        </plugin>
    </plugins>
</build>
proto格式
syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.demo.lib";  //包名
option java_outer_classname = "HelloWorld";     //输出类名

//接口请求入参
message HelloRequest{
    string request = 1;
}
//接口返回出参
message HelloResponse{
    string response = 1;
}
//定义接口
service HelloService{
    //一个简单的rpc
    rpc HelloWorld(HelloRequest) returns (HelloResponse){}
    //一个服务器端流式rpc
    rpc HelloWorldServerStream(HelloRequest) returns (stream HelloResponse){}
    //一个客户端流式rpc
    rpc HelloWorldClientStream(stream HelloRequest) returns (HelloResponse){}
    //一个客户端和服务器端双向流式rpc
    rpc HelloWorldClientAndServerStream(stream HelloRequest) returns (stream HelloResponse){}
}

请注意,这里的proto协议使用的是proto3

相比之前的文件增加了如下部分,这个service 块是用于定义接口

//定义接口
service HelloService{
    //一个简单的rpc
    rpc HelloWorld(HelloRequest) returns (HelloResponse){}
    //一个服务器端流式rpc
    rpc HelloWorldServerStream(HelloRequest) returns (stream HelloResponse){}
    //一个客户端流式rpc
    rpc HelloWorldClientStream(stream HelloRequest) returns (HelloResponse){}
    //一个客户端和服务器端双向流式rpc
    rpc HelloWorldClientAndServerStream(stream HelloRequest) returns (stream HelloResponse){}
}
生成java文件

因为我们已经使用了maven插件,所以不需要像之前那样手动使用命令生成

只需要点击install就可以自动生成代码

在这里插入图片描述

服务提供者工程

添加依赖
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
</dependency>

如果既是服务提供者,又是调用者,使用下面的依赖

<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-spring-boot-starter</artifactId>
</dependency>
配置yml

在yml里面添加配置

grpc:
  server:
    port: 9999 #rpc端口
编写service类

这个类就是对应proto的HelloService实现

package com.demo;

import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import com.demo.lib.HelloServiceGrpc;
import com.demo.lib.HelloWorld;

@GrpcService   //标记这是一个rpc服务
public class HelloWorldService extends HelloServiceGrpc.HelloServiceImplBase {

    
    @Override
    public void helloWorld(HelloWorld.HelloRequest request, StreamObserver<HelloWorld.HelloResponse> responseObserver) {
        //构建一个返回消息并发送
        HelloWorld.HelloResponse.Builder builder = HelloWorld.HelloResponse.newBuilder();
        builder.setResponse("1");
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }
    

}

服务调用端工程

添加依赖

<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-client-spring-boot-starter</artifactId>
</dependency>
配置yml
grpc:
  client:
    hello-world-server: #对应的服务名称
      enableKeepAlive: true #获取是否启用keepAlive。
      keepAliveWithoutCalls: true #获取当连接上没有未完成的RPC时是否执行keepAlive。
      negotiationType: plaintext #获取要在连接上使用的协仪类型。

注意:这里的negotiationType,如果服务器调用者双方都没有使用SL协议,这里就必须选择plaintext类型

编写service类
package com.demo.service;

import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
import proto.HelloServiceGrpc;
import proto.HelloWorld;

@Service
public class UserClientService {

    @GrpcClient("hello-world-server")    //微服务名称,就是yml里面的spring.application.name
    private HelloServiceGrpc.HelloServiceBlockingStub stub;   //对应HelloService


    public String invokeHelloWorld() {
        //构建请求消息
        HelloWorld.HelloRequest build = HelloWorld.HelloRequest.newBuilder().setRequest("1").build();
        //调用方法
        HelloWorld.HelloResponse helloResponse = stub.helloWorld(build);
        return helloResponse.getResponse();
    }
}

以上就是java工程的整合

三、调用go工程

java工程和go工程都采用微服务方式注册到consul上

在这里插入图片描述
在这里插入图片描述

注意:服务提供方的tags里面需要带上gRPC.port=9999这个标记,用于表明tcp的端口,这里spring-grpc会帮我们自动生成,go工程就需要手动设置

然后go服务调用java服务也是需要通过gRPC.port来获取tpc端口进行调用

回答: 错误提示中提到了一个未知的标志"--go-grpc",这可能是因为你的命令中使用了错误的标志。正确的命令应该是"protoc --go-grpc_out=. --go-grpc_opt=paths=source_relative user.proto"。请注意,标志"--go-grpc_out"和"--go-grpc_opt"之间应该有一个下划线"_",而不是一个空格。另外,你还需要确保你已经安装了正确的go协议编译器插件。你可以使用以下命令重新安装插件:"$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest"和"$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest"。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [使用protoc编译grpc问题记录(--go_out: protoc-gen-go: plugins are not supported;)](https://blog.csdn.net/m0_57777971/article/details/127864341)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [protoc-gen-go: plugin are not supported;use ‘protoc --go-grpc_out=...‘ to generate gRPC 的问题](https://blog.csdn.net/weixin_42875684/article/details/125652895)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值