一、微服务架构概述:从单体到微服务的演进
聊微服务之前,我想先聊聊单体架构。说实话,我入行那几年,大部分项目都是单体应用。一个解决方案,一个数据库,一个部署包,搞定一切。那时候觉得挺爽的——开发简单,调试方便,部署也就一个命令的事。
但后来项目越来越大,问题就来了。我记得有个电商项目,代码量到了几十万行,每次编译都要五分钟。改一行代码,整个系统都得重新部署。更头疼的是,团队从几个人扩到几十人,代码冲突成了家常便饭。嗯,这就是单体的痛点。
单体架构的困境
单体架构不是不好,是它有自己的天花板。我总结了几点:
- 部署耦合:一个小功能改动,整个系统都要重新发布
- 技术栈锁定:一旦选了.NET Framework,想切到.NET Core?基本等于重写
- 扩展粒度太粗:某个模块负载高,你得把整个应用都扩一遍,浪费资源
- 团队协作困难:几十个人在同一个代码库改,合并冲突能让你崩溃
核心观点:单体架构适合小团队、小项目。一旦业务复杂度上去,团队规模扩大,它就成了瓶颈。
微服务是怎么来的
微服务的概念其实不是凭空冒出来的。它背后是SOA(面向服务架构)的思想,加上容器化技术的成熟,才真正落地。我个人习惯把微服务理解为「把一个大系统拆成多个小系统,每个小系统独立开发、独立部署、独立扩展」。
为什么会这样?说白了,就是业务太复杂了,一个团队搞不定,那就拆开搞。每个团队负责一个服务,各管各的,互不干扰。
微服务核心原则
做微服务不是把代码拆开就完事了。我见过太多团队,拆完以后比单体还痛苦。为什么?因为没有遵循核心原则。下面这几个原则,是我在项目中踩过坑之后总结出来的。
1. 单一职责原则
每个服务只做一件事,并且做好。比如订单服务只管订单,用户服务只管用户。别想着一个服务既管订单又管支付,那还不如不拆。
我的经验:判断服务边界的一个简单方法——如果这个服务改了,其他服务不需要跟着改,那边界就是合理的。
2. 自治性原则
每个服务要能独立运行。数据库独立、部署独立、故障隔离。我曾经遇到一个项目,所有服务共用一个数据库,结果一个服务慢查询把整个库拖垮了。嗯,这就是没有自治性的代价。
3. 去中心化治理
微服务不要求统一技术栈。订单服务可以用.NET Core,推荐服务可以用Python,只要接口对得上就行。我有个项目,支付服务用了Go,因为那哥们只会Go。没问题,能跑就行。
4. 基础设施自动化
服务多了,手动部署就是噩梦。CI/CD、容器编排、服务发现、配置中心,这些基础设施必须自动化。我建议小团队起步时至少把CI/CD和容器化搞定。
| 原则 | 说明 | 常见反例 |
|---|---|---|
| 单一职责 | 一个服务一个业务边界 | 万能服务,什么功能都往里塞 |
| 自治性 | 独立数据库、独立部署 | 共享数据库、共享缓存 |
| 去中心化 | 允许不同技术栈 | 强制所有服务用同一语言 |
| 自动化 | CI/CD、容器化、监控 | 手动部署、人工运维 |
避坑指南:我曾经接手过一个项目,服务拆了30多个,但每个服务都依赖同一个共享类库。改一个公共方法,所有服务都得重新编译部署。这其实还是单体思维,只是把代码物理拆开了而已。
.NET Core 微服务生态全景
聊完原则,咱们看看.NET Core生态里有哪些好东西。说实话,.NET Core在微服务这块起步比Java晚,但发展很快。现在该有的都有了。
核心框架与工具
- ASP.NET Core:微服务的基础框架,轻量、高性能、跨平台
- Entity Framework Core:ORM框架,支持多种数据库
- Dapper:轻量级ORM,性能更好,我比较喜欢用
- MediatR:实现CQRS模式的利器,适合处理领域事件
服务通信
微服务之间怎么通信?两种主流方式:
- 同步通信:HTTP/REST、gRPC。适合实时性要求高的场景
- 异步通信:消息队列(RabbitMQ、Kafka、Azure Service Bus)。适合解耦、削峰填谷
我的建议:能用异步就别用同步。同步通信会让服务之间产生强依赖,一个服务挂了,调用方也跟着挂。我有个项目就是全用HTTP调用,结果一个服务雪崩,整个系统瘫痪了半小时。
服务治理
服务多了,治理就成了大问题。.NET Core生态里常用的:
- Consul:服务注册与发现,健康检查
- Ocelot:API网关,路由、限流、认证
- Polly:容错处理,重试、熔断、超时
- Steeltoe:整合Spring Cloud的组件,适合混合架构
容器化与编排
微服务离不开容器。Docker + Kubernetes是标配。.NET Core对容器支持很好,镜像可以做到很小(Alpine版本才几十MB)。
// 一个简单的Dockerfile示例
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["OrderService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "OrderService.dll"]
监控与日志
服务多了,出问题你都不知道是哪个服务挂了。所以监控必须到位:
- Prometheus + Grafana:指标监控,可视化
- ELK Stack:日志收集与分析
- Jaeger/Zipkin:分布式链路追踪
- Health Checks:ASP.NET Core内置的健康检查中间件
小技巧:我习惯在每个服务里加一个/health端点,返回服务状态和依赖项状态。Kubernetes的存活探针和就绪探针可以直接用这个端点。
生态全景图
我把.NET Core微服务生态整理成了一张表,方便你对照:
| 领域 | 推荐工具 | 说明 |
|---|---|---|
| 服务框架 | ASP.NET Core | 基础框架,必须掌握 |
| 服务通信 | gRPC, RabbitMQ, Kafka | 同步用gRPC,异步用MQ |
| 服务发现 | Consul, Kubernetes DNS | K8s环境下用DNS更简单 |
| API网关 | Ocelot, YARP | YARP是微软官方出的,性能更好 |
| 容错处理 | Polly | 重试、熔断、超时,一个库搞定 |
| 配置中心 | Consul, Apollo, Azure App Config | 集中管理配置,支持动态刷新 |
| 日志监控 | ELK, Prometheus, Jaeger | 日志、指标、链路,三件套 |
| 容器编排 | Docker, Kubernetes | 生产环境首选K8s |
好了,这一章我们聊了单体到微服务的演进、微服务的核心原则,还有.NET Core的生态全景。你想想看,微服务其实不是什么高深的技术,它更多是一种架构思想。拆得好,事半功倍;拆得不好,还不如不拆。
下一章,我会带你实战——用.NET Core搭建第一个微服务。到时候咱们手把手写代码,把今天讲的原则落地。