Log4j2 异常堆栈存储优化
背景
在微服务架构中,日志的完整性和可读性是排查问题的关键。传统日志框架(如Log4j2)默认会输出异常的全部堆栈信息,但在高并发或复杂调用链路场景下,这会导致以下问题:
日志冗余:一次请求产生的完整堆栈可能包含数百行,增加存储和分析成本;
信息过载:开发人员需手动筛选关键堆栈节点,一般只关注最底部的 Cause By,影响排查效率;
线程安全:异步线程池中,堆栈信息可能因线程复用而断裂。
因此,需要一个 log4j2 插件来解决这些问题。
目标
设计一个轻量级插件,实现异常堆栈倒排,压缩日志内容,零侵入配置。
实现
使用 Log4j2 插件提供的扩展点 LogEventPatternConverter 进行实现。
倒排堆栈
在 LogEventPatternConverter 提供的 format 方法扩展格式化日志输出。
12345678910111213141516171819202122232425262728293031323334353637383940414243@Overridepublic void format(LogEvent event, StringBui ...
Jenkins 密码策略合规优化
背景因 SOX 项目审计,检查到我们使用 Jenkins 开源版本作为发版工具,但 Jenkins 的密码策略不符合基本的安全要求,例如密码长度不能小于 8 个字符,需要包含大小写字母、数字和特殊字符,需要进行整改。
目标选择正确的方案,满足 Jenkins 的密码策略要求。
实现使用 2FA 双因素认证插件在 Jenkins 插件管理搜索 MFA 安装。
插件安全完成后,在系统管理出现新的选项 2FA Global Configurations。
在配置里面勾选 Enable 2FA for all users 和 Mobile Authenticator 表示对所有用户开启 2FA 认证。
接下来我们进行测试,进入登录页面。
输入用户和密码后,弹出二维码,手机下载 Authenticator 软件,扫码。
输入 6 位动态验证码
登陆成功。
一个验证码只能被一个手机APP绑定,更换APP设备需要管理员从系统管理 reset 重置二维码绑定。
整个流程下来,使用 2FA 双因素认证插件是没有问题的,但是,这个插件是收费的,并且对 Jenkins 版本有要求,笔者公司 ...
KubeVela 云原生应用交付实践
背景
KubeVela 是一个开箱即用的现代化应用交付与管理平台,通过开放应用模型(OAM)来作为应用交付的顶层抽象,采用声明式的方式描述应用交付全流程,自动化的集成 CI/CD 及 GitOps 体系,通过 CUE 轻松扩展、复用或重新编写交付过程。
在公司内部,笔者使用 CODING 平台搭建生产环境的 CI/CD 流程,基于 Orbit 落地了 OAM 发布方案。由于 CODING 商业化调整,Orbit 只有旗舰版才能使用。因此,笔者准备调研 KubeVela 是否能平替 CODING。
目标
验证 KubeVela 是否能实现 Orbit 的 CI/CD 流程,并给出对 KubeVela 的评价。
部署
在现有的 Kubernetes 集群搭建 KubeVela,使用官方提供的 Helm 脚本部署,代码片段如下。
123helm repo add kubevela https://kubevela.github.io/chartshelm upgrade --install --create-namespace -n vela-system kubevela kubevel ...
Harbor 私有镜像仓库搭建
背景
由于自建机房无法访问 DockerHub,需要搭建 Harbor 私有镜像仓库,并解决研发团队在本地镜像仓库中拉取镜像的问题。
部署
Helm 部署 Harbor
本次基于 KubeSphere 平台搭建,使用 Helm 安装,从 ArtifaceHub 搜索 Harbor,添加 Helm Chart。
12export KUBECONFIG=/etc/kubernetes/admin.confhelm repo add harbor https://helm.goharbor.io
Harbor 默认使用 DockerHub 镜像,可以在 Helm 模板添加 m.daocloud.io 镜像仓库前缀,以解决拉取镜像失败的问题。代码片段如下:
123# 存储类指定为 data-nfs-client,您可以自行选择其他存储类。# Harbor 使用 Nginx 提供访问入口,此处设置为 http://10.2.2.109:30003helm upgrade --install harbor harbor/harbor --set expose.type=nodePort --set ...
KubeSphere 高可用集群搭建
背景介绍
笔者最近在部署自建机房,准备搭建 KubeSphere 集群,KubeSphere 官网的文档似乎有点小问题,所以用这篇文章来记录一下实际的操作,可以放心食用。
准备环境
假设有 4 台机器节点,规划如下:
10.2.2.109:控制节点和 etcd
10.2.2.140:数据节点1
10.2.2.211:数据节点2
10.2.1.9: NFS 服务器,与 KubeSphere 集群隔离 IP 网段
DNS 初始化
1234567> cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain610.2.2.109 k3s-master k3s-master.novalocal10.2.2.140 k3s-worker-01 k3s-worker-01.nov ...
Dockerfile 构建 Java 应用瘦身优化
背景
早期我们对于 Docker 构建 Spring Boot 工程的方式很简单,直接构建生成 jar 可执行程序,通过 java $JAVA_OPTS -jar 启动。在 Kubernetes 环境下,如果要调整 JVM 参数,则通过 ConfigMap 维护 JAVA_OPTS 变量,方便统一管理同一个 Nacos 配置中心,如下:
123456-Xmn1G-Xmx1G-Xss256k-Dspring.cloud.nacos.config.username=nacos -Dspring.cloud.nacos.config.password=nacos-Dspring.cloud.nacos.config.server-addr=127.0.0.1:8848
在实际的生产环境,可能定义了十几个甚至上百个 Deployment,每个 Deployment 根据不同的负载设置不同的 JVM 参数,没办法共享同一份 ConfigMap 文件。为了解决这个问题,我们应该优化下 Dockerfile 构建模板,把 JVM 参数和运行环境变量分离出去。
目标
制定一套标准 Docker 构建 ...
KubeSphere 持续集成实践
背景
笔者在搭建 KubeSphere 集群时,发现 KubeSphere 控制台提供了内置的 DevOps 可视化工具,可以快速搭建 CI/CD 流水线。因官方文档没有详细说明,笔者决定通过实践的方式来研究 KubeSphere DevOps。
目标
探索 KubeSphere DevOps 能否满足研发团队的 CI/CD 需求。
步骤
创建 DevOps 项目
在 工作台 > 项目 > 流水线 创建您的应用。
选择流水线,KubeSphere 提供了单分支和多分支构建方式。
设置构建参数和触发器规则。
编辑流水线
KubeSphere 的可视化界面不是特别完善,笔者经过调试后,编写下面的脚本。如果您熟悉 Jenkinsfile 的语法,可以直接在流水线编辑界面中编写 Jenkinsfile。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 ...
Higress 金丝雀发布实践
背景
Higress 是阿里巴巴开源的云原生网关,基于 Istio + Envoy 为核心构建,实现了流量网关 + 微服务网关 + 安全网关三合一的高集成能力,深度集成 Dubbo、Nacos、Sentinel 等微服务技术栈。
关于 Higress 具体的介绍,您可以查阅 Higress 文档。
在早期的部署架构,业务通常采用 WAF 安全防护网关 + Nginx 流量网关 + Spring Cloud Gateway 微服务网关 实现。
一次用户请求 -> LB(WAF) -> Nginx -> Spring Cloud Gateway -> 微服务
这样导致在链路分析和日常维护上带来复杂性。因此,我们尝试引入 Higress 网关,去除 Spring Cloud Gateway 的依赖,将请求链缩短如下。
一次用户请求 -> LB(WAF) -> Higress -> 微服务
目标
验证 Higress 网关能否替换 Spring Cloud Gateway,并实现 A/B 测试、金丝雀发布等功能。
部署
为方便维护,使用 Helm 部 ...
Log4j2 扩展日志脱敏插件
背景
日志脱敏是常见的安全需求。为了金融交易的安全性,国家强制规定对于姓名、手机号、身份证号码、住址等信息需要数据脱敏。一般我们会采取注解的形式指定字段进行脱敏处理,但这样对代码的侵入性较高。假设公司有几十个系统要改造,或者采购了一些系统没有源代码,怎么办?还有,日志脱敏后,系统用户需要通过手机号找出对应的日志,怎么匹配?
目标
实现一个零侵入性的日志插件,并能支持原始数据检索。
实现
我们调研了 Github 一些开源项目,发现 https://github.com/houbb/sensitive 能够满足这个需求,它通过 Trie 类对字符进行解析处理,具体的处理逻辑大部分封装在 com.github.houbb.chars.scan.bs.CharsScanBs 这个类,我们只需要引入 CharsScanBs.scanAndReplace(text) 就可以实现对原始日志的脱敏处理,被脱敏的内容后面自动追加原始数据库的 MD5 信息,假设用户反馈系统问题,会提供他的手机号,我们将手机号生成 MD5,去脱敏日志文件匹配,就能定位到原始数据。
Log4j2 插件提供了两个扩展方式 A ...
Spring Boot 实现可扩展的消息队列
背景
在复杂的分布式系统中,消息队列(如 RocketMQ、Kafka、RabbitMQ)常用于优化系统性能。然而,直接在代码中引入这些消息队列的 API 会导致系统与特定消息队列的强耦合,后续难以切换其他消息队列组件。虽然 Spring Cloud Stream 提供了一种抽象层,但其引入了复杂的概念(如绑定器、通道、处理器等),且与低版本的 Spring Boot 不兼容。
为了解决这些问题,我们决定开发一个简洁、可切换的 MQ 组件,保留原生配置的同时,屏蔽底层 API 细节,并通过 Spring Boot 自动装配进行管理。
目标
封装通用接口:提供统一的接口,屏蔽底层消息队列的 API 细节。
保留原生配置:支持 RocketMQ、Kafka 等消息队列的原生配置。
做到开箱即用:通过 Spring Boot 的自动装配机制,简化配置和集成。
实现
消息模型设计
首先,定义一个通用的消息模型 Message,用于封装业务项目中生产和消费的消息内容。该模型兼容 RocketMQ 和 Kafka 的消息结构。
123456789101112131415161718192021 ...