ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux线程调度引起的业务问题

2020-01-22 18:05:05  阅读:465  来源: 互联网

标签:thread stop 调度 send 线程 migration Linux cpu


 一、 问题现象

  1.业务组播出向报文偶尔有延迟;

  2.单播出向报文平滑

二、 分析及定位

  使用wireshark分析了组播出向报文的抓包,报文无丢包,但是IO 输出流量显示有burst和掉坑现象。 

  波形和抓包文件分析如下图:

 

 

   后来在接收侧抓包,并分析日志,接收方没有出现丢包问题,但是有接收码流不足,导致收包不及时,业务不流畅。

 

  通过在系统内核发包udp_sendmsg函数打点,发现有时候有300ms+没有报文发出,说明发包线程被阻塞。

  下面是监控组播出向发包函数udp_sendmsg的打点记录日志:

__dev_xmit_skb:

78      send rate:  9 Mbps

79      send rate:  9 Mbps

80      send rate:  6 Mbps   ##有流量下降

diff_send_time_ms = 346      ##346毫秒无报文发送

81      send rate:  12 Mbps  ##有流量上升

82      send rate:  9 Mbps

83      send rate:  9 Mbps

84      send rate:  8 Mbps

diff_send_time_ms = 316

85      send rate:  7 Mbps   ##被发包线程削峰

86      send rate:  9 Mbps

87      send rate:  9 Mbps

 

  确认系统上有migration实时线程频繁调度,同时发现系统记账功能pacct在系统上写了近70G文件。

 

 

 

 

 

  其中一台设备上的 pacct文件:

 

 

   业务组播发包线程也是实时线程:

 

    关闭psacct服务后,内核migration线程没有再频繁调度,而且发包没有再出现300ms延迟(上图就是去掉psacct服务后的线程调度情况)。

 经过几次抓包分析,出向流量很平稳,没有burst情况,业务阻塞现象消失。

 

  关闭方法:  

  systemctl stop psacct.service

  systemctl disable psacct.service

 

  为什么psacct服务引起了migration,进而影响了业务组播发包线程的延迟?

   一个猜测是,psacct进程写日志时造成cpu占用太高(当时psacct日志已经达到70G),触发了migration调度,而migration调度又导致业务

ForwardThread实时线程阻塞,引起发包抖动。

 

 三、migration和被阻塞线程ForwardThread调度方式

migration线程简介

为什么存在migration线程?

在计算机系统中,资源使用需要均衡,因此在相同硬件上能够获得较好的星星。在Linux内核系统中,使用一些迁移内核线程来做这些事情。

内核怎么创建migration线程?

migration线程相关结构定义:

static struct smp_hotplug_thread cpu_stop_threads = {
    .store            = &cpu_stopper.thread,
    .thread_should_run    = cpu_stop_should_run,
    .thread_fn        = cpu_stopper_thread,
    .thread_comm        = "migration/%u",
    .create            = cpu_stop_create,
    .setup            = cpu_stop_unpark,
    .park            = cpu_stop_park,
    .pre_unpark        = cpu_stop_unpark,
    .selfparking        = true,
};



migration线程创建过程:

static int __init cpu_stop_init(void)
-->BUG_ON(smpboot_register_percpu_thread(&cpu_stop_threads));
    1)__smpboot_create_thread
        ## kthread_create_on_cpu 创建线程调度优先级为0,调度策略为SCHED_NORMAL
        tsk = kthread_create_on_cpu(smpboot_thread_fn, td, cpu, ht->thread_comm);  //register smpboot_thread_fn
            -->kthread_create_on_node
                -->sched_setscheduler_nocheck
    2)## cpu_stop_create 设置调度优先级为MAX_RT_PRIO - 1(99),调度策略为SCHED_FIFO
    ht->create(cpu); ## cpu_stop_create

 

系统中migration线程信息:

 

 

 

 

业务组播发包线程调度方式:

在我们的业务代码中,通过以下接口设置业务发包线程调度策略和优先级:

param.sched_priority = sched_get_priority_max(SCHED_FIFO)  ;   /* 这个优先级为99 */
ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

 批注: 使用pthread_setschedparam函数设置可能会出现EPERM错误,这个又是另外一个问题了,后面单独开篇:)

系统中业务发包线程信息:

 

 

参考资料:

【migration介绍】https://www.systutorials.com/239971/migration-thread-works-inside-linux-kernel/

【Linux调度优先级】https://superuser.com/questions/203657/difference-between-nice-value-and-priority-in-the-top-output

标签:thread,stop,调度,send,线程,migration,Linux,cpu
来源: https://www.cnblogs.com/smith9527/p/12168508.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有