This is an automated email from the ASF dual-hosted git repository.

liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 0f2f7acce2 modify loadbalancer (#6251)
0f2f7acce2 is described below

commit 0f2f7acce28824e56472607be3804407c636b357
Author: xiaoyu <[email protected]>
AuthorDate: Mon Dec 8 09:40:18 2025 +0800

    modify loadbalancer (#6251)
    
    * modify loadbalancer
    
    * modify loadbalancer
    
    * modify loadbalancer
    
    * modify loadbalancer
    
    * modify loadbalancer
    
    * modify loadbalancer
---
 .../shenyu/admin/shiro/config/ShiroRealm.java      |   2 +
 .../loadbalancer/cache/UpstreamCacheManager.java   |   4 +-
 .../loadbalancer/entity/LoadBalanceData.java       | 204 +++++++++++++++++++++
 .../shenyu/loadbalancer/entity/Upstream.java       | 130 ++++++++-----
 .../loadbalancer/factory/LoadBalancerFactory.java  |  10 +-
 .../loadbalancer/spi/AbstractLoadBalancer.java     |  12 +-
 .../shenyu/loadbalancer/spi/HashLoadBalancer.java  |  19 +-
 .../loadbalancer/spi/LeastActiveLoadBalance.java   |  11 +-
 .../shenyu/loadbalancer/spi/LoadBalancer.java      |   5 +-
 .../shenyu/loadbalancer/spi/P2cLoadBalancer.java   |  12 +-
 .../loadbalancer/spi/RandomLoadBalancer.java       |   8 +-
 .../loadbalancer/spi/RoundRobinLoadBalancer.java   |   3 +-
 .../spi/ShortestResponseLoadBalancer.java          |   3 +-
 .../shenyu/loadbalancer/entity/UpstreamTest.java   |   6 +-
 .../factory/LoadBalancerFactoryTest.java           |  14 +-
 .../loadbalancer/spi/HashLoadBalanceTest.java      |  87 ++-------
 .../loadbalancer/spi/HashLoadBalancerTest.java     |   3 +-
 .../spi/LeastActiveLoadBalanceTest.java            |  10 +-
 .../loadbalancer/spi/P2cLoadBalancerTest.java      |   9 +-
 .../loadbalancer/spi/RandomLoadBalancerTest.java   |  11 +-
 .../spi/RoundRobinLoadBalanceTest.java             |  13 +-
 .../spi/ShortestResponseLoadBalancerTest.java      |   5 +-
 shenyu-plugin/shenyu-plugin-base/pom.xml           |   6 +
 .../plugin/base/utils/LoadbalancerUtils.java       | 100 ++++++++++
 .../plugin/httpclient/DefaultRetryStrategy.java    |  26 +--
 .../apache/shenyu/plugin/divide/DividePlugin.java  |  15 +-
 .../dubbo/proxy/ApacheDubboGrayLoadBalance.java    |   4 +-
 .../dubbo/proxy/ApacheDubboProxyService.java       |  18 +-
 .../grpc/loadbalance/picker/ShenyuPicker.java      |  10 +-
 .../shenyu/plugin/websocket/WebSocketPlugin.java   |   5 +-
 .../DefaultConnectionConfigProvider.java           |   5 +-
 .../sdk/core/client/AbstractShenyuSdkClient.java   |   6 +-
 .../shenyu/sdk/feign/ShenyuDiscoveryClient.java    |  16 +-
 33 files changed, 545 insertions(+), 247 deletions(-)

diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/shiro/config/ShiroRealm.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/shiro/config/ShiroRealm.java
index 15431cf693..2cd6ac1428 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/shiro/config/ShiroRealm.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/shiro/config/ShiroRealm.java
@@ -29,6 +29,8 @@ import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authc.BearerToken;
+
+
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.Permission;
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
index ecb86c019c..30a76ed410 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
@@ -26,10 +26,12 @@ import org.apache.shenyu.common.utils.MapUtils;
 import org.apache.shenyu.common.utils.Singleton;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
@@ -155,7 +157,7 @@ public final class UpstreamCacheManager {
         }
 
         // Use a Set for O(1) lookups instead of nested loops
-        java.util.Set<Upstream> existUpstreamSet = new 
java.util.HashSet<>(existUpstreamList);
+        Set<Upstream> existUpstreamSet = new HashSet<>(existUpstreamList);
         offlineUpstreamList.forEach(offlineUp -> {
             if (existUpstreamSet.contains(offlineUp)) {
                 task.triggerRemoveOne(selectorId, offlineUp);
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/LoadBalanceData.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/LoadBalanceData.java
new file mode 100644
index 0000000000..b06ba56813
--- /dev/null
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/LoadBalanceData.java
@@ -0,0 +1,204 @@
+/*
+ * 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.loadbalancer.entity;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The type Load balance data.
+ */
+public class LoadBalanceData {
+    
+    private String httpMethod = "GET";
+    
+    private String ip = "127.0.0.1";
+    
+    private URI url;
+    
+    private Map<String, Collection<String>> headers = new HashMap<>();
+    
+    private Map<String, String> cookies = new HashMap<>();
+    
+    private Map<String, Object> attributes = new HashMap<>();
+    
+    private Map<String, Collection<String>> queryParams = new HashMap<>();
+    
+    /**
+     * Instantiates a new Load balance data.
+     */
+    public LoadBalanceData() {
+    }
+    
+    /**
+     * Instantiates a new Load balance data.
+     *
+     * @param httpMethod the http method
+     * @param ip the ip
+     * @param url the url
+     * @param headers the headers
+     * @param cookies the cookies
+     * @param attributes the attributes
+     * @param queryParams the query params
+     */
+    public LoadBalanceData(final String httpMethod,
+                           final String ip,
+                           final URI url,
+                           final Map<String, Collection<String>> headers,
+                           final Map<String, String> cookies,
+                           final Map<String, Object> attributes,
+                           final Map<String, Collection<String>> queryParams) {
+        this.httpMethod = httpMethod;
+        this.ip = ip;
+        this.url = url;
+        this.headers = headers;
+        this.cookies = cookies;
+        this.attributes = attributes;
+        this.queryParams = queryParams;
+    }
+    
+    
+    /**
+     * Gets http method.
+     *
+     * @return the http method
+     */
+    public String getHttpMethod() {
+        return httpMethod;
+    }
+    
+    /**
+     * Gets ip.
+     *
+     * @return the ip
+     */
+    public String getIp() {
+        return ip;
+    }
+    
+    
+    /**
+     * Gets url.
+     *
+     * @return the url
+     */
+    public URI getUrl() {
+        return url;
+    }
+    
+    /**
+     * Gets headers.
+     *
+     * @return the headers
+     */
+    public Map<String, Collection<String>> getHeaders() {
+        return headers;
+    }
+    
+    /**
+     * Gets cookies.
+     *
+     * @return the cookies
+     */
+    public Map<String, String> getCookies() {
+        return cookies;
+    }
+    
+    /**
+     * Gets attributes.
+     *
+     * @return the attributes
+     */
+    public Map<String, Object> getAttributes() {
+        return attributes;
+    }
+    
+    /**
+     * Gets query params.
+     *
+     * @return the query params
+     */
+    public Map<String, Collection<String>> getQueryParams() {
+        return queryParams;
+    }
+    
+    /**
+     * Sets http method.
+     *
+     * @param httpMethod the http method
+     */
+    public void setHttpMethod(final String httpMethod) {
+        this.httpMethod = httpMethod;
+    }
+    
+    /**
+     * Sets query params.
+     *
+     * @param queryParams the query params
+     */
+    public void setQueryParams(final Map<String, Collection<String>> 
queryParams) {
+        this.queryParams = queryParams;
+    }
+    
+    /**
+     * Sets attributes.
+     *
+     * @param attributes the attributes
+     */
+    public void setAttributes(final Map<String, Object> attributes) {
+        this.attributes = attributes;
+    }
+    
+    /**
+     * Sets cookies.
+     *
+     * @param cookies the cookies
+     */
+    public void setCookies(final Map<String, String> cookies) {
+        this.cookies = cookies;
+    }
+    
+    /**
+     * Sets headers.
+     *
+     * @param headers the headers
+     */
+    public void setHeaders(final Map<String, Collection<String>> headers) {
+        this.headers = headers;
+    }
+    
+    /**
+     * Sets url.
+     *
+     * @param url the url
+     */
+    public void setUrl(final URI url) {
+        this.url = url;
+    }
+    
+    /**
+     * Sets ip.
+     *
+     * @param ip the ip
+     */
+    public void setIp(final String ip) {
+        this.ip = ip;
+    }
+}
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
index 05c962bdc0..c815d67e28 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
@@ -19,8 +19,10 @@ package org.apache.shenyu.loadbalancer.entity;
 
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -102,7 +104,10 @@ public final class Upstream {
      * this is gray.
      */
     private boolean gray;
-
+    
+    private Map<String, String> metadata = new ConcurrentHashMap<>();
+    
+    
     /**
      * Total number of requests being processed.
      */
@@ -123,7 +128,7 @@ public final class Upstream {
         this.version = builder.version;
         this.gray = builder.gray;
     }
-
+    
     /**
      * Gets protocol.
      *
@@ -132,7 +137,7 @@ public final class Upstream {
     public String getProtocol() {
         return protocol;
     }
-
+    
     /**
      * Is status boolean.
      *
@@ -141,7 +146,7 @@ public final class Upstream {
     public boolean isStatus() {
         return status;
     }
-
+    
     /**
      * Sets status.
      *
@@ -150,7 +155,7 @@ public final class Upstream {
     public void setStatus(final boolean status) {
         this.status = status;
     }
-
+    
     /**
      * Gets timestamp.
      *
@@ -159,7 +164,7 @@ public final class Upstream {
     public long getTimestamp() {
         return timestamp;
     }
-
+    
     /**
      * Gets warmup.
      *
@@ -168,7 +173,7 @@ public final class Upstream {
     public int getWarmup() {
         return warmup;
     }
-
+    
     /**
      * Gets url.
      *
@@ -177,7 +182,7 @@ public final class Upstream {
     public String getUrl() {
         return url;
     }
-
+    
     /**
      * Sets url.
      *
@@ -186,7 +191,7 @@ public final class Upstream {
     public void setUrl(final String url) {
         this.url = url;
     }
-
+    
     /**
      * get weight.
      *
@@ -195,7 +200,7 @@ public final class Upstream {
     public int getWeight() {
         return weight;
     }
-
+    
     /**
      * Sets weight.
      *
@@ -204,7 +209,7 @@ public final class Upstream {
     public void setWeight(final int weight) {
         this.weight = weight;
     }
-
+    
     /**
      * Is healthy boolean.
      *
@@ -213,7 +218,7 @@ public final class Upstream {
     public boolean isHealthy() {
         return healthy;
     }
-
+    
     /**
      * Sets healthy.
      *
@@ -222,7 +227,7 @@ public final class Upstream {
     public void setHealthy(final boolean healthy) {
         this.healthy = healthy;
     }
-
+    
     /**
      * Gets last health timestamp.
      *
@@ -231,7 +236,7 @@ public final class Upstream {
     public long getLastHealthTimestamp() {
         return lastHealthTimestamp;
     }
-
+    
     /**
      * Sets last health timestamp.
      *
@@ -240,7 +245,7 @@ public final class Upstream {
     public void setLastHealthTimestamp(final long lastHealthTimestamp) {
         this.lastHealthTimestamp = lastHealthTimestamp;
     }
-
+    
     /**
      * Gets last unhealthy timestamp.
      *
@@ -249,7 +254,7 @@ public final class Upstream {
     public long getLastUnhealthyTimestamp() {
         return lastUnhealthyTimestamp;
     }
-
+    
     /**
      * Sets last unhealthy timestamp.
      *
@@ -258,7 +263,7 @@ public final class Upstream {
     public void setLastUnhealthyTimestamp(final long lastUnhealthyTimestamp) {
         this.lastUnhealthyTimestamp = lastUnhealthyTimestamp;
     }
-
+    
     /**
      * Gets group.
      *
@@ -267,7 +272,7 @@ public final class Upstream {
     public String getGroup() {
         return group;
     }
-
+    
     /**
      * Sets group.
      *
@@ -276,7 +281,7 @@ public final class Upstream {
     public void setGroup(final String group) {
         this.group = group;
     }
-
+    
     /**
      * Gets version.
      *
@@ -285,7 +290,7 @@ public final class Upstream {
     public String getVersion() {
         return version;
     }
-
+    
     /**
      * Sets version.
      *
@@ -294,7 +299,7 @@ public final class Upstream {
     public void setVersion(final String version) {
         this.version = version;
     }
-
+    
     /**
      * Gets lag.
      *
@@ -303,15 +308,16 @@ public final class Upstream {
     public long getLag() {
         return lag;
     }
-
+    
     /**
      * Sets lag.
+     *
      * @param lag the lag
      */
     public void setLag(final long lag) {
         this.lag = lag;
     }
-
+    
     /**
      * Gets responseStamp.
      *
@@ -320,15 +326,16 @@ public final class Upstream {
     public long getResponseStamp() {
         return responseStamp;
     }
-
+    
     /**
      * Sets responseStamp.
+     *
      * @param responseStamp the responseStamp
      */
     public void setResponseStamp(final long responseStamp) {
         this.responseStamp = responseStamp;
     }
-
+    
     /**
      * Gets lastPickedStamp.
      *
@@ -337,15 +344,16 @@ public final class Upstream {
     public long getLastPicked() {
         return lastPicked;
     }
-
+    
     /**
      * Sets lastPickedStamp.
+     *
      * @param lastPicked the lastPickedStamp
      */
     public void setLastPicked(final long lastPicked) {
         this.lastPicked = lastPicked;
     }
-
+    
     /**
      * Gets inflight.
      *
@@ -354,24 +362,25 @@ public final class Upstream {
     public AtomicLong getInflight() {
         return inflight;
     }
-
+    
     /**
      * Sets inflight.
+     *
      * @param inflight the inflight
      */
     public void setInflight(final AtomicLong inflight) {
         this.inflight = inflight;
     }
-
+    
     /**
      * gray.
      *
-     * @return Gray
+     * @return Gray boolean
      */
     public boolean isGray() {
         return gray;
     }
-
+    
     /**
      * set gray.
      *
@@ -380,25 +389,46 @@ public final class Upstream {
     public void setGray(final boolean gray) {
         this.gray = gray;
     }
-
+    
+    /**
+     * Gets metadata.
+     *
+     * @return the metadata
+     */
+    public Map<String, String> getMetadata() {
+        return metadata;
+    }
+    
+    /**
+     * Sets metadata.
+     *
+     * @param metadata the metadata
+     */
+    public void setMetadata(final Map<String, String> metadata) {
+        this.metadata = metadata;
+    }
+    
     /**
      * Gets succeeded.
+     *
      * @return the succeeded
      */
     public AtomicLong getSucceeded() {
         return succeeded;
     }
-
+    
     /**
      * Gets succeededElapsed.
+     *
      * @return the succeededElapsed
      */
     public AtomicLong getSucceededElapsed() {
         return succeededElapsed;
     }
-
+    
     /**
      * Gets succeededAverageElapsed.
+     *
      * @return the succeededAverageElapsed.
      */
     public long getSucceededAverageElapsed() {
@@ -408,11 +438,11 @@ public final class Upstream {
         }
         return getSucceededElapsed().get() / succeeded;
     }
-
+    
     /**
      * build request domain.
      *
-     * @return domain
+     * @return domain string
      */
     public String buildDomain() {
         String protocol = this.getProtocol();
@@ -426,12 +456,12 @@ public final class Upstream {
      * Build request with protocol.
      *
      * @param protocol protocol
-     * @return domain
+     * @return domain string
      */
     public String buildDomain(final String protocol) {
         return protocol + 
Optional.ofNullable(this.getUrl()).map(String::trim).orElse(null);
     }
-
+    
     /**
      * class builder.
      *
@@ -471,7 +501,7 @@ public final class Upstream {
                 + ", version='" + version
                 + '}';
     }
-
+    
     /**
      * class builder.
      */
@@ -527,7 +557,7 @@ public final class Upstream {
          */
         private Builder() {
         }
-
+        
         /**
          * build new Object.
          *
@@ -536,7 +566,7 @@ public final class Upstream {
         public Upstream build() {
             return new Upstream(this);
         }
-
+        
         /**
          * build protocol.
          *
@@ -547,7 +577,7 @@ public final class Upstream {
             this.protocol = protocol;
             return this;
         }
-
+        
         /**
          * build url.
          *
@@ -558,7 +588,7 @@ public final class Upstream {
             this.url = url;
             return this;
         }
-
+        
         /**
          * build weight.
          *
@@ -569,7 +599,7 @@ public final class Upstream {
             this.weight = weight;
             return this;
         }
-
+        
         /**
          * build status.
          *
@@ -580,7 +610,7 @@ public final class Upstream {
             this.status = status;
             return this;
         }
-
+        
         /**
          * build timestamp.
          *
@@ -591,7 +621,7 @@ public final class Upstream {
             this.timestamp = timestamp;
             return this;
         }
-
+        
         /**
          * build warmup.
          *
@@ -602,7 +632,7 @@ public final class Upstream {
             this.warmup = warmup;
             return this;
         }
-
+        
         /**
          * build group.
          *
@@ -613,7 +643,7 @@ public final class Upstream {
             this.group = group;
             return this;
         }
-
+        
         /**
          * build version.
          *
@@ -624,8 +654,8 @@ public final class Upstream {
             this.version = version;
             return this;
         }
-
-
+        
+        
         /**
          * build gray.
          *
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactory.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactory.java
index bf1acd88c5..291039da43 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactory.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactory.java
@@ -17,11 +17,13 @@
 
 package org.apache.shenyu.loadbalancer.factory;
 
-import java.util.List;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.loadbalancer.spi.LoadBalancer;
 import org.apache.shenyu.spi.ExtensionLoader;
 
+import java.util.List;
+
 /**
  * The type Load balance Factory.
  */
@@ -35,11 +37,11 @@ public final class LoadBalancerFactory {
      *
      * @param upstreamList the upstream list
      * @param algorithm    the loadBalance algorithm
-     * @param ip           the ip
+     * @param data the data
      * @return the upstream
      */
-    public static Upstream selector(final List<Upstream> upstreamList, final 
String algorithm, final String ip) {
+    public static Upstream selector(final List<Upstream> upstreamList, final 
String algorithm, final LoadBalanceData data) {
         LoadBalancer loadBalance = 
ExtensionLoader.getExtensionLoader(LoadBalancer.class).getJoin(algorithm);
-        return loadBalance.select(upstreamList, ip);
+        return loadBalance.select(upstreamList, data);
     }
 }
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/AbstractLoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/AbstractLoadBalancer.java
index 070960ca96..052194a127 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/AbstractLoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/AbstractLoadBalancer.java
@@ -17,10 +17,12 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
-import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 
+import java.util.List;
+
 /**
  * The type Abstract load balancer.
  */
@@ -30,20 +32,20 @@ public abstract class AbstractLoadBalancer implements 
LoadBalancer {
      * Do select upstream.
      *
      * @param upstreamList the upstream list
-     * @param ip           the ip
+     * @param data  the data
      * @return the upstream
      */
-    protected abstract Upstream doSelect(List<Upstream> upstreamList, String 
ip);
+    protected abstract Upstream doSelect(List<Upstream> upstreamList, 
LoadBalanceData data);
 
     @Override
-    public Upstream select(final List<Upstream> upstreamList, final String ip) 
{
+    public Upstream select(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         if (CollectionUtils.isEmpty(upstreamList)) {
             return null;
         }
         if (upstreamList.size() == 1) {
             return upstreamList.get(0);
         }
-        return doSelect(upstreamList, ip);
+        return doSelect(upstreamList, data);
     }
 
     protected int getWeight(final Upstream upstream) {
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancer.java
index 4fad9f7e18..8de25c0e2f 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancer.java
@@ -17,6 +17,10 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.apache.shenyu.spi.Join;
+
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -24,8 +28,6 @@ import java.util.List;
 import java.util.SortedMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.stream.IntStream;
-import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.spi.Join;
 
 /**
  * hash algorithm impl.
@@ -37,22 +39,15 @@ public class HashLoadBalancer extends AbstractLoadBalancer {
      * virtual node used to solve unbalanced load.
      */
     private static final int VIRTUAL_NODE_NUM = 5;
-
-    /**
-     * consistent hash with virtual node to select upstream.
-     *
-     * @param upstreamList the upstream list
-     * @param ip           the ip
-     * @return selected upstream
-     */
+    
     @Override
-    public Upstream doSelect(final List<Upstream> upstreamList, final String 
ip) {
+    public Upstream doSelect(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         final ConcurrentSkipListMap<Long, Upstream> treeMap = new 
ConcurrentSkipListMap<>();
         upstreamList.forEach(upstream -> IntStream.range(0, 
VIRTUAL_NODE_NUM).forEach(i -> {
             long addressHash = hash("SHENYU-" + upstream.getUrl() + "-HASH-" + 
i);
             treeMap.put(addressHash, upstream);
         }));
-        long hash = hash(ip);
+        long hash = hash(data.getIp());
         SortedMap<Long, Upstream> lastRing = treeMap.tailMap(hash);
         if (!lastRing.isEmpty()) {
             return lastRing.get(lastRing.firstKey());
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalance.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalance.java
index 5d1b016bb4..5d117a1c08 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalance.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalance.java
@@ -17,6 +17,10 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.apache.shenyu.spi.Join;
+
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -24,9 +28,6 @@ import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
-import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.spi.Join;
-
 /**
  * least active algorithm impl.
  */
@@ -36,7 +37,7 @@ public class LeastActiveLoadBalance extends 
AbstractLoadBalancer {
     private final Map<String, Long> countMap = new ConcurrentHashMap<>();
 
     @Override
-    protected Upstream doSelect(final List<Upstream> upstreamList, final 
String ip) {
+    protected Upstream doSelect(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         Map<String, Upstream> domainMap = upstreamList.stream()
                 .collect(Collectors.toConcurrentMap(Upstream::buildDomain, 
upstream -> upstream));
 
@@ -51,7 +52,7 @@ public class LeastActiveLoadBalance extends 
AbstractLoadBalancer {
                 .map(Map.Entry::getKey)
                 .orElse(upstreamList.get(0).buildDomain());
 
-        countMap.computeIfPresent(domain, (key, actived) -> 
Optional.of(actived).orElse(Long.MIN_VALUE) + 1);
+        countMap.computeIfPresent(domain, (key, activated) -> 
Optional.of(activated).orElse(Long.MIN_VALUE) + 1);
         return domainMap.get(domain);
     }
     
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LoadBalancer.java
index 4809aa6212..ad0d0de3e2 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/LoadBalancer.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.spi.SPI;
 
@@ -32,8 +33,8 @@ public interface LoadBalancer {
      * this is select one for upstream list.
      *
      * @param upstreamList upstream list
-     * @param ip ip
+     * @param data data
      * @return upstream
      */
-    Upstream select(List<Upstream> upstreamList, String ip);
+    Upstream select(List<Upstream> upstreamList, LoadBalanceData data);
 }
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
index 684e4579df..dd0edb7ceb 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.spi.Join;
 
@@ -45,16 +46,9 @@ public class P2cLoadBalancer extends AbstractLoadBalancer {
     private static final int PICK_TIMES = 3;
 
     private final Random random = new Random();
-
-    /**
-     * pick of 2 choices to select upstream.
-     *
-     * @param upstreamList the upstream list
-     * @param ip           the ip
-     * @return selected upstream
-     */
+    
     @Override
-    protected Upstream doSelect(final List<Upstream> upstreamList, final 
String ip) {
+    protected Upstream doSelect(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         long start = System.currentTimeMillis();
         Upstream[] upstreams = pickTwoUpstreams(upstreamList);
         Upstream picked;
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancer.java
index eabb899940..5f5d7bbe33 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancer.java
@@ -17,11 +17,13 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
-import java.security.SecureRandom;
-import java.util.List;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.spi.Join;
 
+import java.security.SecureRandom;
+import java.util.List;
+
 /**
  * random algorithm impl.
  */
@@ -31,7 +33,7 @@ public class RandomLoadBalancer extends AbstractLoadBalancer {
     private static final SecureRandom RANDOM = new SecureRandom();
 
     @Override
-    public Upstream doSelect(final List<Upstream> upstreamList, final String 
ip) {
+    public Upstream doSelect(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         int length = upstreamList.size();
         // every upstream has the same weight?
         boolean sameWeight = true;
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalancer.java
index da3e62bece..8e3a1c3c0b 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalancer.java
@@ -18,6 +18,7 @@
 package org.apache.shenyu.loadbalancer.spi;
 
 import org.apache.shenyu.common.utils.MapUtils;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.spi.Join;
 
@@ -41,7 +42,7 @@ public class RoundRobinLoadBalancer extends 
AbstractLoadBalancer {
     private final AtomicBoolean updateLock = new AtomicBoolean();
 
     @Override
-    public Upstream doSelect(final List<Upstream> upstreamList, final String 
ip) {
+    public Upstream doSelect(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         String key = upstreamList.get(0).getUrl();
         ConcurrentMap<String, WeightedRoundRobin> map = 
MapUtils.computeIfAbsent(methodWeightMap, key, k -> new 
ConcurrentHashMap<>(16));
         int totalWeight = 0;
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancer.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancer.java
index 615608881b..edf4f15aa6 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancer.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancer.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.spi.Join;
 
@@ -31,7 +32,7 @@ import java.util.concurrent.atomic.AtomicLong;
 public class ShortestResponseLoadBalancer extends AbstractLoadBalancer {
 
     @Override
-    protected Upstream doSelect(final List<Upstream> upstreamList, final 
String ip) {
+    protected Upstream doSelect(final List<Upstream> upstreamList, final 
LoadBalanceData data) {
         int length = upstreamList.size();
         long shortestResponse = Long.MAX_VALUE;
         int shortestCount = 0;
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
index 0ce8dc53a7..9a9146f6b0 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
@@ -62,10 +62,10 @@ public class UpstreamTest {
                 .weight(1)
                 .status(true)
                 .build();
-        Assertions.assertEquals(upstream2.buildDomain(), "https://url";);
+        Assertions.assertEquals("https://url";, upstream2.buildDomain());
         Assertions.assertNotEquals(upstream, upstream2);
-        Assertions.assertNotEquals(upstream, null);
-        Assertions.assertNotEquals(upstream, "");
+        Assertions.assertNotEquals(null, upstream);
+        Assertions.assertNotEquals("", upstream);
         Assertions.assertEquals(upstream, upstream);
         Upstream upstream3 = Upstream.builder()
                 .protocol("https://";)
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactoryTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactoryTest.java
index cabe6c91f6..e7b7f2f280 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactoryTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/factory/LoadBalancerFactoryTest.java
@@ -17,15 +17,17 @@
 
 package org.apache.shenyu.loadbalancer.factory;
 
+import org.apache.shenyu.common.enums.LoadBalanceEnum;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.junit.jupiter.api.Test;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
-import org.apache.shenyu.common.enums.LoadBalanceEnum;
-import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
@@ -48,7 +50,7 @@ public final class LoadBalancerFactoryTest {
                         .collect(Collectors.toList());
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, 120).forEach(i -> {
-            Upstream result = LoadBalancerFactory.selector(upstreamList, 
LoadBalanceEnum.ROUND_ROBIN.getName(), "");
+            Upstream result = LoadBalancerFactory.selector(upstreamList, 
LoadBalanceEnum.ROUND_ROBIN.getName(), new LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
@@ -66,7 +68,7 @@ public final class LoadBalancerFactoryTest {
                         .collect(Collectors.toList());
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, 120).forEach(i -> {
-            Upstream result = LoadBalancerFactory.selector(upstreamList, 
LoadBalanceEnum.ROUND_ROBIN.getName(), "");
+            Upstream result = LoadBalancerFactory.selector(upstreamList, 
LoadBalanceEnum.ROUND_ROBIN.getName(), new LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
@@ -84,7 +86,7 @@ public final class LoadBalancerFactoryTest {
                         .collect(Collectors.toList());
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, 120).forEach(i -> {
-            Upstream result = LoadBalancerFactory.selector(upstreamList, 
LoadBalanceEnum.ROUND_ROBIN.getName(), "");
+            Upstream result = LoadBalancerFactory.selector(upstreamList, 
LoadBalanceEnum.ROUND_ROBIN.getName(), new LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalanceTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalanceTest.java
index 9f643fa58a..f00057e4d0 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalanceTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalanceTest.java
@@ -17,16 +17,13 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.mockito.MockedStatic;
 
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.List;
 import java.util.SortedMap;
 import java.util.concurrent.ConcurrentSkipListMap;
@@ -34,8 +31,6 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.mockStatic;
 
 /**
  * The type Hash balance test.
@@ -44,8 +39,6 @@ public final class HashLoadBalanceTest {
 
     private Method hash;
 
-    private List<Upstream> onlyOneList;
-
     private List<Upstream> hashLoadBalancesOrdered;
 
     private List<Upstream> hashLoadBalancesDisordered;
@@ -62,12 +55,6 @@ public final class HashLoadBalanceTest {
     public void setUp() throws Exception {
         this.hash = HashLoadBalancer.class.getDeclaredMethod("hash", 
String.class);
         this.hash.setAccessible(true);
-        this.onlyOneList = Stream.of(1)
-                .map(weight -> Upstream.builder()
-                        .url("upstream-" + weight)
-                        .status(false)
-                        .build())
-                .collect(Collectors.toList());
         this.hashLoadBalancesOrdered = Stream.of(1, 2, 3)
                 .map(weight -> Upstream.builder()
                         .url("upstream-" + weight)
@@ -109,56 +96,15 @@ public final class HashLoadBalanceTest {
         }
     }
 
-    /**
-     * Hash load balance test.
-     */
-    @Test
-    public void onlyOneListTest() {
-        final String ip = "127.0.0.1";
-        final HashLoadBalancer hashLoadBalance = new HashLoadBalancer();
-        Assertions.assertNotNull(hashLoadBalance.select(onlyOneList, ip));
-        
Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder().status(false).build()),
 0);
-        Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder()
-                .timestamp(System.currentTimeMillis() - 3L)
-                .warmup(4)
-                .weight(1)
-                .build()), 1);
-        Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder()
-                .timestamp(System.currentTimeMillis() + 3L)
-                .warmup(4)
-                .weight(1)
-                .build()), 1);
-        Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder()
-                .timestamp(System.currentTimeMillis() - 3000L)
-                .warmup(4000)
-                .weight(4)
-                .build()), 3);
-        Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder()
-                .timestamp(System.currentTimeMillis() - 3L)
-                .warmup(1)
-                .weight(1)
-                .build()), 1);
-        Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder()
-                .warmup(1)
-                .weight(0)
-                .build()), 0);
-        Assertions.assertEquals(hashLoadBalance.getWeight(Upstream.builder()
-                .warmup(0)
-                .weight(1)
-                .build()), 1);
-
-    }
-
     /**
      * Hash load balance test.
      */
     @Test
     public void hashLoadBalanceOrderedWeightTest() throws Exception {
-        final String ip = "127.0.0.1";
         final HashLoadBalancer hashLoadBalance = new HashLoadBalancer();
-        Assertions.assertNull(hashLoadBalance.select(null, ip));
-        final Upstream upstream = 
hashLoadBalance.select(hashLoadBalancesOrdered, ip);
-        final Long hashKey = Long.parseLong(hash.invoke(null, ip).toString());
+        Assertions.assertNull(hashLoadBalance.select(null, new 
LoadBalanceData()));
+        final Upstream upstream = 
hashLoadBalance.select(hashLoadBalancesOrdered, new LoadBalanceData());
+        final Long hashKey = Long.parseLong(hash.invoke(null, 
"127.0.0.1").toString());
         final SortedMap<Long, Upstream> lastRing = 
treeMapOrdered.tailMap(hashKey);
         final Upstream assertUp = lastRing.get(lastRing.firstKey());
         assertEquals(assertUp.getUrl(), upstream.getUrl());
@@ -167,27 +113,19 @@ public final class HashLoadBalanceTest {
     @Test
     public void selectTest() {
         final String ip = "SHENYU-upstream-2-HASH-100";
+        LoadBalanceData data = new LoadBalanceData();
+        data.setIp(ip);
         final HashLoadBalancer hashLoadBalance = new HashLoadBalancer();
-        Assertions.assertNull(hashLoadBalance.select(null, ip));
-        final Upstream upstream = 
hashLoadBalance.select(hashLoadBalancesOrdered, ip);
+        Assertions.assertNull(hashLoadBalance.select(null, new 
LoadBalanceData()));
+        final Upstream upstream = 
hashLoadBalance.select(hashLoadBalancesOrdered, data);
         assertEquals(treeMapOrdered.firstEntry().getValue().getUrl(), 
upstream.getUrl());
     }
 
-    @Test
-    public void hashErrorTest() throws NoSuchAlgorithmException {
-        final String ip = "127.0.0.1";
-        MockedStatic<MessageDigest> messageDigestMockedStatic = 
mockStatic(MessageDigest.class);
-        messageDigestMockedStatic.when((MockedStatic.Verification) 
MessageDigest.getInstance("MD5")).thenThrow(NoSuchAlgorithmException.class);
-        assertThrows(InvocationTargetException.class, () -> hash.invoke(null, 
ip));
-        messageDigestMockedStatic.close();
-    }
-
     @Test
     public void hashLoadBalanceDisorderedWeightTest() throws Exception {
-        final String ip = "127.0.0.1";
         final HashLoadBalancer hashLoadBalance = new HashLoadBalancer();
-        final Upstream upstream = 
hashLoadBalance.select(hashLoadBalancesDisordered, ip);
-        final Long hashKey = Long.parseLong(hash.invoke(null, ip).toString());
+        final Upstream upstream = 
hashLoadBalance.select(hashLoadBalancesDisordered, new LoadBalanceData());
+        final Long hashKey = Long.parseLong(hash.invoke(null, 
"127.0.0.1").toString());
         final SortedMap<Long, Upstream> lastRing = 
treeMapDisordered.tailMap(hashKey);
         final Upstream assertUp = lastRing.get(lastRing.firstKey());
         assertEquals(assertUp.getUrl(), upstream.getUrl());
@@ -196,10 +134,9 @@ public final class HashLoadBalanceTest {
 
     @Test
     public void hashLoadBalanceReversedWeightTest() throws Exception {
-        final String ip = "127.0.0.1";
         final HashLoadBalancer hashLoadBalance = new HashLoadBalancer();
-        final Upstream divideUpstream = 
hashLoadBalance.select(hashLoadBalancesReversed, ip);
-        final Long hashKey = Long.parseLong(hash.invoke(null, ip).toString());
+        final Upstream divideUpstream = 
hashLoadBalance.select(hashLoadBalancesReversed, new LoadBalanceData());
+        final Long hashKey = Long.parseLong(hash.invoke(null, 
"127.0.0.1").toString());
         final SortedMap<Long, Upstream> lastRing = 
treeMapReversed.tailMap(hashKey);
         final Upstream assertUp = lastRing.get(lastRing.firstKey());
         assertEquals(assertUp.getUrl(), divideUpstream.getUrl());
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancerTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancerTest.java
index e7c9d1fca4..a58beff641 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancerTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/HashLoadBalancerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Test;
 
@@ -38,7 +39,7 @@ class HashLoadBalancerTest {
         upstreamList.add(Upstream.builder().url("http://2.2.2.2/api";).build());
         upstreamList.add(Upstream.builder().url("http://3.3.3.3/api";).build());
 
-        final Upstream upstream = hashLoadBalancer.doSelect(upstreamList, 
"127.0.0.1");
+        Upstream upstream = hashLoadBalancer.doSelect(upstreamList, new 
LoadBalanceData());
         assertEquals(upstreamList.get(2).getUrl(), upstream.getUrl());
     }
 
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalanceTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalanceTest.java
index 49c1e70ab9..44a6851dc2 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalanceTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/LeastActiveLoadBalanceTest.java
@@ -17,12 +17,14 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
-import java.util.ArrayList;
-import java.util.List;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * The type least activity load balance test.
  */
@@ -49,8 +51,8 @@ public class LeastActiveLoadBalanceTest {
     public void testResponseTimeBalancer() throws Exception {
         buildUpstreamList();
         final LeastActiveLoadBalance leastActiveLoadBalance = new 
LeastActiveLoadBalance();
-        Upstream upstream = leastActiveLoadBalance.doSelect(onlyOneList, 
"localhost");
-        Upstream upstream1 = leastActiveLoadBalance.doSelect(onlyOneList, 
"localhost");
+        Upstream upstream = leastActiveLoadBalance.doSelect(onlyOneList, new 
LoadBalanceData());
+        Upstream upstream1 = leastActiveLoadBalance.doSelect(onlyOneList, new 
LoadBalanceData());
         Assertions.assertTrue(upstream.getUrl().equals("baidu.com") && 
upstream1.getUrl().equals("pro.jd.com")
                 || upstream1.getUrl().equals("baidu.com") && 
upstream.getUrl().equals("pro.jd.com"));
     }
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
index 493418656b..5b760949fc 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -47,8 +48,8 @@ public class P2cLoadBalancerTest {
     public void testResponseTimeBalancerSameLag() {
         buildUpstreamList();
         final P2cLoadBalancer p2cLoadBalancer = new P2cLoadBalancer();
-        Upstream upstream = p2cLoadBalancer.doSelect(upstreamList, 
"localhost");
-        Upstream upstream1 = p2cLoadBalancer.doSelect(upstreamList, 
"localhost");
+        Upstream upstream = p2cLoadBalancer.doSelect(upstreamList, new 
LoadBalanceData());
+        Upstream upstream1 = p2cLoadBalancer.doSelect(upstreamList, new 
LoadBalanceData());
         Assertions.assertTrue(upstream.getUrl().equals("baidu.com") && 
upstream1.getUrl().equals("pro.jd.com")
                 || upstream1.getUrl().equals("baidu.com") && 
upstream.getUrl().equals("pro.jd.com"));
     }
@@ -58,8 +59,8 @@ public class P2cLoadBalancerTest {
         buildUpstreamList();
         final P2cLoadBalancer p2cLoadBalancer = new P2cLoadBalancer();
         upstreamList.get(0).setLag(1);
-        Upstream upstream = p2cLoadBalancer.doSelect(upstreamList, 
"localhost");
-        Upstream upstream1 = p2cLoadBalancer.doSelect(upstreamList, 
"localhost");
+        Upstream upstream = p2cLoadBalancer.doSelect(upstreamList, new 
LoadBalanceData());
+        Upstream upstream1 = p2cLoadBalancer.doSelect(upstreamList, new 
LoadBalanceData());
         Assertions.assertTrue(upstream.getUrl().equals("baidu.com") && 
upstream1.getUrl().equals("pro.jd.com"));
     }
 }
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancerTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancerTest.java
index b6c8ad979f..f733a82b3b 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancerTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RandomLoadBalancerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Test;
 
@@ -37,7 +38,7 @@ public class RandomLoadBalancerTest {
                         .url("upstream-" + weight)
                         .weight(weight)
                         .build())
-                .collect(Collectors.toList()), "");
+                .collect(Collectors.toList()), new LoadBalanceData());
         assertNotNull(upstreamOrdered);
     }
 
@@ -48,7 +49,7 @@ public class RandomLoadBalancerTest {
                         .url("upstream-" + weight)
                         .weight(weight)
                         .build())
-                .collect(Collectors.toList()), "");
+                .collect(Collectors.toList()), new LoadBalanceData());
         assertNotNull(upstreamOrdered);
     }
 
@@ -62,7 +63,7 @@ public class RandomLoadBalancerTest {
                         .url("upstream-" + weight)
                         .weight(weight)
                         .build())
-                .collect(Collectors.toList()), "");
+                .collect(Collectors.toList()), new LoadBalanceData());
         assertNotNull(upstreamOrdered);
     }
 
@@ -73,7 +74,7 @@ public class RandomLoadBalancerTest {
                         .url("upstream-" + weight)
                         .weight(weight)
                         .build())
-                .collect(Collectors.toList()), "");
+                .collect(Collectors.toList()), new LoadBalanceData());
         assertNotNull(upstreamDisordered);
     }
 
@@ -84,7 +85,7 @@ public class RandomLoadBalancerTest {
                         .url("upstream-" + weight)
                         .weight(weight)
                         .build())
-                .collect(Collectors.toList()), "");
+                .collect(Collectors.toList()), new LoadBalanceData());
         assertNotNull(upstreamReversed);
     }
 }
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalanceTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalanceTest.java
index c21daab40d..dde5d3d0f8 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalanceTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/RoundRobinLoadBalanceTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Test;
 
@@ -54,7 +55,7 @@ public final class RoundRobinLoadBalanceTest {
         RoundRobinLoadBalancer roundRobinLoadBalancer = new 
RoundRobinLoadBalancer();
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, 120).forEach(i -> {
-            Upstream result = roundRobinLoadBalancer.select(upstreamList, "");
+            Upstream result = roundRobinLoadBalancer.select(upstreamList, new 
LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
@@ -74,7 +75,7 @@ public final class RoundRobinLoadBalanceTest {
         RoundRobinLoadBalancer roundRobinLoadBalancer = new 
RoundRobinLoadBalancer();
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, 120).forEach(i -> {
-            Upstream result = roundRobinLoadBalancer.select(upstreamList, "");
+            Upstream result = roundRobinLoadBalancer.select(upstreamList, new 
LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
@@ -94,7 +95,7 @@ public final class RoundRobinLoadBalanceTest {
         RoundRobinLoadBalancer roundRobinLoadBalancer = new 
RoundRobinLoadBalancer();
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, 120).forEach(i -> {
-            Upstream result = roundRobinLoadBalancer.select(upstreamList, "");
+            Upstream result = roundRobinLoadBalancer.select(upstreamList, new 
LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
@@ -121,19 +122,19 @@ public final class RoundRobinLoadBalanceTest {
         RoundRobinLoadBalancer roundRobinLoadBalancer = new 
RoundRobinLoadBalancer();
         
         // Test with weighted upstream list
-        Upstream result1 = roundRobinLoadBalancer.select(upstreamList, "");
+        Upstream result1 = roundRobinLoadBalancer.select(upstreamList, new 
LoadBalanceData());
         assertNotNull(result1, "Selected upstream should not be null");
         assertTrue(upstreamList.contains(result1), "Selected upstream should 
be from the provided list");
         
         // Test with equal weight upstream list
-        Upstream result2 = roundRobinLoadBalancer.select(upstreamList2, "");
+        Upstream result2 = roundRobinLoadBalancer.select(upstreamList2, new 
LoadBalanceData());
         assertNotNull(result2, "Selected upstream should not be null");
         assertTrue(upstreamList2.contains(result2), "Selected upstream should 
be from the provided list");
         
         // Test multiple selections to verify round-robin behavior
         Map<String, Integer> countMap = new HashMap<>();
         IntStream.range(0, SELECTION_ITERATIONS).forEach(i -> {
-            Upstream result = roundRobinLoadBalancer.select(upstreamList2, "");
+            Upstream result = roundRobinLoadBalancer.select(upstreamList2, new 
LoadBalanceData());
             int count = countMap.getOrDefault(result.getUrl(), 0);
             countMap.put(result.getUrl(), ++count);
         });
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancerTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancerTest.java
index abd579e029..b6bb359d20 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancerTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/ShortestResponseLoadBalancerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.loadbalancer.spi;
 
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -45,7 +46,7 @@ public class ShortestResponseLoadBalancerTest {
         int loop = 10000;
         ShortestResponseLoadBalancer lb = new ShortestResponseLoadBalancer();
         for (int i = 0; i < loop; i++) {
-            Upstream upstream = lb.select(upstreamList, "");
+            Upstream upstream = lb.select(upstreamList, new LoadBalanceData());
             if (upstream.getUrl().equals("upstream-1")) {
                 select1++;
             }
@@ -71,7 +72,7 @@ public class ShortestResponseLoadBalancerTest {
         upstreamList.get(0).getSucceeded().addAndGet(1);
         upstreamList.get(0).getSucceededElapsed().addAndGet(50000);
         for (int i = 0; i < loop; i++) {
-            Upstream upstream = lb.select(upstreamList, "");
+            Upstream upstream = lb.select(upstreamList, new LoadBalanceData());
             if (upstream.getUrl().equals("upstream-1")) {
                 select1++;
             }
diff --git a/shenyu-plugin/shenyu-plugin-base/pom.xml 
b/shenyu-plugin/shenyu-plugin-base/pom.xml
index 2cea6d65bc..ec9f557b66 100644
--- a/shenyu-plugin/shenyu-plugin-base/pom.xml
+++ b/shenyu-plugin/shenyu-plugin-base/pom.xml
@@ -40,6 +40,12 @@
             <artifactId>shenyu-spi</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-loadbalancer</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-collections4</artifactId>
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/LoadbalancerUtils.java
 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/LoadbalancerUtils.java
new file mode 100644
index 0000000000..91e8e850ab
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/LoadbalancerUtils.java
@@ -0,0 +1,100 @@
+/*
+ * 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.plugin.base.utils;
+
+import org.apache.commons.collections4.MapUtils;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
+import org.springframework.http.HttpCookie;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.server.ServerWebExchange;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * The type Loadbalancer utils.
+ */
+public final class LoadbalancerUtils {
+    
+    private LoadbalancerUtils() {
+    }
+    
+    /**
+     * Gets for exchange.
+     *
+     * @param upstreamList the upstream list
+     * @param algorithm the algorithm
+     * @param exchange the exchange
+     * @return the for exchange
+     */
+    public static Upstream getForExchange(final List<Upstream> upstreamList, 
final String algorithm, final ServerWebExchange exchange) {
+        LoadBalanceData loadBalanceData = buildLoadBalanceData(exchange);
+        return LoadBalancerFactory.selector(upstreamList, algorithm, 
loadBalanceData);
+    }
+    
+    /**
+     * Gets for no exchange.
+     *
+     * @param upstreamList the upstream list
+     * @param algorithm the algorithm
+     * @return the for no exchange
+     */
+    public static Upstream getForNoExchange(final List<Upstream> upstreamList, 
final String algorithm) {
+        return LoadBalancerFactory.selector(upstreamList, algorithm, new 
LoadBalanceData());
+    }
+    
+    private static LoadBalanceData buildLoadBalanceData(final 
ServerWebExchange exchange) {
+        ServerHttpRequest request = exchange.getRequest();
+        String ip = 
Objects.requireNonNull(request.getRemoteAddress()).getAddress().getHostAddress();
+        String httpMethod = request.getMethod().name();
+        URI uri = exchange.getRequest().getURI();
+        HttpHeaders headers = request.getHeaders();
+        MultiValueMap<String, HttpCookie> cookies = request.getCookies();
+        Map<String, Object> attributes = exchange.getAttributes();
+        MultiValueMap<String, String> queryParams = request.getQueryParams();
+        return new LoadBalanceData(httpMethod, ip, uri,
+                buildMultiValueMap(headers),
+                buildCookies(cookies),
+                attributes,
+                buildMultiValueMap(queryParams));
+    }
+    
+    private static Map<String, Collection<String>> buildMultiValueMap(final 
MultiValueMap<String, String> queryParams) {
+        Map<String, Collection<String>> resultMap = new HashMap<>();
+        if (MapUtils.isNotEmpty(queryParams)) {
+            resultMap.putAll(queryParams);
+        }
+        return resultMap;
+    }
+    
+    private static Map<String, String> buildCookies(final 
MultiValueMap<String, HttpCookie> cookies) {
+        Map<String, String> resultMap = new HashMap<>();
+        if (MapUtils.isNotEmpty(cookies)) {
+            cookies.forEach((key, value) -> value.forEach((cookie) -> 
resultMap.put(cookie.getName(), cookie.getValue())));
+        }
+        return resultMap;
+    }
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/DefaultRetryStrategy.java
 
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/DefaultRetryStrategy.java
index c7a259c951..6339ddbee6 100644
--- 
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/DefaultRetryStrategy.java
+++ 
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/DefaultRetryStrategy.java
@@ -17,23 +17,13 @@
 
 package org.apache.shenyu.plugin.httpclient;
 
-import java.net.URI;
-import java.time.Duration;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.TimeoutException;
-import java.util.stream.Collectors;
 import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.enums.RetryEnum;
 import org.apache.shenyu.common.exception.ShenyuException;
 import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.plugin.api.utils.RequestUrlUtils;
+import org.apache.shenyu.plugin.base.utils.LoadbalancerUtils;
 import org.apache.shenyu.plugin.httpclient.exception.ShenyuTimeoutException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,6 +34,17 @@ import reactor.core.publisher.Mono;
 import reactor.util.retry.Retry;
 import reactor.util.retry.RetryBackoffSpec;
 
+import java.net.URI;
+import java.time.Duration;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
 
 /**
  * Default Retry Policy Class
@@ -119,8 +120,7 @@ public class DefaultRetryStrategy<R> implements 
RetryStrategy<R> {
                 // no need to retry anymore
                 return Mono.error(new 
ShenyuException("CANNOT_FIND_HEALTHY_UPSTREAM_URL_AFTER_FAILOVER"));
             }
-            final String ip = 
Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
-            final Upstream upstream = 
LoadBalancerFactory.selector(upstreamList, loadBalance, ip);
+            final Upstream upstream = 
LoadbalancerUtils.getForExchange(upstreamList, loadBalance, exchange);
             if (Objects.isNull(upstream)) {
                 // no need to retry anymore
                 return Mono.error(new 
ShenyuException("CANNOT_FIND_HEALTHY_UPSTREAM_URL_AFTER_FAILOVER"));
diff --git 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
index 39a514b2ee..d1d1cd7342 100644
--- 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
@@ -29,7 +29,6 @@ import org.apache.shenyu.common.enums.RetryEnum;
 import org.apache.shenyu.common.enums.RpcTypeEnum;
 import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.plugin.api.ShenyuPluginChain;
 import org.apache.shenyu.plugin.api.context.ShenyuContext;
 import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
@@ -38,6 +37,7 @@ import org.apache.shenyu.plugin.api.utils.RequestUrlUtils;
 import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
 import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
 import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
+import org.apache.shenyu.plugin.base.utils.LoadbalancerUtils;
 import org.apache.shenyu.plugin.divide.handler.DividePluginDataHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -97,16 +97,16 @@ public class DividePlugin extends AbstractShenyuPlugin {
             Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL);
             return WebFluxResultUtils.result(exchange, error);
         }
-        String ip = 
Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
-        Upstream upstream = LoadBalancerFactory.selector(upstreamList, 
ruleHandle.getLoadBalance(), ip);
+        Upstream upstream = LoadbalancerUtils.getForExchange(upstreamList, 
ruleHandle.getLoadBalance(), exchange);
         if (Objects.isNull(upstream)) {
             LOG.error("divide has no upstream");
             Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL);
             return WebFluxResultUtils.result(exchange, error);
         }
         // set the http url
-        if 
(CollectionUtils.isNotEmpty(exchange.getRequest().getHeaders().get(Constants.SPECIFY_DOMAIN)))
 {
-            
upstream.setUrl(exchange.getRequest().getHeaders().get(Constants.SPECIFY_DOMAIN).get(0));
+        List<String> specifyDomains = 
exchange.getRequest().getHeaders().get(Constants.SPECIFY_DOMAIN);
+        if (CollectionUtils.isNotEmpty(specifyDomains)) {
+            upstream.setUrl(specifyDomains.get(0));
         }
         // set domain
         String domain = upstream.buildDomain();
@@ -115,8 +115,8 @@ public class DividePlugin extends AbstractShenyuPlugin {
         exchange.getAttributes().put(Constants.HTTP_TIME_OUT, 
ruleHandle.getTimeout());
         exchange.getAttributes().put(Constants.HTTP_RETRY, 
ruleHandle.getRetry());
         // set retry strategy stuff
-        exchange.getAttributes().put(Constants.RETRY_STRATEGY, 
StringUtils.defaultString(ruleHandle.getRetryStrategy(), 
RetryEnum.CURRENT.getName()));
-        exchange.getAttributes().put(Constants.LOAD_BALANCE, 
StringUtils.defaultString(ruleHandle.getLoadBalance(), 
LoadBalanceEnum.RANDOM.getName()));
+        exchange.getAttributes().put(Constants.RETRY_STRATEGY, 
StringUtils.defaultIfEmpty(ruleHandle.getRetryStrategy(), 
RetryEnum.CURRENT.getName()));
+        exchange.getAttributes().put(Constants.LOAD_BALANCE, 
StringUtils.defaultIfEmpty(ruleHandle.getLoadBalance(), 
LoadBalanceEnum.RANDOM.getName()));
         exchange.getAttributes().put(Constants.DIVIDE_SELECTOR_ID, 
selector.getId());
         if (ruleHandle.getLoadBalance().equals(P2C)) {
             return chain.execute(exchange).doOnSuccess(e -> 
responseTrigger(upstream
@@ -185,4 +185,5 @@ public class DividePlugin extends AbstractShenyuPlugin {
         upstream.getSucceededElapsed().addAndGet(System.currentTimeMillis() - 
beginTime);
         upstream.getSucceeded().incrementAndGet();
     }
+    
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboGrayLoadBalance.java
 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboGrayLoadBalance.java
index bacbf901b2..9551ff2f18 100644
--- 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboGrayLoadBalance.java
+++ 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboGrayLoadBalance.java
@@ -32,8 +32,8 @@ import 
org.apache.shenyu.common.dto.convert.rule.impl.DubboRuleHandle;
 import org.apache.shenyu.common.dto.convert.selector.DubboUpstream;
 import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import 
org.apache.shenyu.plugin.apache.dubbo.handler.ApacheDubboPluginDataHandler;
+import org.apache.shenyu.plugin.base.utils.LoadbalancerUtils;
 
 import java.util.List;
 import java.util.Objects;
@@ -54,7 +54,7 @@ public class ApacheDubboGrayLoadBalance implements 
LoadBalance {
         DubboRuleHandle dubboRuleHandle = 
ApacheDubboPluginDataHandler.RULE_CACHED_HANDLE.get().obtainHandle(shenyuRuleId);
         // if gray list is not empty,just use load balance to choose one.
         if (CollectionUtils.isNotEmpty(dubboUpstreams)) {
-            Upstream upstream = 
LoadBalancerFactory.selector(UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(shenyuSelectorId),
 dubboRuleHandle.getLoadBalance(), remoteAddressIp);
+            Upstream upstream = 
LoadbalancerUtils.getForNoExchange(UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(shenyuSelectorId),
 dubboRuleHandle.getLoadBalance());
             if (Objects.isNull(upstream)) {
                 return dubboSelect(invokers, url, invocation);
             }
diff --git 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboProxyService.java
 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboProxyService.java
index 8bfcaf45ad..cdbe6375c2 100644
--- 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboProxyService.java
+++ 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-dubbo/shenyu-plugin-apache-dubbo/src/main/java/org/apache/shenyu/plugin/apache/dubbo/proxy/ApacheDubboProxyService.java
@@ -17,12 +17,6 @@
 
 package org.apache.shenyu.plugin.apache.dubbo.proxy;
 
-import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
-import java.util.stream.Collectors;
-import java.util.List;
-import java.util.Collections;
-import java.util.Optional;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -44,13 +38,20 @@ import org.apache.shenyu.common.utils.GsonUtils;
 import org.apache.shenyu.common.utils.JsonUtils;
 import org.apache.shenyu.common.utils.ParamCheckUtils;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.plugin.apache.dubbo.cache.ApacheDubboConfigCache;
+import org.apache.shenyu.plugin.base.utils.LoadbalancerUtils;
 import org.apache.shenyu.plugin.dubbo.common.param.DubboParamResolveService;
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
 /**
  * dubbo proxy service is  use GenericService.
  */
@@ -140,8 +141,7 @@ public class ApacheDubboProxyService {
         }
 
         List<Upstream> upstreams = this.convertUpstreamList(dubboUpstreams);
-        String ip = 
Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
-        Upstream upstream = LoadBalancerFactory.selector(upstreams, 
LoadBalanceEnum.RANDOM.getName(), ip);
+        Upstream upstream = LoadbalancerUtils.getForExchange(upstreams, 
LoadBalanceEnum.RANDOM.getName(), exchange);
         DubboUpstream dubboUpstream = dubboUpstreams.get(0);
         for (DubboUpstream upstreamItem : dubboUpstreams) {
             if (Objects.equals(upstreamItem.getRegistry(), upstream.getUrl())
diff --git 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/loadbalance/picker/ShenyuPicker.java
 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/loadbalance/picker/ShenyuPicker.java
index ef71b3ef98..616ab9f3e6 100644
--- 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/loadbalance/picker/ShenyuPicker.java
+++ 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/loadbalance/picker/ShenyuPicker.java
@@ -22,6 +22,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.common.dto.convert.rule.impl.GrpcRuleHandle;
 import org.apache.shenyu.common.dto.convert.selector.GrpcUpstream;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.plugin.grpc.cache.ApplicationConfigCache;
@@ -45,19 +46,19 @@ public class ShenyuPicker extends AbstractReadyPicker {
 
     @Override
     protected SubChannelCopy pick(final List<SubChannelCopy> list) {
-
         String grpcRuleId = GrpcConstants.GRPC_RULE_ID.get();
         String selectorId = GrpcConstants.GRPC_SELECTOR_ID.get();
         String remoteAddressIp = GrpcConstants.GRPC_REMOTE_ADDRESS.get();
         final GrpcRuleHandle cacheRuleHandle = 
ApplicationConfigCache.getInstance().getCacheRuleHandle(grpcRuleId);
         List<GrpcUpstream> grpcUpstreams = 
ApplicationConfigCache.getInstance().getGrpcUpstreamListCache(selectorId);
         if (CollectionUtils.isNotEmpty(grpcUpstreams)) {
-            Upstream upstream = 
LoadBalancerFactory.selector(convertUpstreamList(grpcUpstreams), 
cacheRuleHandle.getLoadBalance(), remoteAddressIp);
+            LoadBalanceData data = new LoadBalanceData();
+            data.setIp(remoteAddressIp);
+            Upstream upstream = 
LoadBalancerFactory.selector(convertUpstreamList(grpcUpstreams), 
cacheRuleHandle.getLoadBalance(), data);
             if (StringUtils.isBlank(upstream.getUrl()) && 
StringUtils.isBlank(upstream.getGroup()) && 
StringUtils.isBlank(upstream.getVersion())) {
                 return randomPicker.pick(list);
             }
-
-            final List<SubChannelCopy> invokerGrays = 
list.stream().filter(each -> 
each.getUrl().equals(upstream.getUrl())).collect(Collectors.toList());
+            final List<SubChannelCopy> invokerGrays = 
list.stream().filter(each -> each.getUrl().equals(upstream.getUrl())).toList();
             return invokerGrays.stream().findFirst().orElse(null);
         }
         return randomPicker.pick(list);
@@ -72,5 +73,4 @@ public class ShenyuPicker extends AbstractReadyPicker {
                 .timestamp(u.getTimestamp())
                 .build()).collect(Collectors.toList());
     }
-
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
index 11e5f3cfd9..697238e15e 100644
--- 
a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
@@ -27,7 +27,6 @@ import org.apache.shenyu.common.enums.PluginEnum;
 import org.apache.shenyu.common.enums.RpcTypeEnum;
 import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
-import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.plugin.api.ShenyuPluginChain;
 import org.apache.shenyu.plugin.api.context.ShenyuContext;
 import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
@@ -36,6 +35,7 @@ import org.apache.shenyu.plugin.api.utils.RequestUrlUtils;
 import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
 import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
 import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
+import org.apache.shenyu.plugin.base.utils.LoadbalancerUtils;
 import org.apache.shenyu.plugin.websocket.handler.WebSocketPluginDataHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -96,8 +96,7 @@ public class WebSocketPlugin extends AbstractShenyuPlugin {
             return chain.execute(exchange);
         }
         final WebSocketRuleHandle ruleHandle = buildRuleHandle(rule);
-        final String ip = 
Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
-        Upstream upstream = LoadBalancerFactory.selector(upstreamList, 
ruleHandle.getLoadBalance(), ip);
+        Upstream upstream = LoadbalancerUtils.getForExchange(upstreamList, 
ruleHandle.getLoadBalance(), exchange);
         if (Objects.isNull(upstream)) {
             LOG.error("websocket has no upstream, error:{}", rule);
             Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL);
diff --git 
a/shenyu-protocol/shenyu-protocol-tcp/src/main/java/org/apache/shenyu/protocol/tcp/connection/DefaultConnectionConfigProvider.java
 
b/shenyu-protocol/shenyu-protocol-tcp/src/main/java/org/apache/shenyu/protocol/tcp/connection/DefaultConnectionConfigProvider.java
index d126ac086e..2e597276f5 100644
--- 
a/shenyu-protocol/shenyu-protocol-tcp/src/main/java/org/apache/shenyu/protocol/tcp/connection/DefaultConnectionConfigProvider.java
+++ 
b/shenyu-protocol/shenyu-protocol-tcp/src/main/java/org/apache/shenyu/protocol/tcp/connection/DefaultConnectionConfigProvider.java
@@ -20,6 +20,7 @@ package org.apache.shenyu.protocol.tcp.connection;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.shenyu.common.exception.ShenyuException;
 import org.apache.shenyu.common.utils.JsonUtils;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.protocol.tcp.UpstreamProvider;
@@ -62,7 +63,9 @@ public class DefaultConnectionConfigProvider implements 
ClientConnectionConfigPr
         if (CollectionUtils.isEmpty(upstreamList)) {
             throw new ShenyuException("shenyu TcpProxy don't have any 
upstream");
         }
-        Upstream upstream = LoadBalancerFactory.selector(upstreamList, 
loadBalanceAlgorithm, ip);
+        LoadBalanceData data = new LoadBalanceData();
+        data.setIp(ip);
+        Upstream upstream = LoadBalancerFactory.selector(upstreamList, 
loadBalanceAlgorithm, data);
         return cover(upstream);
     }
 
diff --git 
a/shenyu-sdk/shenyu-sdk-core/src/main/java/org/apache/shenyu/sdk/core/client/AbstractShenyuSdkClient.java
 
b/shenyu-sdk/shenyu-sdk-core/src/main/java/org/apache/shenyu/sdk/core/client/AbstractShenyuSdkClient.java
index f044d28f60..102eeefdfb 100644
--- 
a/shenyu-sdk/shenyu-sdk-core/src/main/java/org/apache/shenyu/sdk/core/client/AbstractShenyuSdkClient.java
+++ 
b/shenyu-sdk/shenyu-sdk-core/src/main/java/org/apache/shenyu/sdk/core/client/AbstractShenyuSdkClient.java
@@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.exception.ShenyuException;
 import org.apache.shenyu.common.utils.UriUtils;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.registry.api.ShenyuInstanceRegisterRepository;
@@ -169,7 +170,10 @@ public abstract class AbstractShenyuSdkClient implements 
ShenyuSdkClient {
                     .collect(Collectors.toList());
         }
         // loadBalancer upstreams
-        final Upstream upstream = LoadBalancerFactory.selector(upstreams, 
algorithm, "");
+        LoadBalanceData data = new LoadBalanceData();
+        data.setHeaders(request.getHeaders());
+        data.setHttpMethod(request.getHttpMethod().name());
+        final Upstream upstream = LoadBalancerFactory.selector(upstreams, 
algorithm, data);
         return replaceUrl(upstream.getUrl(), request.getUrl());
     }
 
diff --git 
a/shenyu-sdk/shenyu-sdk-feign/src/main/java/org/apache/shenyu/sdk/feign/ShenyuDiscoveryClient.java
 
b/shenyu-sdk/shenyu-sdk-feign/src/main/java/org/apache/shenyu/sdk/feign/ShenyuDiscoveryClient.java
index af4b79fafb..894888e3eb 100644
--- 
a/shenyu-sdk/shenyu-sdk-feign/src/main/java/org/apache/shenyu/sdk/feign/ShenyuDiscoveryClient.java
+++ 
b/shenyu-sdk/shenyu-sdk-feign/src/main/java/org/apache/shenyu/sdk/feign/ShenyuDiscoveryClient.java
@@ -17,18 +17,13 @@
 
 package org.apache.shenyu.sdk.feign;
 
-import java.net.URI;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.stream.Collectors;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.enums.HttpSchemeEnum;
 import org.apache.shenyu.common.exception.ShenyuException;
 import org.apache.shenyu.common.utils.UriUtils;
+import org.apache.shenyu.loadbalancer.entity.LoadBalanceData;
 import org.apache.shenyu.loadbalancer.entity.Upstream;
 import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
 import org.apache.shenyu.registry.api.ShenyuInstanceRegisterRepository;
@@ -39,6 +34,13 @@ import org.slf4j.LoggerFactory;
 import org.springframework.cloud.client.DefaultServiceInstance;
 import org.springframework.cloud.client.ServiceInstance;
 
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
 public class ShenyuDiscoveryClient {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(ShenyuDiscoveryClient.class);
@@ -92,7 +94,7 @@ public class ShenyuDiscoveryClient {
         }
         Upstream upstream = upstreams.get(0);
         if (CollectionUtils.isNotEmpty(upstreams) && upstreams.size() > 1) {
-            upstream = LoadBalancerFactory.selector(upstreams, algorithm, "");
+            upstream = LoadBalancerFactory.selector(upstreams, algorithm, new 
LoadBalanceData());
         }
 
         final URI uri = UriUtils.createUri(upstream.getUrl());

Reply via email to