Grpc项目集成到java方式调用实践

news2024/9/29 11:32:16

背景:由于项目要对接到grcp 的框架,然后需要对接老外的东西,还有签名和证书刚开始没有接触其实有点懵逼。

gRPC 是由 Google 开发的高性能、开源的远程过程调用(RPC)框架。它建立在 HTTP/2 协议之上,使用 Protocol Buffers 作为其接口定义语言(IDL)。gRPC 被设计为可跨多种环境(包括客户端、服务器和各种语言)使用,支持多种编程语言,如 C、C++、Java、Go、Python、Ruby、Node.js 等。

gRPC 具有以下特点:

  1. 性能高效:gRPC 使用基于 HTTP/2 的传输协议,能够复用连接、多路复用请求、支持头部压缩等特性,从而提高了性能。

  2. 跨语言支持:gRPC 支持多种编程语言,使得客户端和服务器可以使用不同的编程语言实现,并且它们之间的通信依然高效。

  3. IDL 和自动代码生成:gRPC 使用 Protocol Buffers 作为接口定义语言(IDL),定义服务接口和消息格式,并提供了自动生成客户端和服务器代码的工具。

  4. 多种调用方式:gRPC 支持四种调用方式,包括简单 RPC、服务器流式 RPC、客户端流式 RPC 和双向流式 RPC,可以根据业务需求选择合适的调用方式。

  5. 安全性:gRPC 支持 TLS/SSL 加密传输,保障通信的安全性。

  6. 插件机制:gRPC 提供了插件机制,可以扩展其功能,例如添加认证、日志、监控等功能。

总的来说,gRPC 是一个强大的远程过程调用框架,适用于构建分布式系统中的各种服务,并且在性能、跨语言支持和安全性方面具有很多优势。

一,开发工具集成:

安装指定插件,网上说还要Protobuf buffer 安装,但是我用的idea2018的版本搜索不到,这个不是必须的,可以不用。

二 protobuf编译器一定要安装配置一个: Releases · protocolbuffers/protobuf · GitHub

三,安装好插件后就可以看的了这俩个就是生产java代码的。

四,grpc 的文件格式:

syntax = "proto3";

package c3_vanilla_app;

option java_package = "com.test.conncar.c3vanillaapp";
option java_outer_classname = "C3VanillaAppProtos";

import "google/protobuf/empty.proto";


message ExampleRequestMessage {
  string id = 1;
  int64 timestamp = 2;
  string message = 3;
}

message ExampleResponseMessage {
  string message = 1;
}

service ExampleService {
  rpc PostExampleMessages(ExampleRequestMessage) returns (ExampleResponseMessage) {}
}

生成出来的代码就是:

可以用命令生成,然后也可以用maven自动生成

pom加上这个插件就可以生产代码了:

 <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <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>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

完整的pom文件:

 <properties>
        <protoc.version>3.25.2</protoc.version>
        <grpc.version>1.61.1</grpc.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>${grpc.version}</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>${grpc.version}</version>

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

        </dependency>

        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.25.2</version> <!-- 或者与你的 protoc.version 相匹配的版本 -->
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
            <version>${grpc.version}</version>
        </dependency>
        <dependency>
            <!-- necessary for Java 9+ -->
            <groupId>org.apache.tomcat</groupId>
            <artifactId>annotations-api</artifactId>
            <version>6.0.53</version>
        </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:${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>
                </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.10.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jfrog.buildinfo</groupId>
                <artifactId>artifactory-maven-plugin</artifactId>
                <version>3.3.0</version>
                <inherited>false</inherited>
                <executions>
                    <execution>
                        <id>build-info</id>
                        <goals>
                            <goal>publish</goal>
                        </goals>
                        <configuration>
                            <artifactory>
                                <includeEnvVars>false</includeEnvVars>
                                <timeoutSec>60</timeoutSec>
                                <propertiesFile>publish.properties</propertiesFile>
                            </artifactory>
                            <publisher>
                                <contextUrl>${env.ARTIFACTORY_HOST_POM}</contextUrl>
                                <username>${env.ARTIFACTORY_CCAR_USER}</username>
                                <password>${env.ARTIFACTORY_CCAR_APIKEY}</password>
                                <excludePatterns>*-tests.jar</excludePatterns>
                                <repoKey>${CI_PROJECT_NAMESPACE}</repoKey>
                                <snapshotRepoKey>${CI_PROJECT_NAMESPACE}</snapshotRepoKey>
                            </publisher>
                            <buildInfo>
                                <buildName>${CI_PROJECT_NAME}</buildName>
                                <buildNumber>${CI_PIPELINE_ID}</buildNumber>
                                <buildUrl>${CI_PROJECT_URL}</buildUrl>
                            </buildInfo>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

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

        </plugins>
    </build>

生成的代码路径:

生成的代码,记得install的时候注释掉插件,然后进行install

然后本地写个client和sever就行了:

server:

package com.grpc.mistra.server;


import com.grpc.mistra.generate.MistraRequest;
import com.grpc.mistra.generate.MistraResponse;
import com.grpc.mistra.generate.MistraServiceGrpc;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

import java.io.IOException;

/**
 * Time: 14:46
 * Description:
 */
public class MistraServer {

    private int port = 8001;
    private Server server;

    private void start() throws IOException {
        server = ServerBuilder.forPort(port)
                .addService((BindableService) new MistraHelloWorldImpl())
                .build()
                .start();

        System.out.println("------------------- 服务端服务已开启,等待客户端访问 -------------------");

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {

                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                MistraServer.this.stop();
                System.err.println("*** server shut down");
            }
        });
    }

    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    private void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        final MistraServer server = new MistraServer();
        //启动服务
        server.start();
        //服务一直在线,不关闭
        server.blockUntilShutdown();
    }

    // 定义一个实现服务接口的类
    private class MistraHelloWorldImpl extends MistraServiceGrpc.MistraServiceImplBase {

        @Override
        public void sayHello(MistraRequest mistraRequest, StreamObserver<MistraResponse> responseObserver) {
            // 具体其他丰富的业务实现代码
            System.err.println("server:" + mistraRequest.getName());
            MistraResponse reply = MistraResponse.newBuilder().setMessage(("响应信息: " + mistraRequest.getName())).build();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}

client:

package com.grpc.mistra.client;


import com.grpc.mistra.generate.MistraRequest;
import com.grpc.mistra.generate.MistraResponse;
import com.grpc.mistra.generate.MistraServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

import java.util.concurrent.TimeUnit;

/**
 * Time: 14:46
 * Description:
 */
public class MistraClient {

    private final ManagedChannel channel;
    private final MistraServiceGrpc.MistraServiceBlockingStub blockingStub;

    public MistraClient(String host, int port) {
        channel = ManagedChannelBuilder.forAddress(host, port)
                .usePlaintext(true)
                .build();

        blockingStub = MistraServiceGrpc.newBlockingStub(channel);
    }

    public void shutdown() throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }

    public void greet(String name) {
        MistraRequest request = MistraRequest.newBuilder().setName(name).build();
        MistraResponse response = blockingStub.sayHello(request);
        System.out.println(response.getMessage());

    }

    public static void main(String[] args) throws InterruptedException {
        MistraClient client = new MistraClient("127.0.0.1", 8001);
        System.out.println("-------------------客户端开始访问请求-------------------");
        for (int i = 0; i < 10; i++) {
            client.greet("你若想生存,绝处也能缝生: " + i);
        }
    }
}

效果图:

grpc的调用类:

package com.grpc.mistra.generate;

import static io.grpc.MethodDescriptor.generateFullMethodName;
import static io.grpc.stub.ClientCalls.asyncUnaryCall;
import static io.grpc.stub.ClientCalls.blockingUnaryCall;
import static io.grpc.stub.ClientCalls.futureUnaryCall;
import static io.grpc.stub.ServerCalls.asyncUnaryCall;
import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;

/**
 * <pre>
 * 声明一个服务名称
 * </pre>
 */
@javax.annotation.Generated(
        value = "by gRPC proto compiler (version 1.11.0)",
        comments = "Source: helloworld.proto")
public final class MistraServiceGrpc {

    private MistraServiceGrpc() {
    }

    public static final String SERVICE_NAME = "mistra.MistraService";

    // Static method descriptors that strictly reflect the proto.
    @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
    @Deprecated // Use {@link #getSayHelloMethod()} instead.
    public static final io.grpc.MethodDescriptor<MistraRequest,
            MistraResponse> METHOD_SAY_HELLO = getSayHelloMethodHelper();

    private static volatile io.grpc.MethodDescriptor<MistraRequest,
            MistraResponse> getSayHelloMethod;

    @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
    public static io.grpc.MethodDescriptor<MistraRequest,
            MistraResponse> getSayHelloMethod() {
        return getSayHelloMethodHelper();
    }

    private static io.grpc.MethodDescriptor<MistraRequest,
            MistraResponse> getSayHelloMethodHelper() {
        io.grpc.MethodDescriptor<MistraRequest, MistraResponse> getSayHelloMethod;
        if ((getSayHelloMethod = MistraServiceGrpc.getSayHelloMethod) == null) {
            synchronized (MistraServiceGrpc.class) {
                if ((getSayHelloMethod = MistraServiceGrpc.getSayHelloMethod) == null) {
                    MistraServiceGrpc.getSayHelloMethod = getSayHelloMethod =
                            io.grpc.MethodDescriptor.<MistraRequest, MistraResponse>newBuilder()
                                    .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
                                    .setFullMethodName(generateFullMethodName(
                                            "mistra.MistraService", "SayHello"))
                                    .setSampledToLocalTracing(true)
                                    .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                                            MistraRequest.getDefaultInstance()))
                                    .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                                            MistraResponse.getDefaultInstance()))
                                    .setSchemaDescriptor(new MistraServiceMethodDescriptorSupplier("SayHello"))
                                    .build();
                }
            }
        }
        return getSayHelloMethod;
    }

    /**
     * Creates a new async stub that supports all call types for the service
     */
    public static MistraServiceStub newStub(io.grpc.Channel channel) {
        return new MistraServiceStub(channel);
    }

    /**
     * Creates a new blocking-style stub that supports unary and streaming output calls on the service
     */
    public static MistraServiceBlockingStub newBlockingStub(
            io.grpc.Channel channel) {
        return new MistraServiceBlockingStub(channel);
    }

    /**
     * Creates a new ListenableFuture-style stub that supports unary calls on the service
     */
    public static MistraServiceFutureStub newFutureStub(
            io.grpc.Channel channel) {
        return new MistraServiceFutureStub(channel);
    }

    /**
     * <pre>
     * 声明一个服务名称
     * </pre>
     */
    public static abstract class MistraServiceImplBase implements io.grpc.BindableService {

        /**
         * <pre>
         * 请求参数MistraRequest   响应参数MistraResponse
         * </pre>
         */
        public void sayHello(MistraRequest request,
                             io.grpc.stub.StreamObserver<MistraResponse> responseObserver) {
            asyncUnimplementedUnaryCall(getSayHelloMethodHelper(), responseObserver);
        }

        @Override
        public final io.grpc.ServerServiceDefinition bindService() {
            return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
                    .addMethod(
                            getSayHelloMethodHelper(),
                            asyncUnaryCall(
                                    new MethodHandlers<
                                            MistraRequest,
                                            MistraResponse>(
                                            this, METHODID_SAY_HELLO)))
                    .build();
        }
    }

    /**
     * <pre>
     * 声明一个服务名称
     * </pre>
     */
    public static final class MistraServiceStub extends io.grpc.stub.AbstractStub<MistraServiceStub> {
        private MistraServiceStub(io.grpc.Channel channel) {
            super(channel);
        }

        private MistraServiceStub(io.grpc.Channel channel,
                                  io.grpc.CallOptions callOptions) {
            super(channel, callOptions);
        }

        @Override
        protected MistraServiceStub build(io.grpc.Channel channel,
                                          io.grpc.CallOptions callOptions) {
            return new MistraServiceStub(channel, callOptions);
        }

        /**
         * <pre>
         * 请求参数MistraRequest   响应参数MistraResponse
         * </pre>
         */
        public void sayHello(MistraRequest request,
                             io.grpc.stub.StreamObserver<MistraResponse> responseObserver) {
            asyncUnaryCall(
                    getChannel().newCall(getSayHelloMethodHelper(), getCallOptions()), request, responseObserver);
        }
    }

    /**
     * <pre>
     * 声明一个服务名称
     * </pre>
     */
    public static final class MistraServiceBlockingStub extends io.grpc.stub.AbstractStub<MistraServiceBlockingStub> {
        private MistraServiceBlockingStub(io.grpc.Channel channel) {
            super(channel);
        }

        private MistraServiceBlockingStub(io.grpc.Channel channel,
                                          io.grpc.CallOptions callOptions) {
            super(channel, callOptions);
        }

        @Override
        protected MistraServiceBlockingStub build(io.grpc.Channel channel,
                                                  io.grpc.CallOptions callOptions) {
            return new MistraServiceBlockingStub(channel, callOptions);
        }

        /**
         * <pre>
         * 请求参数MistraRequest   响应参数MistraResponse
         * </pre>
         */
        public MistraResponse sayHello(MistraRequest request) {
            return blockingUnaryCall(
                    getChannel(), getSayHelloMethodHelper(), getCallOptions(), request);
        }
    }

    /**
     * <pre>
     * 声明一个服务名称
     * </pre>
     */
    public static final class MistraServiceFutureStub extends io.grpc.stub.AbstractStub<MistraServiceFutureStub> {
        private MistraServiceFutureStub(io.grpc.Channel channel) {
            super(channel);
        }

        private MistraServiceFutureStub(io.grpc.Channel channel,
                                        io.grpc.CallOptions callOptions) {
            super(channel, callOptions);
        }

        @Override
        protected MistraServiceFutureStub build(io.grpc.Channel channel,
                                                io.grpc.CallOptions callOptions) {
            return new MistraServiceFutureStub(channel, callOptions);
        }

        /**
         * <pre>
         * 请求参数MistraRequest   响应参数MistraResponse
         * </pre>
         */
        public com.google.common.util.concurrent.ListenableFuture<MistraResponse> sayHello(
                MistraRequest request) {
            return futureUnaryCall(
                    getChannel().newCall(getSayHelloMethodHelper(), getCallOptions()), request);
        }
    }

    private static final int METHODID_SAY_HELLO = 0;

    private static final class MethodHandlers<Req, Resp> implements
            io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
            io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
            io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
            io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
        private final MistraServiceImplBase serviceImpl;
        private final int methodId;

        MethodHandlers(MistraServiceImplBase serviceImpl, int methodId) {
            this.serviceImpl = serviceImpl;
            this.methodId = methodId;
        }

        @Override
        @SuppressWarnings("unchecked")
        public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
            switch (methodId) {
                case METHODID_SAY_HELLO:
                    serviceImpl.sayHello((MistraRequest) request,
                            (io.grpc.stub.StreamObserver<MistraResponse>) responseObserver);
                    break;
                default:
                    throw new AssertionError();
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public io.grpc.stub.StreamObserver<Req> invoke(
                io.grpc.stub.StreamObserver<Resp> responseObserver) {
            switch (methodId) {
                default:
                    throw new AssertionError();
            }
        }
    }

    private static abstract class MistraServiceBaseDescriptorSupplier
            implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
        MistraServiceBaseDescriptorSupplier() {
        }

        @Override
        public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
            return MistraProto.getDescriptor();
        }

        @Override
        public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
            return getFileDescriptor().findServiceByName("MistraService");
        }
    }

    private static final class MistraServiceFileDescriptorSupplier
            extends MistraServiceBaseDescriptorSupplier {
        MistraServiceFileDescriptorSupplier() {
        }
    }

    private static final class MistraServiceMethodDescriptorSupplier
            extends MistraServiceBaseDescriptorSupplier
            implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
        private final String methodName;

        MistraServiceMethodDescriptorSupplier(String methodName) {
            this.methodName = methodName;
        }

        @Override
        public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
            return getServiceDescriptor().findMethodByName(methodName);
        }
    }

    private static volatile io.grpc.ServiceDescriptor serviceDescriptor;

    public static io.grpc.ServiceDescriptor getServiceDescriptor() {
        io.grpc.ServiceDescriptor result = serviceDescriptor;
        if (result == null) {
            synchronized (MistraServiceGrpc.class) {
                result = serviceDescriptor;
                if (result == null) {
                    serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
                            .setSchemaDescriptor(new MistraServiceFileDescriptorSupplier())
                            .addMethod(getSayHelloMethodHelper())
                            .build();
                }
            }
        }
        return result;
    }
}

咋们就完成了grpc接入到java里面调用了本质上其实代码没有区别,小杨看了一下,他就是多了一些设计模式生产的代码,工厂构建等。 

 ————没有与生俱来的天赋,都是后天的努力拼搏(我是小杨,谢谢你的关注和支持)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1485601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL的一行数据是如何存储的?

目录 1.COMPACT 行格式长什么样&#xff1f; 例子1&#xff1a;用户设置了主键值&#xff0c;列都是not null的。(默认字符集是utf8mb4,在这种情况下&#xff0c;char(N)类型就不是定长的了&#xff09; 例子2&#xff1a;没有设置主键&#xff0c;也没有唯一索引&#xff0…

【间说八股】面试官:我看你这里用到了模板模式?你能不能说一下什么是模板模式

模板模式 行为模式&#xff1a;这类模式负责对象间的高效沟通和职责委派。 模板方法模式是一种行为设计模式&#xff0c; 它在超类中定义了一个算法的框架&#xff0c; 允许子类在不修改结构的情况下重写算法的特定步骤。 模板方法模式是一种行为设计模式&#xff0c;其核心思想…

【【C语言简单小题学习-1】】

实现九九乘法表 // 输出乘法口诀表 int main() {int i 0;int j 0;for (i 1; i < 9; i){for (j 1; j < i;j)printf("%d*%d%d ", i , j, i*j);printf("\n"); }return 0; }猜数字的游戏设计 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdi…

【STK】手把手教你利用STK进行仿真-STK软件基础02 STK系统的软件界面02 STK的主菜单

STK系统的菜单工具栏包含9个标准的下拉菜单&#xff0c;菜单项分别为“File”&#xff08;文件&#xff09;、“Edit”&#xff08;编辑&#xff09;、“Insert”&#xff08;插入&#xff09;、“View”&#xff08;查看&#xff09;、“Scenario”&#xff08;场景&#xff0…

文件操作和IO(2):Java中操作文件

目录 一、File的属性 二、File的构造方法 三、File的方法 四、代码示例 1、getName&#xff0c;getParent&#xff0c;getPath方法 2、getAbsolutePath&#xff0c;getCanonicalPath方法 3、exists&#xff0c;isDirectory&#xff0c;createNewFile方法 4、createNewF…

EtlCloud安装部署及简单应用

背景 最近碰到了一个数据同步的业务场景&#xff0c;客户要求生产环境的某些特定数据定时同步到指定的数据池中&#xff0c;并对数据池中的表名称有特殊要求&#xff0c;必须以t_xxxx_tablename的格式命名&#xff0c;其中xxxx为单位编号&#xff0c;tablename可以是应用中的表…

k8s资源管理之声明式管理方式

1 声明式管理方式 1.1 声明式管理方式支持的格式 JSON 格式&#xff1a;主要用于 api 接口之间消息的传递 YAML 格式&#xff1a;用于配置和管理&#xff0c;YAML 是一种简洁的非标记性语言&#xff0c;内容格式人性化&#xff0c;较易读 1.2 YAML 语法格式&#xff1a; ●…

Java网络通信UDP

目录 网络通信基础 UDP通信 服务器 1.想要使用UDP通信 要先打开DatagramSocket文件 端口号可以手动指定或系统随机分配 2.阻塞等待接收客户端数据&#xff1b;创建DatagramPacket接收客户端传来的数据 3.处理客户端传来的数据&#xff0c;并进行业务处理&#xff08;这里…

雷电将军部分技能AOE范围测试

简单说一下&#xff0c;以往的AOE范围数据大部分来自Dim提供的拆包文件或泄露的GM端控制台显示的距离数据&#xff0c;如《AOE范围学》中的数据&#xff0c;然而米哈游自1.6版本及以后未再公开泄露过GM端&#xff0c;因为一些原因Dim也没再更新拆包文件中角色技能参数相关的部分…

二路归并排序的算法设计和复杂度分析and周记

数据结构实验报告 实验目的: 通过本次实验&#xff0c;了解算法复杂度的分析方法&#xff0c;掌握递归算法时间复杂度的递推计算过程。 实验内容&#xff1a; 二路归并排序的算法设计和复杂度分析 实验过程&#xff1a; 1.算法设计 第一步&#xff0c;首先要将数组进行…

Vue3快速上手(十五)Vue3路由器使用和简单路由切换

一、路由的概念 1.1 路由及路由器 路由器&#xff1a;通常指的是我们家里上网用的路由器&#xff0c;通过网络接口&#xff0c;一根网线&#xff0c;链接至电脑&#xff0c;一般我们的电脑就可以上网了&#xff0c;多个网络接口&#xff0c;链接多个电脑&#xff0c;形成一组…

图神经网络实战——图论基础

图神经网络实战——图论基础 0. 前言1. 图属性1.1 有向图和无向图1.2 加权图和非加权图1.3 连通图和非连通图1.4 其它图类型 2. 图概念2.1 基本对象2.2 图的度量指标2.2 邻接矩阵表示法 3. 图算法3.1 广度优先搜索3.2 深度优先搜索 小结系列链接 0. 前言 图论 (Graph theory) …

springboot-基础-eclipse集成mybatis+使用方法+排错

备份笔记。所有代码都是2019年测试通过的&#xff0c;如有问题请自行搜索解决&#xff01; 目录 集成mybatis安装mybatis的jar包安装插件&#xff1a;mybatis-generator安装方法生成方法报错&#xff1a;java.lang.RuntimeException: Exception getting JDBC Driver mybatis注解…

深入了解Kafka的文件存储原理

Kafka简介 Kafka最初由Linkedin公司开发的分布式、分区的、多副本的、多订阅者的消息系统。它提供了类似于JMS的特性&#xff0c;但是在设计实现上完全不同&#xff0c;此外它并不是JMS规范的实现。kafka对消息保存是根据Topic进行归类&#xff0c;发送消息者称为Producer&…

【鸿蒙开发】第十五章 ArkTS基础类库-并发

1 简述 并发是指在同一时间段内&#xff0c;能够处理多个任务的能力。为了提升应用的响应速度与帧率&#xff0c;以及防止耗时任务对主线程的干扰&#xff0c;OpenHarmony系统提供了异步并发和多线程并发两种处理策略&#xff0c;ArkTS支持异步并发和多线程并发。并发能力在多…

部署bpmn项目实现activiti流程图的在线绘制

本教程基于centos7.6环境中完成 github开源项目: https://github.com/Yiuman/bpmn-vue-activiti软件&#xff1a;git、docker 1. 下载源代码 git clone https://github.com/Yiuman/bpmn-vue-activiti.git2. 修改Dockerfile文件 声明基础镜像&#xff0c;将项目打包&#xff…

LeetCode---386周赛

题目列表 3046. 分割数组 3047. 求交集区域内的最大正方形面积 3048. 标记所有下标的最早秒数 I 3049. 标记所有下标的最早秒数 II 一、分割数组 这题简单的思维题&#xff0c;要想将数组分为两个数组&#xff0c;且分出的两个数组中数字不会重复&#xff0c;很显然一个数…

AI又进化了

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 一直想做但没做的板块&#xff0c;整理一段时间内AI领域的前沿动态&#xff08;符合大多粉丝研究领域/感兴趣方向&#xff09;&#xff0c;了解了解外面世界发展成啥样了&#xff0c;一起看看吧~ 谷歌…

网关kong记录接口处理请求和响应插件 tcp-log-with-body的安装

tcp-log-with-body 介绍 Kong的tcp-log-with-body插件是一个高效的工具&#xff0c;它能够转发Kong处理的请求和响应。这个插件非常适用于需要详细记录API请求和响应信息的情景&#xff0c;尤其是在调试和排查问题时。 软件环境说明 kong version 2.1.4 - 2.8.3 [可用亲测]C…

8、Redis-Jedis、Lettuce和一个Demo

目录 一、Jedis 二、Lettuce 三、一个Demo Java集成Redis主要有3个方案&#xff1a;Jedis、Lettuce和Redisson。 其中&#xff0c;Jedis、Lettuce侧重于单例Redis&#xff0c;而Redisson侧重于分布式服务。 项目资源在文末 一、Jedis 1、创建SpringBoot项目 2、引入依赖 …