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>
我使用 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>