3.微服务灰度发布落地实践(组件灰度增强)
前言
上一篇介绍,agent基础框架的实现,本篇主要介绍灰度标签在各种组件、协议之间续传,以及路由规则改写;从用户客户端发送请求,到用户收到后端响应信息,整个请求链路会经过各种组件,
调用链示图
-
dubbo服务之间的的调链
-
clooud. 服务之间的调用链
上面展示的组件调用链为: 用户->网关->servlet容器服务->线程池->dubbo服务或cloud服务;这仅展示某一种调用路径,实际环境可能更复杂,有经过cloud或消息队列等等,不再一一列举。
网关
网关交互相对杂复一些,单独开篇
servlet容器增强
通常web容器服务,都会实现servlet,找到适合的组件接口,
-
从http请求头获取灰度标签,并设置到threadLocal,
-
请求处理完后,清除该信息;
-
分析发现比较合适对HandlerAdapter(不是唯一)进行拦截:
-
定义插件
public class HandlerAdapterDefine extends ClassEnhancePluginDefine { private static final String CLASS_INTERCEPTOR = "com.dbcat.gray.agent.mvc.HandlerAdapterInterceptor"; @Override protected ClassMatch enhanceClass() {return HierarchyMatch.byHierarchyMatch("org.springframework.web.servlet.HandlerAdapter"); } @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {return new InstanceMethodsInterceptPoint[] {new InstanceMethodsInterceptPoint() {@Overridepublic ElementMatcher<MethodDescription> getMethodsMatcher() {return named("handle").and(takesArguments(3));}@Overridepublic String getMethodsInterceptor() {return CLASS_INTERCEPTOR;}@Overridepublic boolean isOverrideArgs() {return false;}}}; }@Override public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {return new StaticMethodsInterceptPoint[0]; }
}
-
实现灰度增强拦截
public class HandlerAdapterInterceptor implements InInterceptor, InstanceMethodsAroundInterceptor {@Overridepublic void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result){String routingEnv = getRoutingEnv(allArguments);this.setContext(routingEnv);CounterManager.increaseConsume(ComponentType.MVC,routingEnv);}@Overridepublic Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) {//清除threadLocal里的数据this.removeContext();return ret;}private String getRoutingEnv(Object[] allArguments){//从http 请求头或Attribute 获取灰度标签设置到threadLocalObject request = allArguments[0];Method getHeader = ReflectUtils.getMethod(request, "getHeader", String.class);String env = (String)ReflectUtils.invokeMethod(getHeader, request, X_ENV);if(env != null && !env.trim().equals("")){return env;}Method getAttribute = ReflectUtils.getMethod(request, "getAttribute", String.class);return (String)ReflectUtils.invokeMethod(getAttribute, request, X_ENV);}
}
这里只是介绍Servlet容器,如果项目实际使用其它类型web容器,也可以用类似的方式对其增强
线程池灰度增强
dubbo服务灰度增强
cloud 服务灰度增强
nacos 增强
未完,待续…
最后,不要脸给大家安利一款mysql监控软件: 安装方便,消耗低,可视化,傻瓜式操作,可以监控慢日志详情、cpu、内存、连接数、tps 等信息
体验演示
下载地址