2025年5月阅读清单

微服务VS单体应用

文章地址:Microservices Are a Tax Your Startup Probably Can’t Afford / 微服务是您的初创公司可能无法负担的负担

一些摘录总结:

  1. 结构良好的单体应用可以让团队专注于交付,而不是处理紧急情况。通过一些“最佳实践(Best practice)”案例,避免单体应用内部糟糕的模块化
  2. 把微服务视为拓展工具,在遇到实际拓展瓶颈时考虑,而不是作为项目的初始模板。过早地引入微服务将遇到重复的基础设施、脆弱的本地设置和缓慢迭代的问题
  3. 按照业务逻辑拆分微服务,在早期产品阶段可能会过早地固化结构。这种随意的服务边界,最终会导致共享的数据库、服务间调用仅用来实现简单工作流、伪装成分离的耦合。因此又回到了第2点,将微服务视为拓展工具,按实际瓶颈拆分微服务
  4. 单个项目中通常会包括一些基础内容(代码风格检查Lint、测试基础设施、本地环境配置、文档、CI/CD配置),在处理微服务时这些内容将乘以服务的数量。早期可以利用共享设施的单代码库结构来简化工作
  5. 微服务引入了一些无形的网络:服务发现、API版本控制、重试熔断降级、分布式链路追踪、集中式日志和告警
  6. 微服务适用的情况:工作负载隔离、差异化的拓展需求、模块间使用不同的运行时

早期模拟微服务拆分:
使用内部标志或部署开关来模拟未来的服务拆分

单代码库的实践:
这里提到了一点Go语言项目从单体应用过渡到微服务的一种组织方式:

  1. 项目的早期开发时,如果已经拆分了(微服务)模块(module),可以多个模块使用单一的工作空间
  2. 同时,Go 的模块化设计允许我们在开发时在 go.mod 通过 replace 指令把依赖替换为本地路径,例如:
    replace github.com/my-org/common-lib => ../common-lib

    即,把原本依赖的远程库 github.com/my-org/common-lib 替换为本地的 ../common-lib 文件夹。这样利用 replace 实现本地模块的替换,有利于前期软件项目的快速迭代和开发

  3. 后期扩展后,再将各模块独立出来放到不同的 Git 仓库,能够轻松地过渡成完整的分布式的架构

选择微服务需要关注的部分:

  1. 评估支撑你微服务架构的技术栈,投资于开发者体验工具:可能需要实现一些工具来实现生产和本地开发环境的配置。
  2. 专注于服务间通信的可靠通信协议:异步消息需要确保消息模式一致且标准化。REST需要关注 OpenAPI 文档。服务间通信客户端必须实现许多开箱即用的功能:指数退避的重试、超时。一个典型的基础 gRPC 客户端需要手动添加这些额外功能,以确保不会遭受瞬时错误。
  3. 确保单元测试、集成测试和端到端测试设置稳定,并且能够随着引入代码库中的服务级别分离数量而扩展。
  4. 尽量使微服务间共用的共享库(utils,可能是包含监控和通信的通用辅助工具)尽可能小,避免重大变更而导致整个依赖服务重建。
  5. 尽早注意服务日志观测:添加结构化 JSON 日志并创建各种关联 ID 以用于调试;或者早期能够利用一些基本的输出丰富日志信息的辅助工具。

线上故障应急处理要点

从先前某运营商的内网系统到现在社区化线上电商平台的开发,今后面临的是更高用户量和数据量的生产环境,故障时周末的随时响应可能也将成为常态。

线上故障应急处理:4 年多 on call 经验总结

  • 故障止血优先:在故障发生时,首要任务是快速恢复服务,确保业务正常运行;立即追查责任归属在当前情况下时毫无意义的。
  • 止血的最快手段:在服务侧发生的故障,通过识别系统产品的变动,能够快速定位问题并制定止血方案。
  • 谨慎执行止血方案:即使止血方案明确,执行过程中仍需小心谨慎。设计新功能时需要考虑回滚无问题,故障止血时也应考虑灰度发布,逐步推向全网。
  • 高效沟通:排查思路需要尽可能清晰地同步给相关研发;同时研发要敢于下判断,并说清楚自己的判断依据,才能达到集思广益

继续Go语言规范学习

Uber Go 语言编码规范

继续go语言-传参何时使用指针

作为一个java转型go语言的程序员,以前用java时,直接将对象作为参数传递就可以了。而在go语言项目中,由于其保留了一些指针的特性,有时则推荐传递对象的指针,否则将因为拷贝新对象而造成额外的开销。

这里为自己整理一下需要使用指针类型或需要值类型作为参数传递的场景。

继续阅读继续go语言-传参何时使用指针

2025年3月阅读清单

RAG知识库搭建的一些想法

在完成知识库召回后,还可以结合重排序模型对初步检索的结果进行二次排序,确保相关信息的优先展示。

硅基流动提供了bge-m3嵌入模型和bge-reranker-v2-m3重排序模型的免费接入API。

对于表格这类数据的分析统计处理,知识库的片段信息则起不到太大的作用,需要配置MCP服务。

继续阅读2025年3月阅读清单

[K8S – Helm]近期开发Helm包的一些理解 – 202503

相比于一开始作为Web前端工程师入职公司,现在我的工作内容已经远远超出了当时的范畴,JAVA的后端开发到Linux单机、K8S云原生的运维,最近是go开发一些项目需要的Agent应用。

而在将公司项目开发的Agent应用通过Helm安装到客户正式环境集群时,遇到了要求标明资源限制和镜像拉取凭证的问题,我将在这篇文章里讲讲我对这两个问题的理解。

继续阅读[K8S – Helm]近期开发Helm包的一些理解 – 202503

[前端-CSS]CSS的unset关键字

unset关键字的作用

在CSS中,unset关键字用于将属性重置为其继承值初始值

  • 是继承属性,并且在父元素中有定义,那么使用unset会使该属性继承父元素的值。类似于inherit关键字。
  • 不是继承属性,unset则会将其重置为初始值。类似于initial关键字。

继续阅读[前端-CSS]CSS的unset关键字

2025年2月阅读清单

我的2025年2月的阅读笔记整理

除了技术还包括打工人心态的调节

梳理情绪,转变心境

自洽的程序员

带着问题找答案。时常会过来翻一翻,目前是工作哲学、工作方法论、工作中的人际关系,未来或许还会看看工作与家庭,以及对Gap和副业的一些建议。

继续阅读2025年2月阅读清单