当前位置: 首页 > news >正文

2.微服务灰度发布落地实践(agent实现)

前言

据上一篇,设计方案的分析,综合考虑,最终决定,客户端采用agent方案实现,具本原因不再赘述,
感觉兴趣的小伙伴可以回头了解一下.该篇主要讲java agent的实现,灰度agent客户端的基础框架实现

java agent的介绍

java Agent 是一种允许你在 Java 应用程序启动时或运行时修改其字节码的技术。
它通过 JVM 提供的 java.lang.instrument 包来实现,可以用于各种用途,
如性能监控、代码增强、AOP(面向切面编程)、日志记录等。
Java Agent 的核心功能是能够在类加载到 JVM 之前对其进行修改,
而无需修改应用程序的源代码。启动时代理(Premain Agent):在 JVM 启动时加载的代理。你需要通过 -javaagent 参数指定代理的 JAR 文件路径,并提供一个 premain 方法作为入口点。

public static void premain(String agentArgs, Instrumentation inst) {// 在这里注册 ClassFileTransformer 或执行其他初始化逻辑
}

基础实现

agent的实现的基础,是基于开源项目skywalking的插件核心实现,没必要重复造轮子,要做的是专注
去实现灰度相关的功能.

agent端 http服务实现

为了方便灰度管理端,给agent端实时推送数据,agent端,基于netty实现单简的http服务,; 会提供接口,供服务端对实例状态的控制,以及其它服务实例状态的推送;实例在收发消息或路由时,依赖这些信息作相应处理。
如果不太了解这块功能的作用,可以去第一篇看一下整个系统的架构图;下需要agent http server代码片段

SimpleChannelInboundHandler agentServerHttpInboundHandler = new AgentServerHttpInboundHandler();
agentChannelInitializer = new AgentServerChannelInitializer(agentServerHttpInboundHandler);
Thread serverThread = new Thread(new RunnableWithExceptionProtection(() -> {LOGGER.info("dbcat gray agent netty server.");ServerBootstrap serverBootstrap = new ServerBootstrap();bossGroup = new NioEventLoopGroup(1, new DefaultNamedThreadFactory("server-boss"));workerGroup = new NioEventLoopGroup(4, new DefaultNamedThreadFactory("server-worker"));serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_REUSEADDR, true).option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT).childOption(ChannelOption.TCP_NODELAY, true).childOption(ChannelOption.SO_KEEPALIVE, true).childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT).childHandler(agentChannelInitializer);int port = Config.Agent.SERVER_PORT;try {ChannelFuture f = serverBootstrap.bind(port).sync();LOGGER.info("dbcat gray agent server started, port is {}.", port);f.channel().closeFuture().sync();LOGGER.info("dbcat gray agent server closed, port is {}.", port);} catch (InterruptedException e) {LOGGER.error("dbcat gray agent server start failed", e);Thread.currentThread().interrupt();}
}, t -> {
}), "gray-agent-server");
serverThread.setDaemon(true);
serverThread.start();

agent端api接口

上面实现agent端的http服务,灰度服务端如果需要控制agent客户端,必需还要提供api接口,才能进行交互
http 接口实现片段

   public class AgentServerHttpInboundHandler extends SimpleChannelInboundHandler<FullHttpRequest> {private static final ILog log = LogManager.getLogger(AgentServerHttpInboundHandler.class);private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) {ctx.flush();}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {//收到http请求QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.uri());String requestUri = queryStringDecoder.rawPath();String method = request.method().name();if (!"POST".equals(method.toUpperCase())) {complete(ctx, request,  RestResult.buildFailure(HttpResponseStatus.METHOD_NOT_ALLOWED.toString(),HttpResponseStatus.METHOD_NOT_ALLOWED.code()));return;}//通过url配置接口对应用实现Endpoint endpoint = EndpointManager.getEndpoint(requestUri);if (endpoint == null) {complete(ctx, request, RestResult.buildFailure(HttpResponseStatus.NOT_FOUND.toString(),HttpResponseStatus.NOT_FOUND.code()));return;}Throwable throwable = null;RestResult result = null;try {ByteBuf content = request.content();byte[] requestBodyBytes = new byte[content.readableBytes()];content.readBytes(requestBodyBytes);String requestBodyString = new String(requestBodyBytes, "UTF-8");ParameterizedType parameterizedType = ((ParameterizedType) endpoint.getClass().getGenericInterfaces()[0]);Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();Object data =  GSON.fromJson(requestBodyString,actualTypeArguments[0]);//调用相应的接口result = endpoint.invoke(data);} catch (Throwable e) {log.error(String.format("接口响应异常%s", requestUri), e);throwable = e;} finally {if (throwable == null) {complete(ctx, request, result);} else {complete(ctx, request, RestResult.buildFailure(throwable.getMessage(),HttpResponseStatus.INTERNAL_SERVER_ERROR.code()));}}}}

Endpoint api 接口类,通过spi 方式加载实现

    public class EndpointManager {private static final Map<String, Endpoint> ENDPOINT_INVOKER_MAP = new HashMap<>();static {for (final Endpoint endpointInvoker : ServiceLoader.load(Endpoint.class, AgentClassLoader.getDefault())) {ENDPOINT_INVOKER_MAP.put(endpointInvoker.path(), endpointInvoker);}}public static Endpoint<?, ?> getEndpoint(String requestUri) {return ENDPOINT_INVOKER_MAP.get(requestUri);}}

Endpoint 的实某个实现,如更新实例状态接口

public class EnvStatusUpdateEndpoint implements Endpoint<InstanceEnvUpdateRequest, List<ExecuteResponse>> {private static final ILog log = LogManager.getLogger(EnvStatusUpdateEndpoint.class);@Overridepublic String path() {return "/env-status/update";}@Overridepublic RestResult<List<ExecuteResponse>> invoke(InstanceEnvUpdateRequest request) throws Exception {log.info("更新实例信息");ServerInstance.getInstance().setEnvStatus(request.getEnvStatus());List<ExecuteResponse> executeResponses = MQConnectionManager.restartAll(request.getStrategy());return RestResult.buildSuccess(executeResponses);}
}

到此,agent客户端的基础框加已实现,下一篇将开始介绍相关核心组件灰度的增强实现

硬广

最后,不要脸给大家安利一款mysql监控软件: 安装方便,消耗低,可视化,傻瓜式操作,可以监控慢日志详情、cpu、内存、连接数、tps 等信息
体验演示
下载地址

相关文章:

2.微服务灰度发布落地实践(agent实现)

前言 据上一篇&#xff0c;设计方案的分析&#xff0c;综合考虑&#xff0c;最终决定,客户端采用agent方案实现&#xff0c;具本原因不再赘述&#xff0c; 感觉兴趣的小伙伴可以回头了解一下.该篇主要讲java agent的实现,灰度agent客户端的基础框架实现 java agent的介绍 ja…...

搭建医疗客服知识库:智慧医疗的基石

在医疗行业&#xff0c;客服知识库不仅是提供患者咨询和支持的平台&#xff0c;更是提升医疗服务效率和质量的关键工具。 1. 明确知识库的目标和价值 构建医疗行业客服知识库的首要任务是明确其目标和价值。这包括提供患者教育、辅助临床决策、优化患者服务流程等。明确目标后…...

CES Asia 2025的低空经济展区有哪些亮点?

CES Asia 2025&#xff08;赛逸展&#xff09;的低空经济展区有以下亮点&#xff1a; • 前沿科技产品展示&#xff1a; 多款新型无人机将亮相&#xff0c;如固定翼无人机和系留无人机的最新型号&#xff0c;其在监测、救援和货物运输等方面功能强大。此外&#xff0c;还有可能…...

Java/Spring项目包名为何以“com”开头?

文章目录 包名的基本概念域名反转规则历史背景包名的结构实际应用总结 在Java和Spring项目中&#xff0c;我们常常看到包名以“com”开头&#xff0c;比如com.example.project。这种命名方式看似简单&#xff0c;其实背后蕴含着不少学问。今天&#xff0c;我们就来聊聊这个话题…...

影刀进阶应用 | 知乎发布想法

文章目录 影刀进阶应用 | 知乎发布想法一、流程流程解释&#xff1a; 二、单条想法发布2.1 素材生产2.2 **进入发布流程**2.3 **输入文本**2.4 插入图片2.5 发布查看 三、批量发布 影刀进阶应用 | 知乎发布想法 一、流程 流程解释&#xff1a; 素材生产 &#xff1a;用AI生成待…...

v-if 和 v-for 优先级

一、优先级规则 在 Vue.js 中&#xff0c;v-for的优先级比v-if高。这意味着当它们同时出现在一个元素上时&#xff0c;v-for会首先被解析和执行。 <div v-for"item in items" v-if"shouldShow(item)">{{ item }}</div> 二、可能导致的问题 …...

【数据结构与算法】单向链表

一、什么是链表 链表由一系列节点组成&#xff0c;每个节点都包含一个 data 域&#xff08;存放数据&#xff09;和一个 next 域&#xff08;指向下一节点&#xff09;。链表中的节点可以按照任意顺序存放在内存中&#xff0c;它们之间并不连续。每个节点都记录了下一个节点的地…...

网络编程UDP—socket实现(C++)

网络编程UDP—socket实现 前言UDP客户端和服务端UDP使用场景UDP socket C代码示例服务端接收数据示例&#xff08;bindrecvfrom 阻塞式接收信息&#xff09;&#xff1a;bind 绑定-监听 函数为什么一般都是监听所有网络接口呢&#xff1f;为什么需要用inet_addr进行转换&#x…...

系统思考—冰山模型

“卓越不是因机遇而生&#xff0c;而是智慧的选择与用心的承诺。”—— 亚里士多德 卓越&#xff0c;从来不是一次性行为&#xff0c;而是一种习惯。正如我们在日常辅导中常提醒自己&#xff1a;行为的背后&#xff0c;隐藏着选择的逻辑&#xff0c;而选择的根源&#xff0c;源…...

MySQL 中存储金额数据一般使用什么数据类型

在 MySQL 中存储金额数据时&#xff0c;应该谨慎选择数据类型&#xff0c;以确保数据的精度和安全性。以下是几种常用的数据类型及其适用性&#xff1a; DECIMAL 类型&#xff1a; 描述&#xff1a;DECIMAL 类型是专门为存储精确的小数而设计的。它可以指定小数点前后的数字位数…...

Excel中一次查询返回多列

使用Excel或wps的时候&#xff0c;有时候需要一次查询返回多列内容&#xff0c;这种情况可以选择多次vlookup或者多次xlookup&#xff0c;但是这种做法费时费力不说&#xff0c;效率还有些低下&#xff0c;特别是要查询的列数过多时。我放了3种查询方法&#xff0c;效果图&…...

Java中各种数组复制方式的效率对比

在 Java 中&#xff0c;数组复制是一个常见的操作&#xff0c;尤其是在处理动态数组&#xff08;如 ArrayList&#xff09;时。Java 提供了多种数组复制的方式&#xff0c;每种方式在性能和使用场景上都有所不同。以下是对几种主要数组复制方式的比较&#xff0c;包括 System.a…...

STM32 FLASHdb

FlashDB是一款超轻量级的嵌入式数据库&#xff0c;专注于为嵌入式产品提供数据存储方案。以下是对STM32 FlashDB的详细介绍&#xff1a; 一、主要特性 资源占用极低&#xff1a;FlashDB的内存占用几乎为0&#xff0c;非常适合资源有限的嵌入式系统。支持多分区、多实例&#…...

【漏洞复现】Struts2(CVE-2024-53677)任意文件上传逻辑绕过漏洞

文章目录 前言一、漏洞描述二、漏洞详情三、影响版本四、危害描述五、漏洞分析六、漏洞复现七、修复建议前言 Struts2框架是一个用于开发Java EE网络应用程序的开放源代码网页应用程序架构。它利用并延伸了Java Servlet API,鼓励开发者采用MVC架构。Struts2以WebWork优秀的设…...

图的最短路径(C++实现图【4】)

目录 1. 最短路径 1.1单源最短路径--Dijkstra算法 代码实现 1.2 单源最短路径--Bellman-Ford算法 代码实现 1.3 多源最短路径--Floyd-Warshall算法 代码实现 1. 最短路径 最短路径问题&#xff1a;从在带权有向图G中的某一顶点出发&#xff0c;找出一条通往另一顶点的最短路径&…...

Pandas01

文章目录 内容简介1 常用数据分析三方库2 Jupyter notebook3 Series的创建3.1 通过Numpy的Ndarray 创建一个Series3.2 通过列表创建Series 4 Series的属性和方法4.1 常用属性4.2 常用方法4.3 布尔值列表筛选部分数据4.4 Series 的运算 5 DataFrame的创建通过字典创建通过列表[元…...

opencl 封装简单api

这是cl代码 kernel.c __kernel void add_one(__global float *output,__global float* pnum) {int xget_global_id(0);output[x]pnum[0]; } c代码 #include <CL/cl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include<st…...

超快速的路径优化IKD-SWOpt:SHIFT Planner 中增量 KD 树滑动窗口优化算法详解

IKD-SWOpt&#xff1a;SHIFT Planner 中增量 KD 树滑动窗口优化算法详解 今天本博主王婆卖瓜自卖自夸&#x1f604;&#xff0c;介绍自己paper中的算法&#xff0c;本算法已经持续开源中(部分关键内容)Github&#xff0c;之前很多读者朋友一直说要详细讲讲路径优化算法&#x…...

精读DeepSeek v3技术文档的心得感悟

最近宋大宝同学读完了DeepSeekv3的文档&#xff0c;心中颇多感慨&#xff0c;忍不住想在这里记录一下对这款“业界有望启示未来低精度训练走向”的开源大模型的观察与思考。DeepSeek v3的亮点绝不仅仅是“Float8”或“超长上下文”这么简单&#xff0c;而是贯穿了从数值精度、注…...

【Java数据结构】LinkedList与链表

认识LinkedList LinkedList就是一个链表&#xff0c;它也是实现List接口的一个类。LinkedList就是通过next引用将所有的结点链接起来&#xff0c;所以不需要数组。LinkedList也是以泛型的方法实现的&#xff0c;所以使用这个类都需要实例化对象。 链表分为很多种&#xff0c;比…...

实战指南:如何为你的应用选择最优Cache替换算法(附性能对比)

实战指南&#xff1a;如何为你的应用选择最优Cache替换算法&#xff08;附性能对比&#xff09; 在构建高性能应用时&#xff0c;缓存系统的设计往往是决定整体性能的关键因素之一。想象一下&#xff0c;一个电商网站在大促期间&#xff0c;每秒需要处理数十万次商品详情查询&a…...

深入解析Spring AI与MilvusVectorStore的集成实践

1. Spring AI与MilvusVectorStore集成概述 当我们需要处理海量非结构化数据时&#xff0c;传统数据库往往力不从心。想象一下你有一个装满各种文档的仓库&#xff0c;每次查找相关内容都需要人工翻阅——这正是向量数据库要解决的问题。Spring AI与Milvus的集成就像给这个仓库配…...

特征选择新思路:Laplacian Score与PCA/Lasso对比实验报告

特征选择方法深度对比&#xff1a;Laplacian Score在真实数据集中的突围表现 当面对高维数据时&#xff0c;特征选择就像是在嘈杂的市场中寻找真正有价值的声音。传统的PCA和Lasso方法已经服务了我们多年&#xff0c;但Laplacian Score带来的图论视角正在悄然改变游戏规则。本文…...

终极指南:如何使用Docker Stacks与Git Hooks实现自动化代码质量检查

终极指南&#xff1a;如何使用Docker Stacks与Git Hooks实现自动化代码质量检查 【免费下载链接】docker-stacks Ready-to-run Docker images containing Jupyter applications 项目地址: https://gitcode.com/gh_mirrors/do/docker-stacks Docker Stacks是一个提供现成…...

Rolify 项目部署指南:从开发环境到生产环境的完整迁移流程

Rolify 项目部署指南&#xff1a;从开发环境到生产环境的完整迁移流程 【免费下载链接】rolify Role management library with resource scoping 项目地址: https://gitcode.com/gh_mirrors/ro/rolify Rolify 是一款功能强大的角色管理库&#xff0c;支持资源范围的权限…...

从素材到成片:AI 一站式极速输出——影视创作的新时代革命

在数字化浪潮席卷全球的今天&#xff0c;影视创作领域正经历着前所未有的变革。传统影视制作流程繁琐复杂&#xff0c;从素材采集、剪辑、特效添加到成片输出&#xff0c;往往需要耗费大量的人力、物力和时间。然而&#xff0c;随着人工智能&#xff08;AI&#xff09;技术的飞…...

PingFangSC字体系统:跨平台中文字体解决方案的技术实践

PingFangSC字体系统&#xff1a;跨平台中文字体解决方案的技术实践 【免费下载链接】PingFangSC PingFangSC字体包文件、苹果平方字体文件&#xff0c;包含ttf和woff2格式 项目地址: https://gitcode.com/gh_mirrors/pi/PingFangSC 在数字化产品开发中&#xff0c;字体选…...

5个技巧让普通鼠标在Mac上秒变专业工具:Mac Mouse Fix深度解析

5个技巧让普通鼠标在Mac上秒变专业工具&#xff1a;Mac Mouse Fix深度解析 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 你是否曾为Mac上的鼠标体验感到沮…...

Bunker_mini_dev实战:多雷达(AVIA MID360)ROS1驱动融合与rviz点云同屏可视化

1. 多雷达ROS1驱动融合实战背景 最近在Bunker_mini_dev机器人开发平台上折腾多激光雷达融合&#xff0c;发现不少开发者对Livox AVIA和MID360这两款雷达的ROS1驱动配置存在困惑。我自己踩过不少坑&#xff0c;今天就把从驱动安装到rviz同屏显示的全流程梳理一遍。这种配置在自动…...

如何将Serge与LangChain集成:打造企业级AI应用的终极指南

如何将Serge与LangChain集成&#xff1a;打造企业级AI应用的终极指南 【免费下载链接】serge A web interface for chatting with Alpaca through llama.cpp. Fully dockerized, with an easy to use API. 项目地址: https://gitcode.com/gh_mirrors/se/serge Serge是一…...