java调用https的接口报错javax.net.ssl.SSLException: Read timed out

前言

用这个Dockerfile构建的镜像,运行一年了也没啥问题,突然有一天我们的程序请求第三方api报以下错误:

FROM openjdk:8-jre
#作者
MAINTAINER wt

#解决主机日期与镜像日期不同步
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

#挂载目录
VOLUME /home/wt
#创建目录
RUN mkdir -p /home/wt/image
#指定路径
WORKDIR /home/wt

# 复制jar文件到路径
COPY wt-admin.jar /home/wt/wt-admin.jar
# 启动服务
ENTRYPOINT ["java","-jar","wt-admin.jar","--spring.profiles.active=prod"]
admin    | cn.hutool.core.io.IORuntimeException: SSLException: Read timed out
admin    |      at cn.hutool.http.HttpRequest.send(HttpRequest.java:1350)
admin    |      at cn.hutool.http.HttpRequest.doExecute(HttpRequest.java:1188)
admin    |      at cn.hutool.http.HttpRequest.execute(HttpRequest.java:1051)
admin    |      at cn.hutool.http.HttpRequest.execute(HttpRequest.java:1027)
admin    |      at com.ruoyi.web.controller.system.ImageController.change(ImageController.java:78)
admin    |      at com.ruoyi.web.controller.system.ImageController$$FastClassBySpringCGLIB$$c7c6a131.invoke(<generated>)
admin    |      at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
admin    |      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
admin    |      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
admin    |      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
admin    |      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
admin    |      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
admin    |      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
admin    |      at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
admin    |      at com.ruoyi.web.controller.system.ImageController$$EnhancerBySpringCGLIB$$ae9542b4.change(<generated>)
admin    |      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
admin    |      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
admin    |      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
admin    |      at java.lang.reflect.Method.invoke(Method.java:498)
admin    |      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
admin    |      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
admin    |      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
admin    |      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
admin    |      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
admin    |      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
admin    |      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
admin    |      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
admin    |      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
admin    |      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
admin    |      at javax.servlet.http.HttpServlet.service(HttpServlet.java:497)
admin    |      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
admin    |      at javax.servlet.http.HttpServlet.service(HttpServlet.java:584)
admin    |      at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:114)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at com.ruoyi.common.filter.RepeatableFilter.doFilter(RepeatableFilter.java:36)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
admin    |      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
admin    |      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121)
admin    |      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
admin    |      at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter.doFilterInternal(JwtAuthenticationTokenFilter.java:42)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
admin    |      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
admin    |      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
admin    |      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
admin    |      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
admin    |      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
admin    |      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
admin    |      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
admin    |      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
admin    |      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
admin    |      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
admin    |      at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
admin    |      at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
admin    |      at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
admin    |      at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
admin    |      at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
admin    |      at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
admin    |      at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
admin    |      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
admin    |      at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
admin    |      at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
admin    |      at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
admin    |      at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
admin    |      at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
admin    |      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
admin    |      at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
admin    |      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:79)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
admin    |      at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
admin    |      at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:79)
admin    |      at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
admin    |      at io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
admin    |      at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
admin    |      at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
admin    |      at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2019)
admin    |      at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1558)
admin    |      at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1449)
admin    |      at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
admin    |      at java.lang.Thread.run(Thread.java:750)
admin    | Caused by: javax.net.ssl.SSLException: Read timed out
admin    |      at sun.security.ssl.Alert.createSSLException(Alert.java:127)
admin    |      at sun.security.ssl.TransportContext.fatal(TransportContext.java:324)
admin    |      at sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
admin    |      at sun.security.ssl.TransportContext.fatal(TransportContext.java:262)
admin    |      at sun.security.ssl.SSLTransport.decode(SSLTransport.java:138)
admin    |      at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1397)
admin    |      at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1305)
admin    |      at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
admin    |      at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
admin    |      at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
admin    |      at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)
admin    |      at cn.hutool.http.HttpConnection.connect(HttpConnection.java:387)
admin    |      at cn.hutool.http.HttpRequest.send(HttpRequest.java:1345)
admin    |      ... 133 common frames omitted
admin    | Caused by: java.net.SocketTimeoutException: Read timed out
admin    |      at java.net.SocketInputStream.socketRead0(Native Method)
admin    |      at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
admin    |      at java.net.SocketInputStream.read(SocketInputStream.java:171)
admin    |      at java.net.SocketInputStream.read(SocketInputStream.java:141)
admin    |      at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464)
admin    |      at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:165)
admin    |      at sun.security.ssl.SSLTransport.decode(SSLTransport.java:109)
admin    |      ... 141 common frames omitted

排查

这个错误在google上搜索了一下,基本没人问过,而且有人在github上问过的也是没有人回复,无奈只能自己慢慢探索了,我的请求第三方代码如下所示:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-http</artifactId>
    <version>5.8.29</hutool.versioin>
</dependency>
String body = HttpRequest.get(url)
    .bearerAuth(token)
    .timeout(30000)
    .execute()
    .body();
log.info("res:{}", body);

是不是超级简单,就这么几行代码,怎么突然就不好使了,起初看到 Read timed out,第一印象我做了以下几个事情:

  1. 增加readTimeout时间 ,我加大到5分钟、10分钟后再次确认(还是报相同的错误)
  2. 确认第三方接口+端口是不是通的(网络正常)
  3. 使用curl命令在服务器上调用第三方接口(能请求到,返回结果正常)
  4. 在本地开发机上windows系统直接请求第三方接口(能请求到,返回结果正常)

其实到这里我比较懵逼了,为啥在服务器上部署的代码请求就报错 javax.net.ssl.SSLException: Read timed out,在本地windows开发机以及使用curl命令在服务器上都没有问题,此处懵逼1小时。。。。。。。。

后来又仔细想了一下,SSLException这个异常一般跟请求https有关,https请求会有证书加解密操作,这时我就去咨询了下第三方最近是不是对接口的域名更换过证书的操作,他们给我的回复是更新过证书,以前的证书是ZeroSSL的,最近更新成了google证书。那看来方向能确认了,这个错误跟网站的域名证书有关,但是疑问又来了,为啥我本地windows电脑请求第三方接口没有问题呢?

带着这个疑问去google检索,找到了一些方向点,jdk默认有证书的信任库,不受信任的证书是访问不到的,忽然想到了本地windows电脑使用的是jdk,而我的服务器上使用的是openjdk,怀疑是跟这个有关,于是决定换个镜像试试,因为工程主要是基于jdk1.8,去网上检索开源的openjdk镜像主要也是基于1.8的,找到了两个国内大厂还在开源维护的openjdk:

个人比较倾向阿里的,所以就基于阿里的镜像部署了下项目, 修改Dockerfile如下所示:

FROM alibabadragonwell/dragonwell:8-standard-ga-ubuntu
#作者
MAINTAINER wt

#解决主机日期与镜像日期不同步
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone

#挂载目录
VOLUME /home/wt
#创建目录
RUN mkdir -p /home/wt/image
#指定路径
WORKDIR /home/wt

# 复制jar文件到路径
COPY wt-admin.jar /home/wt/wt-admin.jar
# 启动服务
ENTRYPOINT ["java","-jar","wt-admin.jar","--spring.profiles.active=prod"]

终于不在报错了,第三方接口返回正常!!!

心得

  • 有些openjdk的镜像不支持字体,我也是测试了很多,发现有的openjdk不支持字体,需要自己额外安装,报错内容如下:libfontmanager.so:libfreetype.so.6: cannot open shared object file,一般这种就需要单独安装下,但是使用上边我推荐的那两个镜像不会有这个问题
  • 8-jre-alpine 用这个镜像虽然体积减少了,但是不稳定,上传大文件程序会崩溃
  • 今年AIGC太火,程序员很多东西用GPT就能搞定Talk-Bot
  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值