具体参考:nginx通过自定义header属性来转发不同的服务
SpringCloud 存在的问题:请求头是前端设置的,如果请求不是H5发起的,比如MQ的消费涉及两个微服务组件(A>B),请求头在A是没有的,这种场景就需要在Feign中配置蓝绿请求头标识,代码如下:
@FeignClient(name = "CONSUMER-SERVICE", fallbackFactory = ConsumerInfoServiceImpl.class)
public interface ConsumerInfoService{
@PostMapping(value = "/consumer/info", headers = {"cluster-env=${spring.cloud.system.app.version}"})
Result<Object> notifyChange(@RequestBody Map map);
}
然后见一个公共的拦截器去获取@FeignClient里面的请求头,跟日志链路trace.id的设置一样。
import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class OpenfeignInterceptor implements RequestInterceptor {
private static final Logger log = LoggerFactory.getLogger(PhcloudOpenfeignInterceptor.class);
private static final String CLUSTER_ENV_KEY = "cluster-env";
@Value("${logging.enabled:false}")
private boolean langEnabled;
@Value("${proenv.enabled:false}")
private boolean grayEnabled;
public OpenfeignInterceptor() {
}
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (this.loggingEnabled) {
String traceId = MDC.get("trace.id");
if (traceId == null) {
traceId = UUID.randomUUID().toString();
}
requestTemplate.header("traceId", new String[]{traceId});
}
if (this.grayEnabled && attributes != null && attributes.getRequest() != null && StringUtils.isNotBlank(attributes.getRequest().getHeader("cluster-env"))) {
requestTemplate.header("cluster-env", new String[]{attributes.getRequest().getHeader("cluster-env")});
log.info("set cluster-env = {} success!", attributes.getRequest().getHeader("cluster-env"));
}
}
}