TAG 工作总结
这个是我工作了 1.5 年的一个小总结
我在 TAG 的职责
负责 Clinical 微服务开发和维护(TAG 是大型医疗集团,旗下 Aspen Dental 有 1400+ 门店,使用自研系统,需要持续维护和迭代)
- 采用 Model-Service-Repository 设计模式,优化代码结构,提高可维护性
- 日常维护多个 .NET 微服务,修复 bug,开发新业务功能
负责 Monolith 维护 (也是 .NET) 和 Bug 修复
- 阅读和理解遗留代码,定位并修复问题
- 将 Clinical 相关功能从 Monolith 拆分到微服务
数据库相关工作
- Monolith 用 SQL Server,微服务用 PostgreSQL
- 根据 PM 需求开发新功能或调整数据
跨团队协作
- 帮后端队友做 Code Review (团队里唯一非 Senior)
- 帮前端队友解答后端相关问题,协助前后端联调
- 帮 PM 做技术研究(SPIKE)
- 需要时支援其他 team
我在 TAG 的技术栈
- Frontend: 能读懂 Angular 和 React(微前端)
- Backend: C#, .NET 6 到 9 (Monolith 是 .NET 6, 其他微服务基本上都是 .NET 9), GraphQL (是的我们有 GraphQL layer, 但我个人并不喜欢), gRPC
- Database: PostgreSQL, SQL Server, AlloyDB, Firestore (GCP)
- ORM: Dapper, Entity Framework (主要用的还是 Dapper, Monolith用的是 Entity Framework)
- Cloud: GCP (Pub/Sub, AlloyDB, DMS, BigQuery)
- DevOps: Docker, Kubernetes, Terraform, Spinnaker, Liquibase
- Monitoring: Grafana
- Other Tools: LaunchDarkly, Nuget, Git, GitHub
我自己主导的项目
虽然我是初入职场,但能力还是可以的,所以除了日常维护我们组的微服务,我也有一些自己开发的项目,为公司带来收益
TAG Notifications
从零搭建的完整服务,从数据库设计到微服务开发全程独立完成。用于患者 recall exam (也就是复诊) 管理——当患者来到诊所时,系统会根据历史 procedure 记录提醒进行复检,提升诊所服务质量和营收。
下面是整个 data flow 的设计图
┌─────────────┐ |
1. 数据库设计
使用 AlloyDB + PostgreSQL 作为数据存储,通过 Liquibase 管理 schema 变更。独立设计数据库 schema,与 Senior 和 Tech Lead 多次讨论修改。在完成 MS 和 Cron Job 开发后,根据需求设计 index 优化性能。
2. Nightly Cron Job (定时任务)
Cron Job 主要负责两件事
- Populate database: 从 Monolith 拿取需要的数据,populate 所需的 notification
- 每日增量同步: 每天晚上根据 checkpoint 从 Monolith 更新所需数据,确保与 Monolith 保持一致(Monolith 是 source of truth)
由于 Monolith 数据量是千万级别,学习并应用了多种优化技术
- Batch operation: 无法一次读完所有数据,将 table 数据分批读取
- Parallel programming: 设置 concurrent worker,每个 batch 读出后用空闲 thread 进行 bulk upsert,这样就可以不需要等待 upsert 直接进入下一个 batch
- Task 并行: 让互不冲突的 task 同时运行
通过这些优化,可以在 10 秒内处理 100,000 条数据。
3. Notification Subscriber (发布-订阅)
Subscriber 是一个独立的 Worker,专门处理 GCP Pub/Sub subscription,监听从 Monolith 和其他 team 发来的 event,实时更新数据库,确保用户在白天可以获得最准确的数据。
之所以没有在 MS 里集成 Subscriber,是因为这个服务需要高并发且流量很大 (因为是在类似 Visit Manager 里被使用),如果在 MS 里处理,流量上来就得 scale MS,这显然不合理。独立出 Subscriber 可以单独 scale,实现服务解耦。
技术要点
- 用 Terraform 创建 GCP subscription 和 dead letter queue
- 研究并确定所需的 event,针对不同 event 写了不同的 message handler
- 应用 Cron Job 中学到的优化: 互不冲突的 task 同时运行
- 加 Redis 缓存静态数据,减少数据库查询
4. Notification MS (微服务)
一个标准的 .NET 9 微服务,为前端、GraphQL team 和其他 MS team 提供所需的 API。
总结
通过这个项目学到了很多,包括数据库设计和 PostgreSQL 的使用、parallel programming 和 Cron Job 开发(通过 GCP Log Explorer + Stopwatch 进行速度测试)、GCP Pub/Sub 的使用并处理不同的 Messaage,以及如何将 PM 比较宽泛的需求落地成具体的技术方案(Notification 概念简单,但实现复杂)。
最重要的是,这个服务设计了很强的扩展性。不止我们 Clinical team 在用,其他 team 也会依赖这个服务并提出自己的 notification 需求,不同的 stakeholder 也可以为自己的 brand 提出不同的要求。所以这算是我比较大的一个项目,并且正在持续完善整个服务。
TAG LaunchDarkly
之所以做这个项目,是因为我一部分负责的工作是 pilot project(试点项目),就是在一部分 facility 中先试用新功能。之前我们控制 pilot 是用 Monolith 的数据库,有专门的 pilot project 和 pilot facility 表,但问题在于 Monolith 数据库不能随便 deploy,要等每周固定时间。这样就导致新的 pilot project 需要等到下周才能上线,影响业务敏捷性。
正好那时候前端刚采用了 LaunchDarkly 作为 feature flag 控制,我的 manager 就让我研究后端怎么用 LaunchDarkly 作为 modern solution 进行 pilot 控制。

技术实现
我设计并实现了一个 Feature Flag NuGet Package,包含两部分
- Abstraction package: 避免 vendor lock-in,统一 API 设计 (意思就是如果将来从 Launchdarkly 换成其他 feature flag 产品,都需要 implement 这个 package)
- Implementation package: 使用 LaunchDarkly,采用 Factory Pattern + Lazy Client Initialization 优化性能
成果
这个 package 被多个 team 采用,服务全国 2000+ dental facilities。各 team 可以独立管理和上线 pilot project,不用等 database release。现在还和 Metric team 合作,可以在他们那边看到 pilot project 的 adoption rate。
总结
通过这个项目学会了怎么写 NuGet package(类似 npm package),以及怎么设计低耦合的软件
我学会的东西
如何设计微服务
在我们 Clinical team,采用 Model-Service-Repository 模式构建 C# 微服务,以提升代码的可维护性和扩展性:
- Model: 定义数据结构,Request 或 Response 的结构
- Repository: 负责数据库操作,封装 SQL 查询,提供数据访问接口(使用 Dapper 写和数据库交互的逻辑)
- Service: 负责核心业务逻辑,调用 Repository 获取和修改数据
对于 Repository 和 Service,需要建立对应的 Interface,用来定义方法签名和写注释说明方法的用途。
如何使用 IaC (Terraform)
之前团队都是用 GCP Console 手动创建资源,不好管理也难以回溯。我自己学习了 Terraform, 就可以在不影响 Devops 的情况下
- 创建 Pub/Sub subscription 和 dead letter queue
- 写 GCP DMS template,用于数据迁移
之前团队用 SSIS 做数据迁移(从 Monolith SQL Server 迁移到 AlloyDB),非常复杂而且没有很多人知道怎么做。所以在写 PubSub template 的同时我研究了 GCP DMS (Database Migration Service),并且组合了 Terraform 提供的 DMS tempalte,让其他 team 可以更方便地进行数据迁移。
如何提高 API Performance
在 Aspen,我们用两种方式衡量 API 性能: 用 Grafana 监控 response time 等指标,以及做 stress testing 了解 API 在高负载下的表现。
性能优化方面主要是 SQL query optimization、caching strategies(如 Redis 缓存静态数据)、和 Senior 做 Code Review 讨论 API 设计。
如何从零开始做东西
不管是做 MS 还是 NuGet Package,最重要的是做一个 template 出来,可以让别人复用。这样后续的项目可以基于 template 快速开始,不需要从头配置。




