未设置超时时间导致线程池资源耗尽,排查过程

错误分析:

        @Scheduled进行定时任务的时候,spring会创建一个线程,然后用这个线程来执行任务,如果这个任务阻塞了,那么这个任务就会停滞,出现不执行的情况。而使用原生的方法进行http请求时,如果不设置超时时间,定时任务的那个线程就会一直等待对方的响应,就会一直处于运行状态处理该任务,等待下个任务到的时候就没有线程运行了。

        正常任务执行完毕后线程的状态应该是TIMED_WAITING,在异常的状态下线程的状态却是RUNNABLE,说明上个任务没有执行完毕,线程一直在执行。

执行完毕后正常状态:

执行完毕后异常状态: 

错误代码:

@Component
@Log4j2
public class ScheduleTask {

    @Autowired
    private SecondUserMapper secondUserMapper;

    @Scheduled(cron = "0 0/2 * * * ?") //定时任务注解+cron表达式
    public void testScheduleTask() throws IOException, InterruptedException {
        List<String> urlList = secondUserMapper.getRandomUrlList();
        Thread.sleep(3000);
        for (String s : urlList) {
            URL url = new URL(s);

            // 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求方法为GET
            connection.setRequestMethod("GET");
            // 添加自定义的请求头信息
            String agent = secondUserMapper.getRandomAgent();
            connection.addRequestProperty("User-Agent", agent);
            connection.addRequestProperty("Accept-Language", "en-US,en;q=0.9");

            // 获取服务器返回的状态码
            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 读取服务器返回的数据
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                String line;
                StringBuilder response = new StringBuilder();

                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }

                reader.close();

                System.out.println("Server Response:" + responseCode);
            } else {
                System.out.println("Error Code: " + responseCode);
            }

            // 关闭连接
            connection.disconnect();
        }
        log.info("线程名称为{},线程状态为{}",Thread.currentThread().getName(),Thread.currentThread().getState().name());

    }
}

正确代码:

增加超时时间即可

@Component
@Log4j2
public class ScheduleTask {

    @Autowired
    private SecondUserMapper secondUserMapper;

    @Scheduled(cron = "0 0/2 * * * ?") //定时任务注解+cron表达式
    public void testScheduleTask() throws IOException, InterruptedException {
        List<String> urlList = secondUserMapper.getRandomUrlList();
        Thread.sleep(3000);
        for (String s : urlList) {
            URL url = new URL(s);

            // 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求方法为GET
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(100000);
            connection.setReadTimeout(100000);
            // 添加自定义的请求头信息
            String agent = secondUserMapper.getRandomAgent();
            connection.addRequestProperty("User-Agent", agent);
            connection.addRequestProperty("Accept-Language", "en-US,en;q=0.9");

            // 获取服务器返回的状态码
            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 读取服务器返回的数据
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                String line;
                StringBuilder response = new StringBuilder();

                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }

                reader.close();

                System.out.println("Server Response:" + responseCode);
            } else {
                System.out.println("Error Code: " + responseCode);
            }

            // 关闭连接
            connection.disconnect();
        }
        log.info("线程名称为{},线程状态为{}",Thread.currentThread().getName(),Thread.currentThread().getState().name());

    }
}

错误总结:

        我们一般认为线程处于blocked状态的时候线程才是处于阻塞状态,但是这个状态只是对于计算机来说的。对于我们来说,只要业务不执行了,线程就是处于阻塞状态的,因此任何状态下的线程对于业务来说都是阻塞的。

        我这个项目是爬虫项目,会去爬取别人网站的数据,有些网站识别爬虫之后不仅会拒绝你访问,还会通过一直不给响应使得你的服务器线程占满,进而导致你的爬虫服务器崩溃。

相关推荐

  1. 线设计---C++

    2024-04-11 15:04:04       24 阅读
  2. feign设置超时时间

    2024-04-11 15:04:04       20 阅读
  3. C-线

    2024-04-11 15:04:04       21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-11 15:04:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-11 15:04:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-11 15:04:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-11 15:04:04       20 阅读

热门阅读

  1. Spring之事务底层源码解析

    2024-04-11 15:04:04       13 阅读
  2. CSS 选择器 – 类、名称、子选择器

    2024-04-11 15:04:04       15 阅读
  3. 为什么俗套的电邮“钓鱼”攻击,频频得手

    2024-04-11 15:04:04       14 阅读
  4. 【c/c++】fprintf和fwrite使用及作用介绍

    2024-04-11 15:04:04       16 阅读
  5. Part1_带复位的8通道I2C开关PCA9548A使用方法介绍

    2024-04-11 15:04:04       17 阅读
  6. 关于c++的命名空间

    2024-04-11 15:04:04       15 阅读
  7. 水土流失监测设备解析

    2024-04-11 15:04:04       15 阅读
  8. 设计模式(013)行为型之观察者模式

    2024-04-11 15:04:04       12 阅读
  9. HTML中meta标签的作用

    2024-04-11 15:04:04       13 阅读
  10. SUBSTRING_INDEX 函数

    2024-04-11 15:04:04       14 阅读