面试题答案
一键面试常见策略和方法
- 重试机制
- 说明:当微服务调用失败时,自动进行重试。可以设置重试次数、重试间隔时间等参数。
- 作用:应对短暂的网络故障、服务过载等临时性问题,避免因偶然因素导致调用失败。
- 熔断机制
- 说明:当微服务调用失败次数达到一定阈值,熔断器开启,后续请求不再调用该服务,直接返回错误。经过一段时间后,熔断器进入半开状态,尝试少量请求,若成功则关闭熔断器恢复正常调用,若失败则继续保持开启状态。
- 作用:防止因某个服务长期不可用,大量无效请求积压导致级联故障。
- 降级处理
- 说明:当服务出现故障或资源紧张时,提供一个兜底的方案,返回简单的、有损的响应。
- 作用:保证核心功能可用,避免因非核心服务故障影响整个系统。
- 异步调用
- 说明:将调用从同步改为异步,调用方无需等待被调用方响应即可继续执行后续逻辑。
- 作用:提高系统的响应速度和吞吐量,避免因等待调用结果而造成线程阻塞。
- 服务发现与注册
- 说明:微服务启动时向服务注册中心注册自己的信息,其他服务通过服务注册中心获取目标服务的地址等信息进行调用。
- 作用:实现服务地址的动态管理,便于服务的扩展和维护。
实际项目运用举例
假设一个电商系统,包含商品服务、库存服务、订单服务。订单服务依赖商品服务获取商品详情,依赖库存服务检查库存。
- 重试机制运用:在订单服务调用商品服务获取商品详情时,如果因网络抖动等原因调用失败,订单服务可设置重试3次,每次重试间隔1秒。代码示例(以Java和Spring Cloud为例):
@FeignClient(name = "product - service")
public interface ProductServiceClient {
@GetMapping("/products/{productId}")
Product getProductById(@PathVariable("productId") Long productId);
}
在配置文件中开启重试:
ribbon:
MaxAutoRetries: 3
MaxAutoRetriesNextServer: 0
OkToRetryOnAllOperations: true
ConnectTimeout: 5000
ReadTimeout: 5000
- 熔断机制运用:当库存服务出现大量超时或错误时,订单服务启用熔断机制。使用Hystrix框架,在订单服务中配置:
@Service
public class InventoryService {
@HystrixCommand(fallbackMethod = "fallbackCheckInventory")
public boolean checkInventory(Long productId, int quantity) {
// 实际调用库存服务检查库存逻辑
}
public boolean fallbackCheckInventory(Long productId, int quantity) {
// 熔断后的兜底逻辑,例如返回库存充足的默认值
return true;
}
}
- 降级处理运用:如果商品服务因高并发出现性能问题,订单服务调用商品服务时进行降级处理。可以返回一个简单的商品信息,告知用户商品信息获取可能不准确。
@FeignClient(name = "product - service", fallback = ProductServiceFallback.class)
public interface ProductServiceClient {
@GetMapping("/products/{productId}")
Product getProductById(@PathVariable("productId") Long productId);
}
@Component
public class ProductServiceFallback implements ProductServiceClient {
@Override
public Product getProductById(Long productId) {
Product fallbackProduct = new Product();
fallbackProduct.setName("商品信息获取失败");
// 设置其他必要的默认属性
return fallbackProduct;
}
}
- 异步调用运用:订单服务创建订单后,需要调用库存服务扣减库存,此调用可改为异步。使用消息队列,订单服务发送扣减库存消息到消息队列,库存服务从消息队列消费消息进行库存扣减。例如使用RabbitMQ: 订单服务发送消息:
@Autowired
private RabbitTemplate rabbitTemplate;
public void createOrder(Order order) {
// 创建订单逻辑
rabbitTemplate.convertAndSend("inventory - queue", order.getProductId() + ":" + order.getQuantity());
}
库存服务消费消息:
@RabbitListener(queues = "inventory - queue")
public void handleInventoryMessage(String message) {
String[] parts = message.split(":");
Long productId = Long.parseLong(parts[0]);
int quantity = Integer.parseInt(parts[1]);
// 扣减库存逻辑
}
- 服务发现与注册运用:商品服务、库存服务、订单服务都注册到Eureka服务注册中心。订单服务启动时,从Eureka获取商品服务和库存服务的地址。在Spring Cloud项目中,各服务在配置文件中配置Eureka客户端:
eureka:
client:
service - url:
defaultZone: http://localhost:8761/eureka/
订单服务通过服务名调用商品服务和库存服务,Ribbon会从Eureka获取服务实例地址进行负载均衡调用:
@Autowired
private RestTemplate restTemplate;
public Product getProductById(Long productId) {
return restTemplate.getForObject("http://product - service/products/" + productId, Product.class);
}
通过以上策略和方法的综合运用,可有效保障微服务架构中服务依赖场景下的稳定性和可靠性。