moremind commented on code in PR #6057:
URL: https://github.com/apache/shenyu/pull/6057#discussion_r2360000488


##########
shenyu-bootstrap/src/main/resources/application.yml:
##########
@@ -194,10 +194,12 @@ shenyu:
 #      workerCount: 8
 #      daemon: true
   register:
-    enabled: false
-    registerType: zookeeper #etcd #consul
-    serverLists: localhost:2181 #http://localhost:2379 #localhost:8848
+    enable: true
+    registerType: http

Review Comment:
   not change the config



##########
shenyu-common/pom.xml:
##########
@@ -89,11 +89,11 @@
             <artifactId>bcprov-jdk18on</artifactId>
         </dependency>
         
-<!--        <dependency>-->
-<!--            <groupId>com.github.oshi</groupId>-->
-<!--            <artifactId>oshi-core</artifactId>-->
-<!--            <version>6.7.0</version>-->
-<!--        </dependency>-->

Review Comment:
   why change?



##########
shenyu-register-center/shenyu-register-client-beat/src/main/java/org/apache/shenyu/register/client/beat/HeartbeatListener.java:
##########
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.register.client.beat;
+
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.config.ShenyuConfig;
+import org.apache.shenyu.common.constant.InstanceTypeConstants;
+import org.apache.shenyu.common.utils.IpUtils;
+import org.apache.shenyu.common.utils.SystemInfoUtils;
+import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.EventListener;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class HeartbeatListener {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(HeartbeatListener.class);
+
+    private static final int INITIAL_DELAY = 0;
+
+    private static final int CHECK_PERIOD = 5;
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final ShenyuClientRegisterRepository httpClientRegisterRepository;
+
+    private final ShenyuConfig shenyuConfig;
+
+    public HeartbeatListener(final ShenyuClientRegisterRepository 
httpClientRegisterRepository, final ShenyuConfig shenyuConfig, final 
ServerProperties serverProperties) {
+        executor = new ScheduledThreadPoolExecutor(1, 
ShenyuThreadFactory.create("scheduled-instance-task", false));
+        this.httpClientRegisterRepository = httpClientRegisterRepository;
+        this.shenyuConfig = shenyuConfig;
+        LOG.info("Web server initialized on port {}, starting heartbeat 
reporter", serverProperties.getPort());
+        //启动心跳任务

Review Comment:
   change the comment



##########
shenyu-register-center/shenyu-register-client-beat/src/main/java/org/apache/shenyu/register/client/beat/HeartbeatListener.java:
##########
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.register.client.beat;
+
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.config.ShenyuConfig;
+import org.apache.shenyu.common.constant.InstanceTypeConstants;
+import org.apache.shenyu.common.utils.IpUtils;
+import org.apache.shenyu.common.utils.SystemInfoUtils;
+import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.EventListener;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class HeartbeatListener {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(HeartbeatListener.class);
+
+    private static final int INITIAL_DELAY = 0;
+
+    private static final int CHECK_PERIOD = 5;
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final ShenyuClientRegisterRepository httpClientRegisterRepository;
+
+    private final ShenyuConfig shenyuConfig;
+
+    public HeartbeatListener(final ShenyuClientRegisterRepository 
httpClientRegisterRepository, final ShenyuConfig shenyuConfig, final 
ServerProperties serverProperties) {
+        executor = new ScheduledThreadPoolExecutor(1, 
ShenyuThreadFactory.create("scheduled-instance-task", false));

Review Comment:
   use scheduled-heartbeat-task???



##########
shenyu-common/src/main/java/org/apache/shenyu/common/utils/SystemInfoUtils.java:
##########
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.common.utils;
+
+import com.sun.management.OperatingSystemMXBean;
+import oshi.SystemInfo;
+
+import java.lang.management.ManagementFactory;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Map;
+
+/**
+ * The type System info utils.
+ */
+public final class SystemInfoUtils {
+    
+    /**
+     * Gets system info.
+     *
+     * @return the system info
+     */
+    public static String getSystemInfo() {
+        try {
+            // Get host information using OSHI
+            SystemInfo systemInfo = new SystemInfo();
+            
+            // Get host information
+            OperatingSystemMXBean osBean =
+                    (OperatingSystemMXBean) 
ManagementFactory.getOperatingSystemMXBean();
+            Map<String, Object> hostInfo = Map.of(
+                    "arch", osBean.getArch(),
+                    "operatingSystem", 
systemInfo.getOperatingSystem().toString(),
+                    "availableProcessors", osBean.getAvailableProcessors(),
+                    "totalMemorySizeGB", 
bytesToGB(osBean.getTotalMemorySize()) + " GB"
+            );
+            return GsonUtils.getInstance().toJson(hostInfo);
+        } catch (Exception e) {
+            // Handle any exceptions that may occur
+            return "Error retrieving system information: " + e.getMessage();
+        }
+    }
+    
+    /**
+     * Bytes to gb double.
+     *
+     * @param bytesValue the bytes value
+     * @return the double
+     */
+    private static double bytesToGB(final long bytesValue) {
+        return BigDecimal.valueOf(bytesValue / (1024.0 * 1024 * 
1024)).setScale(2, RoundingMode.HALF_UP).doubleValue();

Review Comment:
   not use magic value



##########
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/InstanceCheckService.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.admin.service.impl;
+
+import jakarta.annotation.PreDestroy;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.event.instance.InstanceInfoReportEvent;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualLineVO;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualVO;
+import org.apache.shenyu.admin.model.vo.InstanceInfoVO;
+import org.apache.shenyu.admin.service.InstanceInfoService;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.enums.InstanceStatusEnum;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * This is the client check service.
+ */
+@Component
+public class InstanceCheckService {
+
+    private static final int MAX_HISTORY_SIZE = 20;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UpstreamCheckService.class);
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final int scheduledTime;
+
+    private ConcurrentHashMap<String, InstanceInfoVO> instanceHealthBeatInfo;
+
+    private long instanceHeartBeatTimeOut;
+
+    private long deleteTimeout;
+
+    private InstanceInfoService instanceInfoService;
+
+    private final Map<Integer, Deque<Long>> stateHistoryMap;

Review Comment:
   when clear? when remove?



##########
shenyu-common/src/main/java/org/apache/shenyu/common/utils/SystemInfoUtils.java:
##########
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.common.utils;
+
+import com.sun.management.OperatingSystemMXBean;
+import oshi.SystemInfo;
+
+import java.lang.management.ManagementFactory;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Map;
+
+/**
+ * The type System info utils.
+ */
+public final class SystemInfoUtils {
+    
+    /**
+     * Gets system info.
+     *
+     * @return the system info
+     */
+    public static String getSystemInfo() {
+        try {
+            // Get host information using OSHI
+            SystemInfo systemInfo = new SystemInfo();
+            
+            // Get host information
+            OperatingSystemMXBean osBean =
+                    (OperatingSystemMXBean) 
ManagementFactory.getOperatingSystemMXBean();
+            Map<String, Object> hostInfo = Map.of(
+                    "arch", osBean.getArch(),
+                    "operatingSystem", 
systemInfo.getOperatingSystem().toString(),
+                    "availableProcessors", osBean.getAvailableProcessors(),
+                    "totalMemorySizeGB", 
bytesToGB(osBean.getTotalMemorySize()) + " GB"
+            );
+            return GsonUtils.getInstance().toJson(hostInfo);
+        } catch (Exception e) {
+            // Handle any exceptions that may occur
+            return "Error retrieving system information: " + e.getMessage();

Review Comment:
   why not throw ??



##########
shenyu-common/src/main/java/org/apache/shenyu/common/utils/SystemInfoUtils.java:
##########
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.common.utils;
+
+import com.sun.management.OperatingSystemMXBean;
+import oshi.SystemInfo;
+
+import java.lang.management.ManagementFactory;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Map;
+
+/**
+ * The type System info utils.
+ */
+public final class SystemInfoUtils {
+    
+    /**
+     * Gets system info.
+     *
+     * @return the system info
+     */
+    public static String getSystemInfo() {
+        try {
+            // Get host information using OSHI
+            SystemInfo systemInfo = new SystemInfo();
+            
+            // Get host information
+            OperatingSystemMXBean osBean =
+                    (OperatingSystemMXBean) 
ManagementFactory.getOperatingSystemMXBean();
+            Map<String, Object> hostInfo = Map.of(
+                    "arch", osBean.getArch(),
+                    "operatingSystem", 
systemInfo.getOperatingSystem().toString(),

Review Comment:
   not use  magic value???



##########
shenyu-register-center/shenyu-register-client-beat/pom.xml:
##########
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <groupId>org.apache.shenyu</groupId>
+        <artifactId>shenyu-register-center</artifactId>
+        <version>2.7.0.3-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>shenyu-register-client-beat</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>

Review Comment:
   remove the source and target!



##########
shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-beat/src/main/java/org/apache/shenyu/register/client/beat/HeartbeatListenerConfiguration.java:
##########
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.register.client.beat;
+
+import org.apache.shenyu.common.config.ShenyuConfig;
+import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
+import 
org.apache.shenyu.springboot.starter.client.common.config.ShenyuClientCommonBeanConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ImportAutoConfiguration(ShenyuClientCommonBeanConfiguration.class)
+@ConditionalOnProperty(value = "shenyu.register.enabled", matchIfMissing = 
true, havingValue = "true")

Review Comment:
   why configuration?



##########
shenyu-register-center/shenyu-register-client-beat/src/main/java/org/apache/shenyu/register/client/beat/HeartbeatListener.java:
##########
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.register.client.beat;
+
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.config.ShenyuConfig;
+import org.apache.shenyu.common.constant.InstanceTypeConstants;
+import org.apache.shenyu.common.utils.IpUtils;
+import org.apache.shenyu.common.utils.SystemInfoUtils;
+import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.context.event.EventListener;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class HeartbeatListener {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(HeartbeatListener.class);
+
+    private static final int INITIAL_DELAY = 0;
+
+    private static final int CHECK_PERIOD = 5;
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final ShenyuClientRegisterRepository httpClientRegisterRepository;
+
+    private final ShenyuConfig shenyuConfig;
+
+    public HeartbeatListener(final ShenyuClientRegisterRepository 
httpClientRegisterRepository, final ShenyuConfig shenyuConfig, final 
ServerProperties serverProperties) {
+        executor = new ScheduledThreadPoolExecutor(1, 
ShenyuThreadFactory.create("scheduled-instance-task", false));
+        this.httpClientRegisterRepository = httpClientRegisterRepository;
+        this.shenyuConfig = shenyuConfig;
+        LOG.info("Web server initialized on port {}, starting heartbeat 
reporter", serverProperties.getPort());
+        //启动心跳任务
+        executor.scheduleAtFixedRate(() -> {
+            InstanceBeatInfoDTO instanceBeatInfoDTO = new 
InstanceBeatInfoDTO();
+            instanceBeatInfoDTO.setInstancePort(serverProperties.getPort() + 
"");

Review Comment:
   why use +""?? why not use String.valueOf?



##########
shenyu-common/src/main/java/org/apache/shenyu/common/enums/InstanceStatusEnum.java:
##########
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.common.enums;
+
+public enum InstanceStatusEnum {
+
+    /**
+     * OFFLINE.
+     */
+    OFFLINE(2, "OFFLINE"),
+
+    /**
+     * ONLINE.
+     */
+    ONLINE(1, "ONLINE"),
+
+    /**
+     * DELETED.
+     */
+    DELETED(0, "DELETED");
+
+    private final int code;
+
+    private final String name;
+
+    InstanceStatusEnum(final int code, final String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public static String getNameByCode(final int code) {
+        for (InstanceStatusEnum status : values()) {
+            if (status.getCode() == code) {
+                return status.getName();
+            }
+        }
+        return "UNKNOWN";

Review Comment:
   not use magic value, UNKNOW as instance status



##########
shenyu-common/src/main/java/org/apache/shenyu/common/utils/SystemInfoUtils.java:
##########
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.common.utils;
+
+import com.sun.management.OperatingSystemMXBean;
+import oshi.SystemInfo;
+
+import java.lang.management.ManagementFactory;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Map;
+
+/**
+ * The type System info utils.
+ */
+public final class SystemInfoUtils {
+    
+    /**
+     * Gets system info.
+     *
+     * @return the system info
+     */
+    public static String getSystemInfo() {
+        try {
+            // Get host information using OSHI
+            SystemInfo systemInfo = new SystemInfo();
+            
+            // Get host information
+            OperatingSystemMXBean osBean =
+                    (OperatingSystemMXBean) 
ManagementFactory.getOperatingSystemMXBean();
+            Map<String, Object> hostInfo = Map.of(
+                    "arch", osBean.getArch(),
+                    "operatingSystem", 
systemInfo.getOperatingSystem().toString(),
+                    "availableProcessors", osBean.getAvailableProcessors(),
+                    "totalMemorySizeGB", 
bytesToGB(osBean.getTotalMemorySize()) + " GB"
+            );
+            return GsonUtils.getInstance().toJson(hostInfo);
+        } catch (Exception e) {
+            // Handle any exceptions that may occur
+            return "Error retrieving system information: " + e.getMessage();

Review Comment:
   throw new ShenyuException??



##########
shenyu-common/src/main/java/org/apache/shenyu/common/enums/InstanceStatusEnum.java:
##########
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.common.enums;
+
+public enum InstanceStatusEnum {
+
+    /**
+     * OFFLINE.
+     */
+    OFFLINE(2, "OFFLINE"),
+
+    /**

Review Comment:
   sort by code,pls



##########
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/InstanceCheckService.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.admin.service.impl;
+
+import jakarta.annotation.PreDestroy;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.event.instance.InstanceInfoReportEvent;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualLineVO;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualVO;
+import org.apache.shenyu.admin.model.vo.InstanceInfoVO;
+import org.apache.shenyu.admin.service.InstanceInfoService;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.enums.InstanceStatusEnum;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * This is the client check service.
+ */
+@Component
+public class InstanceCheckService {
+
+    private static final int MAX_HISTORY_SIZE = 20;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UpstreamCheckService.class);
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final int scheduledTime;
+
+    private ConcurrentHashMap<String, InstanceInfoVO> instanceHealthBeatInfo;

Review Comment:
   when clear, when remove?



##########
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/InstanceCheckService.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.admin.service.impl;
+
+import jakarta.annotation.PreDestroy;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.event.instance.InstanceInfoReportEvent;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualLineVO;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualVO;
+import org.apache.shenyu.admin.model.vo.InstanceInfoVO;
+import org.apache.shenyu.admin.service.InstanceInfoService;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.enums.InstanceStatusEnum;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * This is the client check service.
+ */
+@Component
+public class InstanceCheckService {
+
+    private static final int MAX_HISTORY_SIZE = 20;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UpstreamCheckService.class);
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final int scheduledTime;
+
+    private ConcurrentHashMap<String, InstanceInfoVO> instanceHealthBeatInfo;
+
+    private long instanceHeartBeatTimeOut;
+
+    private long deleteTimeout;
+
+    private InstanceInfoService instanceInfoService;
+
+    private final Map<Integer, Deque<Long>> stateHistoryMap;
+
+    public InstanceCheckService(final InstanceInfoService instanceInfoService) 
{
+        this.scheduledTime = 10;
+        this.instanceHealthBeatInfo = new ConcurrentHashMap<>();
+        this.instanceHeartBeatTimeOut = 1000 * 20;
+        this.deleteTimeout = 1000 * 60;
+        this.instanceInfoService = instanceInfoService;
+        this.stateHistoryMap = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * Set up.
+     */
+    public void setup() {
+        this.fetchInstanceData();
+        executor = new ScheduledThreadPoolExecutor(1, 
ShenyuThreadFactory.create("scheduled-instance-task", false));
+        executor.scheduleWithFixedDelay(this::scheduled, 30, scheduledTime, 
TimeUnit.SECONDS);
+        executor.scheduleWithFixedDelay(this::syncDB, 40, scheduledTime, 
TimeUnit.SECONDS);
+    }
+
+    /**
+     * fetch instance status data from db.
+     */
+    public void fetchInstanceData() {
+        List<InstanceInfoVO> list = instanceInfoService.list();
+        list.forEach(instanceInfoVO -> {
+            String instanceKey = getInstanceKey(instanceInfoVO);
+            instanceHealthBeatInfo.put(instanceKey, instanceInfoVO);
+        });
+    }
+
+    public String getInstanceKey(final InstanceInfoVO instanceInfoVO) {
+        return instanceInfoVO.getInstanceIp() + ":" + 
instanceInfoVO.getInstancePort() + "@" + instanceInfoVO.getInstanceType() + "#" 
+ instanceInfoVO.getNamespaceId();

Review Comment:
   use new method to do things



##########
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/AbstractShenyuClientRegisterServiceImpl.java:
##########
@@ -250,9 +256,26 @@ public String doHeartbeat(final String selectorName, final 
List<URIRegisterDTO>
                     uriRegisterDTO.getPort(),
                     uriRegisterDTO.getProtocol(),
                     uriRegisterDTO.getNamespaceId());
+
+            try {
+                // publish instance info event
+                publisher.publish(
+                        new InstanceInfoReportEvent(

Review Comment:
   InstanceInfoReportEvent event = new InstanceInfoReportEvent(xxxx)



##########
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/InstanceCheckService.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.admin.service.impl;
+
+import jakarta.annotation.PreDestroy;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.event.instance.InstanceInfoReportEvent;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualLineVO;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualVO;
+import org.apache.shenyu.admin.model.vo.InstanceInfoVO;
+import org.apache.shenyu.admin.service.InstanceInfoService;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.enums.InstanceStatusEnum;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * This is the client check service.
+ */
+@Component
+public class InstanceCheckService {
+
+    private static final int MAX_HISTORY_SIZE = 20;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UpstreamCheckService.class);

Review Comment:
   error !



##########
shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/InstanceCheckService.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shenyu.admin.service.impl;
+
+import jakarta.annotation.PreDestroy;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.event.instance.InstanceInfoReportEvent;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualLineVO;
+import org.apache.shenyu.admin.model.vo.InstanceDataVisualVO;
+import org.apache.shenyu.admin.model.vo.InstanceInfoVO;
+import org.apache.shenyu.admin.service.InstanceInfoService;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.enums.InstanceStatusEnum;
+import org.apache.shenyu.register.common.dto.InstanceBeatInfoDTO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * This is the client check service.
+ */
+@Component
+public class InstanceCheckService {
+
+    private static final int MAX_HISTORY_SIZE = 20;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UpstreamCheckService.class);
+
+    private ScheduledThreadPoolExecutor executor;
+
+    private final int scheduledTime;
+
+    private ConcurrentHashMap<String, InstanceInfoVO> instanceHealthBeatInfo;
+
+    private long instanceHeartBeatTimeOut;
+
+    private long deleteTimeout;
+
+    private InstanceInfoService instanceInfoService;
+
+    private final Map<Integer, Deque<Long>> stateHistoryMap;
+
+    public InstanceCheckService(final InstanceInfoService instanceInfoService) 
{
+        this.scheduledTime = 10;
+        this.instanceHealthBeatInfo = new ConcurrentHashMap<>();
+        this.instanceHeartBeatTimeOut = 1000 * 20;
+        this.deleteTimeout = 1000 * 60;
+        this.instanceInfoService = instanceInfoService;
+        this.stateHistoryMap = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * Set up.
+     */
+    public void setup() {
+        this.fetchInstanceData();
+        executor = new ScheduledThreadPoolExecutor(1, 
ShenyuThreadFactory.create("scheduled-instance-task", false));
+        executor.scheduleWithFixedDelay(this::scheduled, 30, scheduledTime, 
TimeUnit.SECONDS);
+        executor.scheduleWithFixedDelay(this::syncDB, 40, scheduledTime, 
TimeUnit.SECONDS);
+    }
+
+    /**
+     * fetch instance status data from db.
+     */
+    public void fetchInstanceData() {
+        List<InstanceInfoVO> list = instanceInfoService.list();
+        list.forEach(instanceInfoVO -> {
+            String instanceKey = getInstanceKey(instanceInfoVO);
+            instanceHealthBeatInfo.put(instanceKey, instanceInfoVO);
+        });
+    }
+
+    public String getInstanceKey(final InstanceInfoVO instanceInfoVO) {
+        return instanceInfoVO.getInstanceIp() + ":" + 
instanceInfoVO.getInstancePort() + "@" + instanceInfoVO.getInstanceType() + "#" 
+ instanceInfoVO.getNamespaceId();
+    }
+
+    public String getInstanceKey(final InstanceBeatInfoDTO 
instanceBeatInfoDTO) {
+        return instanceBeatInfoDTO.getInstanceIp() + ":" + 
instanceBeatInfoDTO.getInstancePort() + "@" + 
instanceBeatInfoDTO.getInstanceType() + "#" + 
instanceBeatInfoDTO.getNamespaceId();
+    }
+
+    public InstanceInfoVO getInstanceHealthBeatInfo(final InstanceBeatInfoDTO 
instanceBeatInfoDTO) {
+        return instanceHealthBeatInfo.get(getInstanceKey(instanceBeatInfoDTO));
+    }
+
+    public InstanceInfoVO getInstanceHealthBeatInfo(final String instanceKey) {
+        return instanceHealthBeatInfo.get(instanceKey);
+    }
+
+    public void handleBeatInfo(final InstanceBeatInfoDTO instanceBeatInfoDTO) {
+        String instanceKey = getInstanceKey(instanceBeatInfoDTO);
+        if (instanceHealthBeatInfo.containsKey(instanceKey)) {
+            InstanceInfoVO instanceInfoVO = 
instanceHealthBeatInfo.get(instanceKey);
+            instanceInfoVO.setLastHeartBeatTime(System.currentTimeMillis());
+        } else {
+            InstanceInfoVO instanceInfoVO = new InstanceInfoVO();
+            instanceInfoVO.setInstanceIp(instanceBeatInfoDTO.getInstanceIp());
+            instanceInfoVO.setInstanceState(1);
+            
instanceInfoVO.setInstanceInfo(instanceBeatInfoDTO.getInstanceInfo());
+            
instanceInfoVO.setInstanceType(instanceBeatInfoDTO.getInstanceType());
+            instanceInfoVO.setLastHeartBeatTime(System.currentTimeMillis());
+            
instanceInfoVO.setInstancePort(instanceBeatInfoDTO.getInstancePort());
+            
instanceInfoVO.setNamespaceId(instanceBeatInfoDTO.getNamespaceId());
+            instanceInfoVO.setLastHeartBeatTime(System.currentTimeMillis());
+            instanceHealthBeatInfo.put(instanceKey, instanceInfoVO);
+        }
+    }
+
+    private void scheduled() {
+        try {
+            doCheck();
+        } catch (Exception e) {
+            LOG.error("upstream scheduled check error -------- ", e);

Review Comment:
   not use ----------------



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@shenyu.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to