Android11 深休后系统定时唤醒导致网络请求服务器过载

发布于:2025-06-28 ⋅ 阅读:(13) ⋅ 点赞:(0)

硬件平台:QCS6125

软件平台:Android11

问题:每天的7:00和22:00 服务器会突然收到批量设备的网络请求,导致服务器过载。

    通过系统的logcat日志发现了系统在休眠后,每天会有22:00、7:00的唤醒,从而导致这个时间段积累的workmanager定时任务同时批量调度,导致服务器紧张。

06-22 21:57:58.378     0     0 I         : Restarting tasks ... done. 
06-22 22:00:00.313  2108  2108 D Digital_clock: updateClock()!
06-22 22:00:00.314  1402  2696 I BatteryStatsService: In wakeup_callback: resumed from suspend
06-22 21:57:58.394     0     0 I         : Resume caused by misconfigured IRQ 20 glink-native
06-22 22:00:00.314     0     0 I PM      : PM: suspend exit 2025-06-22 14:00:00.314131022 UTC
06-22 22:00:00.314     0     0 I PM      : suspend exit
06-22 22:00:00.316  1402  1402 D ConditionProviders.SCP: onReceive ScheduleConditionProvider.EVALUATE
06-22 22:00:00.317  1402  1402 D ConditionProviders.SCP: evaluateSubscriptionLocked cal=ScheduleCalendar[mDays={1, 2, 3, 4, 5, 6, 7}, mSchedule=ScheduleInfo{days=[1, 2, 3, 4, 5, 6, 7], startHour=22, startMinute=0, endHour=7, endMinute=0, exitAtAlarm=true, nextAlarm=Thu Jan 01 08:00:00 GMT+08:00 1970 (0)}], now=Sun Jun 22 22:00:00 GMT+08:00 2025 (1750600800316), nextUserAlarmTime=Thu Jan 01 08:00:00 GMT+08:00 1970 (0)
06-22 22:00:00.317  1402  1402 D ConditionProviders.SCP: notifyCondition condition://android/schedule?days=1.2.3.4.5.6.7&start=22.0&end=7.0&exitAtAlarm=true STATE_TRUE reason=meetsSchedule
06-22 22:00:00.317  1402  1402 D ConditionProviders.SCP: Scheduling evaluate for Mon Jun 23 07:00:00 GMT+08:00 2025 (1750633200000), in +8h59m59s684ms, now=Sun Jun 22 22:00:00 GMT+08:00 2025 (1750600800316)
06-22 22:00:00.326  2108  2108 D Digital_clock: updateClock()!
06-22 22:00:00.332  2108  2108 D Digital_clock: updateClock()!
06-22 22:00:00.332   839  2062 D AudioPolicyManagerCustom: setForceUse() usage 3, config 8, mPhoneState 0
06-22 22:00:00.415     0     0 I PM      : PM: suspend entry 2025-06-22 14:00:00.415238470 UTC
06-22 22:00:00.415     0     0 I PM      : suspend entry (deep)
06-22 22:00:00.415     0     0 I PM      : Syncing filesystems ... done.
06-22 22:00:00.440     0     0 I         : Freezing user space processes ...
06-22 22:00:00.450     0     0 I PM      : Pending Wakeup Sources: qcom_rx_wakelock
06-22 22:00:00.450     0     0 E         : Freezing of tasks aborted after 0.010 seconds
06-22 22:00:00.450     0     0 I         : OOM killer enabled.
06-22 22:00:00.458  1402  2696 I BatteryStatsService: In wakeup_callback: suspend aborted
06-22 22:00:00.450     0     0 I         : Restarting tasks ... done.
06-22 22:00:00.457     0     0 I         : Resume caused by misconfigured IRQ 20 glink-native
06-22 22:00:00.457     0     0 I PM      : PM: suspend exit 2025-06-22 14:00:00.457686751 UTC

而这个唤醒规则是按照framework层的一个勿扰模式的默认配置文件default_zen_mode_config.xml来的:

<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->

<!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
<zen version="9">
    <allow alarms="true" media="true" system="false" calls="true" callsFrom="2" messages="false"
            reminders="false" events="false" repeatCallers="true" convos="false"
            convosFrom="3"/>
    <automatic ruleId="EVENTS_DEFAULT_RULE" enabled="false" snoozing="false" name="Event" zen="1"
               component="android/com.android.server.notification.EventConditionProvider"
               conditionId="condition://android/event?userId=-10000&amp;calendar=&amp;reply=1"/>
    <automatic ruleId="EVERY_NIGHT_DEFAULT_RULE" enabled="false" snoozing="false" name="Sleeping"
               zen="1" component="android/com.android.server.notification.ScheduleConditionProvider"
               conditionId="condition://android/schedule?days=1.2.3.4.5.6.7&amp;start=22.0&amp;end=7.0&amp;exitAtAlarm=true"/>
    <!-- all visual effects that exist as of P -->
    <disallow visualEffects="511" />
    <!-- whether there are notification channels that can bypass dnd -->
    <state areChannelsBypassingDnd="false" />
</zen>                                                        

这个规则配置的目的可能就是在相应的时间点,触发系统是否进入勿扰模式的状态评估。

    针对我们这个问题,想到了大概两个方案吧,一个是直接禁用这个规则的加载;一个是把规则里边nextAlarm的时间打散,比如随机在22和7点上下浮动20min,即把唤醒的时间点从精准的7:00和22:00调整为散列在21:40~22:20以及6:40~7:20的范围。

    由于不太确定规则禁用对系统的直接影响,所以采用了第二种方式。

具体改动如下:

diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index 35170332a07..df17b091e74 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -45,6 +45,7 @@ import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
+import java.util.Random;
 
 /**
  * Built-in zen condition provider for daily scheduled time-based conditions.
@@ -70,6 +71,7 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
     private AlarmManager mAlarmManager;
     private boolean mConnected;
     private boolean mRegistered;
+    private boolean mShakeValue;
     private long mNextAlarmTime;
 
     public ScheduleConditionProvider() {
@@ -181,6 +183,27 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
         updateAlarm(now, mNextAlarmTime);
     }
 
+    private long getRandomTimeDelta() {
+        Random random = new Random();
+        // create a random num between 0~30
+        long randomNumber = (long) random.nextInt(21);
+
+        // set mShakeValue
+        mShakeValue = (randomNumber & 1) == 0;
+
+        if (mShakeValue)
+            return (randomNumber * 60 * 1000);
+
+        return -(randomNumber * 60 * 1000);
+    }
+
+    private boolean isNeedRandomTime(String cal) {
+        if (cal.contains("startHour=22"))
+            return true;
+
+               return false;
+    }
+
     @VisibleForTesting
     @GuardedBy("mSubscriptions")
     Condition evaluateSubscriptionLocked(Uri conditionId, ScheduleCalendar cal,
@@ -211,6 +234,13 @@ public class ScheduleConditionProvider extends SystemConditionProviderService {
         if (nextChangeTime > 0 && nextChangeTime > now) {
             if (mNextAlarmTime == 0 || nextChangeTime < mNextAlarmTime) {
                 mNextAlarmTime = nextChangeTime;
+                if (DEBUG) Slog.d(TAG, String.format("mNextAlarmTime:  %s",
+                        ts(mNextAlarmTime)));
+                if (isNeedRandomTime(String.format("%s", cal))) {
+                    mNextAlarmTime = nextChangeTime + getRandomTimeDelta();
+                    if (DEBUG) Slog.d(TAG, String.format("Add random value mNextAlarmTime:  %s",
+                            ts(mNextAlarmTime)));
+                }
             }
         }
         return condition;

修改完成,编译验证日志:

06-25 16:50:39.122  1404  1404 D ConditionProviders.SCP: evaluateSubscriptionLocked cal=ScheduleCalendar[mDays={1, 2, 3, 4, 5, 6, 7}, mSchedule=ScheduleInfo{days=[1, 2, 3, 4, 5, 6, 7], startHour=22, startMinute=0, endHour=7, endMinute=0, exitAtAlarm=true, nextAlarm=Thu Jan 01 08:00:00 GMT+08:00 1970 (0)}], now=Wed Jun 25 16:50:39 GMT+08:00 2025 (1750841439104), nextUserAlarmTime=Thu Jan 01 08:00:00 GMT+08:00 1970 (0)
06-25 16:50:39.122  1404  1404 D ConditionProviders.SCP: notifyCondition condition://android/schedule?days=1.2.3.4.5.6.7&start=22.0&end=7.0&exitAtAlarm=true STATE_FALSE reason=!meetsSchedule
06-25 16:50:39.123  1404  1404 D ConditionProviders.SCP: mNextAlarmTime:  Wed Jun 25 22:00:00 GMT+08:00 2025 (1750860000000)
06-25 16:50:39.124  1404  1404 D ConditionProviders.SCP: Add random value mNextAlarmTime:  Wed Jun 25 22:18:00 GMT+08:00 2025 (1750861080000)
06-25 16:50:39.125  1404  1404 D ConditionProviders.SCP: Scheduling evaluate for Wed Jun 25 22:18:00 GMT+08:00 2025 (1750861080000), in +5h27m20s896ms, now=Wed Jun 25 16:50:39 GMT+08:00 2025 (1750841439104)

可以看到,默认设置的是22:00,但是通过修改的代码逻辑,下次alram的时间变成了22:18:00,即随机数生成的是18,目标达成。


网站公告

今日签到

点亮在社区的每一天
去签到