使用InstancePrincipalsLoginModule时遇Client instance已关闭问题求助
问题分析:OCI Instance Principal结合Kafka Producer调用元数据服务时Jersey Client已关闭异常
问题背景
尝试通过OCI Instance Principal授权机制,结合Kafka Producer API向OCI Streams端点发送消息,代码运行在OCI计算实例的容器中,但调用元数据服务时触发java.lang.IllegalStateException: Client instance has been closed异常,关键报错日志如下:
2022-08-13 07:33:17.393 INFO [,d6d94a84e30ed614,d6d94a84e30ed614] 9 --- [tp1638249646-16] ePrincipalsAuthenticationDetailsProvider : Instance principals authentication can only be used on OCI compute instances. Please confirm this code is running on an OCI compute instance. See https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm for more info. 2022-08-13 07:33:17.394 WARN [,d6d94a84e30ed614,d6d94a84e30ed614] 9 --- [tp1638249646-16] ientAuthenticationDetailsProviderBuilder : Attempt 1 - Rest call to get region from metadata service failed java.lang.IllegalStateException: Client instance has been closed. at org.glassfish.jersey.internal.guava.Preconditions.checkState(Preconditions.java:169) at org.glassfish.jersey.client.JerseyClient.checkNotClosed(JerseyClient.java:257) at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:272) at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:56) at com.oracle.bmc.auth.AbstractFederationClientAuthenticationDetailsProviderBuilder.simpleRetry(AbstractFederationClientAuthenticationDetailsProviderBuilder.java:502) at com.oracle.bmc.auth.AbstractFederationClientAuthenticationDetailsProviderBuilder.simpleRetry(AbstractFederationClientAuthenticationDetailsProviderBuilder.java:490) at com.oracle.bmc.auth.AbstractFederationClientAuthenticationDetailsProviderBuilder.executeInstanceFallback(AbstractFederationClientAuthenticationDetailsProviderBuilder.java:342) at com.oracle.bmc.auth.AbstractFederationClientAuthenticationDetailsProviderBuilder.autoDetectEndpointUsingMetadataUrl(AbstractFederationClientAuthenticationDetailsProviderBuilder.java:249) at com.oracle.bmc.auth.AbstractFederationClientAuthenticationDetailsProviderBuilder.autoDetectUsingMetadataUrl(AbstractFederationClientAuthenticationDetailsProviderBuilder.java:237) at com.oracle.bmc.auth.InstancePrincipalsAuthenticationDetailsProvider$InstancePrincipalsAuthenticationDetailsProviderBuilder.build(InstancePrincipalsAuthenticationDetailsProvider.java:99) at com.oracle.bmc.auth.sasl.InstancePrincipalsLoginModule.loadAuthenticationProvider(InstancePrincipalsLoginModule.java:31) at com.oracle.bmc.auth.sasl.OciLoginModule.initialize(OciLoginModule.java:36) at com.oracle.bmc.auth.sasl.InstancePrincipalsLoginModule.initialize(InstancePrincipalsLoginModule.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at javax.security.auth.login.LoginContext.invoke(LoginContext.java:736) at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) at javax.security.auth.login.LoginContext.login(LoginContext.java:587) at org.apache.kafka.common.security.authenticator.AbstractLogin.login(AbstractLogin.java:60) at org.apache.kafka.common.security.authenticator.LoginManager.<init>(LoginManager.java:62) at org.apache.kafka.common.security.authenticator.LoginManager.acquireLoginManager(LoginManager.java:105) at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:170) at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:192) at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:81) at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:104) at org.apache.kafka.clients.producer.KafkaProducer.newSender(KafkaProducer.java:447) at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:428) at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:290) at org.springframework.kafka.core.DefaultKafkaProducerFactory.createRawProducer(DefaultKafkaProducerFactory.java:863) at org.springframework.kafka.core.DefaultKafkaProducerFactory.createKafkaProducer(DefaultKafkaProducerFactory.java:704) at org.springframework.kafka.core.DefaultKafkaProducerFactory.doCreateProducer(DefaultKafkaProducerFactory.java:664) at org.springframework.kafka.core.DefaultKafkaProducerFactory.createProducer(DefaultKafkaProducerFactory.java:639) at org.springframework.kafka.core.DefaultKafkaProducerFactory.createProducer(DefaultKafkaProducerFactory.java:633) at org.springframework.kafka.core.KafkaTemplate.getTheProducer(KafkaTemplate.java:752) at org.springframework.kafka.core.KafkaTemplate.doSend(KafkaTemplate.java:638) at org.springframework.kafka.core.KafkaTemplate.send(KafkaTemplate.java:429) at com.oracle.cxmarketing.messaging.kafka.producer.KafkaMessageProducer.send(KafkaMessageProducer.java:84) at com.oracle.cxmarketing.messaging.kafka.producer.KafkaMessageProducer.send(KafkaMessageProducer.java:78) at com.oracle.centralpod.poc.streams.messaging.producer.AccountsProducer.produceMessage(AccountsProducer.java:19) at com.oracle.centralpod.poc.streams.service.impl.StreamsPocServiceImpl.sendMessage(StreamsPocServiceImpl.java:22) at com.oracle.centralpod.poc.streams.web.controller.v1.StreamsPocController.sendMessage(StreamsPocController.java:33)
可能原因
- Jersey Client生命周期管理异常:OCI SDK构建InstancePrincipals认证提供者时会创建Jersey Client调用元数据服务,若Client被提前关闭(容器资源回收逻辑、SDK内部Bug),重试调用时就会触发该异常。
- 容器元数据访问权限问题:虽运行在OCI实例中,但容器可能未正确继承实例的元数据服务访问权限,首次调用失败后SDK复用已关闭的Client实例重试,导致报错。
- SDK与Kafka版本兼容性问题:使用的OCI Java SDK、Kafka SASL插件版本不匹配,导致Client实例的管理逻辑出错。
排查与解决方向
- 升级依赖版本:将OCI Java SDK、Kafka SASL插件升级到官方推荐的稳定版本,避免版本不匹配引发的资源管理问题。
- 验证容器元数据访问能力:在容器内执行
curl http://169.254.169.254/opc/v1/instance/,确认能正常获取实例元数据,排除网络或权限拦截问题。 - 检查资源回收逻辑:排查代码中是否存在手动关闭Jersey Client的逻辑,或容器的资源限制/回收策略是否误关了SDK创建的Client实例。
- 显式指定Region:构建InstancePrincipals认证提供者时手动设置Region信息,跳过SDK自动调用元数据服务获取Region的步骤,减少元数据服务调用次数。
内容的提问来源于stack exchange,提问作者Abhiram
相关产品推荐
相关产品推荐

