✨ Introducing new features. 支持全局的服务灰度路由
This commit is contained in:
1 parent
006cbbb953
commit
93fdad4dd0
36 files changed
+566
-449
No files matched your search
@@ -68,6 +68,11 @@
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
<!--路由控制-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
</dependency>
|
||||
<!--JDBC相关-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-datasource</artifactId>
|
||||
|
||||
+7
-3
@@ -51,8 +51,8 @@ import java.nio.charset.StandardCharsets;
|
||||
@Slf4j
|
||||
@UtilityClass
|
||||
public class WebUtils extends org.springframework.web.util.WebUtils {
|
||||
private final String BASIC_ = "Basic ";
|
||||
private final String UNKNOWN = "unknown";
|
||||
private final String BASIC_ = "Basic ";
|
||||
private final String UNKNOWN = "unknown";
|
||||
|
||||
/**
|
||||
* 判断是否ajax请求
|
||||
@@ -122,7 +122,11 @@ public class WebUtils extends org.springframework.web.util.WebUtils {
|
||||
* @return {HttpServletRequest}
|
||||
*/
|
||||
public HttpServletRequest getRequest() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
try {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
} catch (IllegalStateException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,5 +50,9 @@
|
||||
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.configuration;
|
||||
|
||||
import com.pig4cloud.pigx.common.gateway.rule.GrayLoadBalancer;
|
||||
import com.pig4cloud.pigx.common.gateway.rule.VersionGrayLoadBalancer;
|
||||
import com.pig4cloud.pigx.common.gateway.filter.GrayReactiveLoadBalancerClientFilter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration;
|
||||
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
|
||||
import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Mica ribbon rule auto configuration.
|
||||
*
|
||||
* @author L.cm
|
||||
* @link https://github.com/lets-mica/mica
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(LoadBalancerProperties.class)
|
||||
@ConditionalOnProperty(value = "gray.rule.enabled", havingValue = "true")
|
||||
@AutoConfigureBefore(GatewayReactiveLoadBalancerClientAutoConfiguration.class)
|
||||
public class GrayLoadBalancerClientConfiguration {
|
||||
|
||||
@Bean
|
||||
public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(GrayLoadBalancer grayLoadBalancer,
|
||||
LoadBalancerProperties properties) {
|
||||
return new GrayReactiveLoadBalancerClientFilter(properties, grayLoadBalancer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GrayLoadBalancer grayLoadBalancer(DiscoveryClient discoveryClient) {
|
||||
return new VersionGrayLoadBalancer(discoveryClient);
|
||||
}
|
||||
}
|
||||
-76
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.configuration;
|
||||
|
||||
import com.alibaba.cloud.nacos.ribbon.NacosServer;
|
||||
import com.pig4cloud.pigx.common.gateway.filter.GrayLoadBalancerClientFilter;
|
||||
import com.pig4cloud.pigx.common.gateway.rule.AbstractDiscoveryEnabledRule;
|
||||
import com.pig4cloud.pigx.common.gateway.rule.MetadataAwareRule;
|
||||
import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
|
||||
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
/**
|
||||
* Mica ribbon rule auto configuration.
|
||||
*
|
||||
* @author L.cm
|
||||
* @link https://github.com/lets-mica/mica
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnClass(NacosServer.class)
|
||||
@AutoConfigureBefore(RibbonClientConfiguration.class)
|
||||
@EnableConfigurationProperties(PigxRibbonRuleProperties.class)
|
||||
@ConditionalOnProperty(value = "ribbon.rule.enabled", matchIfMissing = true)
|
||||
public class PigxRibbonRuleAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public AbstractDiscoveryEnabledRule metadataAwareRule() {
|
||||
return new MetadataAwareRule();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LoadBalancerClient.class)
|
||||
public LoadBalancerClient loadBalancerClient(SpringClientFactory springClientFactory) {
|
||||
return new RibbonLoadBalancerClient(springClientFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LoadBalancerClientFilter.class)
|
||||
public LoadBalancerClientFilter loadBalancerClientFilter(RibbonLoadBalancerClient client
|
||||
, LoadBalancerProperties properties) {
|
||||
return new GrayLoadBalancerClientFilter(client, properties);
|
||||
}
|
||||
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.filter;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
|
||||
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Tim Ysewyn
|
||||
*/
|
||||
public class GrayLoadBalancerClientFilter extends LoadBalancerClientFilter {
|
||||
private final RibbonLoadBalancerClient loadBalancer;
|
||||
|
||||
public GrayLoadBalancerClientFilter(RibbonLoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
|
||||
super(loadBalancer, properties);
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceInstance choose(ServerWebExchange exchange) {
|
||||
HttpHeaders headers = exchange.getRequest().getHeaders();
|
||||
return loadBalancer.choose(((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost(), headers);
|
||||
}
|
||||
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.filter;
|
||||
|
||||
import com.pig4cloud.pigx.common.gateway.rule.GrayLoadBalancer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.DefaultResponse;
|
||||
import org.springframework.cloud.client.loadbalancer.reactive.Response;
|
||||
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
|
||||
import org.springframework.cloud.gateway.support.DelegatingServiceInstance;
|
||||
import org.springframework.cloud.gateway.support.NotFoundException;
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/1/11
|
||||
*/
|
||||
@Slf4j
|
||||
public class GrayReactiveLoadBalancerClientFilter extends ReactiveLoadBalancerClientFilter {
|
||||
private static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150;
|
||||
private LoadBalancerProperties properties;
|
||||
|
||||
private GrayLoadBalancer grayLoadBalancer;
|
||||
|
||||
public GrayReactiveLoadBalancerClientFilter(LoadBalancerProperties properties, GrayLoadBalancer grayLoadBalancer) {
|
||||
super(null, properties);
|
||||
this.properties = properties;
|
||||
this.grayLoadBalancer = grayLoadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return LOAD_BALANCER_CLIENT_FILTER_ORDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
|
||||
String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
|
||||
if (url == null
|
||||
|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
// preserve the original url
|
||||
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName()
|
||||
+ " url before: " + url);
|
||||
}
|
||||
|
||||
return choose(exchange).doOnNext(response -> {
|
||||
|
||||
if (!response.hasServer()) {
|
||||
throw NotFoundException.create(properties.isUse404(),
|
||||
"Unable to find instance for " + url.getHost());
|
||||
}
|
||||
|
||||
URI uri = exchange.getRequest().getURI();
|
||||
|
||||
// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
|
||||
// if the loadbalancer doesn't provide one.
|
||||
String overrideScheme = null;
|
||||
if (schemePrefix != null) {
|
||||
overrideScheme = url.getScheme();
|
||||
}
|
||||
|
||||
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(
|
||||
response.getServer(), overrideScheme);
|
||||
|
||||
URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
|
||||
}
|
||||
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
|
||||
}).then(chain.filter(exchange));
|
||||
}
|
||||
|
||||
private Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {
|
||||
URI uri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
|
||||
ServiceInstance serviceInstance = grayLoadBalancer.choose(uri.getHost(),exchange.getRequest());
|
||||
return Mono.just(new DefaultResponse(serviceInstance));
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.predicate;
|
||||
|
||||
import com.alibaba.cloud.nacos.ribbon.NacosServer;
|
||||
import com.netflix.loadbalancer.AbstractServerPredicate;
|
||||
import com.netflix.loadbalancer.PredicateKey;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* 过滤服务
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public abstract class AbstractDiscoveryEnabledPredicate extends AbstractServerPredicate {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean apply(@Nullable PredicateKey input) {
|
||||
return input != null
|
||||
&& input.getServer() instanceof NacosServer
|
||||
&& apply((NacosServer) input.getServer(), (HttpHeaders) input.getLoadBalancerKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specific {@link NacosServer} matches this predicate.
|
||||
*
|
||||
* @param server the discovered server
|
||||
* @param headers 请求头
|
||||
* @return whether the server matches the predicate
|
||||
*/
|
||||
abstract boolean apply(NacosServer server, HttpHeaders headers);
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.predicate;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.cloud.nacos.ribbon.NacosServer;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
|
||||
import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 基于 Metadata version 的服务筛选
|
||||
*
|
||||
* @author L.cm
|
||||
* @author lengleng
|
||||
*/
|
||||
@Slf4j
|
||||
public class GrayMetadataAwarePredicate extends AbstractDiscoveryEnabledPredicate {
|
||||
|
||||
@Override
|
||||
protected boolean apply(NacosServer server, HttpHeaders headers) {
|
||||
PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
|
||||
|
||||
if (!ribbonProperties.isGrayEnabled()) {
|
||||
log.debug("gray closed,GrayMetadataAwarePredicate return true");
|
||||
return true;
|
||||
}
|
||||
|
||||
final Map<String, String> metadata = server.getMetadata();
|
||||
String version = metadata.get(CommonConstants.VERSION);
|
||||
// 判断Nacos服务是否有版本标签
|
||||
if (StrUtil.isBlank(version)) {
|
||||
log.debug("nacos server tag is blank ,GrayMetadataAwarePredicate return true");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 判断请求中是否有版本
|
||||
String target = headers.getFirst(CommonConstants.VERSION);
|
||||
if (StrUtil.isBlank(target)) {
|
||||
log.debug("request headers version is blank,GrayMetadataAwarePredicate return true");
|
||||
return true;
|
||||
}
|
||||
|
||||
log.debug("请求版本:{} ,当前服务版本:{}", target, version);
|
||||
return target.equals(version);
|
||||
}
|
||||
|
||||
}
|
||||
-76
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.rule;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.netflix.loadbalancer.*;
|
||||
import com.pig4cloud.pigx.common.gateway.predicate.AbstractDiscoveryEnabledPredicate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ribbon 路由规则
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public abstract class AbstractDiscoveryEnabledRule extends PredicateBasedRule {
|
||||
private final CompositePredicate predicate;
|
||||
|
||||
public AbstractDiscoveryEnabledRule(AbstractDiscoveryEnabledPredicate discoveryEnabledPredicate) {
|
||||
Assert.notNull(discoveryEnabledPredicate, "Parameter 'discoveryEnabledPredicate' can't be null");
|
||||
this.predicate = createCompositePredicate(discoveryEnabledPredicate, new AvailabilityPredicate(this, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AbstractServerPredicate getPredicate() {
|
||||
return predicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server choose(Object key) {
|
||||
ILoadBalancer lb = getLoadBalancer();
|
||||
|
||||
List<Server> allServers = lb.getAllServers();
|
||||
// 过滤服务列表
|
||||
List<Server> serverList = filterServers(allServers);
|
||||
|
||||
Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(serverList, key);
|
||||
if (server.isPresent()) {
|
||||
return server.get();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤服务
|
||||
*
|
||||
* @param serverList 服务列表
|
||||
* @return 服务列表
|
||||
*/
|
||||
public abstract List<Server> filterServers(List<Server> serverList);
|
||||
|
||||
private CompositePredicate createCompositePredicate(AbstractDiscoveryEnabledPredicate discoveryEnabledPredicate, AvailabilityPredicate availabilityPredicate) {
|
||||
return CompositePredicate.withPredicates(discoveryEnabledPredicate, availabilityPredicate)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.rule;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/1/12
|
||||
* <p>
|
||||
* 灰度路由
|
||||
*/
|
||||
public interface GrayLoadBalancer {
|
||||
|
||||
/**
|
||||
* 根据serviceId 筛选可用服务
|
||||
*
|
||||
* @param serviceId 服务ID
|
||||
* @param request 当前请求
|
||||
* @return
|
||||
*/
|
||||
ServiceInstance choose(String serviceId, ServerHttpRequest request);
|
||||
}
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.rule;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.system.HostInfo;
|
||||
import cn.hutool.system.SystemUtil;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
|
||||
import com.pig4cloud.pigx.common.gateway.predicate.AbstractDiscoveryEnabledPredicate;
|
||||
import com.pig4cloud.pigx.common.gateway.predicate.GrayMetadataAwarePredicate;
|
||||
import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ribbon 路由规则器
|
||||
*
|
||||
* @author dream.lu
|
||||
*/
|
||||
@Slf4j
|
||||
public class MetadataAwareRule extends AbstractDiscoveryEnabledRule {
|
||||
|
||||
public MetadataAwareRule() {
|
||||
this(new GrayMetadataAwarePredicate());
|
||||
}
|
||||
|
||||
public MetadataAwareRule(AbstractDiscoveryEnabledPredicate predicate) {
|
||||
super(predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> filterServers(List<Server> serverList) {
|
||||
PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
|
||||
List<String> priorIpPattern = ribbonProperties.getPriorIpPattern();
|
||||
|
||||
if (ribbonProperties.isGrayEnabled()) {
|
||||
return serverList;
|
||||
}
|
||||
|
||||
// 1. 查找是否有本机 ip
|
||||
HostInfo hostInfo = SystemUtil.getHostInfo();
|
||||
String hostIp = hostInfo.getAddress();
|
||||
|
||||
// 优先的 ip 规则
|
||||
boolean hasPriorIpPattern = !priorIpPattern.isEmpty();
|
||||
String[] priorIpPatterns = priorIpPattern.toArray(new String[0]);
|
||||
|
||||
List<Server> priorServerList = new ArrayList<>();
|
||||
for (Server server : serverList) {
|
||||
String host = server.getHost();
|
||||
// 2. 优先本地 ip 的服务
|
||||
if (!hasPriorIpPattern && ObjectUtil.equal(hostIp, host)) {
|
||||
log.debug("{} 不存在优先配置,本地路由条件", hostIp);
|
||||
return Collections.singletonList(server);
|
||||
}
|
||||
// 3. 优先的 ip 服务
|
||||
if (hasPriorIpPattern && PatternMatchUtils.simpleMatch(priorIpPatterns, host)) {
|
||||
log.debug("{} 存在优先配置,ribbon 强制路由", priorIpPatterns);
|
||||
priorServerList.add(server);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 如果优先的有数据直接返回
|
||||
if (!priorServerList.isEmpty()) {
|
||||
return priorServerList;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(serverList);
|
||||
}
|
||||
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gateway.rule;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.gateway.support.NotFoundException;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/1/12
|
||||
* <p>
|
||||
* 基于客户端版本号灰度路由
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class VersionGrayLoadBalancer implements GrayLoadBalancer {
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
|
||||
/**
|
||||
* 根据serviceId 筛选可用服务
|
||||
*
|
||||
* @param serviceId 服务ID
|
||||
* @param request 当前请求
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId, ServerHttpRequest request) {
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
|
||||
|
||||
//注册中心无实例 抛出异常
|
||||
if (CollUtil.isEmpty(instances)) {
|
||||
log.warn("No instance available for {}", serviceId);
|
||||
throw new NotFoundException("No instance available for " + serviceId);
|
||||
}
|
||||
|
||||
// 获取请求version,无则随机返回可用实例
|
||||
String reqVersion = request.getHeaders().getFirst(CommonConstants.VERSION);
|
||||
if (StrUtil.isBlank(reqVersion)) {
|
||||
return instances.get(RandomUtil.randomInt(instances.size()));
|
||||
}
|
||||
|
||||
// 遍历可以实例元数据,若匹配则返回此实例
|
||||
for (ServiceInstance instance : instances) {
|
||||
Map<String, String> metadata = instance.getMetadata();
|
||||
String targetVersion = MapUtil.getStr(metadata, CommonConstants.VERSION);
|
||||
if (reqVersion.equalsIgnoreCase(targetVersion)) {
|
||||
log.debug("gray requst match success :{} {}", reqVersion, instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return instances.get(RandomUtil.randomInt(instances.size()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>3.6.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<description>pigx 灰度路由</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gray;
|
||||
|
||||
import com.pig4cloud.pigx.common.gray.feign.GrayFeignRequestInterceptor;
|
||||
import com.pig4cloud.pigx.common.gray.rule.GrayRibbonLoadBalancerRule;
|
||||
import feign.RequestInterceptor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/1/12
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "gray.rule.enabled", havingValue = "true")
|
||||
public class GrayRibbonLoadBalancerConfiguration {
|
||||
@Bean
|
||||
public GrayRibbonLoadBalancerRule ribbonLoadBalancerRule() {
|
||||
return new GrayRibbonLoadBalancerRule();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestInterceptor pigxFeignTenantInterceptor() {
|
||||
return new GrayFeignRequestInterceptor();
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gray.feign;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.WebUtils;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/1/12
|
||||
* <p>
|
||||
* feign 请求VERSION 传递
|
||||
*/
|
||||
@Slf4j
|
||||
public class GrayFeignRequestInterceptor implements RequestInterceptor {
|
||||
/**
|
||||
* Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
|
||||
*
|
||||
* @param template
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
String reqVersion = WebUtils.getRequest() != null
|
||||
? WebUtils.getRequest().getHeader(CommonConstants.VERSION) : null;
|
||||
|
||||
if (StrUtil.isNotBlank(reqVersion)) {
|
||||
log.debug("feign gray add header version :{}", reqVersion);
|
||||
template.header(CommonConstants.VERSION, reqVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng 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 pig4cloud.com 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: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.gray.rule;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.cloud.nacos.ribbon.NacosServer;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.WebUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/1/12
|
||||
*/
|
||||
@Slf4j
|
||||
public class GrayRibbonLoadBalancerRule extends AbstractLoadBalancerRule {
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig iClientConfig) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server choose(Object key) {
|
||||
return choose(getLoadBalancer(), key);
|
||||
}
|
||||
|
||||
|
||||
public Server choose(ILoadBalancer lb, Object key) {
|
||||
List<Server> reachableServers = lb.getReachableServers();
|
||||
|
||||
//注册中心无可用实例 抛出异常
|
||||
if (CollUtil.isEmpty(reachableServers)) {
|
||||
log.warn("No instance available for {}", key);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取请求version,无则随机返回可用实例
|
||||
String reqVersion = WebUtils.getRequest() != null
|
||||
? WebUtils.getRequest().getHeader(CommonConstants.VERSION) : null;
|
||||
if (StrUtil.isBlank(reqVersion)) {
|
||||
return reachableServers.get(RandomUtil.randomInt(reachableServers.size()));
|
||||
}
|
||||
|
||||
// 遍历可以实例元数据,若匹配则返回此实例
|
||||
for (Server server : reachableServers) {
|
||||
NacosServer nacosServer = (NacosServer) server;
|
||||
Map<String, String> metadata = nacosServer.getMetadata();
|
||||
String targetVersion = MapUtil.getStr(metadata, CommonConstants.VERSION);
|
||||
if (reqVersion.equalsIgnoreCase(targetVersion)) {
|
||||
log.debug("gray requst match success :{} {}", reqVersion, nacosServer);
|
||||
return nacosServer;
|
||||
}
|
||||
}
|
||||
return reachableServers.get(RandomUtil.randomInt(reachableServers.size()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.pig4cloud.pigx.common.gray.GrayRibbonLoadBalancerConfiguration
|
||||
+5
-5
@@ -15,14 +15,14 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job;
|
||||
package com.pig4cloud.pigx.common.gray;
|
||||
|
||||
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
|
||||
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
|
||||
import com.pig4cloud.pigx.common.job.jobinit.DataflowJobInitialization;
|
||||
import com.pig4cloud.pigx.common.job.jobinit.ScriptJobInitialization;
|
||||
import com.pig4cloud.pigx.common.job.jobinit.SimpleJobInitialization;
|
||||
import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
|
||||
import com.pig4cloud.pigx.common.gray.jobinit.DataflowJobInitialization;
|
||||
import com.pig4cloud.pigx.common.gray.jobinit.ScriptJobInitialization;
|
||||
import com.pig4cloud.pigx.common.gray.jobinit.SimpleJobInitialization;
|
||||
import com.pig4cloud.pigx.common.gray.properties.ElasticJobProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
+3
-3
@@ -15,9 +15,9 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job;
|
||||
package com.pig4cloud.pigx.common.gray;
|
||||
|
||||
import com.pig4cloud.pigx.common.job.properties.XxlJobProperties;
|
||||
import com.pig4cloud.pigx.common.gray.properties.XxlJobProperties;
|
||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -32,7 +32,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan("com.pig4cloud.pigx.common.job.properties")
|
||||
@ComponentScan("com.pig4cloud.pigx.common.gray.properties")
|
||||
public class XxlJobAutoConfiguration {
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "destroy")
|
||||
+2
-2
@@ -15,9 +15,9 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.annotation;
|
||||
package com.pig4cloud.pigx.common.gray.annotation;
|
||||
|
||||
import com.pig4cloud.pigx.common.job.ElasticJobAutoConfiguration;
|
||||
import com.pig4cloud.pigx.common.gray.ElasticJobAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
+2
-2
@@ -15,9 +15,9 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.annotation;
|
||||
package com.pig4cloud.pigx.common.gray.annotation;
|
||||
|
||||
import com.pig4cloud.pigx.common.job.XxlJobAutoConfiguration;
|
||||
import com.pig4cloud.pigx.common.gray.XxlJobAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
+3
-3
@@ -15,7 +15,7 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.jobinit;
|
||||
package com.pig4cloud.pigx.common.gray.jobinit;
|
||||
|
||||
import com.dangdang.ddframe.job.api.ElasticJob;
|
||||
import com.dangdang.ddframe.job.api.JobType;
|
||||
@@ -30,7 +30,7 @@ import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
|
||||
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
|
||||
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
|
||||
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
|
||||
import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
|
||||
import com.pig4cloud.pigx.common.gray.properties.ElasticJobProperties;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -46,7 +46,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.pig4cloud.pigx.common.job.ElasticJobAutoConfiguration.DEFAULT_REGISTRY_CENTER_NAME;
|
||||
import static com.pig4cloud.pigx.common.gray.ElasticJobAutoConfiguration.DEFAULT_REGISTRY_CENTER_NAME;
|
||||
|
||||
|
||||
/**
|
||||
+2
-2
@@ -15,12 +15,12 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.jobinit;
|
||||
package com.pig4cloud.pigx.common.gray.jobinit;
|
||||
|
||||
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
|
||||
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
|
||||
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
|
||||
import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
|
||||
import com.pig4cloud.pigx.common.gray.properties.ElasticJobProperties;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+2
-2
@@ -15,12 +15,12 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.jobinit;
|
||||
package com.pig4cloud.pigx.common.gray.jobinit;
|
||||
|
||||
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
|
||||
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
|
||||
import com.dangdang.ddframe.job.config.script.ScriptJobConfiguration;
|
||||
import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
|
||||
import com.pig4cloud.pigx.common.gray.properties.ElasticJobProperties;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+2
-2
@@ -15,12 +15,12 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.jobinit;
|
||||
package com.pig4cloud.pigx.common.gray.jobinit;
|
||||
|
||||
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
|
||||
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
|
||||
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
|
||||
import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
|
||||
import com.pig4cloud.pigx.common.gray.properties.ElasticJobProperties;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.properties;
|
||||
package com.pig4cloud.pigx.common.gray.properties;
|
||||
|
||||
import com.dangdang.ddframe.job.api.JobType;
|
||||
import lombok.Getter;
|
||||
@@ -25,7 +25,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.pig4cloud.pigx.common.job.ElasticJobAutoConfiguration.DEFAULT_REGISTRY_CENTER_NAME;
|
||||
import static com.pig4cloud.pigx.common.gray.ElasticJobAutoConfiguration.DEFAULT_REGISTRY_CENTER_NAME;
|
||||
|
||||
|
||||
/**
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.properties;
|
||||
package com.pig4cloud.pigx.common.gray.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.properties;
|
||||
package com.pig4cloud.pigx.common.gray.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.common.job.properties;
|
||||
package com.pig4cloud.pigx.common.gray.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
-8
@@ -22,14 +22,12 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
@@ -62,14 +60,8 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public UserDetails loadUserByUsername(String username) {
|
||||
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
|
||||
if (cache != null && cache.get(username) != null) {
|
||||
return (PigxUser) cache.get(username).get();
|
||||
}
|
||||
|
||||
R<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
|
||||
UserDetails userDetails = getUserDetails(result);
|
||||
cache.put(username, userDetails);
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<module>pigx-common-data</module>
|
||||
<module>pigx-common-datasource</module>
|
||||
<module>pigx-common-gateway</module>
|
||||
<module>pigx-common-gray</module>
|
||||
<module>pigx-common-job</module>
|
||||
<module>pigx-common-log</module>
|
||||
<module>pigx-common-minio</module>
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
</dependency>
|
||||
<!--注册中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
|
||||
@@ -5,6 +5,9 @@ spring:
|
||||
application:
|
||||
name: @artifactId@
|
||||
cloud:
|
||||
loadbalancer:
|
||||
ribbon:
|
||||
enabled: false
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS-HOST:pigx-register}:${NACOS-PORT:8848}
|
||||
@@ -13,4 +16,4 @@ spring:
|
||||
file-extension: yml
|
||||
shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
profiles:
|
||||
active: @profiles.active@
|
||||
active: @profiles.active@
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
|
||||
package com.pig4cloud.pigx.daemon.elastic;
|
||||
|
||||
import com.pig4cloud.pigx.common.job.annotation.EnablePigxXxlJob;
|
||||
import com.pig4cloud.pigx.common.gray.annotation.EnablePigxXxlJob;
|
||||
import com.pig4cloud.pigx.common.security.annotation.EnablePigxFeignClients;
|
||||
import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer;
|
||||
import com.pig4cloud.pigx.common.swagger.annotation.EnablePigxSwagger2;
|
||||
|
||||
Reference in new issue
Block a user