1.zuul 1.x的架构如下所示:

线程模型:

其web应用的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5"> <listener>
<listener-class>com.netflix.zuul.StartServer</listener-class>
</listener> <servlet>
<servlet-name>ZuulServlet</servlet-name>
<servlet-class>com.netflix.zuul.http.ZuulServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ZuulServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping> <filter>
<filter-name>ContextLifecycleFilter</filter-name>
<filter-class>com.netflix.zuul.context.ContextLifecycleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ContextLifecycleFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>

从上面可以看出,启动时有三个主类:

1.1. StartServer

    @Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("starting server"); // mocks monitoring infrastructure as we don't need it for this simple app
MonitoringHelper.initMocks(); // initializes groovy filesystem poller
initGroovyFilterManager(); // initializes a few java filter examples
initJavaFilters();
}

1.2. ZuulServlet

@Override
public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
try {
init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); // Marks this request as having passed through the "Zuul engine", as opposed to servlets
// explicitly bound in web.xml, for which requests will not have the same data attached
RequestContext context = RequestContext.getCurrentContext();
context.setZuulEngineRan(); try {
preRoute();
} catch (ZuulException e) {
error(e);
postRoute();
return;
}
try {
route();
} catch (ZuulException e) {
error(e);
postRoute();
return;
}
try {
postRoute();
} catch (ZuulException e) {
error(e);
return;
} } catch (Throwable e) {
error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
} finally {
RequestContext.getCurrentContext().unset();
}
}

1.3. ContextLifecycleFilter

public class ContextLifecycleFilter implements Filter {

    public void destroy() {}

    public void init(FilterConfig filterConfig) throws ServletException {}

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
try {
chain.doFilter(req, res);
} finally {
RequestContext.getCurrentContext().unset();
}
} }

2. zuul2的线程模型

其应用的web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5"> <filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter> <filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <listener>
<listener-class>com.netflix.zuul.StartServer</listener-class>
</listener> </web-app>

2.1. StartServer

 /**
* Overridden solely so we can tell how much time is being spent in overall initialization. Without
* overriding we can't tell how much time was spent in BaseServer doing its own initialization.
*
* @param sce
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
server.start();
} catch (Exception e) {
LOG.error("Error while starting karyon.", e);
throw Throwables.propagate(e);
}
try {
initialize();
} catch (Exception e) {
e.printStackTrace();
}
super.contextInitialized(sce);
}

2.2. ZuulServlet

   @Override
public void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException
{
try {
zuulProcessor
.process(servletRequest, servletResponse)
.doOnNext(msg -> {
// Store this response as an attribute for any later ServletFilters that may want access to info in it.
servletRequest.setAttribute("_zuul_response", msg);
})
.subscribe();
}
catch (Throwable e) {
LOG.error("Unexpected error running ZuulHttpProcessor for this request.", e);
throw new ServletException("Unexpected error running ZuulHttpProcessor for this request.");
}
}

2.3 ZuulHttpProcessor

/**
* The main processing class for Zuul.
*
* 1. Translates the inbound native request (ie. HttpServletRequest, or rxnetty HttpServerRequest) into a zuul HttpRequestMessage.
* 2. Builds the filter chain and passes the request through it.
* 3. Writes out the HttpResponseMessage to the native response object.
*/

处理过程:

  public Observable<ZuulMessage> process(final I nativeRequest, final O nativeResponse)
{
// Setup the context for this request.
final SessionContext context; // Optionally decorate the context.
if (decorator == null) {
context = new SessionContext();
} else {
context = decorator.decorate(new SessionContext());
} return Observable.defer((Func0<Observable<ZuulMessage>>) () -> { // Build a ZuulMessage from the netty request.
final ZuulMessage request = contextFactory.create(context, nativeRequest, nativeResponse); // Start timing the request.
request.getContext().getTimings().getRequest().start(); /*
* Delegate all of the filter application logic to {@link FilterProcessor}.
* This work is some combination of synchronous and asynchronous.
*/
Observable<ZuulMessage> chain = filterProcessor.applyFilterChain(request); return chain
.flatMap(msg -> {
// Wrap this in a try/catch because we need to ensure no exception stops the observable, as
// we need the following doOnNext to always run - as it records metrics.
try {
// Write out the response.
return contextFactory.write(msg, nativeResponse);
}
catch (Exception e) {
LOG.error("Error in writing response! request=" + request.getInfoForLogging(), e); // Generate a default error response to be sent to client.
return Observable.just(new HttpResponseMessageImpl(context, ((HttpResponseMessage) msg).getOutboundRequest(), 500));
}
finally {
// End the timing.
msg.getContext().getTimings().getRequest().end();
}
})
.doOnError(e -> {
LOG.error("Unexpected error in filter chain! request=" + request.getInfoForLogging(), e);
})
.doOnNext(msg -> {
// Notify requestComplete listener if configured.
try {
if (requestCompleteHandler != null)
requestCompleteHandler.handle(((HttpRequestMessage) request).getInboundRequest(), (HttpResponseMessage) msg);
}
catch (Exception e) {
LOG.error("Error in RequestCompleteHandler.", e);
}
})
;
}).finallyDo(() -> {
// Cleanup any resources related to this request/response.
sessionCleaner.cleanup(context);
});
}
}

参考文献:

【1】http://techblog.netflix.com/2013/06/announcing-zuul-edge-service-in-cloud.html

【2】http://techblog.netflix.com/2016/09/zuul-2-netflix-journey-to-asynchronous.html?utm_source=tuicool&utm_medium=referral

netflix zuul 1.x与zuul2.x之比较的更多相关文章

  1. Netflix Zuul 了解

    Zuul 是提供动态路由,监控,弹性,安全等的边缘服务.Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门.Zuul 可以适当的对多个 Amazon Auto Scal ...

  2. netflix zuul 学习

    netflix zuul 是netflix开发的一个EDGE SERVICE. 主要是作为一个API Gateway 服务器,可以实现安全,流量控制等功能. 我看的是1.x的版本,Zuul1.x的实现 ...

  3. com.netflix.zuul.exception.ZuulException: Hystrix Readed time out

    通过API网关路由来访问用户服务,zuul默认路由规则 :http://zuul的Host地址:zuul端口/要调用的服务名/服务方法地址 浏览器中打开http://127.0.0.1:8000/wa ...

  4. 聊聊 API Gateway 和 Netflix Zuul

    最近参与了公司 API Gateway 的搭建工作,技术选型是 Netflix Zuul,主要聊一聊其中的一些心得和体会. 本文主要是介绍使用 Zuul 且在不强制使用其他 Neflix OSS 组件 ...

  5. 关于SpringCloud配置网关转发时出现一下啊错误:“com.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.handleException”

    com.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud.netflix.zuul ...

  6. Spring Cloud Netflix Zuul 重试会自动跳过经常超时的服务实例的简单说明和分析

    在使用E版本的Spring Cloud Netflix Zuul内置的Ribbon重试功能时,发现Ribbon有一个非常有用的特性: 如果某个服务的某个实例经常需要重试,Ribbon则会在自己维护的一 ...

  7. com.netflix.zuul.exception.ZuulException: Forwarding error

    一.问题描述 在使用Spring Cloud的zuul组件,做路由转发时,每次重新启动后端服务,头几次调用都会出现com.netflix.zuul.exception.ZuulException: F ...

  8. 启动zuul时候报错:The bean 'proxyRequestHelper', defined in class path resource [org/springframework/cloud/netflix/zuul

    启动zuul时候报错:The bean 'proxyRequestHelper', defined in class path resource [org/springframework/cloud/ ...

  9. springcloud初次zuul超时报错com.netflix.zuul.exception.ZuulException:Forwarding error

    报错如下 com.netflix.zuul.exception.ZuulException:Forwarding error Caused by: com.netflix.hystrix.except ...

随机推荐

  1. c的面向对象思想记录

    在一家公司做实习生,努力学习,keep moving. //c1.h typedef struct { +]; int (*tr)(); } trans; //c1.c #include<str ...

  2. [Typescript] Promise based delay function using async / await

    Learn how to write a promise based delay function and then use it in async await to see how much it ...

  3. 【甘道夫】Sqoop1.99.3基础操作--导入Oracle的数据到HDFS

    第一步:进入clientShell fulong@FBI008:~$ sqoop.sh client Sqoop home directory: /home/fulong/Sqoop/sqoop-1. ...

  4. iOS:界面上下空出黑条

    启动图没有加入完整造成

  5. 怎么样才算是精通 C++?

    C++是一门非常奇妙的语言.让人又爱又恨. 在知乎上看到的一个帖子.怎么样才算是精通C++,这里节选一些精彩的回复. 链接:http://www.zhihu.com/question/20201972 ...

  6. Android 提示: The connection to adb is down, and a severe error has occured.

    今天早上打开Eclipse,一直提示 The connection to adb is down, and a severe error has occured,无法执行程序.重新启动Eclipse. ...

  7. nyoj--116--士兵杀敌(二)(树状数组)

    士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常想知 ...

  8. tomcat和nginx相互结合的优化调整

    在工作中遇到这样的情况 Tomcat为后台 nginx为反向代理 需要往后台导入数据,由于处理时间过长,导致访问时出现504和500  通过修改tomcat中maxParameterCount=&qu ...

  9. Python 序列化处理

    序列化 文件为dump 字符串为dumps dumps()方法返回一个str,内容就是标准的JSON loads()方法将其还原 在程序运行的过程中,所有的变量都是在内存 d = dict(name= ...

  10. 基于分布式的短文本命题实体识别之----人名识别(python实现)

    目前对中文分词精度影响最大的主要是两方面:未登录词的识别和歧义切分. 据统计:未登录词中中文姓人名在文本中一般只占2%左右,但这其中高达50%以上的人名会产生切分错误.在所有的分词错误中,与人名有关的 ...