1 Star 0 Fork 2

LianxuanYu/Java-Programmer

forked from Blue_Fish/Java-Programmer 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
技术扩展.md 10.64 KB
一键复制 编辑 原始数据 按行查看 历史
Blue_Fish 提交于 2024-04-22 21:08 . disruptor

一、低代码

低代码专指低代码应用开发平台(LCAP)

二、可观测性

Observability,可观测性

1、概念

可观测性被定义为一种度量方法,这是控制论的一部分,可观测性意味着从系统向外部输出的信息可以推断出系统内部状态的好坏。

一个软件应用程序具有可观测性,意味着它能够让我们通过各种维度和各种角度去分析和理解这个系统当前所处的任何状态,无论这种状态有多奇怪、无论我们之前有没有遇到过,都不需要预先定义或预测。如果能够在不发布新代码(如增加一个用于调试的日志)的情况下理解任何奇怪或不确定性的状态,那么我们的系统就具备可观测性

因此,可观测性是描述人们如何与他们的复杂系统互动,以及如何理解这些复杂系统的概念;

可观测性通常被错误地描述为包含指标、日志和追踪的“三个支柱”,但其实这些只是遥测数据类型。如果我们必须拥有可观测性的三个支柱,那么它们应该是支持高基数、高维度和可探索性工具;

2、传统监控与可观测性

基于监控的调试方法(包括使用指标和仪表盘,结合专家知识对生产环境中的问题进行分类)是软件行业多年以来的一种普遍实践。在数据量有限的单一应用架构时代,考虑到传统系统较为简单,依靠人类的经验和直觉来检测系统问题是高效和有意义的。然而,现代应用基础系统的复杂性和大规模,已经让这种方法越来越站不住脚了;

可观测性工具将高基数、高维度的遥测数据放在一起展现,方便我们轻松地进行切片、放大、缩小,或跟随“面包屑”找到最终答案。此外,通过在一个工具中保持这种上下文,问题的分析依靠的就是明确的数据,而不再是经验和直觉了。可观测性将关键知识从最有经验的工程师的头脑中转移到共享现实中,任何工程师都可以根据需要进行探索

3、OpenTelemetry

可观测领域非常成熟和热门的标准和规范,OpenTelemetry 简称 OTel, 是 CNCF ( Cloud Native Computing Foundation,云原生计算基金会,是一个开源软件基金会,致力于云原生技术的普及和可持续发展) 的一个可观测性项目;

OpenTelemetry 旨在提供可观测性领域的标准化方案,解决遥测数据的数据建模、采集、处理、导出等标准化问题,并能够将这些数据发送到你选择的后端(开源或商业均可)。这样你就可以建立不被供应商锁定的可观测,灵活地更改后端,不需要再次更改代码,重新进行插桩(Instrument)了

4、可观测与云原生、DevOps 和 SRE

4.1、云原生

云原生架构和技术是一种方法,它用于设计、构建和管理用云计算模型搭建的工作负载;

云原生技术使组织能够在公有云、私有云和混合云等现代动态环境中构建和运行可扩展的应用程序。容器、服务网格、微服务、不可变基础设施和声明式 API 就是这种方法的例证。这些技术支持具有弹性、可管理和可观测的松散耦合系统。结合强大的自动化功能,它们使工程师能够以最少的工作量频繁且可预测地进行高影响力的更改;

云原生是注重速度和敏捷性的

4.2、DevOps

DevOps 实际上就是 Dev 和 Ops 的组合。Dev 指的是开发,Ops 指的是运维。DevOps 强调的是开发和运维的协作,因为在应用开发和上线的流程中,开发和运维是最重要的两个角色;

在云原生时代,开发和运维本质上有着共同的目标,也就是更快速地为最终用户交付高质量的应用。DevOps 就是为了移除实现这个目标的路上的阻碍而诞生的;

从技术层面讲,DevOps 是实现从代码、构建、测试到部署等的全流程自动化流水线,从软件开发全生命周期的角度出发,它致力于解决前面所说的那些影响软件发布和上线的因素,优化研发流程、提高研发效率和产品质量,从而最终提升用户使用产品的满意度,帮助业务发展;

4.3、SRE

System Reliability Engineering,也可以指 Site Reliability Engineering;

DevOps 在一个较高的维度(High level)定义了要实现自动化、流线型的应用发布流程应该去做什么,而 SRE 则更加关注具体如何实施和实现 DevOps 的规则和流程;

为了实现 SRE,一个很重要的实践就是需要提升整体项目的工程化水平,减少传统运维的行为,尤其是那些手工的、重复的、为了临时解决一个问题而进行的工作;

4.4、构建可观测性

建立可观测性不仅仅是运维团队的事情,更是整个开发、测试以及 SRE 团队的事情,这是全团队的工作

开发团队

从数据采集的插桩(也就是常说的埋点)开始,开发团队就必须为可观测性负责,因为整个产品、服务和组件都是这个系统的开发人员构建的

5、可观测性工具

一个好的可观测性工具需要具有下面几种能力:

  • 丰富的基础数据集成能力:好的可观测性工具要能通过这些丰富的数据来确定更精准的监测,并且可以尽量丰富记录真实的系统运行状态;
  • 强大的分析诊断能力:要保证系统的可靠性,一个重要的能力就是及时发现并定位可能造成系统不可靠的原因,或者在有问题的时候尽量缩短问题的持续时间,尽快找到问题根因并予以解决;
  • 灵活的自定义能力:每一个业务 / 服务,以及承载这些业务 / 服务的系统都是很特殊的,它们在云环境的部署形态,所使用的组件各不相同。因此,只有具备强大的自定义能力的平台才能为我们有效地提供可观测性,针对不同维度建立可视化,快速定位问题;
  • 数据的统一和联合能力:最后,还要确认这个工具是不是真的能够将数据统一起来,而不是将一堆单独的工具缝合在一起

6、SLO

SLO-Service Level Objective

SLI

三、Code Review

1、如何发现代码质量

常规checkList:

  • 目录设置是否合理、模块划分是否清晰、代码结构是否满足“高内聚、松耦合”?
  • 是否遵循经典的设计原则和设计思想(SOLID、DRY、KISS、YAGNI、LOD 等)?
  • 设计模式是否应用得当?是否有过度设计?
  • 代码是否容易扩展?如果要添加新功能,是否容易实现?
  • 代码是否可以复用?是否可以复用已有的项目代码或类库?是否有重复造轮子?
  • 代码是否容易测试?单元测试是否全面覆盖了各种正常和异常的情况?
  • 代码是否易读?是否符合编码规范(比如命名和注释是否恰当、代码风格是否一致等)?

业务需求checkList

  • 代码是否实现了预期的业务需求?
  • 逻辑是否正确?是否处理了各种异常情况?
  • 日志打印是否得当?是否方便 debug 排查问题?
  • 接口是否易用?是否支持幂等、事务等?
  • 代码是否存在并发问题?是否线程安全?
  • 性能是否有优化空间,比如,SQL、算法是否可以优化?
  • 是否有安全漏洞?比如输入输出校验是否全面?

2、数据库插入

业务背景:写压测 case 生成,简单来说就是一个插入数据库的操作,将参数中的 caseList 入库。

public boolean batchInsert(List<Case> cazeList) {
    boolean result = false;
    Long start = System.currentTimeMillis();
    try {
        result = caseMapper.batchInsert(cazeList.get(0).getSceneId(), cazeList) == cazeList.size();
    } catch (Exception exp) {
        if (exp.getMessage() != null && exp.getMessage().contains("doesn't exist")) {
            caseMapper.createTable(cazeList.get(0).getSceneId());
            caseMapper.addIndex(cazeList.get(0).getSceneId());
            QMonitor.recordOne("db.case.createTable.success");
            result = caseMapper.batchInsert(cazeList.get(0).getSceneId(), cazeList) ==  cazeList.size();
        }
        log.warn(exp.getMessage() != null ? exp.getMessage() : "", exp);
    }
    if (result) {
        log.info("sceneId_{}_groupId_{}: 批量入库(batchInsert)count:{} , 成功", 
        cazeList.get(0).getSceneId(), cazeList.get(0).getGroupId(), cazeList.size());
        QMonitor.recordOne("db.case.batchInsert.success", System.currentTimeMillis() - start);
    } else {
        log.info("sceneId_{}_groupId_{}: 批量入库(batchInsert)count:{} , 失败", 
        cazeList.get(0).getSceneId(), cazeList.get(0).getGroupId(), cazeList.size());
        QMonitor.recordOne("db.case.batchInsert.failed", System.currentTimeMillis() - start);
    }
    return result;
}

3、事务问题

public class SyncCreateT6OrderService
    protected void doRetry(SyncCreateOrderRequest syncCreateOrderRequest) {
        try {
            createT6OrderFromSyncOrder(syncCreateOrderRequest);
        } catch (Exception e) {
            // 此处省略一些异常处理细节,监控、日志等
            throw e; 
        }
    }
    @Transactional(rollbackFor = RuntimeException.class)
    private void createT6OrderFromSyncOrder(SyncCreateOrderRequest syncCreateOrderRequest) {
        ....
    }
}

四、论文

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/lianxuanyu/Java-Programmer.git
git@gitee.com:lianxuanyu/Java-Programmer.git
lianxuanyu
Java-Programmer
Java-Programmer
main

搜索帮助