Commit 85805d0f by Nepxion

增加网关透传Header信息到下游微服务的功能

parent 0ec0e67e
...@@ -25,5 +25,15 @@ ...@@ -25,5 +25,15 @@
<artifactId>matrix-aop-starter</artifactId> <artifactId>matrix-aop-starter</artifactId>
<version>${matrix.version}</version> <version>${matrix.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package com.nepxion.discovery.plugin.strategy.extension.service.aop;
/**
* <p>Title: Nepxion Discovery</p>
* <p>Description: Nepxion Discovery</p>
* <p>Copyright: Copyright (c) 2017-2050</p>
* <p>Company: Nepxion</p>
* @author Haojun Ren
* @version 1.0
*/
import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class FeignStrategyInterceptor implements RequestInterceptor {
private static final Logger LOG = LoggerFactory.getLogger(FeignStrategyInterceptor.class);
private String feignHeaders;
public FeignStrategyInterceptor(String feignHeaders) {
this.feignHeaders = feignHeaders;
LOG.info("------------- Feign Proxy Information -----------");
LOG.info("Feign interceptor headers are '{}'", feignHeaders);
LOG.info("-------------------------------------------------");
}
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String header = request.getHeader(headerName);
if (feignHeaders.contains(headerName)) {
requestTemplate.header(headerName, header);
}
}
}
}
}
\ No newline at end of file
...@@ -17,6 +17,7 @@ import org.springframework.context.annotation.Bean; ...@@ -17,6 +17,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.nepxion.discovery.plugin.strategy.constant.StrategyConstant; import com.nepxion.discovery.plugin.strategy.constant.StrategyConstant;
import com.nepxion.discovery.plugin.strategy.extension.service.aop.FeignStrategyInterceptor;
import com.nepxion.discovery.plugin.strategy.extension.service.aop.ServiceStrategyAutoScanProxy; import com.nepxion.discovery.plugin.strategy.extension.service.aop.ServiceStrategyAutoScanProxy;
import com.nepxion.discovery.plugin.strategy.extension.service.aop.ServiceStrategyInterceptor; import com.nepxion.discovery.plugin.strategy.extension.service.aop.ServiceStrategyInterceptor;
import com.nepxion.discovery.plugin.strategy.extension.service.constant.ServiceStrategyConstant; import com.nepxion.discovery.plugin.strategy.extension.service.constant.ServiceStrategyConstant;
...@@ -25,16 +26,27 @@ import com.nepxion.discovery.plugin.strategy.extension.service.constant.ServiceS ...@@ -25,16 +26,27 @@ import com.nepxion.discovery.plugin.strategy.extension.service.constant.ServiceS
@AutoConfigureBefore(RibbonClientConfiguration.class) @AutoConfigureBefore(RibbonClientConfiguration.class)
@ConditionalOnProperty(value = StrategyConstant.SPRING_APPLICATION_STRATEGY_CONTROL_ENABLED, matchIfMissing = true) @ConditionalOnProperty(value = StrategyConstant.SPRING_APPLICATION_STRATEGY_CONTROL_ENABLED, matchIfMissing = true)
public class ServiceStrategyAutoConfiguration { public class ServiceStrategyAutoConfiguration {
@Value("${" + ServiceStrategyConstant.SPRING_APPLICATION_STRATEGY_SCAN_PACKAGES + ":}") @Value("${" + ServiceStrategyConstant.SPRING_APPLICATION_STRATEGY_SCAN_PACKAGES + "}")
private String scanPackages; private String scanPackages;
@Value("${" + ServiceStrategyConstant.SPRING_APPLICATION_STRATEGY_FEIGN_HEADERS + "}")
private String feignHeaders;
@Bean @Bean
@ConditionalOnProperty(value = ServiceStrategyConstant.SPRING_APPLICATION_STRATEGY_SCAN_PACKAGES, matchIfMissing = false)
public ServiceStrategyAutoScanProxy serviceStrategyAutoScanProxy() { public ServiceStrategyAutoScanProxy serviceStrategyAutoScanProxy() {
return new ServiceStrategyAutoScanProxy(scanPackages); return new ServiceStrategyAutoScanProxy(scanPackages);
} }
@Bean @Bean
@ConditionalOnProperty(value = ServiceStrategyConstant.SPRING_APPLICATION_STRATEGY_SCAN_PACKAGES, matchIfMissing = false)
public ServiceStrategyInterceptor serviceStrategyInterceptor() { public ServiceStrategyInterceptor serviceStrategyInterceptor() {
return new ServiceStrategyInterceptor(); return new ServiceStrategyInterceptor();
} }
@ConditionalOnProperty(value = ServiceStrategyConstant.SPRING_APPLICATION_STRATEGY_FEIGN_HEADERS, matchIfMissing = false)
@Bean
public FeignStrategyInterceptor feignStrategyInterceptor() {
return new FeignStrategyInterceptor(feignHeaders);
}
} }
\ No newline at end of file
...@@ -11,6 +11,7 @@ package com.nepxion.discovery.plugin.strategy.extension.service.constant; ...@@ -11,6 +11,7 @@ package com.nepxion.discovery.plugin.strategy.extension.service.constant;
public class ServiceStrategyConstant { public class ServiceStrategyConstant {
public static final String SPRING_APPLICATION_STRATEGY_SCAN_PACKAGES = "spring.application.strategy.scan.packages"; public static final String SPRING_APPLICATION_STRATEGY_SCAN_PACKAGES = "spring.application.strategy.scan.packages";
public static final String SPRING_APPLICATION_STRATEGY_FEIGN_HEADERS = "spring.application.strategy.feign.headers";
public static final String CLASS = "class"; public static final String CLASS = "class";
public static final String METHOD = "method"; public static final String METHOD = "method";
public static final String PARAMETER_MAP = "parameterMap"; public static final String PARAMETER_MAP = "parameterMap";
......
...@@ -72,16 +72,6 @@ ...@@ -72,16 +72,6 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId> <artifactId>spring-boot-admin-starter-client</artifactId>
</dependency> </dependency>
......
...@@ -14,6 +14,8 @@ import java.util.Map; ...@@ -14,6 +14,8 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.nepxion.discovery.common.constant.DiscoveryConstant; import com.nepxion.discovery.common.constant.DiscoveryConstant;
import com.nepxion.discovery.plugin.strategy.discovery.DiscoveryEnabledAdapter; import com.nepxion.discovery.plugin.strategy.discovery.DiscoveryEnabledAdapter;
...@@ -24,9 +26,17 @@ import com.netflix.loadbalancer.Server; ...@@ -24,9 +26,17 @@ import com.netflix.loadbalancer.Server;
public class MyDiscoveryEnabledAdapter implements DiscoveryEnabledAdapter { public class MyDiscoveryEnabledAdapter implements DiscoveryEnabledAdapter {
private static final Logger LOG = LoggerFactory.getLogger(MyDiscoveryEnabledAdapter.class); private static final Logger LOG = LoggerFactory.getLogger(MyDiscoveryEnabledAdapter.class);
@SuppressWarnings("unchecked")
@Override @Override
public boolean apply(Server server, Map<String, String> metadata) { public boolean apply(Server server, Map<String, String> metadata) {
if (applyFromMethd(server, metadata)) {
return applyFromHeader(server, metadata);
} else {
return false;
}
}
@SuppressWarnings("unchecked")
private boolean applyFromMethd(Server server, Map<String, String> metadata) {
ServiceStrategyContext context = ServiceStrategyContext.getCurrentContext(); ServiceStrategyContext context = ServiceStrategyContext.getCurrentContext();
Map<String, Object> attributes = context.getAttributes(); Map<String, Object> attributes = context.getAttributes();
...@@ -52,4 +62,23 @@ public class MyDiscoveryEnabledAdapter implements DiscoveryEnabledAdapter { ...@@ -52,4 +62,23 @@ public class MyDiscoveryEnabledAdapter implements DiscoveryEnabledAdapter {
return true; return true;
} }
private boolean applyFromHeader(Server server, Map<String, String> metadata) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String token = attributes.getRequest().getHeader("token");
// String value = attributes.getRequest().getParameter("value");
String serviceId = server.getMetaInfo().getAppName().toLowerCase();
LOG.info("Serivice端负载均衡用户定制触发:serviceId={}, host={}, metadata={}, attributes={}", serviceId, server.toString(), metadata, attributes);
String filterToken = "123";
if (StringUtils.isNotEmpty(token) && token.contains(filterToken)) {
LOG.info("过滤条件:当Token含有'{}'的时候,不能被Ribbon负载均衡到", filterToken);
return false;
}
return true;
}
} }
\ No newline at end of file
...@@ -65,5 +65,7 @@ spring.boot.admin.url=http://localhost:5555 ...@@ -65,5 +65,7 @@ spring.boot.admin.url=http://localhost:5555
# Plugin strategy config # Plugin strategy config
# 开启和关闭用户自定义和编程灰度路由策略的控制,例如用户根据业务参数的不同,负载均衡到不同的服务器。缺失则默认为true # 开启和关闭用户自定义和编程灰度路由策略的控制,例如用户根据业务参数的不同,负载均衡到不同的服务器。缺失则默认为true
# spring.application.strategy.control.enabled=true # spring.application.strategy.control.enabled=true
# 用户自定义和编程灰度路由策略的时候,需要指定对业务Controller类的扫描路径,以便传递上下文对象。该项配置只对服务有效,对网关无效 # 用户自定义和编程灰度路由策略的时候,需要指定对业务Controller类的扫描路径,以便传递上下文对象。该项配置只对服务有效,对网关无效。缺失则默认关闭改功能
spring.application.strategy.scan.packages=com.nepxion.discovery.plugin.example.service.feign spring.application.strategy.scan.packages=com.nepxion.discovery.plugin.example.service.feign
\ No newline at end of file # 用户自定义和编程灰度路由策略的时候,如果采用Feign进行Rest调用,需要把来自网关的某些Header参数传递到服务里,如果多个用“;”分隔,不允许出现空格。该项配置只对服务有效,对网关无效。缺失则默认关闭改功能
spring.application.strategy.feign.headers=token
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment