Skip to content

Commit 6f1b97d

Browse files
committed
- 编译优化
1 parent 784366f commit 6f1b97d

File tree

13 files changed

+228
-32
lines changed

13 files changed

+228
-32
lines changed

example-service-account/src/main/resources/application.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,11 @@ spring:
3838
loadbalancer:
3939
enabled: true
4040

41+
42+
proxy:
43+
config:
44+
host: 192.168.8.183
45+
port: 31684
46+
4147
server:
4248
port: 9001

spring-cloud-kubernetes-coordinator/src/main/java/spring/cloud/kubernetes/coordinator/gateway/apisix/KubernetesServiceChooseFilter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public String name() {
4545

4646
@Override
4747
public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
48+
log.info("current request arg :[{}]", request.getArgs());
49+
log.info("current request path :[{}]", request.getPath());
50+
log.info("current request getArg :[{}]", request.getArg(Cons.LB_IP_PORT_PARAM));
4851
if (loadBalancerClient instanceof BlockingLoadBalancerClient blockingLoadBalancerClient) {
4952
doServiceChoose(blockingLoadBalancerClient, request);
5053
}

spring-cloud-kubernetes-coordinator/src/main/java/spring/cloud/kubernetes/coordinator/service/healthcheck/ServiceHealthCheck.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package spring.cloud.kubernetes.coordinator.service.healthcheck;
22

3+
import io.fabric8.kubernetes.client.KubernetesClient;
34
import org.springframework.beans.factory.annotation.Autowired;
45
import org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient;
56
import org.springframework.scheduling.annotation.Scheduled;
@@ -17,6 +18,9 @@ public class ServiceHealthCheck {
1718
@Autowired
1819
KubernetesDiscoveryClient discoveryClient;
1920

21+
@Autowired
22+
private KubernetesClient client;
23+
2024
@Scheduled(fixedRate = 3, initialDelay = 15, timeUnit = TimeUnit.SECONDS)
2125
public void serviceEndpointCheck() {
2226

spring-cloud-kubernetes-loadbalancer-debugging-starter/src/main/java/spring/cloud/kubernetes/loadbalancer/Cons.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ public class Cons {
99

1010
public static final String LB_IP_PORT = "x-lb-ip-port";
1111

12+
public static final String LB_IP_PORT_PARAM = "x_lb_ip_port";
13+
1214
}
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
package spring.cloud.kubernetes.loadbalancer.debugging;
22

3+
import lombok.extern.slf4j.Slf4j;
34
import org.springframework.cloud.client.ServiceInstance;
5+
import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools;
46
import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
57
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
68
import org.springframework.util.StringUtils;
9+
import org.springframework.web.util.UriComponentsBuilder;
710
import spring.cloud.kubernetes.loadbalancer.ProxyContextHolder;
811

912
import java.net.URI;
13+
import java.util.Objects;
14+
import java.util.Optional;
1015

1116
/**
1217
* @author wxl
1318
* 如果请求的代理. 需要重新url. 增加通用前缀
1419
*/
20+
@Slf4j
1521
public class DebuggingBlockingLoadBalancerClient extends BlockingLoadBalancerClient {
1622

17-
public DebuggingBlockingLoadBalancerClient(ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory) {
23+
private final ProxyProperties proxyProperties;
24+
25+
public DebuggingBlockingLoadBalancerClient(ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory, ProxyProperties proxyProperties) {
1826
super(loadBalancerClientFactory);
27+
this.proxyProperties = proxyProperties;
1928
}
2029

2130
@Override
2231
public URI reconstructURI(ServiceInstance serviceInstance, URI original) {
2332
String podService = ProxyContextHolder.getRealPodService();
2433
if (StringUtils.hasLength(podService)) {
2534
//如果当前需要请求代理. 增加前缀 TODO
26-
27-
28-
29-
35+
URI uri = MyLoadBalancerUriTools.reconstructURI(serviceInstance, original, proxyProperties.getPrefix(), podService);
36+
return uri;
3037
}
31-
32-
return super.reconstructURI(serviceInstance, original);
38+
log.info("DebuggingBlockingLoadBalancerClient reconstructURI.");
39+
return LoadBalancerUriTools.reconstructURI(serviceInstance, original);
3340
}
3441
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package spring.cloud.kubernetes.loadbalancer.debugging;
22

3+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
34
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4-
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
5+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
56
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
67
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
78
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
8-
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
9+
import org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration;
910
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
1011
import org.springframework.context.annotation.Bean;
1112
import org.springframework.context.annotation.Configuration;
@@ -17,15 +18,16 @@
1718
@Profile("test")
1819
@ConditionalOnDiscoveryEnabled
1920
@Configuration(proxyBeanMethods = false)
21+
@EnableConfigurationProperties(ProxyProperties.class)
2022
@LoadBalancerClients(defaultConfiguration = LoadBalanceConfig.class)
23+
@AutoConfigureBefore(BlockingLoadBalancerClientAutoConfiguration.class)
2124
public class LoadBalanceAutoConfiguration {
2225

2326

2427
@Bean
2528
@ConditionalOnBean(LoadBalancerClientFactory.class)
26-
@ConditionalOnMissingBean
27-
public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) {
28-
return new DebuggingBlockingLoadBalancerClient(loadBalancerClientFactory);
29+
public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory, ProxyProperties proxyProperties) {
30+
return new DebuggingBlockingLoadBalancerClient(loadBalancerClientFactory, proxyProperties);
2931
}
3032
}
3133

spring-cloud-kubernetes-loadbalancer-debugging-starter/src/main/java/spring/cloud/kubernetes/loadbalancer/debugging/LoadBalanceConfig.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package spring.cloud.kubernetes.loadbalancer.debugging;
22

3+
import io.fabric8.kubernetes.api.model.Pod;
34
import lombok.extern.slf4j.Slf4j;
45
import org.springframework.beans.factory.ObjectProvider;
56
import org.springframework.boot.web.client.RestTemplateBuilder;
67
import org.springframework.cloud.client.ServiceInstance;
78
import org.springframework.cloud.commons.util.InetUtils;
9+
import org.springframework.cloud.kubernetes.commons.PodUtils;
810
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
911
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
1012
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
1113
import org.springframework.context.ConfigurableApplicationContext;
1214
import org.springframework.context.annotation.Bean;
1315
import org.springframework.core.env.Environment;
1416
import org.springframework.web.client.RestTemplate;
17+
import spring.cloud.kubernetes.discovery.ext.KubernetesRegistration;
1518

1619
import java.time.Duration;
1720

@@ -23,10 +26,12 @@
2326
public class LoadBalanceConfig {
2427

2528
@Bean
26-
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
29+
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory,
30+
PodUtils<Pod> podUtils, ProxyProperties proxyProperties) {
2731
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
2832
log.info("init NetSegmentLoadBalancer.");
29-
return new NetSegmentLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
33+
return new NetSegmentLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name,
34+
environment.getProperty("spring.cloud.kubernetes.discovery.register", "false"), podUtils, proxyProperties);
3035
}
3136

3237
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package spring.cloud.kubernetes.loadbalancer.debugging;
2+
3+
import org.springframework.cloud.client.ServiceInstance;
4+
import org.springframework.web.util.UriComponentsBuilder;
5+
import spring.cloud.kubernetes.loadbalancer.Cons;
6+
7+
import java.net.URI;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.Objects;
11+
import java.util.Optional;
12+
13+
/**
14+
* @author wxl
15+
*/
16+
public class MyLoadBalancerUriTools {
17+
18+
19+
private MyLoadBalancerUriTools() {
20+
throw new IllegalStateException("Can't instantiate a utility class");
21+
}
22+
23+
private static final String PERCENTAGE_SIGN = "%";
24+
25+
private static final String DEFAULT_SCHEME = "http";
26+
27+
private static final String DEFAULT_SECURE_SCHEME = "https";
28+
29+
private static final Map<String, String> INSECURE_SCHEME_MAPPINGS;
30+
31+
static {
32+
INSECURE_SCHEME_MAPPINGS = new HashMap<>();
33+
INSECURE_SCHEME_MAPPINGS.put(DEFAULT_SCHEME, DEFAULT_SECURE_SCHEME);
34+
INSECURE_SCHEME_MAPPINGS.put("ws", "wss");
35+
}
36+
37+
// see original
38+
// https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-core/
39+
// src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java
40+
private static boolean containsEncodedParts(URI uri) {
41+
boolean encoded = (uri.getRawQuery() != null && uri.getRawQuery().contains(PERCENTAGE_SIGN))
42+
|| (uri.getRawPath() != null && uri.getRawPath().contains(PERCENTAGE_SIGN))
43+
|| (uri.getRawFragment() != null && uri.getRawFragment().contains(PERCENTAGE_SIGN));
44+
// Verify if it is really fully encoded. Treat partial encoded as unencoded.
45+
if (encoded) {
46+
try {
47+
UriComponentsBuilder.fromUri(uri).build(true);
48+
return true;
49+
} catch (IllegalArgumentException ignore) {
50+
}
51+
return false;
52+
}
53+
return false;
54+
}
55+
56+
private static int computePort(int port, String scheme) {
57+
if (port >= 0) {
58+
return port;
59+
}
60+
if (Objects.equals(scheme, DEFAULT_SECURE_SCHEME)) {
61+
return 443;
62+
}
63+
return 80;
64+
}
65+
66+
/**
67+
* Modifies the URI in order to redirect the request to a service instance of choice.
68+
*
69+
* @param serviceInstance the {@link ServiceInstance} to redirect the request to.
70+
* @param original the {@link URI} from the original request
71+
* @param prefix
72+
* @param podService
73+
* @return the modified {@link URI}
74+
*/
75+
public static URI reconstructURI(ServiceInstance serviceInstance, URI original, String prefix, String podService) {
76+
if (serviceInstance == null) {
77+
throw new IllegalArgumentException("Service Instance cannot be null.");
78+
}
79+
return doReconstructURI(serviceInstance, original, prefix, podService);
80+
}
81+
82+
private static URI doReconstructURI(ServiceInstance serviceInstance, URI original, String prefix, String podService) {
83+
String host = serviceInstance.getHost();
84+
String scheme = Optional.ofNullable(serviceInstance.getScheme())
85+
.orElse(computeScheme(original, serviceInstance));
86+
int port = computePort(serviceInstance.getPort(), scheme);
87+
88+
if (Objects.equals(host, original.getHost()) && port == original.getPort()
89+
&& Objects.equals(scheme, original.getScheme())) {
90+
return original;
91+
}
92+
93+
boolean encoded = containsEncodedParts(original);
94+
return UriComponentsBuilder
95+
.fromPath(prefix + original.getPath())
96+
.scheme(scheme)
97+
.host(host)
98+
.port(port)
99+
.queryParam(Cons.LB_IP_PORT_PARAM, podService)
100+
.build(encoded).toUri();
101+
}
102+
103+
private static String computeScheme(URI original, ServiceInstance serviceInstance) {
104+
String originalOrDefault = Optional.ofNullable(original.getScheme()).orElse(DEFAULT_SCHEME);
105+
if (serviceInstance.isSecure() && INSECURE_SCHEME_MAPPINGS.containsKey(originalOrDefault)) {
106+
return INSECURE_SCHEME_MAPPINGS.get(originalOrDefault);
107+
}
108+
return originalOrDefault;
109+
}
110+
}

spring-cloud-kubernetes-loadbalancer-debugging-starter/src/main/java/spring/cloud/kubernetes/loadbalancer/debugging/NetSegmentLoadBalancer.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package spring.cloud.kubernetes.loadbalancer.debugging;
22

3+
import io.fabric8.kubernetes.api.model.Pod;
34
import org.apache.commons.logging.Log;
45
import org.apache.commons.logging.LogFactory;
56
import org.springframework.beans.factory.ObjectProvider;
@@ -8,12 +9,17 @@
89
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
910
import org.springframework.cloud.client.loadbalancer.Request;
1011
import org.springframework.cloud.client.loadbalancer.Response;
12+
import org.springframework.cloud.kubernetes.commons.PodUtils;
13+
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesServiceInstance;
1114
import org.springframework.cloud.loadbalancer.core.*;
1215
import reactor.core.publisher.Mono;
16+
import spring.cloud.kubernetes.discovery.ext.KubernetesRegistration;
1317
import spring.cloud.kubernetes.loadbalancer.ProxyContextHolder;
1418

1519
import java.util.List;
20+
import java.util.Map;
1621
import java.util.Random;
22+
import java.util.UUID;
1723
import java.util.concurrent.atomic.AtomicInteger;
1824

1925
/**
@@ -26,11 +32,22 @@ public class NetSegmentLoadBalancer implements ReactorServiceInstanceLoadBalance
2632

2733
final String serviceId;
2834

35+
boolean register;
36+
37+
38+
PodUtils<Pod> podUtils;
39+
40+
ProxyProperties proxyProperties;
41+
2942
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
3043

3144
public NetSegmentLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
32-
String serviceId) {
45+
String serviceId, String register, PodUtils<Pod> podUtils, ProxyProperties proxyProperties) {
3346
this(serviceInstanceListSupplierProvider, serviceId, new Random().nextInt(1000));
47+
this.register = Boolean.parseBoolean(register);
48+
this.podUtils = podUtils;
49+
this.proxyProperties = proxyProperties;
50+
3451
}
3552

3653
public NetSegmentLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
@@ -71,10 +88,23 @@ private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> inst
7188

7289
ServiceInstance instance = instances.get(pos % instances.size());
7390

74-
//如果是本地服务. 而且只能请求公共服务. 那么就要去请求代理服务. 因为无法直接请求pod. TODO 如何判断. 根据当前注册的元数据判断.
91+
//TODO 如何判断. 根据当前注册的元数据判断. ok
92+
//如果是本地服务. 而且只能请求公共服务. 那么就要去请求代理服务. 因为无法直接请求pod.
7593
//要重写URL. 怎么办. 需要在每个框架中独立实现... 或者使用header?
76-
// ProxyContextHolder.setRealPodService(instance.getInstanceId() + ":" + instance.getPort());
7794

95+
//判断标准
96+
// 1. 在 pod 外
97+
// 2. spring.cloud.kubernetes.discovery.register =true 说明是本地服务.
98+
// 3. instance 的元数据中包含 k8s-public-service=true. 这个时候需要请求代理服务
99+
if (!podUtils.isInsideKubernetes() && register && instance.getMetadata().containsKey("k8s-public-service")) {
100+
ProxyContextHolder.setRealPodService(instance.getHost() + ":" + instance.getPort());
101+
instance = getProxyInstance(instance);
102+
}
78103
return new DefaultResponse(instance);
79104
}
105+
106+
private ServiceInstance getProxyInstance(ServiceInstance si) {
107+
108+
return new KubernetesServiceInstance(si.getInstanceId(), si.getServiceId(), proxyProperties.getHost(), proxyProperties.getPort(), si.getMetadata(), si.isSecure());
109+
}
80110
}

spring-cloud-kubernetes-loadbalancer-debugging-starter/src/main/java/spring/cloud/kubernetes/loadbalancer/debugging/NetSegmentServiceInstanceListSupplier.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ private List<ServiceInstance> filterByNetSegment(List<ServiceInstance> instances
5555
List<ServiceInstance> publicPodService = new ArrayList<>();
5656
for (ServiceInstance instance : instances) {
5757
if (IPV4Util.isSameAddress(resourceIp, instance.getHost())) {
58-
//如何排除不健康的instance
5958
targetList.add(instance);
6059
}
6160
//过滤出公共服务
6261
if (isPublicPodService(instance)) {
62+
instance.getMetadata().put("k8s-public-service", "true");
6363
publicPodService.add(instance);
6464
}
6565
}
@@ -75,7 +75,6 @@ private List<ServiceInstance> filterByNetSegment(List<ServiceInstance> instances
7575
}
7676

7777
private boolean isPublicPodService(ServiceInstance instance) {
78-
String pubSvc = instance.getMetadata().getOrDefault("public-service", "true");
79-
return Boolean.parseBoolean(pubSvc);
78+
return instance.getHost().startsWith("10.244");
8079
}
8180
}

0 commit comments

Comments
 (0)