内容大纲
1. 微服务架构概述
微服务架构是一种将应用程序设计为一系列松耦合服务的架构风格。每个服务都专注于单一业务功能,可以独立开发、部署和扩展。
微服务架构的核心特点包括:
- 服务独立性:每个服务可以独立开发、部署和扩展
- 业务聚焦:每个服务专注于特定的业务功能
- 技术多样性:不同服务可以使用不同的技术栈
- 容错性:单个服务故障不会影响整个系统
- 可扩展性:可以根据需要独立扩展各个服务
学习交流加群风哥微信: itpux-com
2. 微服务设计原则
2.1 单一职责原则
每个微服务应该只负责一个特定的业务功能,避免功能耦合。
2.2 服务自治原则
每个服务应该有自己的数据库和业务逻辑,避免与其他服务共享数据存储。
2.3 服务通信原则
服务间通过明确的API进行通信,避免直接访问其他服务的内部实现。
2.4 服务可观测性原则
每个服务应该提供足够的监控和日志信息,以便于问题排查和性能优化。
2.5 服务容错原则
服务应该能够处理依赖服务的故障,避免级联失败。
风哥风哥提示:微服务设计应遵循”服务边界清晰”的原则,确保每个服务的职责明确,避免服务间的紧耦合。
3. 微服务架构模式
3.1 API网关模式
API网关作为所有客户端请求的统一入口,负责路由、认证、限流等功能。
3.2 服务注册与发现模式
服务注册中心用于存储服务实例的地址信息,服务消费者通过注册中心发现服务实例。
3.3 配置中心模式
配置中心用于集中管理所有服务的配置信息,支持配置的动态更新。
3.4 熔断模式
当依赖服务出现故障时,熔断机制可以防止请求继续发送到故障服务,避免级联失败。
3.5 限流模式
限流机制用于控制服务的访问流量,避免服务过载。
3.6 降级模式
当服务负载过高时,降级机制可以暂时关闭一些非核心功能,保证核心功能的正常运行。
更多学习教程www.fgedu.net.cn
4. 微服务技术栈
4.1 语言选择
- Java:Spring Boot + Spring Cloud
- Python:Flask + FastAPI
- Node.js:Express + NestJS
- Go:Gin + Echo
- Rust:Actix Web + Rocket
4.2 框架选择
- Spring Cloud:Java生态系统的微服务框架
- Netflix OSS:包含Eureka、Ribbon、Hystrix等组件
- Service Mesh:Istio、Linkerd等服务网格
- Serverless:AWS Lambda、Azure Functions等
4.3 数据存储
- 关系型数据库:MySQL、PostgreSQL
- NoSQL数据库:MongoDB、Redis、Cassandra
- 消息队列:Kafka、RabbitMQ、RocketMQ
4.4 容器与编排
- Docker:容器化部署
- Kubernetes:容器编排
- Helm:应用包管理
author:www.itpux.com
5. 服务间通信
5.1 同步通信
# 用户服务示例
from flask import Flask, jsonify
app = Flask(__name__)
@app.route(‘/users/
def get_user(user_id):
# 模拟从数据库获取用户信息
user = {
‘id’: user_id,
‘name’: ‘John Doe’,
’email’: ‘john.doe@fgedu.net.cn’
}
return jsonify(user)
if __name__ == ‘__main__’:
app.run(host=’0.0.0.0′, port=5000)
# 订单服务调用用户服务
import requests
def get_user_info(user_id):
response = requests.get(f’http://user-service:5000/users/{user_id}’)
if response.status_code == 200:
return response.json()
else:
return None
5.2 异步通信
# 生产者示例(订单服务)
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(‘rabbitmq’))
channel = connection.channel()
channel.queue_declare(queue=’order_created’)
channel.basic_publish(
exchange=”,
routing_key=’order_created’,
body='{“order_id”: 123, “user_id”: 456, “amount”: 100.0}’
)
print(” [x] Sent ‘Order created'”)
connection.close()
# 消费者示例(通知服务)
import pika
import json
connection = pika.BlockingConnection(pika.ConnectionParameters(‘rabbitmq’))
channel = connection.channel()
channel.queue_declare(queue=’order_created’)
def callback(ch, method, properties, body):
order = json.loads(body)
print(f” [x] Received order: {order}”)
# 发送通知逻辑
print(f” [x] Sending notification for order {order[‘order_id’]}”)
channel.basic_consume(
queue=’order_created’,
on_message_callback=callback,
auto_ack=True
)
print(‘ [*] Waiting for messages. To exit press CTRL+C’)
channel.start_consuming()
5.3 gRPC通信
# 定义proto文件
// user.proto
syntax = “proto3”;
package user;
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}
message GetUserRequest {
int32 user_id = 1;
}
message GetUserResponse {
int32 id = 1;
string name = 2;
string email = 3;
}
# 生成代码
$ protoc –go_out=. –go-grpc_out=. user.proto
# 服务端实现
package main
import (
“context”
“log”
“net”
“google.golang.org/grpc”
pb “fgedu.net.cn/user-service/proto”
)
type server struct {
pb.UnimplementedUserServiceServer
}
func (s *server) GetUser(ctx context.Context, in *pb.GetUserRequest) (*pb.GetUserResponse, error) {
// 模拟从数据库获取用户信息
return &pb.GetUserResponse{
Id: in.UserId,
Name: “John Doe”,
Email: “john.doe@fgedu.net.cn”,
}, nil
}
func main() {
lis, err := net.Listen(“tcp”, “:50051”)
if err != nil {
log.Fatalf(“failed to listen: %v”, err)
}
s := grpc.NewServer()
pb.RegisterUserServiceServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf(“failed to serve: %v”, err)
}
}
# 客户端实现
package main
import (
“context”
“log”
“google.golang.org/grpc”
pb “fgedu.net.cn/user-service/proto”
)
func main() {
conn, err := grpc.Dial(“user-service:50051”, grpc.WithInsecure())
if err != nil {
log.Fatalf(“did not connect: %v”, err)
}
defer conn.Close()
c := pb.NewUserServiceClient(conn)
ctx := context.Background()
res, err := c.GetUser(ctx, &pb.GetUserRequest{UserId: 123})
if err != nil {
log.Fatalf(“could not get user: %v”, err)
}
log.Printf(“User: %v”, res)
}
更多学习教程公众号风哥教程itpux_com
6. 服务发现
6.1 服务注册
# application.yml
spring:
application:
name: user-service
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: http://eureka-server:8761/eureka/
# 启动类
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
6.2 服务发现
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping(“/orders/{orderId}”)
public Order getOrder(@PathVariable Long orderId) {
// 从订单服务获取订单信息
Order order = getOrderFromDatabase(orderId);
// 调用用户服务获取用户信息
User user = restTemplate.getForObject(“http://user-service/users/{userId}”, User.class, order.getUserId());
order.setUser(user);
return order;
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
6.3 使用Consul进行服务发现
# 安装Consul
$ wget https://releases.hashicorp.com/consul/1.10.0/consul_1.10.0_linux_amd64.zip
$ unzip consul_1.10.0_linux_amd64.zip
$ sudo mv consul /usr/local/bin/
# 启动Consul代理
$ consul agent -dev
# 服务注册(使用Consul API)
$ curl -X PUT -d ‘{“ID”: “user-service”, “Name”: “user-service”, “Address”: “127.0.0.1”, “Port”: 8080}’ http://fgedudb:8500/v1/agent/service/register
# 服务发现(使用Consul API)
$ curl http://fgedudb:8500/v1/catalog/service/user-service
{
“ID”: “user-service”,
“Node”: “fgedudb”,
“Address”: “127.0.0.1”,
“Datacenter”: “dc1”,
“TaggedAddresses”: {
“lan”: “127.0.0.1”,
“wan”: “127.0.0.1”
},
“NodeMeta”: {
“consul-network-segment”: “”
},
“ServiceKind”: “”,
“ServiceID”: “user-service”,
“ServiceName”: “user-service”,
“ServiceTags”: [],
“ServiceAddress”: “127.0.0.1”,
“ServiceWeights”: {
“Passing”: 1,
“Warning”: 1
},
“ServiceMeta”: {},
“ServicePort”: 8080,
“ServiceEnableTagOverride”: false,
“ServiceProxy”: {},
“ServiceConnect”: {},
“CreateIndex”: 10,
“ModifyIndex”: 10
}
]
风哥风哥提示:服务发现是微服务架构的关键组件,它确保服务能够动态地找到彼此,特别是在容器化环境中。
7. 负载均衡
7.1 客户端负载均衡
@Configuration
public class RibbonConfig {
@Bean
public IRule ribbonRule() {
// 随机负载均衡策略
return new RandomRule();
// 轮询负载均衡策略
// return new RoundRobinRule();
// 加权响应时间负载均衡策略
// return new WeightedResponseTimeRule();
}
}
7.2 服务端负载均衡
upstream user_service {
server user-service-1:8080;
server user-service-2:8080;
server user-service-3:8080;
}
server {
listen 80;
server_name user-service.fgedu.net.cn;
location / {
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
7.3 使用Kubernetes服务进行负载均衡
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
– port: 80
targetPort: 8080
type: ClusterIP
学习交流加群风哥QQ113257174
8. 微服务安全
8.1 认证与授权
import jwt
import datetime
# 生成JWT令牌
def generate_token(user_id):
payload = {
‘user_id’: user_id,
‘exp’: datetime.datetime.utcnow() + datetime.timedelta(hours=24),
‘iat’: datetime.datetime.utcnow()
}
token = jwt.encode(payload, ‘secret_key’, algorithm=’HS256′)
return token
# 验证JWT令牌
def verify_token(token):
try:
payload = jwt.decode(token, ‘secret_key’, algorithms=[‘HS256’])
return payload
except jwt.ExpiredSignatureError:
return None
except jwt.InvalidTokenError:
return None
# 认证中间件
from flask import request, jsonify
def auth_required(f):
def decorated_function(*args, **kwargs):
token = request.headers.get(‘Authorization’)
if not token:
return jsonify({‘error’: ‘Authorization header required’}), 401
token = token.split(‘ ‘)[1] # Bearer token
payload = verify_token(token)
if not payload:
return jsonify({‘error’: ‘Invalid or expired token’}), 401
request.user_id = payload[‘user_id’]
return f(*args, **kwargs)
return decorated_function
# 使用认证中间件
@app.route(‘/protected’, methods=[‘GET’])
@auth_required
def protected():
return jsonify({‘message’: ‘Protected resource’, ‘user_id’: request.user_id})
8.2 服务间安全通信
# 生成证书
$ openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes -subj “/CN=user-service”
# 配置gRPC使用TLS
# 服务端
creds, err := credentials.NewServerTLSFromFile(“server.crt”, “server.key”)
if err != nil {
log.Fatalf(“Failed to generate credentials: %v”, err)
}
s := grpc.NewServer(grpc.Creds(creds))
# 客户端
creds, err := credentials.NewClientTLSFromFile(“server.crt”, “user-service”)
if err != nil {
log.Fatalf(“Failed to generate credentials: %v”, err)
}
conn, err := grpc.Dial(“user-service:50051”, grpc.WithTransportCredentials(creds))
8.3 安全最佳实践
- 使用HTTPS进行所有通信
- 实施最小权限原则
- 定期更新依赖库和框架
- 使用Secret管理敏感信息
- 实施API网关,集中处理认证和授权
- 定期进行安全审计和渗透测试
更多学习教程www.fgedu.net.cn
9. 微服务监控
9.1 分布式追踪
# 安装Jaeger
$ docker run -d –name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:1.22
# 在Spring Boot应用中集成Jaeger
# pom.xml
# application.yml
opentracing:
jaeger:
service-name: user-service
udp-sender:
host: jaeger
port: 6831
9.2 指标监控
# 在Spring Boot应用中集成Prometheus
# pom.xml
# application.yml
management:
endpoints:
web:
exposure:
include: health,info,prometheus
metrics:
tags:
application: ${spring.application.name}
9.3 日志管理
# 安装ELK Stack
$ docker-compose up -d
# docker-compose.yml
version: ‘3’
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
environment:
– discovery.type=single-node
ports:
– 9200:9200
logstash:
image: docker.elastic.co/logstash/logstash:7.14.0
volumes:
– ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
ports:
– 5044:5044
kibana:
image: docker.elastic.co/kibana/kibana:7.14.0
ports:
– 5601:5601
# logstash.conf
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => [“elasticsearch:9200”]
index => “%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}”
}
}
10. 微服务最佳实践
10.1 设计最佳实践
- 服务边界清晰,职责单一
- API设计遵循RESTful原则
- 使用领域驱动设计(DDD)划分服务边界
- 避免服务间的循环依赖
- 合理使用同步和异步通信方式
10.2 部署最佳实践
- 使用容器化部署
- 使用Kubernetes进行容器编排
- 实施CI/CD流水线
- 使用蓝绿部署或金丝雀发布
- 实现自动化测试
10.3 运维最佳实践
- 实施全面的监控和告警
- 建立完善的日志管理系统
- 制定故障应急预案
- 定期进行性能测试和压测
- 建立服务健康检查机制
10.4 团队协作最佳实践
- 采用DevOps文化
- 使用敏捷开发方法
- 建立服务文档规范
- 实施代码审查制度
- 定期进行技术分享和培训
- 从小规模开始,逐步拆分服务
- 建立服务治理平台,统一管理服务
- 实施服务版本控制,确保兼容性
- 建立完善的监控体系,及时发现和解决问题
- 定期进行架构评审,持续优化微服务架构
author:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
