spring cloud 入门实践系列
来源:互联网 发布:centos 安装桌面 编辑:程序博客网 时间:2024/06/06 03:28
从两条线分析zuul的源代码
1 启动加载配置
ZuulProxyConfiguration
2 请求访问zuul服务
http://172.16.153.1:8963/firstapi/firstapi/speak?words=zxlhgggggggg
列表内容
StandardHostValve invoke方法 (tomcat) 入口
DispatcherServlet 类的doDispatch方法 拦截
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {...try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } ...}protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { if (logger.isTraceEnabled()) { logger.trace( "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'"); } HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }
AbstractHandlerMapping 类的getHandler方法
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; }
AbstractUrlHandlerMapping 类的getHandlerInternal方法
protected Object getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); Object handler = lookupHandler(lookupPath, request); if (handler == null) { // We need to care for the default handler directly, since we need to // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well. Object rawHandler = null; if ("/".equals(lookupPath)) { rawHandler = getRootHandler(); } if (rawHandler == null) { rawHandler = getDefaultHandler(); } if (rawHandler != null) { // Bean name or resolved handler? if (rawHandler instanceof String) { String handlerName = (String) rawHandler; rawHandler = getApplicationContext().getBean(handlerName); } validateHandler(rawHandler, request); handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null); } } if (handler != null && logger.isDebugEnabled()) { logger.debug("Mapping [" + lookupPath + "] to " + handler); } else if (handler == null && logger.isTraceEnabled()) { logger.trace("No handler mapping found for [" + lookupPath + "]"); } return handler; }
ZuulHandlerMapping 类的lookupHandler方法
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception { if (this.errorController != null && urlPath.equals(this.errorController.getErrorPath())) { return null; } String[] ignored = this.routeLocator.getIgnoredPaths().toArray(new String[0]); if (PatternMatchUtils.simpleMatch(ignored, urlPath)) { return null; } RequestContext ctx = RequestContext.getCurrentContext(); if (ctx.containsKey("forward.to")) { return null; } if (this.dirty) { synchronized (this) { if (this.dirty) { registerHandlers(); this.dirty = false; } } } return super.lookupHandler(urlPath, request); }
最终是在super的lookupHandler方法中找到handler了,也就是在AbstractUrlHandlerMapping类的lookupHandler方法中获取到。
可见path最终都是映射到同一个handler即ZuulController。
ZuulController handler
public class ZuulController extends ServletWrappingController { public ZuulController() { setServletClass(ZuulServlet.class); setServletName("zuul"); setSupportedMethods((String[]) null); // Allow all } @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { try { // We don't care about the other features of the base class, just want to // handle the request return super.handleRequestInternal(request, response); } finally { // @see com.netflix.zuul.context.ContextLifecycleFilter.doFilter RequestContext.getCurrentContext().unset(); } }}
ServletWrappingController handleRequestInternal
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { this.servletInstance.service(request, response); return null; }
ZuulServlet handler
@Override public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException { try { init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); 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(); } }
ZuulRunner
public void preRoute() throws ZuulException { FilterProcessor.getInstance().preRoute(); } public void route() throws ZuulException { FilterProcessor.getInstance().route(); } public void postRoute() throws ZuulException { FilterProcessor.getInstance().postRoute(); }
FilterProcessor
public void preRoute() throws ZuulException { try { runFilters("pre"); } catch (ZuulException e) { throw e; } catch (Throwable e) { throw new ZuulException(e, 500, "UNCAUGHT_EXCEPTION_IN_PRE_FILTER_" + e.getClass().getName()); } } public void route() throws ZuulException { try { runFilters("route"); } catch (ZuulException e) { throw e; } catch (Throwable e) { throw new ZuulException(e, 500, "UNCAUGHT_EXCEPTION_IN_ROUTE_FILTER_" + e.getClass().getName()); } } public void postRoute() throws ZuulException { try { runFilters("post"); } catch (ZuulException e) { throw e; } catch (Throwable e) { throw new ZuulException(e, 500, "UNCAUGHT_EXCEPTION_IN_POST_FILTER_" + e.getClass().getName()); } }public Object runFilters(String sType) throws Throwable { if (RequestContext.getCurrentContext().debugRouting()) { Debug.addRoutingDebug("Invoking {" + sType + "} type filters"); } boolean bResult = false; List<ZuulFilter> list = FilterLoader.getInstance().getFiltersByType(sType); if (list != null) { for (int i = 0; i < list.size(); i++) { ZuulFilter zuulFilter = list.get(i); Object result = processZuulFilter(zuulFilter); if (result != null && result instanceof Boolean) { bResult |= ((Boolean) result); } } } return bResult; }
pre包含如下filter
route包含如下filter
post包含如下filter
那么对远程服务调用的封装,也是在Filter里面,我们可以看下
@Override public Object run() { RequestContext context = RequestContext.getCurrentContext(); this.helper.addIgnoredHeaders(); try { RibbonCommandContext commandContext = buildCommandContext(context); ClientHttpResponse response = forward(commandContext); setResponse(response); return response; } catch (ZuulException ex) { throw new ZuulRuntimeException(ex); } catch (Exception ex) { throw new ZuulRuntimeException(ex); } }protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception { Map<String, Object> info = this.helper.debug(context.getMethod(), context.getUri(), context.getHeaders(), context.getParams(), context.getRequestEntity()); RibbonCommand command = this.ribbonCommandFactory.create(context); try { ClientHttpResponse response = command.execute(); this.helper.appendDebug(info, response.getStatusCode().value(), response.getHeaders()); return response; } catch (HystrixRuntimeException ex) { return handleException(info, ex); } }
forward方法中的command.execute即是对远程服务的调用。
阅读全文
0 0
- spring cloud 入门实践系列
- spring cloud 入门实践系列
- spring cloud 入门实践系列
- spring cloud 入门实践系列
- spring cloud 入门实践系列
- spring cloud 入门实践系列
- Spring Cloud 入门系列总结
- SpringBoot系列—Spring Cloud快速入门
- Spring Cloud Security系列教程一:入门
- Spring Cloud Config 实践
- spring cloud系列
- spring cloud 系列文章
- spring-cloud系列-Eureka
- spring cloud入门基础
- Spring cloud入门
- spring cloud入门学习
- Spring Cloud 入门
- Spring Cloud Eureka 入门 (一)服务注册中心详解 「Spring Cloud Eureka 入门系列」 Spring Cloud Eureka 入门 (一)服务注册中心详解 Spr
- scala代码风格指南--<类型>
- 杭电OJ 1004
- manjaro使用国内软件源
- 如何在thinkphp模板中获取控制器session的值
- 如何让c语言使用结构体近似模拟c++中的类
- spring cloud 入门实践系列
- PAT B1033. 旧键盘打字
- android studio的cmake中调用opengles库,实现c++编译opengles
- 百练_4137:最小新整数
- 函数中全局变量与局部变量
- 7.26--SSH学习之SpringMVC小Demo
- linux下NFS服务器的安装与配置 亲测
- NEUOJ 1210(The number of triangulation-计算几何+剪枝)
- CF 86D Powerful array(莫队)