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 服务端的主机和端口、明文传输与否、重试机制等,使得工具类更具通用性,可根据具体需求进行配置。

总结

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

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

相关推荐
Goodbye2 天前
大模型无状态架构:从 HTTP 协议到 Harness AI 工程的深度解析
http
java小白小3 天前
SpringBoot(01): 初识SpringBoot,从Spring的痛点说起
spring boot
用户3169353811833 天前
如何从零编写一个 Spring Boot Starter
spring boot
程序员晓琪4 天前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly4 天前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
用户3521802454755 天前
🎆从 Prompt 到 Skill:让 Spring AI Agent 学会"装新技能"
人工智能·spring boot·ai编程
用户3521802454758 天前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
昵称为空C8 天前
手撸一个动态 SQL 执行引擎:不重启服务,在线增删改查任意数据库
spring boot·后端
霜落长河8 天前
抛弃TCP改用UDP,HTTP3怎么了?
http