微服务设计 - 偏向基于python
2025-09-03 20:14:58 5 举报
AI智能生成
微服务设计是一种架构风格,它主张将单一应用程序开发为一组小型服务,每个服务运行在自己的进程中,并且通常围绕业务能力来组织。这里介绍了选型,注意事项,服务部署。 微服务通常使用轻量级的通信机制如HTTP/REST或MQ传递。微服务强调松耦合和独立部署,每个服务可以由小型跨职能团队独立开发、扩展和更新。 核心内容包括: - 独立的服务粒度 - 服务自治与去中心化治理 - 服务请求,重试,熔断,降级处理 - 弹性与容错性 - 技术多样性和组件化设计
作者其他创作
大纲/内容
微服务理念(Microservices)
微服务是一种架构风格
其核心理念包括
单一职责
每个服务只关注一个业务能力,如用户服务、问答服务、搜索服务等。
服务自治
每个服务可以独立开发、部署、扩展、崩溃而不影响其他服务。
服务间解耦
服务间通过 REST API,gRPC API 或消息(MQ)通信,避免直接代码依赖。
去中心化治理
服务各自拥有自己的数据库、配置、代码生命周期。
技术异构友好 不同服务可以用不同语言/数据库实现(比如 Python + Rust + JS)。
适合的场景
业务功能相对独立:例如用户管理、订单管理、问答主程序、缓存程序,推荐程序,选股程序,实体识别模块,日志等模块,彼此之间没有强烈的依赖。
部署/扩展需求不同:某些服务需要高频更新,另一些服务更稳定;或者某服务需要高并发处理,而其他服务访问较少。
技术异构性强:不同服务可能需要使用不同的数据库、语言、框架、性能要求差异大。
团队规模较大且分工明确:多个团队各自负责不同的服务,提升协作效率。
部署/扩展需求不同:某些服务需要高频更新,另一些服务更稳定;或者某服务需要高并发处理,而其他服务访问较少。
技术异构性强:不同服务可能需要使用不同的数据库、语言、框架、性能要求差异大。
团队规模较大且分工明确:多个团队各自负责不同的服务,提升协作效率。
不合适的场景
不适合微服务的情况(强耦合或上下文紧密)
强事务一致性要求:比如一个业务流程必须保证跨服务的数据一致性(如下单 + 扣库存 + 支付),若频繁进行分布式事务协调会增加复杂度。
调用链深度大:多个服务层层嵌套调用(A→B→C→D),容易引发延迟累积、错误传递、调试困难等问题。
数据模型共享度高:多个服务共用大量表结构,拆分会带来大量重复数据同步和冗余设计。
强事务一致性要求:比如一个业务流程必须保证跨服务的数据一致性(如下单 + 扣库存 + 支付),若频繁进行分布式事务协调会增加复杂度。
调用链深度大:多个服务层层嵌套调用(A→B→C→D),容易引发延迟累积、错误传递、调试困难等问题。
数据模型共享度高:多个服务共用大量表结构,拆分会带来大量重复数据同步和冗余设计。
实现方式(RPC)
RPC(Remote Procedure Call)的本质:
RPC 是一种“调用远程服务像本地函数一样”的编程抽象。
HTTP
HTTP + JSON(可视为一种轻量 RPC);
特点
性能
性能适中
开发体验
多人团队容易上手、调试方便
服务解耦合度
服务耦合度 中(需双方在线)
注意事项
✅**统一 API 规范**
约定 JSON 请求/响应格式
"Accept": "application/json"
"Accept": "text/event-stream"
✅**合理使用status_code**
服务端异常 5xx 状态码
尽量不要返回 全篇服务端代码栈错误
客户端请求错误 4xx 状态码
如用户认证错误,客户端请求参数错误
✅**响应一致结构**
其他响应统一返回结构,便于统一处理:
{
"code": 0,
"msg": "Success.",
"data": {
"ids": "1",
"typing": "单只个股分析"
}
}
"code": 0,
"msg": "Success.",
"data": {
"ids": "1",
"typing": "单只个股分析"
}
}
响应错误案例,非0的code码:
{
"code":4002,
"msg":"没有选股结果",
"data":{},
"event":"Search",
"id":0
}
"code":4002,
"msg":"没有选股结果",
"data":{},
"event":"Search",
"id":0
}
✅**服务健康检查**
每个服务暴露 `/healthz` 接口用于探活
✅**统一日志追踪(Tracing)**
使用 `trace_id` 贯穿所有请求
使用请求重试,请求熔断,请求降级
✅**版本控制**
微服务接口设计应支持多版本(如 `/v1/classifier/`, `/v2/classifier/`)
建议与提升
使用 OpenAPI/Swagger 统一的文档管理
python框架在 HTTP 微服务中的实践
推荐Fastapi, Sanic
使用服务注册与发现 | Consul、Etcd、K8s DNS 或 Envoy 自动发现服务
安全认证 | 采用统一网关进行 Token 验证,服务内部信任 Header 信息,如 OAuth2 / JWT
AMQP
MQ 消息队列的通信方式(如基于 RabbitMQ);
特点
性能
中(异步处理吞吐高)
开发体验
比较复杂,需消息设计
服务解耦合度
高(完全解耦)
流程
请求消息 发送到 MQ 的 RPC 队列;
服务消费者(比如 qa_service)收到消息并处理;
结果作为响应消息 也通过 MQ 回传;
调用方收到响应(如果是同步调用,会阻塞等待结果)。
所以请求和响应都走 RabbitMQ。
服务消费者(比如 qa_service)收到消息并处理;
结果作为响应消息 也通过 MQ 回传;
调用方收到响应(如果是同步调用,会阻塞等待结果)。
所以请求和响应都走 RabbitMQ。
架构分析
在 Nameko 架构中一个 RPC 调用
开始一个简单案例
保证消息正确性
correlation_id 每个请求消息带有唯一 ID,响应消息使用相同 ID 关联
reply_to 字段 每个请求方客户端声明自己的临时响应队列(exclusive queue)
自动 Ack / 重试机制 服务处理成功后会自动 ack,否则消息可重试或入死信队列
Channel 隔离 每个服务使用独立 Channel,避免共享冲突(线程/进程安全)
Timeout 管理 客户端设置超时时间,避免一直等待无响应的请求
请求消息
{
"body": [
{"user_id": 123}
],
"headers": {
"nameko.routing_key": "get_user_info",
"correlation_id": "rpc-call-7f9d12a4",
"reply_to": "rpc.reply.0ee7120f-c880-4937-b7d0-e308ffc8e3a0",
"content_type": "application/json"
}
}
"body": [
{"user_id": 123}
],
"headers": {
"nameko.routing_key": "get_user_info",
"correlation_id": "rpc-call-7f9d12a4",
"reply_to": "rpc.reply.0ee7120f-c880-4937-b7d0-e308ffc8e3a0",
"content_type": "application/json"
}
}
响应消息样例
{
"body": "User info of user_id 123",
"headers": {
"correlation_id": "rpc-call-7f9d12a4"
}
}
"body": "User info of user_id 123",
"headers": {
"correlation_id": "rpc-call-7f9d12a4"
}
}
gRPC
HTTP2(基于 HTTP/2 + Protobuf);
特点
性能
高(压缩 + 多路复用)
开发体验
前期团队配合新协议需要打磨,后期开发加速,自动代码生成
服务解耦合度
低(需定义 proto)
结构分析
服务间通信
🔵 Consul 功能全、Python 生态好、适合自托管部署
特点
所有服务注册到 Consul Server,服务通过 Consul 查找其他服务
🧭 服务发现 自动注册服务,支持 HTTP 查询其他服务实例
🔍 健康检查 HTTP 或 TCP 方式定期检查服务状态
🗺️ Key/Value 存储 用于存储服务配置、元数据等
🌐 DNS 接入 提供 DNS 接口支持域名解析式发现服务
🔐 多数据中心支持 原生支持跨数据中心的服务同步
💬 Consul Connect 实现服务之间的加密通信(Service Mesh)
缺点
需要集成
需要代理逻辑
配置复杂度中等
安装
docker单节点
注册发现
注册服务到 Consul
import requests
def register_service():
url = "http://localhost:8500/v1/agent/service/register"
service_data = {
"ID": "user-service-1",
"Name": "user-service",
"Address": "127.0.0.1",
"Port": 8000,
"Check": {
"HTTP": "http://127.0.0.1:8000/health",
"Interval": "10s"
}
}
requests.put(url, json=service_data)
def register_service():
url = "http://localhost:8500/v1/agent/service/register"
service_data = {
"ID": "user-service-1",
"Name": "user-service",
"Address": "127.0.0.1",
"Port": 8000,
"Check": {
"HTTP": "http://127.0.0.1:8000/health",
"Interval": "10s"
}
}
requests.put(url, json=service_data)
查询服务地址
def discover_service(name="user-service"):
url = f"http://localhost:8500/v1/catalog/service/{name}"
resp = requests.get(url)
data = resp.json()
if data:
return data[0]["ServiceAddress"], data[0]["ServicePort"]
def discover_service(name="user-service"):
url = f"http://localhost:8500/v1/catalog/service/{name}"
resp = requests.get(url)
data = resp.json()
if data:
return data[0]["ServiceAddress"], data[0]["ServicePort"]
FastAPI 集成 Consul 示例
Sanic API 集成Consul
🟢 Kubernetes DNS 最推荐,简洁、无需额外组件,自动服务注册与发现
原生的服务注册与发现机制
原生集成 不需要引入第三方如 Consul、Etcd 等服务注册组件
✅ 自动注册 所有 Service 和 Pod 一创建即自动注册 DNS
✅ DNS 命名一致 统一通过 http://<service-name> 就可访问,命名简洁
DNS 解析 所有服务默认在 cluster.local 域名下自动注册
✅ 自动负载均衡 DNS + kube-proxy 自动做负载均衡
Service Kubernetes 的服务抽象,负载均衡访问 Pod
✅ 高可用 CoreDNS 是集群内置组件,自动冗余部署
Headless Service 不进行负载均衡,返回所有 Pod IP(用于客户端做负载)
环境变量注入 Pod 启动时会注入服务地址(不推荐用于动态场景)
缺点
需要项目环境又成熟的运维人员
需要又成熟的生成级别k8s集群
注册发现
自动通过yalm文件配置后实现
案例
案例
服务间通信(示例代码)
order-service 调用 user-service:
@app.route("/order/<user_id>")
async def get_order(request, user_id):
url = f"http://user-service:8000/user/{user_id}" # 使用 service name 直接访问
async with ClientSession() as session:
async with session.get(url) as resp:
user_data = await resp.json()
...
无需使用 Consul!Kubernetes 会自动解析 user-service 这个名字,做负载均衡并转发请求。
order-service 调用 user-service:
@app.route("/order/<user_id>")
async def get_order(request, user_id):
url = f"http://user-service:8000/user/{user_id}" # 使用 service name 直接访问
async with ClientSession() as session:
async with session.get(url) as resp:
user_data = await resp.json()
...
无需使用 Consul!Kubernetes 会自动解析 user-service 这个名字,做负载均衡并转发请求。
案例结构
k8s/
├── user-service/
│ ├── deployment.yaml
│ └── service.yaml
├── order-service/
│ ├── deployment.yaml
│ └── service.yaml
├── auth-service/
│ ├── deployment.yaml
│ └── service.yaml
├── user-service/
│ ├── deployment.yaml
│ └── service.yaml
├── order-service/
│ ├── deployment.yaml
│ └── service.yaml
├── auth-service/
│ ├── deployment.yaml
│ └── service.yaml
部署步骤
1. 编写 Dockerfile(构建镜像)
2. 编写 Kubernetes 部署文件
deployment.yaml
service.yaml
3. 使用 kubectl 部署
kubectl apply -f user-service/deployment.yaml
kubectl apply -f user-service/service.yaml
4. 服务间通信(例如 order-service 调用 user-service)
在 Sanic / FastAPI 中配置:
url = "http://user-service:8000/user/123"
url = "http://user-service:8000/user/123"
使用脚本批量部署
kubectl apply -f k8s/user-service/
kubectl apply -f k8s/order-service/
kubectl apply -f k8s/auth-service/
kubectl apply -f k8s/order-service/
kubectl apply -f k8s/auth-service/
其他注意事项
🔴 Eureka/ZooKeeper 更重,不推荐用于 Python 轻量微服务除非混合架构需要
0 条评论
下一页