一、微服务架构核心概念
1.1 什么是微服务
传统架构:All in One
├── 前端应用
├── 后端应用
├── 数据库
└── 全部部署在同一台服务器
微服务架构:
├── 服务A(用户服务)
├── 服务B(订单服务)
├── 服务C(商品服务)
├── 服务D(支付服务)
└── 消息队列 + 注册中心 + 配置中心
1.2 微服务优势
| 优势 | 说明 |
|---|---|
| 独立部署 | 每个服务可独立发布,不用影响其他服务 |
| 技术异构 | 不同服务可用不同技术栈 |
| 容错隔离 | 一个服务挂了不影响其他服务 |
| 可扩展 | 按需扩展瓶颈服务 |
二、Eureka服务注册与发现
2.1 Eureka架构
┌─────────────┐
│ Eureka Server │ ← 注册中心
└───────┬───────┘
│注册/发现
▼
┌───────────────┐
│ Provider服务提供者 │ ← 启动时注册自己的地址
└───────────────┘
│
▼
┌───────────────┐
│ Consumer服务消费者 │ ← 从注册中心获取地址列表
└───────────────┘
2.2 服务端配置
yaml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
server:
enable-self-preservation: false
2.3 客户端配置
yaml
spring:
application:
name: user-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
lease-renewal-interval-in-seconds: 10
lease-expiration-duration-in-seconds: 30
三、Ribbon负载均衡
3.1 Ribbon核心组件
java
public interface IRule {
public Server choose(Object key);
}
Ribbon负载均衡策略:
| 策略 | 类名 | 原理 |
|---|---|---|
| 轮询 | RoundRobinRule | 依次选择 |
| 随机 | RandomRule | 随机选择 |
| 重试 | RetryRule | 轮询失败后重试 |
| 响应时间权重 | WeightedResponseTimeRule | 响应时间越短权重越高 |
| 最佳可用 | BestAvailableRule | 选择并发最低的 |
3.2 自定义负载均衡策略
java
public class MyRule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsServerList(ILoadBalancer lb) {}
@Override
public Server choose(Object key) {
ILoadBalancer balancer = getLoadBalancer();
List<Server> servers = balancer.getReachableServers();
return servers.get(servers.size() - 1);
}
}
@Configuration
public class MyRibbonConfig {
@Bean
public IRule myRule() {
return new MyRule();
}
}
四、Feign声明式HTTP客户端
4.1 Feign_vs_Ribbon
| 对比 | Ribbon | Feign |
|---|---|---|
| 调用方式 | RestTemplate | 接口+注解 |
| 代码量 | 多 | 少 |
| 可读性 | 差 | 好 |
4.2 Feign使用
步骤1:引入依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
步骤2:开启Feign
java
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
步骤3:定义调用接口
java
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/user/{id}")
User getUserById(@PathVariable("id") Long id);
@PostMapping("/user")
User createUser(@RequestBody User user);
}
@Component
public class UserClientFallback implements UserClient {
@Override
public User getUserById(Long id) {
return new User(-1L, "默认用户");
}
@Override
public User createUser(User user) {
return null;
}
}
4.3 Feign超时配置
yaml
feign:
client:
config:
default:
connect-timeout: 5000
read-timeout: 5000
五、Hystrix服务降级熔断
5.1 为什么需要Hystrix
用户 → 订单服务 → 用户服务
↓
用户服务挂了
↓
请求堆积,拖垮订单服务
↓
整个系统雪崩
5.2 Hystrix降级
java
@Service
public class UserService {
@HystrixCommand(fallbackMethod = "getUserFallback")
public User getUserById(Long id) {
return userClient.getUserById(id);
}
public User getUserFallback(Long id) {
return new User(-1L, "服务繁忙,请稍后再试");
}
}
5.3 Hystrix熔断配置
yaml
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
circuitBreaker:
requestVolumeThreshold: 20
errorThresholdPercentage: 50
sleepWindowInMilliseconds: 5000
熔断器三种状态:
Closed(关闭)→ 熔断打开 → Open(打开)
↑ ↓
└──── 过了熔断时间 ←───┘
Closed:正常调用
Open:请求直接降级,不调用服务
Half-Open:尝试放行一个请求测试
六、Gateway网关
6.1 Gateway_vs_Zuul
| 对比 | Gateway | Zuul |
|---|---|---|
| 底层 | WebFlux(非阻塞) | Servlet(阻塞) |
| 性能 | 高 | 一般 |
| SpringCloud版本 | Finchley+ | Edgware及以前 |
6.2 Gateway配置
yaml
spring:
cloud:
gateway:
routes:
- id: user-route
uri: lb://user-service
predicates:
- Path=/user/**
filters:
- StripPrefix=1
6.3 全局过滤器
java
@Component
public class AuthFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (StringUtils.isBlank(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
}
七、Config配置中心
7.1 配置中心架构
┌─────────────┐
│ Git仓库 │ ← 配置文件存储
└──────┬──────┘
│
▼
┌─────────────┐
│ Config Server│ ← 配置中心服务
└──────┬──────┘
│
▼
┌─────────────┐
│ 业务服务 │ ← 启动时拉取配置
7.2 配置中心使用
Config Server:
yaml
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/xxx/config-repo
default-label: master
search-paths: config
业务服务:
yaml
spring:
cloud:
config:
name: user-service
profile: dev
label: master
discovery:
enabled: true
service-id: config-server
7.3 配置刷新
java
@RestController
@RefreshScope
public class UserController {
@Value("${user.max-size}")
private int maxSize;
@GetMapping("/config")
public String getConfig() {
return "maxSize = " + maxSize;
}
}
总结
| 组件 | 作用 | 关键词 |
|---|---|---|
| Eureka | 服务注册发现 | 心跳机制 |
| Ribbon | 负载均衡 | 轮询/随机/重试 |
| Feign | 声明式HTTP | 接口+注解 |
| Hystrix | 降级熔断 | 线程隔离/熔断器 |
| Gateway | 网关路由 | 断言/过滤器 |
| Config | 配置中心 | Git集成/自动刷新 |