定义
Microservices Architecture(微服务架构)是 ICMP 采用的分拆式系统架构,将平台能力拆分为多个独立部署、独立扩展的微服务,通过 API 与消息队列协作。微服务架构保障系统高可用性、弹性扩展与快速迭代,与 Multi-Region 多区域、Region Failover 区域容灾配合,支撑全球 7×24 服务。
架构特点
微服务架构的特点包括:服务自治——各服务独立开发、部署、扩展,技术栈可差异化;松耦合——通过 REST、gRPC、消息队列通信,降低依赖;弹性——单服务故障可隔离,不影响整体;可扩展——按需对高负载服务水平扩展。ICMP 典型微服务包括:卡管理、计费、用量聚合、API Gateway、通知、报表等。
与高可用的关系
微服务架构支持 Multi-Region 多区域部署:各区域独立部署完整或部分服务;结合 Region Failover,单区域故障时流量切换至其他区域;结合 Failover、负载均衡、健康检查,实现高可用。平台通过 API Gateway 统一对外暴露,内部服务间通过服务发现与负载均衡通信。
在 ICMP 中的实践
达希物联 ICMP 采用微服务架构,各业务域独立服务;支持 Multi-Region、Geo-Distributed 部署;结合 Region Failover 保障高可用;通过 RESTful API、Event Subscription 对外提供能力;支持敏捷迭代与独立发布。
服务拆分后的数据所有权
微服务架构在连接管理里的含义,是按业务边界把卡生命周期、用量、计费、通知和对外接口拆成可以独立发布的服务,再用同步调用或消息协作。拆分的目的是让故障和发布不要绑在同一个进程上,而不是让每一项数据都有多份权威副本。每类事实只能有一个所有者:卡状态由卡服务维护,话单由用量服务接收,账单金额由计费服务计算。其他服务可以保存副本用于查询,但副本过期时必须能说明自己不是权威来源。
采用这种拆分的条件,是边界已经稳定,团队也能独立部署和观察每个服务。若开通、计费和通知仍由同一批人在同一次发布里修改,拆成多个进程只会增加调用失败点。跨服务动作要有明确的完成定义。例如开通成功,应是运营商侧接受并且卡服务已记录,而不是通知服务把邮件发出去。与运营支撑系统交换的网络状态、与业务支撑系统交换的订单,也不应写进同一个服务的私有表里再互相直接改库。
独立部署并不等于账已闭合
容易出错的是认为服务各自扩容之后,用量和账单就自然一致。用量服务先收到话单,计费服务尚未消费消息时,门户上的流量已经增加,费用仍是旧的。把这种短暂差异展示成“实时账单”,客户会认为扣费错误。另一个错误是用分布式事务把所有服务锁在一起,任何一个下游变慢,开通接口就全部失败,拆分带来的隔离被抵消掉。
共享数据库同样会破坏边界。计费服务直接改卡服务的表,卡服务发布时无法判断哪些字段还被别人依赖。超时后的重试如果不带幂等键,同一次暂停会被执行两次,状态来回抖动。设计微服务时,要为每条跨服务消息规定所有者、重试上限和对账方法,让独立部署服务于发布和故障隔离,而不是制造多套互相矛盾的账。
发布顺序也要服从数据所有权。先升级只读副本的消费者,再升级拥有权威数据的服务,可以减少旧进程把新字段写成空值。回滚时同样不能只退回其中一个服务:计费已经按新规则写出的金额,不能被旧版本的卡服务覆盖成上一次的状态。每个服务的健康检查应验证它能否读到自己的权威存储,而不是只验证进程还在监听端口。
跨服务的写操作要能说明做到了哪一步。开通若先改了卡状态、再通知计费、最后推送客户,中途失败时必须知道计费有没有听到。补偿可以是继续完成,也可以是把卡状态改回并通知调用方失败,但不能把两个结果都留着。每个步骤使用同一个业务标识,重试时靠这个标识认出已经完成的步骤,避免通知发了两次、状态却只改了一次。
字段变更先在拥有该数据的服务里定义,再通知消费方。消费方暂时不认识的新字段应被忽略而不是导致整条消息失败;消费方依赖的旧字段被删除之前,要先确认没有服务仍在读取。直接改共享表会绕过这个过程,发布时无法判断谁还会读旧列。观察每个服务时,要能看到它积压了多少未处理消息,积压本身就是用量和账单暂时不一致的原因。
故障隔离意味着下游慢时,上游要有明确的超时和退路。查询用量的接口可以返回“暂时不可用”,不应该把卡管理的开通也拖死。相反,真正必须一起成功的步骤要写在同一个服务的权威数据里,不要假装拆开后又用远程锁把它们捆住。拆分是否合理,看的是一张卡的状态是否仍然只有一个所有者。