OkHttp Address already in use: no further information异常

yizhihongxing

  说下场景,我的程序在多线程场景下一个循环体中处理业务数据,其中需要调用一个外部http接口去获取一些数据,程序总会在在本地执行一段时间后会抛出Address already in use: no further information错误。

  这是大量并发场景下出现的问题,经过查阅原因是OkHttp的链接没有被有效回收和复用导致的端口资源占用,okHttp在发起请求调用外部接口时也会占用本地的端口资源,因为okHttp需要建立Socket链接来和对方通信,端口是本地一个随机的未被使用的端口,okHttp会尽量复用这些资源以减少服务器消耗,但如果在短时间内出现大量的请求都在创建新的okHttp对象去发起请求,那么每个okHttp对象的资源占用都不会共享,导致资源被浪费,亦或者没有及时关闭响应体,比如response.close()。最终,资源被耗尽,出现 Address already in use: no further information。而我的调用代码就是为了图方便简单的每次请求创建一个新的OkHttpClient

  解决方式很简单,使用单例的OkHttpClient并配置好超时时间,同时注意资源关闭,如果是在Spring环境下做个配置就行,其中线程数和连接回收时间根据自己情况进行调整:

@Configuration
public class HttpClientConfiguration {
    @Bean
    public OkHttpClient httpClient(){
        return  new OkHttpClient().newBuilder()
                //设置线程池              最大200线程     最大保持10秒连接既自动回收
                .connectionPool(new ConnectionPool(200, 10, TimeUnit.SECONDS))
                //设置超时时间
                .connectTimeout(5, TimeUnit.SECONDS).readTimeout(5,TimeUnit.SECONDS)
                .writeTimeout(5,TimeUnit.SECONDS).build();
    }
}
 
 
class Test{
 
  @Autowired
  private OkHttpClient httpClient;
 
  public JsonNode getFieldData(String token){
        String body = "{xxx}";
 
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"),body);
        Request request = new Request.Builder().url("http://xxxx").post(requestBody).header("token",token).build();
 
        //请求成功结果正常则返回数据
        try (Response response = httpClient.newCall(request).execute()){
            if(response.isSuccessful()){
                String resultJsonStr = response.body().string();
                JsonNode resJson = objectMapper.readTree(resultJsonStr);
                return resJson.get("result");
            }
        }catch (Exception e){
            logger.error(e.getMessage(),e);
        }
        return objectMapper.createObjectNode();
    }
}

另外,根据找到的资料,单例模式下的OkHttp性能也会更好:

如果okhttp客户端不是单例的,那么每次发送请求时都会创建一个新的客户端对象,这样会导致资源浪费和性能下降,而且可能会导致内存泄漏。okhttp客户端是设计成单例的,它可以共享连接池、响应缓存和配置。因此,建议使用单例模式来创建和管理okhttp客户端,或者至少为每个主机名保持一个客户端实例。

原文链接:https://www.cnblogs.com/dwyanesw/p/17316183.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:OkHttp Address already in use: no further information异常 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • Java的Struts框架报错“ChainConfigException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“ChainConfigException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置,则可能会出现此错误。在这种情况下,需要检查文件以解决此问题。 链错误:如果链不正确,则可能会出现此错误。在这种情况下,需要检查链以解决此问题。 以下是两个实例: 例 1 如果配置文件中没有正确配…

    Java 2023年5月5日
    00
  • java实现简单的给sql语句赋值的示例

    下面为你详细讲解Java实现简单的给SQL语句赋值的示例攻略。 1. 前置知识 在进行此操作之前,需要了解以下知识点: JDBC连接MySQL或其他关系型数据库的方式和方法 SQL查询和更新的基本语法 PreparedStatement对象的用法 2. SQL语句赋值的示例 2.1 查询示例 例如,我们需要查询学生表中的某个学生的信息,SQL语句如下: SE…

    Java 2023年5月20日
    00
  • Spring boot jpa 删除数据和事务管理的问题实例详解

    下面我会详细讲解关于Spring Boot JPA删除数据和事务管理的问题实例,希望能对您有所帮助。 1. 删除数据 在Spring Boot JPA中,我们可以使用deleteById()和delete()方法来删除数据。deleteById()方法使用主键来删除数据记录,而delete()方法则使用实体作为删除条件。 以下是一个示例,演示如何使用dele…

    Java 2023年5月20日
    00
  • 怎么开启Java小程序脚本? 浏览器采用Java小程序脚本的技巧

    开启Java小程序脚本: Java小程序(Java applet)是用Java语言编写的小程序,可以在网络浏览器上运行,为在浏览器中使用Java小程序,需要遵循以下步骤: 安装Java运行环境(Java runtime environment,JRE),只要在Java官网下载JRE安装即可,注意选择与你电脑系统相匹配的版本。 将Java小程序嵌入到HTML页…

    Java 2023年5月23日
    00
  • Spring AOP核心功能示例代码详解

    关于《Spring AOP核心功能示例代码详解》的攻略,我会从以下三个方面详细讲解。 一、背景介绍 Spring AOP是Spring框架的一个核心组件,它提供了一种在方法调用时动态地将代码织入到原始方法体中的能力,从而可在保持应用程序开发简单性的前提下,实现横切关注点的模块化复用。 在学习Spring AOP的过程中,我们需要了解一些基本概念,例如: 连接…

    Java 2023年5月19日
    00
  • SpringBoot实现接口幂等性的4种方案

    下面是“SpringBoot实现接口幂等性的4种方案”的完整攻略: 什么是接口幂等性? 接口幂等性指的是对于同一请求,多次调用接口所产生的结果是一致的。常见的应用场景包括支付、订单创建等需要保证数据一致性的场景。 在实际开发中,由于应用的多实例部署,以及网络延迟等原因,可能会导致接口被重复调用,进而产生数据不一致的问题。因此,保证接口幂等性非常重要。 Spr…

    Java 2023年5月19日
    00
  • Spring动态加载bean后调用实现方法解析

    全文内容如下: 什么是Spring动态加载bean? Spring动态加载bean可以理解为在运行时通过编写代码动态地向Spring容器中添加新的bean。相比于静态配置文件中声明bean,动态添加bean更加灵活方便。 怎么实现Spring动态加载bean后调用实现方法解析? 步骤一:定义抽象实现方法 首先我们需要定义一个抽象方法,让后续动态添加的bean…

    Java 2023年5月19日
    00
  • springboot集成CAS实现单点登录的示例代码

    关于“springboot集成CAS实现单点登录的示例代码”的完整攻略,我将为您详细讲解,包括以下几个步骤: 添加依赖 使用SpringBoot集成CAS需要添加cas-client-support-spring-boot-starter依赖。例如: <dependency> <groupId>org.apereo.cas</g…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部