-
Notifications
You must be signed in to change notification settings - Fork 222
request context
请求上下文用于在调用链中传递公共信息,比如trace id、微服务名称、实例ID等。
使用如下典型的微服务架构:
Spring Cloud Gateway --> Consumer --> Provider
在Spring Cloud Gateway添加一个上下文信息,可以在Consumer和Provider获取到上下文。
可以通过如下代码获取和添加上下文
InvocationContext context = InvocationContextHolder.getOrCreateInvocationContext();
// 读取
context.getContext(InvocationContext.CONTEXT_TRACE_ID);
// 设置
context.putContext(InvocationContext.CONTEXT_TRACE_ID, InvocationContext.generateTraceId());
在 WebFilter
中可以通过如下代码获取和添加上下文
InvocationContext context = exchange.getAttribute(InvocationContextHolder.ATTRIBUTE_KEY);
// 读取
context.getContext(InvocationContext.CONTEXT_TRACE_ID);
// 设置
context.putContext(InvocationContext.CONTEXT_TRACE_ID, InvocationContext.generateTraceId());
如果是 Spring Cloud Gateway,也可以在 GlobalFilter
, GatewayFilter
中通过如下代码获取和添加上下文
InvocationContext context = exchange.getAttribute(InvocationContextHolder.ATTRIBUTE_KEY);
// 读取
context.getContext(InvocationContext.CONTEXT_TRACE_ID);
// 设置
context.putContext(InvocationContext.CONTEXT_TRACE_ID, InvocationContext.generateTraceId());
在 RestController
中可以通过注入 ServerWebExchange
获取请求上下文:
@RequestMapping("/testWebFluxInvocationContext")
public Mono<String> testWebFluxInvocationContext(ServerWebExchange exchange, @RequestParam("name") String name){
InvocationContext context=exchange.getAttribute(InvocationContextHolder.ATTRIBUTE_KEY);
...
}
使用 WebClient
访问下游服务的时候,需要从 ServerWebExchange
获取上下文并传递,然后就可以在 ExchangeFilterFunction
获取上下文。
// controller 设置上下文
@GetMapping(
path = "/testWebClientRetry",
produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<String> testWebClientRetry(ServerWebExchange exchange,
@RequestParam(name = "invocationID") String invocationID) {
return webClientBuilder.build().get()
.uri("http://webflux/testWebClientRetry?invocationID={1}", invocationID)
.attribute(InvocationContextHolder.ATTRIBUTE_KEY, exchange.getAttribute(InvocationContextHolder.ATTRIBUTE_KEY))
.retrieve()
.bodyToMono(String.class);
}
// ExchangeFilterFunction获取上下文
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next){
InvocationContext context=request.attribute(InvocationContextHolder.ATTRIBUTE_KEY).isPresent()?
(InvocationContext)request.attribute(InvocationContextHolder.ATTRIBUTE_KEY).get():new InvocationContext();
...
}
很多场景需要从系统外部传递一些信息,比如JS端生成trace-id, 需要将trace-id在整个请求过程中传递。 可以在网关或者微服务 应用配置哪些 header 或者 query 参数需要添加到上下文中,并指定上下文的键名称。
spring:
cloud:
servicecomb:
context:
headerContextMapper:
header-context: x-header-context
trace-id: x-trace-id
queryContextMapper:
query-context: x-query-context
上述方式将 query 参数 query-context
和 header 参数 header-context
设置到上下文中,上下文的 key 分别为 x-query-context
和 x-header-context
。
对于比较复杂的场景,还可以使用 contextMapper
流量治理能力来设置上下文。示例如下:
servicecomb:
matchGroup:
testWebMvcInvocationContext: |
matches:
- apiPath:
exact: "/testWebMvcInvocationContext"
contextMapper:
testWebMvcInvocationContext: |
target:
x-c: foo
x-header-context: $H{header-context}
x-u: $U
x-m: $M
contextMapper
流量治理的含义是如果流量特征匹配,那么将 target
定义的键值对设置到请求上下文中。contextMapper
流量治理包含几个特殊标签:
-
$U
: 将 uri 设置到请求上下文中。 上述例子会设置x-u
=/testWebMvcInvocationContext
。 -
$M
: 将 method 设置到请求上下文中。 上述例子会设置x-m
=GET
。 -
$H{header-name}
: 将 header-name 对应的 HTTP header设置到请求上下文中。 上述例子会设置x-header-context
=header-context请求头的值
。 - 其他 : 将 key -value 键值对设置到请求上下文中。 上述例子会设置
x-c
=foo
。
-
使用Spring Cloud Huawei功能
-
使用服务治理
-
生态集成
-
迁移改造问题
-
配置参考
-
优秀实践
-
常见问题