add 自定义负载均衡模块 用于多团队开发
parent
72a9b05a7b
commit
94c732c439
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>0.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-common-loadbalancer</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-common-loadbalancer 自定义负载均衡(多团队开发使用)
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-dubbo</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,15 @@
|
||||
package com.ruoyi.common.loadbalance.config;
|
||||
|
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
/**
|
||||
* 自定义负载均衡自动配置
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@PropertySource(value = "classpath:loadbalance.properties", encoding = "UTF-8")
|
||||
@LoadBalancerClients(defaultConfiguration = CustomLoadBalanceClientConfiguration.class)
|
||||
public class CustomLoadBalanceAutoConfiguration {
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.loadbalance.config;
|
||||
|
||||
import com.ruoyi.common.loadbalance.core.CustomSpringCloudLoadBalancer;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
|
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* 自定义负载均衡客户端配置
|
||||
*
|
||||
* @author LionLi
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class CustomLoadBalanceClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(LoadBalancerClientFactory.class)
|
||||
public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(Environment environment,
|
||||
LoadBalancerClientFactory loadBalancerClientFactory) {
|
||||
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
|
||||
return new CustomSpringCloudLoadBalancer(name,
|
||||
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.loadbalance.constant;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
* 常量类
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public class LoadBalancerConstant {
|
||||
|
||||
/**
|
||||
* 获取服务host
|
||||
* 默认自动获取
|
||||
*/
|
||||
public static String getHost() {
|
||||
String host = "127.0.0.1";
|
||||
try {
|
||||
// 如需自定义ip可修改此处
|
||||
String address = InetAddress.getLocalHost().getHostAddress();
|
||||
if (address != null) {
|
||||
host = address;
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return host;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.loadbalance.core;
|
||||
|
||||
import com.ruoyi.common.loadbalance.constant.LoadBalancerConstant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 自定义 Dubbo 负载均衡算法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomDubboLoadBalancer extends AbstractLoadBalance {
|
||||
|
||||
@Override
|
||||
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
|
||||
for (Invoker<T> invoker : invokers) {
|
||||
if (invoker.getUrl().getHost().equals(LoadBalancerConstant.getHost())) {
|
||||
return invoker;
|
||||
}
|
||||
}
|
||||
return invokers.get(ThreadLocalRandom.current().nextInt(invokers.size()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package com.ruoyi.common.loadbalance.core;
|
||||
|
||||
import com.ruoyi.common.loadbalance.constant.LoadBalancerConstant;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
|
||||
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
|
||||
import org.springframework.cloud.client.loadbalancer.Request;
|
||||
import org.springframework.cloud.client.loadbalancer.Response;
|
||||
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
|
||||
import org.springframework.cloud.loadbalancer.core.SelectedInstanceCallback;
|
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 自定义 SpringCloud 负载均衡算法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class CustomSpringCloudLoadBalancer implements ReactorServiceInstanceLoadBalancer {
|
||||
|
||||
private final String serviceId;
|
||||
|
||||
private final ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
|
||||
|
||||
@Override
|
||||
public Mono<Response<ServiceInstance>> choose(Request request) {
|
||||
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
|
||||
return supplier.get(request).next().map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
|
||||
}
|
||||
|
||||
private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
|
||||
List<ServiceInstance> serviceInstances) {
|
||||
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
|
||||
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
|
||||
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
|
||||
}
|
||||
return serviceInstanceResponse;
|
||||
}
|
||||
|
||||
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
|
||||
if (instances.isEmpty()) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("No servers available for service: " + serviceId);
|
||||
}
|
||||
return new EmptyResponse();
|
||||
}
|
||||
for (ServiceInstance instance : instances) {
|
||||
if (instance.getHost().equals(LoadBalancerConstant.getHost())) {
|
||||
return new DefaultResponse(instance);
|
||||
}
|
||||
}
|
||||
return new DefaultResponse(instances.get(ThreadLocalRandom.current().nextInt(instances.size())));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
customDubboLoadBalancer=com.ruoyi.common.loadbalance.core.CustomDubboLoadBalancer
|
||||
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.ruoyi.common.loadbalance.config.CustomLoadBalanceAutoConfiguration
|
||||
@ -0,0 +1 @@
|
||||
dubbo.consumer.loadbalance=customDubboLoadBalancer
|
||||
Loading…
Reference in New Issue