From 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a Mon Sep 17 00:00:00 2001 From: xiejun <xiejun@vci-tech.com> Date: 星期五, 01 十一月 2024 15:11:19 +0800 Subject: [PATCH] Revert "集成获取mdm分发通用数据格式接口集成" --- Source/BladeX-Tool/blade-starter-loadbalancer/src/main/java/org/springblade/core/loadbalancer/rule/GrayscaleLoadBalancer.java | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 115 insertions(+), 0 deletions(-) diff --git a/Source/BladeX-Tool/blade-starter-loadbalancer/src/main/java/org/springblade/core/loadbalancer/rule/GrayscaleLoadBalancer.java b/Source/BladeX-Tool/blade-starter-loadbalancer/src/main/java/org/springblade/core/loadbalancer/rule/GrayscaleLoadBalancer.java new file mode 100644 index 0000000..476ad47 --- /dev/null +++ b/Source/BladeX-Tool/blade-starter-loadbalancer/src/main/java/org/springblade/core/loadbalancer/rule/GrayscaleLoadBalancer.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 搴勯獮 (smallchill@163.com) + */ +package org.springblade.core.loadbalancer.rule; + +import com.alibaba.nacos.common.utils.StringUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.loadbalancer.props.BladeLoadBalancerProperties; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.*; +import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier; +import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; +import org.springframework.http.HttpHeaders; +import org.springframework.util.CollectionUtils; +import org.springframework.util.PatternMatchUtils; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +import static org.springblade.core.loadbalancer.constant.LoadBalancerConstant.VERSION_NAME; + +/** + * LoadBalancer 璐熻浇瑙勫垯 + * + * @author Chill + */ +@Slf4j +@RequiredArgsConstructor +public class GrayscaleLoadBalancer implements ReactorServiceInstanceLoadBalancer { + private final ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider; + private final BladeLoadBalancerProperties bladeLoadBalancerProperties; + + @Override + public Mono<Response<ServiceInstance>> choose(Request request) { + ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider + .getIfAvailable(NoopServiceInstanceListSupplier::new); + return supplier.get(request).next() + .map(serviceInstances -> getInstanceResponse(serviceInstances, request)); + } + + /** + * 鑷畾涔夎妭鐐硅鍒欒繑鍥炵洰鏍囪妭鐐� + */ + private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances, Request request) { + // 娉ㄥ唽涓績鏃犲彲鐢ㄥ疄渚� 杩斿洖绌� + if (CollectionUtils.isEmpty(instances)) { + return new EmptyResponse(); + } + // 鎸囧畾ip鍒欒繑鍥炴弧瓒砳p鐨勬湇鍔� + List<String> priorIpPattern = bladeLoadBalancerProperties.getPriorIpPattern(); + if (!priorIpPattern.isEmpty()) { + String[] priorIpPatterns = priorIpPattern.toArray(new String[0]); + List<ServiceInstance> priorIpInstances = instances.stream().filter( + (i -> PatternMatchUtils.simpleMatch(priorIpPatterns, i.getHost())) + ).collect(Collectors.toList()); + if (!priorIpInstances.isEmpty()) { + instances = priorIpInstances; + } + } + + // 鑾峰彇鐏板害鐗堟湰鍙� + DefaultRequestContext context = (DefaultRequestContext) request.getContext(); + RequestData requestData = (RequestData) context.getClientRequest(); + HttpHeaders headers = requestData.getHeaders(); + String versionName = headers.getFirst(VERSION_NAME); + + // 娌℃湁鎸囧畾鐏板害鐗堟湰鍒欒繑鍥炴寮忕殑鏈嶅姟 + if (StringUtils.isBlank(versionName)) { + List<ServiceInstance> noneGrayscaleInstances = instances.stream().filter( + i -> !i.getMetadata().containsKey(VERSION_NAME) + ).collect(Collectors.toList()); + return randomInstance(noneGrayscaleInstances); + } + + // 鎸囧畾鐏板害鐗堟湰鍒欒繑鍥炴爣璁扮殑鏈嶅姟 + List<ServiceInstance> grayscaleInstances = instances.stream().filter(i -> { + String versionNameInMetadata = i.getMetadata().get(VERSION_NAME); + return StringUtils.equalsIgnoreCase(versionNameInMetadata, versionName); + }).collect(Collectors.toList()); + return randomInstance(grayscaleInstances); + } + + /** + * 閲囩敤闅忔満瑙勫垯杩斿洖 + */ + private Response<ServiceInstance> randomInstance(List<ServiceInstance> instances) { + // 鑻ユ病鏈夊彲鐢ㄨ妭鐐瑰垯杩斿洖绌� + if (instances.isEmpty()) { + return new EmptyResponse(); + } + + // 鎸戦�夐殢鏈鸿妭鐐硅繑鍥� + int randomIndex = ThreadLocalRandom.current().nextInt(instances.size()); + ServiceInstance instance = instances.get(randomIndex % instances.size()); + return new DefaultResponse(instance); + } +} -- Gitblit v1.9.3