You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Spring Cloud 2021.0.0之后的版本使用的是Spring Cloud LoadBalancer进行负载均衡,我找到了一个合适的增强点:
org.springframework.cloud.loadbalancer.core#getInstanceResponse
private Response getInstanceResponse(List instances) {
if (instances.isEmpty()) {
if (log.isWarnEnabled()) {
log.warn("No servers available for service: " + serviceId);
}
return new EmptyResponse();
}
// Do not move position when there is only 1 instance, especially some suppliers
// have already filtered instances
if (instances.size() == 1) {
return new DefaultResponse(instances.get(0));
}
// Ignore the sign bit, this allows pos to loop sequentially from 0 to
// Integer.MAX_VALUE
int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;
ServiceInstance instance = instances.get(pos % instances.size());
return new DefaultResponse(instance);
}
现在想实现通过agent的增强,对openfeign远程调用做定制化的负载均衡策略。
Spring Cloud 2021.0.0之后的版本使用的是Spring Cloud LoadBalancer进行负载均衡,我找到了一个合适的增强点:
org.springframework.cloud.loadbalancer.core#getInstanceResponse
private Response getInstanceResponse(List instances) {
if (instances.isEmpty()) {
if (log.isWarnEnabled()) {
log.warn("No servers available for service: " + serviceId);
}
return new EmptyResponse();
}
其中,最后return的new DefaultResponse(instance) 中的instance为org.springframework.cloud.netflix.eureka.EurekaServiceInstance
我编写的module代码如下:
public void loadCompleted() {
new EventWatchBuilder(moduleEventWatcher)
.onClass(CLASS_NAME)
.includeBootstrap()
.onBehavior(BEHAVIOR_NAME)
.onWatch(new AdviceListener() {
@OverRide
protected void before(Advice advice) {
defectLogger.info("触发zone-avoidance-rule模块");
try {
// List instances = (List) advice.getParameterArray()[0];
// defectLogger.info("zone-avoidance-rule模块:返回zone2的服务实例");
// Class defaultResponseClass = Class.forName("org.springframework.cloud.client.loadbalancer.DefaultResponse"); // Constructor constructor = defaultResponseClass.getConstructor(EurekaServiceInstance.class);
// DefaultResponse defaultResponse = (DefaultResponse) constructor.newInstance(obj);
// ProcessController.returnImmediately(defaultResponse);
// ProcessController.returnImmediately(new DefaultResponse((EurekaServiceInstance)obj));
// InstanceInfo instanceInfo = (InstanceInfo)MethodUtils.invokeExactMethod(obj,"getInstanceInfo");
// EurekaServiceInstance eurekaServiceInstance = new EurekaServiceInstance(instanceInfo);
// defectLogger.info("zone-avoidance-rule模块:创建eurekaServiceInstance:" + eurekaServiceInstance);
// ProcessController.returnImmediately(new DefaultResponse(eurekaServiceInstance));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
}
现在遇到的问题:
因为classloader不同,所以 List instances = (List) advice.getParameterArray()[0]强转会报错,我使用反射可以获取到想要的信息。
但是最后,我要通过ProcessController.returnImmediately方法返回new DefaultResponse(eurekaServiceInstance)时,怎么也绕不过去类型转换的问题。
我尝试了好多方法,可见注释的内容,核心问题是我要new DefaultResponse的构造函数需要传递ServiceInstance实例,我将obj传递进去后是构造不出来的。
困扰我好久了,望不吝赐教
The text was updated successfully, but these errors were encountered: