Browse Source

Fix the bug that the Zuul adapter does not exit the entry with parameters (#1148)

master
tao.zhang Eric Zhao 5 years ago
parent
commit
73188b46b7
3 changed files with 67 additions and 20 deletions
  1. +41
    -0
      sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/EntryHolder.java
  2. +17
    -12
      sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelEntryUtils.java
  3. +9
    -8
      sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelZuulPreFilter.java

+ 41
- 0
sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/EntryHolder.java View File

@@ -0,0 +1,41 @@
/*
* Copyright 1999-2019 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.gateway.zuul.filters;

import com.alibaba.csp.sentinel.Entry;

/**
* @author wavesZh
*/
class EntryHolder {

final private Entry entry;

final private Object[] params;

public EntryHolder(Entry entry, Object[] params) {
this.entry = entry;
this.params = params;
}

public Entry getEntry() {
return entry;
}

public Object[] getParams() {
return params;
}
}

+ 17
- 12
sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelEntryUtils.java View File

@@ -17,7 +17,7 @@ package com.alibaba.csp.sentinel.adapter.gateway.zuul.filters;

import java.util.Deque;

import com.alibaba.csp.sentinel.AsyncEntry;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.constants.ZuulConstant;
import com.alibaba.csp.sentinel.context.ContextUtil;
@@ -34,11 +34,11 @@ final class SentinelEntryUtils {
static void tryExitFromCurrentContext() {
RequestContext ctx = RequestContext.getCurrentContext();
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
Deque<AsyncEntry> asyncEntries = (Deque<AsyncEntry>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
AsyncEntry entry;
while (!asyncEntries.isEmpty()) {
entry = asyncEntries.pop();
entry.exit();
Deque<EntryHolder> holders = (Deque<EntryHolder>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
EntryHolder holder;
while (!holders.isEmpty()) {
holder = holders.pop();
exit(holder);
}
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
}
@@ -50,17 +50,22 @@ final class SentinelEntryUtils {
static void tryTraceExceptionThenExitFromCurrentContext(Throwable t) {
RequestContext ctx = RequestContext.getCurrentContext();
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
Deque<AsyncEntry> asyncEntries = (Deque<AsyncEntry>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
AsyncEntry entry;
while (!asyncEntries.isEmpty()) {
entry = asyncEntries.pop();
Tracer.traceEntry(t, entry);
entry.exit();
Deque<EntryHolder> holders = (Deque<EntryHolder>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
EntryHolder holder;
while (!holders.isEmpty()) {
holder = holders.pop();
Tracer.traceEntry(t, holder.getEntry());
exit(holder);
}
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
}
ContextUtil.exit();
}

static void exit(EntryHolder holder) {
Entry entry = holder.getEntry();
entry.exit(1, holder.getParams());
}

private SentinelEntryUtils() {}
}

+ 9
- 8
sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelZuulPreFilter.java View File

@@ -89,7 +89,7 @@ public class SentinelZuulPreFilter extends ZuulFilter {
}

private void doSentinelEntry(String resourceName, final int resType, RequestContext requestContext,
Deque<AsyncEntry> asyncEntries) throws BlockException {
Deque<EntryHolder> holders) throws BlockException {
Object[] params = paramParser.parseParameterFor(resourceName, requestContext,
new Predicate<GatewayFlowRule>() {
@Override
@@ -98,8 +98,9 @@ public class SentinelZuulPreFilter extends ZuulFilter {
}
});
AsyncEntry entry = SphU.asyncEntry(resourceName, ResourceTypeConstants.COMMON_API_GATEWAY,
EntryType.IN, params);
asyncEntries.push(entry);
EntryType.IN, params);
EntryHolder holder = new EntryHolder(entry, params);
holders.push(holder);
}

@Override
@@ -108,12 +109,12 @@ public class SentinelZuulPreFilter extends ZuulFilter {
String origin = parseOrigin(ctx.getRequest());
String routeId = (String)ctx.get(ZuulConstant.PROXY_ID_KEY);

Deque<AsyncEntry> asyncEntries = new ArrayDeque<>();
Deque<EntryHolder> holders = new ArrayDeque<>();
String fallBackRoute = routeId;
try {
if (StringUtil.isNotBlank(routeId)) {
ContextUtil.enter(GATEWAY_CONTEXT_ROUTE_PREFIX + routeId, origin);
doSentinelEntry(routeId, RESOURCE_MODE_ROUTE_ID, ctx, asyncEntries);
doSentinelEntry(routeId, RESOURCE_MODE_ROUTE_ID, ctx, holders);
}

Set<String> matchingApis = pickMatchingApiDefinitions(ctx);
@@ -122,7 +123,7 @@ public class SentinelZuulPreFilter extends ZuulFilter {
}
for (String apiName : matchingApis) {
fallBackRoute = apiName;
doSentinelEntry(apiName, RESOURCE_MODE_CUSTOM_API_NAME, ctx, asyncEntries);
doSentinelEntry(apiName, RESOURCE_MODE_CUSTOM_API_NAME, ctx, holders);
}
} catch (BlockException ex) {
ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(
@@ -140,8 +141,8 @@ public class SentinelZuulPreFilter extends ZuulFilter {
} finally {
// We don't exit the entry here. We need to exit the entries in post filter to record Rt correctly.
// So here the entries will be carried in the request context.
if (!asyncEntries.isEmpty()) {
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, asyncEntries);
if (!holders.isEmpty()) {
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, holders);
}
}
return null;


Loading…
Cancel
Save