JVM 在验证时崩溃 pub/sub

JVM crashes while authenticating pub/sub

我使用 GCP client libraries 在我的 spring-boot 应用程序中实施 pub/sub 模型。为了进行身份验证,我正在使用 GOOGLE_APPLICATION_CREDENTIALS 路径环境变量。它与其他版本的 JDK/JRE 一起工作正常,但它失败并出现下面提到的 jdk/jre

的分段错误

环境详情

Java版本:

openjdk version "1.8.0_322"
OpenJDK Runtime Environment (Zulu 8.60.0.22-SA-linux-musl-x64) (build 1.8.0_322-b06)
OpenJDK 64-Bit Server VM (Zulu 8.60.0.22-SA-linux-musl-x64) (build 25.322-b06, mixed mode)

日志:

# A fatal error has been detected by the Java Runtime Environment: 
# SIGSEGV (0xb) at pc=0x0000000000003fd6, pid=1, tid=0x00007f99a14fcb38 
# 
# JRE version: OpenJDK Runtime Environment (Zulu 8.60.0.22-SA-linux-musl-x64) (8.0_322-b06) (build 1.8.0_322-b06) 
# 
# Java VM: OpenJDK 64-Bit Server VM (25.322-b06 mixed mode linux-amd64 compressed oops) 
# Problematic frame: 
# C 0x0000000000003fd6 
# 
# Core dump written. Default location: //core or core.1 
# 
# An error report file with more information is saved as: 
# /tmp/hs_err_pid1.log 
# 
# If you would like to submit a bug report, please visit: 
# http://www.azul.com/support/


Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  java.lang.ClassLoader$NativeLibrary.load(Ljava/lang/String;Z)V+0
j  java.lang.ClassLoader.loadLibrary0(Ljava/lang/Class;Ljava/io/File;)Z+328
j  java.lang.ClassLoader.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)V+92
j  java.lang.Runtime.load0(Ljava/lang/Class;Ljava/lang/String;)V+57
j  java.lang.System.load(Ljava/lang/String;)V+7
j  io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryUtil.loadLibrary(Ljava/lang/String;Z)V+5
v  ~StubRoutines::call_stub
J 2066  sun.reflect.NativeMethodAccessorImpl.invoke0(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (0 bytes) @ 0x00007f5cad99bdf7 [0x00007f5cad99bd80+0x77]
J 2065 C1 sun.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (104 bytes) @ 0x00007f5cad9a2a8c [0x00007f5cad9a1900+0x118c]
J 1974 C1 sun.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (10 bytes) @ 0x00007f5cad961784 [0x00007f5cad961680+0x104]
J 2084 C1 java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (62 bytes) @ 0x00007f5cad9a3e8c [0x00007f5cad9a3aa0+0x3ec]
j  io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryLoader.run()Ljava/lang/Object;+53
v  ~StubRoutines::call_stub
J 1349  java.security.AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object; (0 bytes) @ 0x00007f5cad764f4f [0x00007f5cad764f00+0x4f]
j  io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryLoader.loadLibraryByHelper(Ljava/lang/Class;Ljava/lang/String;Z)V+10
j  io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryLoader.loadLibrary(Ljava/lang/ClassLoader;Ljava/lang/String;Z)V+15
j  io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryLoader.load(Ljava/lang/String;Ljava/lang/ClassLoader;)V+359
j  io.grpc.netty.shaded.io.netty.channel.epoll.Native.loadNativeLibrary()V+60
j  io.grpc.netty.shaded.io.netty.channel.epoll.Native.<clinit>()V+76
v  ~StubRoutines::call_stub
j  io.grpc.netty.shaded.io.netty.channel.epoll.Epoll.<clinit>()V+28
v  ~StubRoutines::call_stub
J 993  java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class; (0 bytes) @ 0x00007f5cad6995fa [0x00007f5cad699580+0x7a]
J 1952 C1 java.lang.Class.forName(Ljava/lang/String;)Ljava/lang/Class; (15 bytes) @ 0x00007f5cad948d4c [0x00007f5cad948ba0+0x1ac]
j  io.grpc.netty.shaded.io.grpc.netty.Utils.isEpollAvailable()Z+3
j  io.grpc.netty.shaded.io.grpc.netty.Utils.<clinit>()V+144
v  ~StubRoutines::call_stub
j  io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<clinit>()V+16
v  ~StubRoutines::call_stub
j  io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForAddress(Ljava/lang/String;I)Lio/grpc/netty/shaded/io/grpc/netty/NettyChannelBuilder;+2
j  io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForAddress(Ljava/lang/String;I)Lio/grpc/ManagedChannelBuilder;+3
j  io.grpc.ManagedChannelBuilder.forAddress(Ljava/lang/String;I)Lio/grpc/ManagedChannelBuilder;+5
j  com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel()Lio/grpc/ManagedChannel;+285
j  com.google.api.gax.grpc.InstantiatingGrpcChannelProvider$$Lambda6.createSingleChannel()Lio/grpc/ManagedChannel;+4
j  com.google.api.gax.grpc.ChannelPool.<init>(Lcom/google/api/gax/grpc/ChannelPoolSettings;Lcom/google/api/gax/grpc/ChannelFactory;Ljava/util/concurrent/ScheduledExecutorService;)V+71
j  com.google.api.gax.grpc.ChannelPool.create(Lcom/google/api/gax/grpc/ChannelPoolSettings;Lcom/google/api/gax/grpc/ChannelFactory;)Lcom/google/api/gax/grpc/ChannelPool;+9
j  com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel()Lcom/google/api/gax/rpc/TransportChannel;+10
j  com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel()Lcom/google/api/gax/rpc/TransportChannel;+35
j  com.google.api.gax.rpc.ClientContext.create(Lcom/google/api/gax/rpc/StubSettings;)Lcom/google/api/gax/rpc/ClientContext;+179
j  com.google.cloud.pubsub.v1.stub.GrpcSubscriberStub.create(Lcom/google/cloud/pubsub/v1/stub/SubscriberStubSettings;)Lcom/google/cloud/pubsub/v1/stub/GrpcSubscriberStub;+6
j  com.google.cloud.pubsub.v1.Subscriber.doStart()V+16
j  com.google.api.core.AbstractApiService$InnerService.doStart()V+4
j  com.google.common.util.concurrent.AbstractService.startAsync()Lcom/google/common/util/concurrent/Service;+33
j  com.google.api.core.AbstractApiService.startAsync()Lcom/google/api/core/ApiService;+4
j  com.google.cloud.pubsub.v1.Subscriber.startAsync()Lcom/google/api/core/ApiService;+1

依赖关系:

        <dependencies>
            <dependency>
                <groupId>com.google.cloud</groupId>
                <artifactId>libraries-bom</artifactId>
                <version>25.1.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-pubsub</artifactId>
        </dependency>
   <dependencies>

而且我还想知道除了使用路径环境变量之外还有其他方法可以进行身份​​验证吗?我可以将 spring.cloud.gcp.credentials.location=file:{location} 与 GCP 客户端库一起使用,而不是环境变量吗?

如@Juraj Martinka 所述,这是底层 google 库 io.grpc.netty.shaded 的问题。 Netty 似乎不支持 Alpine,因为 Netty 依赖于 glibc,但 Alpine 没有,它有 musl libc。

如果禁用 Netty 的本机支持,问题就会消失 或者如果您使用具有 glibc 的图像,例如:

azul/zulu-openjdk-alpine:11-jre:Alpine-based,没有 glibc -> 不起作用
azul/zulu-openjdk:11:Ubuntu-based,有 glibc -> 有效

使用-Dio.grpc.netty.shaded.io.netty.transport.noNative=true避免段错误
示例:

java -jar -D-Dio.grpc.netty.shaded.io.netty.transport.noNative=true app.jar

另一种解决方法是,使用 grpc-netty 而不是 grpc-netty-shaded

<dependency>
  <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-pubsub</artifactId>
  <exclusions>
    <exclusion>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty-shaded</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>io.grpc</groupId>
  <artifactId>grpc-netty</artifactId>
</dependency>

参考链接:Link 1, Link 2