gRPC 封装了一个非常好用的Utils ~

前言

最近一直在用gRPC做服务间的通讯,目前针对于java来说市面上主要的通讯方式还是http,对于gRPC的生态还不太成熟,能实现通讯方式就已经很不错了,至于说还给你封装好完整的gRPC工具类就根本没有好用的。所以为了解决这一问题,我自己搞了一个实现发送gRPC的Util。

如果你不知道如何在SpringBoot中集成gRPC的话,请参考这篇:

手把手教你 SpringBoot 如何集成 gRPC 实现服务间通讯 ~ - 掘金 (juejin.cn)

废话不多说,直接上代码

通道工具类:

java 复制代码
public class ManagedChannelUtils {

    /**
     * 初始化通道 ManagedChannel 直接就把需要配置中心的地址 端口号写死在代码中。
     *
     * 为什么直接把配置写死在代码中,因为application.yml已经不存在了,所以需要将固定连接的配置写死在代码中
     * 我在想是不是还有其他方法来记载这些固定的配置,也可以实现动态加载配置的效果。
     *
     * 每句的注释:
     * forAddress() 指定 gRPC 服务端的主机和端口
     * usePlaintext() 使用明文传输,实际环境建议使用 TLS
     * enableRetry() 启用 gRPC 的重试机制
     * maxRetryAttempts() 配置最大重试次数5
     * keepAliveTime() 保持活动连接的时间 5分钟
     *
     * @return
     */
    private static ManagedChannel initClientServe(String url, String port) {
        return ManagedChannelBuilder
                .forAddress(url, Integer.parseInt(port))
                .usePlaintext()
                .enableRetry()
                .maxRetryAttempts(5)
                .keepAliveTime(5, TimeUnit.SECONDS)
                .build();
    }

    /**
     * 获取配置好的通道,并在使用完毕后自动关闭
     *
     * @return
     */
    public static void runWithManagedChannel(String url, String port, ChannelConsumer consumer) {
        try (ManagedChannelWrapper channelWrapper = new ManagedChannelWrapper(initClientServe(url, port))) {
            ManagedChannel channel = channelWrapper.getChannel();
            consumer.accept(channel);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 包装类,实现 AutoCloseable 接口
     */
    public static class ManagedChannelWrapper implements AutoCloseable {
        private final ManagedChannel channel;

        public ManagedChannelWrapper(ManagedChannel channel) {
            this.channel = channel;
        }

        @Override
        public void close() {
            if (channel != null && !channel.isShutdown()) {
                channel.shutdown();
            }
        }

        public ManagedChannel getChannel() {
            return channel;
        }
    }

    /**
     * 函数式接口,用于接收 ManagedChannel 并执行相关操作
     */
    @FunctionalInterface
    public interface ChannelConsumer {
        void accept(ManagedChannel channel) throws Exception;
    }
    
}

使用:

ini 复制代码
ManagedChannelUtils.runWithManagedChannel(regiserveUrl, regiservePort, channel -> {
        PullConfigServiceGrpc.PullConfigServiceBlockingStub pullConfigServiceBlockingStub = PullConfigServiceGrpc.newBlockingStub(channel);

        /**
         * 调用
         */
        PullConfigResponse response = pullConfigServiceBlockingStub.getConfigByTag(PullConfigRequest
                .newBuilder()
                .setStr("user")
                .build());
        });

Utils的好处

  1. 封装连接细节: 通过提供 initClientServe 方法,将 gRPC 客户端连接的初始化细节封装在单独的方法中。这样,使用者只需调用 runWithManagedChannel 方法,而不必关心连接的具体初始化过程,使代码更简洁。
  2. 自动关闭连接: 利用 ManagedChannelWrapper 类实现了 AutoCloseable 接口,确保 ManagedChannel 在使用完毕后会自动关闭,防止连接泄漏。这种自动关闭的机制通过 try-with-resources 语句在使用 runWithManagedChannel 方法时得以体现,提高了代码的健壮性。
  3. 异常处理: ChannelConsumer 函数式接口声明了可能抛出异常的 accept 方法,使得连接的使用者可以在连接操作中处理可能出现的异常。这样的设计使代码更加健壮,同时允许使用者自定义异常处理逻辑。
  4. 灵活性: 使用者可以通过实现 ChannelConsumer 接口来执行各种连接操作,从而实现更大的灵活性。这种设计允许在接口中定义不同的连接操作,根据实际需要执行相应的逻辑。
  5. 参数配置: initClientServe 方法中提供了连接参数的配置,包括 gRPC 服务端的主机和端口、明文传输与否、重试机制等,使得工具类更具通用性,可根据具体需求进行配置。

总结

一定要多思考,如果人永远待在舒适圈的话,人永远不会成长。共勉

觉得作者写的不错的,值得你们借鉴的话,就请点一个免费的赞吧!这个对我来说真的很重要。૮(˶ᵔ ᵕ ᵔ˶)ა

相关推荐
爱吃羊的老虎7 小时前
【JAVA】python转java:Spring Boot 入门
java·spring boot·python
_qingche8 小时前
H2 数据库到 MySQL 数据迁移
java·数据库·spring boot·mysql·spring·重构·kotlin
码语智行11 小时前
系统启动时初始化数据功能分析
java·spring boot
invicinble11 小时前
推荐一下,遇到的几本比较好的书
spring boot
二营长111 小时前
后端请求https协议接口地址报错
网络协议·http·https
憧憬成为java架构高手的小白12 小时前
git工作流程简化版
java·spring boot·git
YDS82913 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— 动态决策策略的接口对接
java·spring boot·ai·agent·spring ai·deepseek
淘源码A14 小时前
专科医院云HIS系统源码:技术栈包括SpringBoot、Angular、MySQL等
spring boot·后端·源码·云his·医院信息系统·医院his系统
小马爱打代码14 小时前
基于 SpringBoot 的微服务文件上传下载组件设计与实现
spring boot·后端