From 58820393776c50a0b74c2b4593ae42a18ae7e1ba Mon Sep 17 00:00:00 2001 From: thetumbled <843221020@qq.com> Date: Mon, 12 Dec 2022 12:23:29 +0800 Subject: [PATCH 1/3] fix bug caused by down nics. --- .../broker/loadbalance/LinuxInfoUtils.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java index 2119398fe62fa..8ea6b1ad7ecb6 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java @@ -163,6 +163,21 @@ private static boolean isPhysicalNic(Path nicPath) { } } + /** + * Determine whether nic is up. + * @param nicPath Nic path + * @return whether nic is up. + */ + private static boolean isUp(Path nicPath) { + try { + String operateState = readTrimStringFromFile(nicPath.resolve("operstate")); + return operateState.equals("up"); + } catch (Exception e) { + log.warn("[LinuxInfo] Failed to read {} NIC operstate, the detail is: {}", nicPath, e.getMessage()); + return false; + } + } + /** * Get all physical nic limit. * @param nics All nic path @@ -199,12 +214,13 @@ public static double getTotalNicUsage(List nics, NICUsageType type, BitR } /** - * Get all physical nic path. - * @return All physical nic path + * Get all path of physical nic whose state are up. + * @return All physical nic path whose state are up */ public static List getPhysicalNICs() { try (Stream stream = Files.list(Paths.get(NIC_PATH))) { return stream.filter(LinuxInfoUtils::isPhysicalNic) + .filter(LinuxInfoUtils::isUp) .map(path -> path.getFileName().toString()) .collect(Collectors.toList()); } catch (IOException e) { From 1a546a132064f1d5179ec30785df1f0601ef4af0 Mon Sep 17 00:00:00 2001 From: thetumbled <843221020@qq.com> Date: Mon, 12 Dec 2022 14:21:37 +0800 Subject: [PATCH 2/3] handle all possible nic states. --- .../broker/loadbalance/LinuxInfoUtils.java | 53 +++++++++++++++---- .../impl/LinuxBrokerHostUsageImpl.java | 4 +- .../LoadReportNetworkLimitTest.java | 8 +-- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java index 8ea6b1ad7ecb6..42ef264b6db04 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/LinuxInfoUtils.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -164,16 +165,25 @@ private static boolean isPhysicalNic(Path nicPath) { } /** - * Determine whether nic is up. + * Determine whether nic is usable. * @param nicPath Nic path - * @return whether nic is up. + * @return whether nic is usable. */ - private static boolean isUp(Path nicPath) { + private static boolean isUsable(Path nicPath) { try { - String operateState = readTrimStringFromFile(nicPath.resolve("operstate")); - return operateState.equals("up"); + String operstate = readTrimStringFromFile(nicPath.resolve("operstate")); + Operstate operState = Operstate.valueOf(operstate.toUpperCase(Locale.ROOT)); + switch (operState) { + case UP: + case UNKNOWN: + case DORMANT: + return true; + default: + return false; + } } catch (Exception e) { log.warn("[LinuxInfo] Failed to read {} NIC operstate, the detail is: {}", nicPath, e.getMessage()); + // Read operstate got error. return false; } } @@ -214,13 +224,13 @@ public static double getTotalNicUsage(List nics, NICUsageType type, BitR } /** - * Get all path of physical nic whose state are up. - * @return All physical nic path whose state are up + * Get paths of all usable physical nic. + * @return All usable physical nic paths. */ - public static List getPhysicalNICs() { + public static List getUsablePhysicalNICs() { try (Stream stream = Files.list(Paths.get(NIC_PATH))) { return stream.filter(LinuxInfoUtils::isPhysicalNic) - .filter(LinuxInfoUtils::isUp) + .filter(LinuxInfoUtils::isUsable) .map(path -> path.getFileName().toString()) .collect(Collectors.toList()); } catch (IOException e) { @@ -234,7 +244,7 @@ public static List getPhysicalNICs() { * @return Whether the VM has nic speed */ public static boolean checkHasNicSpeeds() { - List physicalNICs = getPhysicalNICs(); + List physicalNICs = getUsablePhysicalNICs(); if (CollectionUtils.isEmpty(physicalNICs)) { return false; } @@ -258,6 +268,29 @@ private static double readDoubleFromFile(Path path) throws IOException { return Double.parseDouble(readTrimStringFromFile(path)); } + /** + * TLV IFLA_OPERSTATE + * contains RFC2863 state of the interface in numeric representation: + * See ... + */ + enum Operstate { + // Interface is in unknown state, neither driver nor userspace has set + // operational state. Interface must be considered for user data as + // setting operational state has not been implemented in every driver. + UNKNOWN, + // Interface is unable to transfer data on L1, f.e. ethernet is not + // plugged or interface is ADMIN down. + DOWN, + // Interfaces stacked on an interface that is IF_OPER_DOWN show this + // state (f.e. VLAN). + LOWERLAYERDOWN, + // Interface is L1 up, but waiting for an external event, f.e. for a + // protocol to establish. (802.1X) + DORMANT, + // Interface is operational up and can be used. + UP + } + @AllArgsConstructor public enum NICUsageType { // transport diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java index 9e920c01a3077..575c941d2810b 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java @@ -21,7 +21,7 @@ import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.NICUsageType; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getCpuUsageForCGroup; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getCpuUsageForEntireHost; -import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getPhysicalNICs; +import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getUsablePhysicalNICs; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getTotalCpuLimit; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getTotalNicLimit; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getTotalNicUsage; @@ -88,7 +88,7 @@ public SystemResourceUsage getBrokerHostUsage() { @Override public void calculateBrokerHostUsage() { - List nics = getPhysicalNICs(); + List nics = getUsablePhysicalNICs(); double totalNicLimit = getTotalNicLimitWithConfiguration(nics); double totalNicUsageTx = getTotalNicUsage(nics, NICUsageType.TX, BitRateUnit.Kilobit); double totalNicUsageRx = getTotalNicUsage(nics, NICUsageType.RX, BitRateUnit.Kilobit); diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/LoadReportNetworkLimitTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/LoadReportNetworkLimitTest.java index 82e5a8212fab0..bec971dfa40e7 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/LoadReportNetworkLimitTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/loadbalance/LoadReportNetworkLimitTest.java @@ -29,7 +29,7 @@ @Test(groups = "broker") public class LoadReportNetworkLimitTest extends MockedPulsarServiceBaseTest { - int nicCount; + int usableNicCount; @Override protected void doInitConf() throws Exception { @@ -43,7 +43,7 @@ protected void doInitConf() throws Exception { public void setup() throws Exception { super.internalSetup(); if (SystemUtils.IS_OS_LINUX) { - nicCount = LinuxInfoUtils.getPhysicalNICs().size(); + usableNicCount = LinuxInfoUtils.getUsablePhysicalNICs().size(); } } @@ -60,8 +60,8 @@ public void checkLoadReportNicSpeed() throws Exception { LoadManagerReport report = admin.brokerStats().getLoadReport(); if (SystemUtils.IS_OS_LINUX) { - assertEquals(report.getBandwidthIn().limit, nicCount * 5.4 * 1000 * 1000); - assertEquals(report.getBandwidthOut().limit, nicCount * 5.4 * 1000 * 1000); + assertEquals(report.getBandwidthIn().limit, usableNicCount * 5.4 * 1000 * 1000); + assertEquals(report.getBandwidthOut().limit, usableNicCount * 5.4 * 1000 * 1000); } else { // On non-Linux system we don't report the network usage assertEquals(report.getBandwidthIn().limit, -1.0); From 1dd84698f9c45b31ffb36cfe7aa702c9a7dae7f9 Mon Sep 17 00:00:00 2001 From: thetumbled <843221020@qq.com> Date: Mon, 12 Dec 2022 14:49:42 +0800 Subject: [PATCH 3/3] fix checkstyle error --- .../broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java index 575c941d2810b..318f37f7f7a97 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/loadbalance/impl/LinuxBrokerHostUsageImpl.java @@ -21,10 +21,10 @@ import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.NICUsageType; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getCpuUsageForCGroup; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getCpuUsageForEntireHost; -import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getUsablePhysicalNICs; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getTotalCpuLimit; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getTotalNicLimit; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getTotalNicUsage; +import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.getUsablePhysicalNICs; import static org.apache.pulsar.broker.loadbalance.LinuxInfoUtils.isCGroupEnabled; import static org.apache.pulsar.common.util.Runnables.catchingAndLoggingThrowables; import com.google.common.annotations.VisibleForTesting;