一、微服务架构概述:从单体到微服务的演进

聊微服务之前,我想先聊聊单体架构。说实话,我入行那几年,大部分项目都是单体应用。一个解决方案,一个数据库,一个部署包,搞定一切。那时候觉得挺爽的——开发简单,调试方便,部署也就一个命令的事。

但后来项目越来越大,问题就来了。我记得有个电商项目,代码量到了几十万行,每次编译都要五分钟。改一行代码,整个系统都得重新部署。更头疼的是,团队从几个人扩到几十人,代码冲突成了家常便饭。嗯,这就是单体的痛点。

单体架构的困境

单体架构不是不好,是它有自己的天花板。我总结了几点:

  • 部署耦合:一个小功能改动,整个系统都要重新发布
  • 技术栈锁定:一旦选了.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搭建第一个微服务。到时候咱们手把手写代码,把今天讲的原则落地。