bizKey 路由

This commit is contained in:
Jesse-Ma
2023-03-07 17:58:46 +08:00
parent 9d73209f8b
commit facbe4a5d5
4 changed files with 130 additions and 14 deletions

View File

@@ -2,10 +2,13 @@ package com.flagnote.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import com.flagnote.gateway.config.BkrLoadBalancerConfiguration;
@SpringBootApplication
@LoadBalancerClient(name = "noteCommonService", configuration = BkrLoadBalancerConfiguration.class)
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}

View File

@@ -0,0 +1,91 @@
package com.flagnote.gateway.config;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.RequestData;
import org.springframework.cloud.client.loadbalancer.RequestDataContext;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.SelectedInstanceCallback;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import com.flagnote.gateway.utils.BizKeyUtils;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
@Slf4j
public class BizKeyLoadBalancerClient implements ReactorServiceInstanceLoadBalancer {
private final String serviceId;
private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
public BizKeyLoadBalancerClient(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
String serviceId) {
this.serviceId = serviceId;
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
}
@SuppressWarnings("rawtypes")
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next()
.map(serviceInstances -> processInstanceResponse(request, supplier, serviceInstances));
}
@SuppressWarnings("rawtypes")
private Response<ServiceInstance> processInstanceResponse(Request request, ServiceInstanceListSupplier supplier,
List<ServiceInstance> serviceInstances) {
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(request, serviceInstances);
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
}
return serviceInstanceResponse;
}
@SuppressWarnings("rawtypes")
private Response<ServiceInstance> getInstanceResponse(Request request, List<ServiceInstance> instances) {
if (instances.isEmpty()) {
if (log.isWarnEnabled()) {
log.warn("No servers available for service: " + serviceId);
}
return new EmptyResponse();
}
RequestDataContext rdContext = (RequestDataContext)request.getContext();
RequestData rdata = rdContext.getClientRequest();
String path = rdata.getUrl().getPath();
String pattern = "^/note/([abcdefhikmnopqstuvwxyz23456789]{16})(\\.txt|/noteMeta|/delete)?$";
Pattern pt = Pattern.compile(pattern);
Matcher m = pt.matcher(path);
//默认随机
int index = ThreadLocalRandom.current().nextInt(instances.size());
//如果有key则为key分配指定服务。
if(m.find()) {
String mixKey = BizKeyUtils.mixKey(m.group(1));
index = Math.abs(mixKey.hashCode())%instances.size();
}
ServiceInstance instance = instances.get(index);
log.info("path:{},service:{}",path,instance.getUri().toString());
return new DefaultResponse(instance);
}
}

View File

@@ -0,0 +1,17 @@
package com.flagnote.gateway.config;
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.core.env.Environment;
//@Configuration 必须注释掉
public class BkrLoadBalancerConfiguration {
@Bean
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new BizKeyLoadBalancerClient(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}

View File

@@ -32,14 +32,19 @@ spring:
client:
simple:
instances:
noteService: # 一定要带端口
noteCommonService: # 一定要带端口
- uri: http://127.0.0.1:20000
# - uri: http://94.103.5.10:20001
- uri: http://127.0.0.1:20001
keyMetaService: # 一定要带端口
- uri: http://127.0.0.1:20000
- uri: http://127.0.0.1:20001
loadbalancer:
configurations: health-check
health-check:
path:
noteService: /f2w8u47ie56edc93/actuator/health
noteCommonService: /f2w8u47ie56edc93/actuator/health
keyMetaService: /f2w8u47ie56edc93/actuator/health
initial-delay: 0
interval: 5s
inetutils:
@@ -53,7 +58,7 @@ spring:
# allowedMethods: "*"
routes:
- id: keyMeta
uri: lb://noteService
uri: lb://keyMetaService
order: -1
predicates:
- Path=/note/keyMeta
@@ -91,7 +96,7 @@ spring:
- id: noteMeta
uri: lb://noteService
uri: lb://noteCommonService
order: -1
predicates:
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/noteMeta
@@ -99,7 +104,7 @@ spring:
filters:
- ValidateNoteKey
- id: getNote
uri: lb://noteService
uri: lb://noteCommonService
order: -1
predicates:
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}
@@ -107,7 +112,7 @@ spring:
filters:
- ValidateNoteKey
- id: saveNote
uri: lb://noteService
uri: lb://noteCommonService
order: -1
predicates:
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}
@@ -115,7 +120,7 @@ spring:
filters:
- ValidateNoteKey
- id: deleteNote
uri: lb://noteService
uri: lb://noteCommonService
order: -1
predicates:
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/delete
@@ -123,7 +128,7 @@ spring:
filters:
- ValidateNoteKey
- id: secretKey
uri: lb://noteService
uri: lb://noteCommonService
order: -1
predicates:
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}/secretKey
@@ -131,7 +136,7 @@ spring:
filters:
- ValidateNoteKey
- id: getNoteTxt
uri: lb://noteService
uri: lb://noteCommonService
order: -1
predicates:
- Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}}.txt
@@ -160,6 +165,6 @@ management:
logging:
level:
org.springframework.cloud.gateway: trace
org.springframework.cloud.loadbalancer: trace
org.springframework.web.reactive: trace
org.springframework.cloud.gateway: info
org.springframework.cloud.loadbalancer: info
org.springframework.web.reactive: info