Zuul 2终于开源了 。 我第一次听到Zuul 2年Spring由米奇·科恩一个2016的讲就是可以在这里找到 ,这是好事,终于可以用它玩。
为了快速实现Zuul 2之类的网关的目的–网关提供了微服务生态系统的切入点。 由于所有客户的请求都是通过网关路由的,因此它可以控制路由,请求和响应流经网关的各个方面–
- 基于不同标准的路由-uri模式,标头等
- 监控服务运行状况
- 对原始服务器的负载平衡和限制请求
- 安全
- 金丝雀测试
我在这篇文章中的目标很简单–编写一个Zuul2过滤器,该过滤器可以删除路径前缀并将请求发送到下游服务并返回。
Zuul2过滤器是定制Zuul的机制。 假设客户发送请求到/ passthrough / someapi调用,那么我希望Zuul 2层使用/ someapi uri将请求转发到下游服务。 Zuul2过滤器通常打包为常规文件,并动态加载(并可能刷新)并应用。 不过,我的示例会有所不同,我的过滤器是用Java编码的,因此我不得不绕过Zuul内置的加载机制。
简单地遵循代码即可,该代码可在我的github存储库中找到 – https://github.com/bijukunjummen/boot2-load-demo/tree/master/applications/zuul2-sample,与以下代码打包在一起提供相似功能的一组样本。 该代码基于此处提供的Zuul 2示例。
这是我的过滤器的外观:
import com.netflix.zuul.context.SessionContext;
import com.netflix.zuul.filters.http.HttpInboundSyncFilter;
import com.netflix.zuul.message.http.HttpRequestMessage;import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class StripPrefixFilter extends HttpInboundSyncFilter {private final List<String> prefixPatterns;public StripPrefixFilter(List<String> prefixPatterns) {this.prefixPatterns = prefixPatterns;}@Overridepublic HttpRequestMessage apply(HttpRequestMessage input) {SessionContext context = input.getContext();String path = input.getPath();String[] parts = path.split("/");if (parts.length > 0) {String targetPath = Arrays.stream(parts).skip(1).collect(Collectors.joining("/"));context.set("overrideURI", targetPath);}return input;}@Overridepublic int filterOrder() {return 501;}@Overridepublic boolean shouldFilter(HttpRequestMessage msg) {for (String target: prefixPatterns) {if (msg.getPath().matches(target)) {return true;}}return false;}
}
它扩展了“ HttpInboundSyncFilter”,这些过滤器处理入站到原始服务器的请求。 可以想象,有一个“ HttpOutboundSyncFilter”可以拦截来自原始服务器的出站呼叫。 这些“同步”过滤器有一个“ HttpInboundFilter”和“ HttpOutboundFilter”对应物,它们返回RxJava Observable类型。
我的过滤器实现中有一个魔术字符串“ overrideUri”。 如果您对我如何发现它是替代uri感到好奇,那就是通过扫描Zuul2代码库。 Netflix内部可能使用了很多过滤器,但尚未发布以供一般使用。
有了此过滤器后,我通过使用此组件显式注册我的自定义过滤器来绕过Zuul2的动态groovy脚本加载功能:
import com.netflix.zuul.filters.FilterRegistry;
import com.netflix.zuul.filters.ZuulFilter;import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;public class FiltersRegisteringService {private final List<ZuulFilter> filters;private final FilterRegistry filterRegistry;@Injectpublic FiltersRegisteringService(FilterRegistry filterRegistry, Set<ZuulFilter> filters) {this.filters = new ArrayList<>(filters);this.filterRegistry = filterRegistry;}public List<ZuulFilter> getFilters() {return filters;}@PostConstructpublic void initialize() {for (ZuulFilter filter: filters) {this.filterRegistry.put(filter.filterName(), filter);}}
}
我不得不做一些较小的调整,以引导我的自定义过滤器来完成整个设置,这些可以在github repo中进行 。
一旦启动了带有该自定义过滤器的Zuul2示例,其行为就是在删除了前缀“ / passthrough”之后,对/ passthrough / messages的任何请求都会路由到下游系统。 启动Zuul 2应用程序的说明是repo的README的一部分。
这是编写自定义Zuul2过滤器的快速入门,我希望这给了足够的感觉来评估Zuul 2。
翻译自: https://www.javacodegeeks.com/2018/06/zuul-2-sample-filter.html