GCP PubSub Java订阅程序Unix环境下因GLIBC版本兼容问题启动失败
问题详情
环境信息
- 操作系统:
Linux 3.0.101-108.108-default x86_64 - Java版本:
Java(TM) SE Runtime Environment (build 1.8.0_66-b17) - 系统GLIBC版本:2.11.3
复现步骤
- 基于GCP官方文档编写简单的PubSub订阅者代码,打包为Spring Boot可执行Jar
- 将Jar直接部署到上述Unix服务器运行,未修改服务器软件配置
问题现象
Jar在Windows环境运行正常,但在Unix环境启动时抛出UnsatisfiedLinkError,netty-tcnative、conscrypt等本地库加载失败,日志提示需要GLIBC_2.14版本,与当前系统的2.11.3不兼容。
解决办法
1. 调整netty-tcnative依赖版本,适配低版本GLIBC
netty-tcnative的部分旧版本基于低版本GLIBC编译,可在项目依赖中指定兼容版本。比如选择2.0.56.Final版本的netty-tcnative-boringssl-static,该版本兼容GLIBC 2.11及以上。
Maven依赖配置:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> <version>2.0.56.Final</version> </dependency>
Gradle依赖配置:
implementation 'io.netty:netty-tcnative-boringssl-static:2.0.56.Final'
同时需排除项目中引入的高版本netty-tcnative或conscrypt依赖,避免版本冲突。
2. 禁用本地SSL库,改用纯Java实现
如果不需要本地库的性能优化,可以配置PubSub客户端强制使用Java内置SSL实现,绕过本地库依赖。
在PubSub订阅者初始化代码中添加配置:
Subscriber subscriber = Subscriber.newBuilder(subscriptionName, receiver) .setChannelProvider(ProviderChannelProvider.createDefault()) .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) // 禁用native SSL实现 .setTransportChannelProvider( TransportChannelProvider.newBuilder() .setEndpoint("pubsub.googleapis.com:443") .setCredentialsProvider(FixedCredentialsProvider.create(credentials)) .setExecutorProvider(InstantiatingExecutorProvider.newBuilder().build()) .build() ) .build();
也可以直接在项目依赖中排除conscrypt和netty-tcnative的本地依赖:
Maven排除示例:
<dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-pubsub</artifactId> <version>你的项目使用版本</version> <exclusions> <exclusion> <groupId>org.conscrypt</groupId> <artifactId>conscrypt-openjdk-uber</artifactId> </exclusion> <exclusion> <groupId>io.netty</groupId> <artifactId>netty-tcnative-boringssl-static</artifactId> </exclusion> </exclusions> </dependency>
3. (谨慎操作)升级系统GLIBC版本
如果服务器权限允许且无兼容性顾虑,可以升级系统GLIBC到2.14及以上。但直接升级GLIBC可能导致系统其他依赖异常,建议采用编译安装并行版本的方式,或者使用Docker容器化部署隔离环境。
内容的提问来源于stack exchange,提问作者Molay
相关产品推荐
相关产品推荐

