欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot中5種服務(wù)可用性保障技術(shù)分享

 更新時(shí)間:2025年05月06日 08:52:58   作者:風(fēng)象南  
服務(wù)可用性已成為系統(tǒng)設(shè)計(jì)的核心關(guān)注點(diǎn),SpringBoot作為Java生態(tài)系統(tǒng)中流行的應(yīng)用開發(fā)框架,提供了豐富的工具和庫(kù)來保障服務(wù)的高可用性,本文將介紹SpringBoot中5種關(guān)鍵的服務(wù)可用性保障技術(shù),需要的朋友可以參考下

1. 熔斷器模式(Circuit Breaker)

基本原理

熔斷器模式借鑒了電路熔斷器的概念,當(dāng)檢測(cè)到系統(tǒng)中某個(gè)服務(wù)或組件頻繁失敗時(shí),自動(dòng)"斷開"對(duì)該服務(wù)的調(diào)用,防止級(jí)聯(lián)故障,同時(shí)為故障服務(wù)提供恢復(fù)時(shí)間。熔斷器有三種狀態(tài):

  • 關(guān)閉狀態(tài):正常執(zhí)行操作,同時(shí)監(jiān)控失敗率
  • 開啟狀態(tài):拒絕訪問,直接返回錯(cuò)誤或執(zhí)行降級(jí)邏輯
  • 半開狀態(tài):嘗試恢復(fù),允許有限的請(qǐng)求通過以測(cè)試服務(wù)是否恢復(fù)

SpringBoot實(shí)現(xiàn)與集成

在SpringBoot中,我們可以使用Resilience4j實(shí)現(xiàn)熔斷器模式,它是Hystrix的輕量級(jí)替代方案,專為Java 8和函數(shù)式編程設(shè)計(jì)。

首先添加依賴:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
    <version>1.7.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

然后在application.yml中配置熔斷器參數(shù):

resilience4j:
  circuitbreaker:
    instances:
      orderService:
        registerHealthIndicator: true
        slidingWindowSize: 10
        minimumNumberOfCalls: 5
        permittedNumberOfCallsInHalfOpenState: 3
        automaticTransitionFromOpenToHalfOpenEnabled: true
        waitDurationInOpenState: 5s
        failureRateThreshold: 50
        eventConsumerBufferSize: 10

使用熔斷器的示例代碼:

@Service
public class OrderService {
    
    private final PaymentServiceClient paymentServiceClient;
    
    public OrderService(PaymentServiceClient paymentServiceClient) {
        this.paymentServiceClient = paymentServiceClient;
    }
    
    @CircuitBreaker(name = "orderService", fallbackMethod = "processOrderFallback")
    public OrderResponse processOrder(OrderRequest orderRequest) {
        // 正常的訂單處理邏輯,包括調(diào)用支付服務(wù)
        PaymentResponse paymentResponse = paymentServiceClient.processPayment(orderRequest.getPaymentDetails());
        return new OrderResponse(orderRequest.getOrderId(), "PROCESSED", paymentResponse.getTransactionId());
    }
    
    // 降級(jí)方法,在熔斷器觸發(fā)時(shí)執(zhí)行
    public OrderResponse processOrderFallback(OrderRequest orderRequest, Exception e) {
        log.error("Circuit breaker triggered for order: {}. Error: {}", orderRequest.getOrderId(), e.getMessage());
        // 返回降級(jí)響應(yīng),可能是從本地緩存獲取,或使用默認(rèn)值
        return new OrderResponse(orderRequest.getOrderId(), "PENDING", null);
    }
}

最佳實(shí)踐

  • 適當(dāng)?shù)拇翱诖笮?/strong>:設(shè)置合理的slidingWindowSize,太小可能導(dǎo)致熔斷器過于敏感,太大則反應(yīng)遲鈍。
  • 合理的閾值:根據(jù)業(yè)務(wù)需求設(shè)置failureRateThreshold,一般建議在50%-60%之間。
  • 監(jiān)控熔斷器狀態(tài):集成Spring Boot Actuator監(jiān)控熔斷器狀態(tài):
management:
  endpoints:
    web:
      exposure:
        include: health,circuitbreakers
  health:
    circuitbreakers:
      enabled: true
  • 細(xì)粒度熔斷:為不同的服務(wù)依賴配置不同的熔斷器實(shí)例,避免一個(gè)服務(wù)故障影響多個(gè)業(yè)務(wù)流程。
  • 測(cè)試熔斷行為:通過混沌測(cè)試驗(yàn)證熔斷器在故障情況下的行為是否符合預(yù)期。

2. 限流技術(shù)(Rate Limiting)

基本原理

限流用于控制系統(tǒng)的請(qǐng)求處理速率,防止系統(tǒng)過載。常見的限流算法包括:

  • 令牌桶:以固定速率向桶中添加令牌,請(qǐng)求需要消耗令牌才能被處理。
  • 漏桶:請(qǐng)求以固定速率處理,超出部分排隊(duì)或拒絕。
  • 計(jì)數(shù)器:在固定時(shí)間窗口內(nèi)限制請(qǐng)求數(shù)量。

SpringBoot實(shí)現(xiàn)與集成

在SpringBoot中,我們可以使用Bucket4j實(shí)現(xiàn)API限流,這是一個(gè)基于令牌桶算法的Java限流庫(kù)。

添加依賴:

<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>4.10.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

配置緩存和限流:

@Configuration
public class RateLimitingConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager("rateLimit");
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(1, TimeUnit.HOURS)
                .maximumSize(1000));
        return cacheManager;
    }
    
    @Bean
    public Bucket4jCacheConfiguration bucket4jCacheConfiguration() {
        return new Bucket4jCacheConfiguration(cacheManager(), "rateLimit");
    }
}

實(shí)現(xiàn)限流攔截器:

@Component
public class RateLimitingInterceptor implements HandlerInterceptor {

    private final Cache<String, Bucket> cache;
    
    public RateLimitingInterceptor() {
        this.cache = Caffeine.newBuilder()
                .expireAfterWrite(1, TimeUnit.HOURS)
                .maximumSize(1000)
                .build();
    }
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String apiKey = request.getHeader("X-API-KEY");
        if (apiKey == null || apiKey.isEmpty()) {
            response.sendError(HttpStatus.BAD_REQUEST.value(), "Missing API key");
            return false;
        }
        
        Bucket bucket = cache.get(apiKey, key -> createNewBucket());
        ConsumptionProbe probe = bucket.tryConsumeAndReturnRemaining(1);
        
        if (probe.isConsumed()) {
            response.addHeader("X-Rate-Limit-Remaining", String.valueOf(probe.getRemainingTokens()));
            return true;
        } else {
            long waitForRefill = probe.getNanosToWaitForRefill() / 1_000_000_000;
            response.addHeader("X-Rate-Limit-Retry-After-Seconds", String.valueOf(waitForRefill));
            response.sendError(HttpStatus.TOO_MANY_REQUESTS.value(), "Rate limit exceeded");
            return false;
        }
    }
    
    private Bucket createNewBucket() {
        BucketConfiguration config = Bucket4j.configurationBuilder()
                .addLimit(Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1))))
                .addLimit(Bandwidth.classic(1000, Refill.intervally(1000, Duration.ofHours(1))))
                .build();
        return Bucket4j.builder().withConfiguration(config).build();
    }
}

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private RateLimitingInterceptor rateLimitingInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(rateLimitingInterceptor)
                .addPathPatterns("/api/**");
    }
}

在Spring Cloud Gateway中實(shí)現(xiàn)限流:

spring:
  cloud:
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/orders/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
                redis-rate-limiter.requestedTokens: 1
                key-resolver: "#{@userKeyResolver}"
@Configuration
public class GatewayConfig {
    
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> {
            String userId = exchange.getRequest().getHeaders().getFirst("User-Id");
            if (userId == null) {
                userId = "anonymous";
            }
            return Mono.just(userId);
        };
    }
}

最佳實(shí)踐

  • 分級(jí)限流:基于不同用戶類型或API重要性設(shè)置不同的限流閾值。
  • 應(yīng)用多級(jí)限流:例如,同時(shí)應(yīng)用用戶級(jí)、IP級(jí)和全局級(jí)限流。
  • 限流響應(yīng):在限流觸發(fā)時(shí)返回合適的HTTP狀態(tài)碼(通常是429)和明確的錯(cuò)誤信息,包括重試建議。
  • 監(jiān)控限流指標(biāo):收集限流指標(biāo),用于分析和調(diào)整限流策略。
  • 優(yōu)雅降級(jí):當(dāng)達(dá)到限流閾值時(shí),考慮提供降級(jí)服務(wù)而非完全拒絕。

3. 服務(wù)降級(jí)與容錯(cuò)處理

基本原理

服務(wù)降級(jí)是一種在系統(tǒng)高負(fù)載或部分服務(wù)不可用時(shí),通過提供有限但可接受的服務(wù)來維持系統(tǒng)整體可用性的策略。容錯(cuò)處理則是指系統(tǒng)能夠檢測(cè)并處理錯(cuò)誤,同時(shí)繼續(xù)正常運(yùn)行的能力。

SpringBoot實(shí)現(xiàn)與集成

在SpringBoot中,服務(wù)降級(jí)可以通過多種方式實(shí)現(xiàn),包括與熔斷器結(jié)合、使用異步回退,以及實(shí)現(xiàn)超時(shí)控制。

使用Resilience4j的Fallback實(shí)現(xiàn)服務(wù)降級(jí):

@Service
public class ProductService {
    
    private final ProductRepository productRepository;
    private final ProductCacheService productCacheService;
    
    @Autowired
    public ProductService(ProductRepository productRepository, ProductCacheService productCacheService) {
        this.productRepository = productRepository;
        this.productCacheService = productCacheService;
    }
    
    @CircuitBreaker(name = "productService", fallbackMethod = "getProductDetailsFallback")
    @Bulkhead(name = "productService", fallbackMethod = "getProductDetailsFallback")
    @TimeLimiter(name = "productService", fallbackMethod = "getProductDetailsFallback")
    public CompletableFuture<ProductDetails> getProductDetails(String productId) {
        return CompletableFuture.supplyAsync(() -> {
            // 正常的產(chǎn)品詳情獲取邏輯
            Product product = productRepository.findById(productId)
                    .orElseThrow(() -> new ProductNotFoundException(productId));
            
            // 獲取實(shí)時(shí)庫(kù)存和價(jià)格信息
            InventoryInfo inventory = inventoryService.getInventory(productId);
            PricingInfo pricing = pricingService.getCurrentPrice(productId);
            
            return new ProductDetails(product, inventory, pricing);
        });
    }
    
    // 降級(jí)方法,提供基本產(chǎn)品信息和緩存的庫(kù)存和價(jià)格
    public CompletableFuture<ProductDetails> getProductDetailsFallback(String productId, Exception e) {
        log.warn("Fallback for product {}. Reason: {}", productId, e.getMessage());
        return CompletableFuture.supplyAsync(() -> {
            // 從緩存獲取基本產(chǎn)品信息
            Product product = productCacheService.getProductFromCache(productId)
                    .orElse(new Product(productId, "Unknown Product", "No details available"));
            
            // 使用默認(rèn)的庫(kù)存和價(jià)格信息
            InventoryInfo inventory = new InventoryInfo(productId, 0, false);
            PricingInfo pricing = new PricingInfo(productId, 0.0, false);
            
            return new ProductDetails(product, inventory, pricing, true);
        });
    }
}

配置超時(shí)和服務(wù)隔離:

resilience4j:
  timelimiter:
    instances:
      productService:
        timeoutDuration: 2s
        cancelRunningFuture: true
  bulkhead:
    instances:
      productService:
        maxConcurrentCalls: 20
        maxWaitDuration: 500ms

實(shí)現(xiàn)優(yōu)雅降級(jí)策略的過濾器:

@Component
public class GracefulDegradationFilter extends OncePerRequestFilter {
    
    private final HealthCheckService healthCheckService;
    
    @Autowired
    public GracefulDegradationFilter(HealthCheckService healthCheckService) {
        this.healthCheckService = healthCheckService;
    }
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                  FilterChain filterChain) throws ServletException, IOException {
        
        String path = request.getRequestURI();
        
        // 檢查系統(tǒng)健康狀態(tài)
        SystemHealth health = healthCheckService.getCurrentHealth();
        
        if (health.isHighLoad() && isNonCriticalPath(path)) {
            // 在高負(fù)載下降級(jí)非關(guān)鍵路徑請(qǐng)求
            sendDegradedResponse(response, "Service temporarily operating at reduced capacity");
            return;
        } else if (health.isInMaintenance() && !isAdminPath(path)) {
            // 在維護(hù)模式下只允許管理請(qǐng)求
            sendMaintenanceResponse(response);
            return;
        } else if (health.hasFailedDependencies() && dependsOnFailedServices(path, health.getFailedServices())) {
            // 如果請(qǐng)求依賴的服務(wù)不可用,返回降級(jí)響應(yīng)
            sendDependencyFailureResponse(response, health.getFailedServices());
            return;
        }
        
        // 正常處理請(qǐng)求
        filterChain.doFilter(request, response);
    }
    
    private boolean isNonCriticalPath(String path) {
        // 判斷請(qǐng)求是否是非關(guān)鍵路徑
        return path.startsWith("/api/recommendations") || 
               path.startsWith("/api/analytics") ||
               path.startsWith("/api/marketing");
    }
    
    private boolean isAdminPath(String path) {
        return path.startsWith("/admin") || path.startsWith("/management");
    }
    
    private boolean dependsOnFailedServices(String path, List<String> failedServices) {
        // 檢查請(qǐng)求是否依賴失敗的服務(wù)
        Map<String, List<String>> serviceDependencies = new HashMap<>();
        serviceDependencies.put("/api/orders", Arrays.asList("payment-service", "inventory-service"));
        serviceDependencies.put("/api/payments", Arrays.asList("payment-service"));
        // ... 其他路徑與服務(wù)的依賴關(guān)系
        
        String matchingPath = findMatchingPath(path, serviceDependencies.keySet());
        if (matchingPath != null) {
            List<String> dependencies = serviceDependencies.get(matchingPath);
            return dependencies.stream().anyMatch(failedServices::contains);
        }
        return false;
    }
    
    private String findMatchingPath(String requestPath, Set<String> configuredPaths) {
        // 查找請(qǐng)求路徑匹配的配置路徑
        return configuredPaths.stream()
                .filter(requestPath::startsWith)
                .findFirst()
                .orElse(null);
    }
    
    private void sendDegradedResponse(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        
        Map<String, Object> responseBody = new HashMap<>();
        responseBody.put("status", "degraded");
        responseBody.put("message", message);
        responseBody.put("retry_after", 30); // 建議30秒后重試
        
        response.getWriter().write(new ObjectMapper().writeValueAsString(responseBody));
    }
    
    // 其他響應(yīng)處理方法...
}

最佳實(shí)踐

  • 分級(jí)降級(jí)策略:針對(duì)不同的故障場(chǎng)景和服務(wù)重要性制定分級(jí)降級(jí)策略。
  • 靜態(tài)降級(jí):預(yù)先準(zhǔn)備好靜態(tài)資源或緩存數(shù)據(jù),在服務(wù)不可用時(shí)使用。
  • 功能降級(jí):暫時(shí)關(guān)閉非核心功能,保證核心業(yè)務(wù)正常。
  • 特定用戶群體降級(jí):在高負(fù)載情況下,優(yōu)先保證VIP用戶的體驗(yàn)。
  • 服務(wù)隔離:使用Bulkhead模式隔離不同服務(wù)的資源,防止一個(gè)服務(wù)的問題影響其他服務(wù)。
  • 超時(shí)控制:設(shè)置合理的超時(shí)時(shí)間,防止長(zhǎng)時(shí)間等待影響用戶體驗(yàn)。

4. 重試機(jī)制(Retry)

基本原理

重試機(jī)制用于處理暫時(shí)性故障,通過自動(dòng)重新嘗試失敗的操作來提高系統(tǒng)的彈性。對(duì)于網(wǎng)絡(luò)抖動(dòng)、數(shù)據(jù)庫(kù)臨時(shí)不可用等場(chǎng)景尤其有效。

SpringBoot實(shí)現(xiàn)與集成

SpringBoot中可以使用Spring Retry庫(kù)實(shí)現(xiàn)重試功能。

添加依賴:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

啟用重試功能:

@SpringBootApplication
@EnableRetry
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

使用聲明式重試:

@Service
public class RemoteServiceClient {
    
    private final RestTemplate restTemplate;
    
    @Autowired
    public RemoteServiceClient(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    
    @Retryable(
        value = {ResourceAccessException.class, HttpServerErrorException.class},
        maxAttempts = 3,
        backoff = @Backoff(delay = 1000, multiplier = 2)
    )
    public ResponseEntity<OrderData> getOrderDetails(String orderId) {
        log.info("Attempting to fetch order details for {}", orderId);
        return restTemplate.getForEntity("/api/orders/" + orderId, OrderData.class);
    }
    
    @Recover
    public ResponseEntity<OrderData> recoverGetOrderDetails(Exception e, String orderId) {
        log.error("All retries failed for order {}. Last error: {}", orderId, e.getMessage());
        // 返回緩存數(shù)據(jù)或默認(rèn)響應(yīng)
        return ResponseEntity.ok(new OrderData(orderId, "UNKNOWN", new Date(), Collections.emptyList()));
    }
}

使用編程式重試:

@Service
public class PaymentService {
    
    private final RetryTemplate retryTemplate;
    
    @Autowired
    public PaymentService(RetryTemplate retryTemplate) {
        this.retryTemplate = retryTemplate;
    }
    
    public PaymentResult processPayment(PaymentRequest paymentRequest) {
        return retryTemplate.execute(context -> {
            // 獲取當(dāng)前重試次數(shù)
            int retryCount = context.getRetryCount();
            log.info("Processing payment attempt {} for order {}", 
                     retryCount + 1, paymentRequest.getOrderId());
            
            try {
                // 執(zhí)行支付處理
                return paymentGateway.submitPayment(paymentRequest);
            } catch (PaymentGatewayException e) {
                // 分析異常并決定是否重試
                if (e.isRetryable()) {
                    log.warn("Retryable payment error: {}. Will retry.", e.getMessage());
                    throw e; // 拋出異常以觸發(fā)重試
                } else {
                    log.error("Non-retryable payment error: {}", e.getMessage());
                    throw new NonRetryableException("Payment failed with non-retryable error", e);
                }
            }
        }, context -> {
            // 恢復(fù)策略
            log.error("All payment retries failed for order {}", paymentRequest.getOrderId());
            // 返回失敗結(jié)果并記錄需要后續(xù)處理
            return PaymentResult.failed(paymentRequest.getOrderId(), "Maximum retries exceeded");
        });
    }
}

@Configuration
public class RetryConfig {
    
    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        
        // 設(shè)置重試策略
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3);
        
        // 設(shè)置退避策略
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(1000); // 1秒
        backOffPolicy.setMultiplier(2.0);       // 每次失敗后等待時(shí)間翻倍
        backOffPolicy.setMaxInterval(10000);    // 最長(zhǎng)等待10秒
        
        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        
        return retryTemplate;
    }
}

結(jié)合Resilience4j的重試功能:

resilience4j.retry:
  instances:
    paymentService:
      maxRetryAttempts: 3
      waitDuration: 1s
      enableExponentialBackoff: true
      exponentialBackoffMultiplier: 2
      retryExceptions:
        - org.springframework.web.client.ResourceAccessException
        - com.example.service.exception.TemporaryServiceException
@Service
public class PaymentServiceWithResilience4j {
    
    private final PaymentGateway paymentGateway;
    
    @Autowired
    public PaymentServiceWithResilience4j(PaymentGateway paymentGateway) {
        this.paymentGateway = paymentGateway;
    }
    
    @Retry(name = "paymentService", fallbackMethod = "processPaymentFallback")
    public PaymentResult processPayment(PaymentRequest request) {
        return paymentGateway.submitPayment(request);
    }
    
    public PaymentResult processPaymentFallback(PaymentRequest request, Exception e) {
        log.error("Payment processing failed after retries for order: {}", request.getOrderId());
        return PaymentResult.failed(request.getOrderId(), "Payment processing temporarily unavailable");
    }
}

最佳實(shí)踐

  • 區(qū)分暫時(shí)性和永久性故障:只對(duì)暫時(shí)性故障進(jìn)行重試,對(duì)永久性故障立即失敗。
  • 指數(shù)退避:使用指數(shù)退避策略,避免重試風(fēng)暴。
  • 合理的重試次數(shù):設(shè)置適當(dāng)?shù)淖畲笾卦嚧螖?shù),通常3-5次。
  • 重試后監(jiān)控:記錄重試次數(shù)和結(jié)果,幫助識(shí)別問題服務(wù)。
  • 冪等操作:確保被重試的操作是冪等的,以避免重復(fù)處理導(dǎo)致的問題。
  • 設(shè)置超時(shí):每次重試都應(yīng)該有合理的超時(shí)時(shí)間。
  • 與熔斷器結(jié)合:將重試機(jī)制與熔斷器結(jié)合使用,當(dāng)故障持續(xù)存在時(shí)快速失敗。

5. 健康檢查與監(jiān)控(Health Checks and Monitoring)

基本原理

健康檢查和監(jiān)控是保障服務(wù)可用性的基礎(chǔ)設(shè)施,用于實(shí)時(shí)了解系統(tǒng)狀態(tài),及早發(fā)現(xiàn)并解決問題。通過系統(tǒng)指標(biāo)收集、健康狀態(tài)檢查和警報(bào)機(jī)制,可以提前預(yù)防或快速解決服務(wù)故障。

SpringBoot實(shí)現(xiàn)與集成

SpringBoot Actuator提供了豐富的監(jiān)控和管理功能,可以輕松集成到應(yīng)用中。

添加依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

配置Actuator端點(diǎn):

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus,loggers,env
  endpoint:
    health:
      show-details: always
      group:
        readiness:
          include: db,redis,rabbit,diskSpace
  health:
    circuitbreakers:
      enabled: true
    ratelimiters:
      enabled: true
  metrics:
    export:
      prometheus:
        enabled: true
    enable:
      jvm: true
      system: true
      process: true
      http: true

自定義健康檢查器:

@Component
public class ExternalServiceHealthIndicator implements HealthIndicator {
    
    private final RestTemplate restTemplate;
    
    @Autowired
    public ExternalServiceHealthIndicator(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    
    @Override
    public Health health() {
        try {
            // 檢查外部服務(wù)健康狀態(tài)
            ResponseEntity<Map> response = restTemplate.getForEntity("https://api.external-service.com/health", Map.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                return Health.up()
                        .withDetail("status", response.getBody().get("status"))
                        .withDetail("version", response.getBody().get("version"))
                        .build();
            } else {
                return Health.down()
                        .withDetail("statusCode", response.getStatusCodeValue())
                        .withDetail("reason", "Unexpected status code")
                        .build();
            }
        } catch (Exception e) {
            return Health.down()
                    .withDetail("error", e.getMessage())
                    .build();
        }
    }
}

配置應(yīng)用就緒探針和活性探針:

@Configuration
public class HealthCheckConfig {
    
    @Bean
    public HealthContributorRegistry healthContributorRegistry(
            ApplicationAvailabilityBean availabilityBean) {
        
        HealthContributorRegistry registry = new DefaultHealthContributorRegistry();
        
        // 添加應(yīng)用啟動(dòng)完成的就緒檢查
        registry.registerContributor("readiness", new ApplicationAvailabilityHealthIndicator(
                availabilityBean, ApplicationAvailabilityBean.LivenessState.CORRECT));
        
        // 添加應(yīng)用正在運(yùn)行的活性檢查
        registry.registerContributor("liveness", new ApplicationAvailabilityHealthIndicator(
                availabilityBean, ApplicationAvailabilityBean.ReadinessState.ACCEPTING_TRAFFIC));
        
        return registry;
    }
}

自定義指標(biāo)收集:

@Component
public class OrderMetrics {
    
    private final MeterRegistry meterRegistry;
    private final Counter orderCounter;
    private final DistributionSummary orderAmountSummary;
    private final Timer orderProcessingTimer;
    
    public OrderMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        this.orderCounter = Counter.builder("orders.created")
                .description("Number of orders created")
                .tag("application", "order-service")
                .register(meterRegistry);
        
        this.orderAmountSummary = DistributionSummary.builder("orders.amount")
                .description("Order amount distribution")
                .tag("application", "order-service")
                .publishPercentiles(0.5, 0.95, 0.99)
                .register(meterRegistry);
        
        this.orderProcessingTimer = Timer.builder("orders.processing.time")
                .description("Order processing time")
                .tag("application", "order-service")
                .publishPercentiles(0.5, 0.95, 0.99)
                .register(meterRegistry);
    }
    
    public void recordOrderCreated(String orderType) {
        orderCounter.increment();
        meterRegistry.counter("orders.created.by.type", "type", orderType).increment();
    }
    
    public void recordOrderAmount(double amount) {
        orderAmountSummary.record(amount);
    }
    
    public Timer.Sample startOrderProcessing() {
        return Timer.start(meterRegistry);
    }
    
    public void endOrderProcessing(Timer.Sample sample) {
        sample.stop(orderProcessingTimer);
    }
}

@Service
public class OrderServiceWithMetrics {
    
    private final OrderRepository orderRepository;
    private final OrderMetrics orderMetrics;
    
    @Autowired
    public OrderServiceWithMetrics(OrderRepository orderRepository, OrderMetrics orderMetrics) {
        this.orderRepository = orderRepository;
        this.orderMetrics = orderMetrics;
    }
    
    public Order createOrder(OrderRequest request) {
        Timer.Sample timer = orderMetrics.startOrderProcessing();
        
        try {
            Order order = new Order();
            // 處理訂單
            order.setItems(request.getItems());
            order.setTotalAmount(calculateTotalAmount(request.getItems()));
            order.setType(request.getType());
            
            Order savedOrder = orderRepository.save(order);
            
            // 記錄指標(biāo)
            orderMetrics.recordOrderCreated(order.getType());
            orderMetrics.recordOrderAmount(order.getTotalAmount());
            
            return savedOrder;
        } finally {
            orderMetrics.endOrderProcessing(timer);
        }
    }
    
    private double calculateTotalAmount(List<OrderItem> items) {
        // 計(jì)算總金額
        return items.stream()
                .mapToDouble(item -> item.getPrice() * item.getQuantity())
                .sum();
    }
}

集成Grafana和Prometheus監(jiān)控:

# docker-compose.yml
version: '3.8'
services:
  app:
    image: my-spring-boot-app:latest
    ports:
      - "8080:8080"
    
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    
  grafana:
    image: grafana/grafana:latest
    depends_on:
      - prometheus
    ports:
      - "3000:3000"
    volumes:
      - grafana-storage:/var/lib/grafana
    
volumes:
  grafana-storage:
# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'spring-boot-app'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['app:8080']

最佳實(shí)踐

  • 多層次健康檢查:實(shí)現(xiàn)淺層和深層健康檢查,前者快速響應(yīng),后者全面檢查。
  • 關(guān)鍵業(yè)務(wù)指標(biāo)監(jiān)控:監(jiān)控關(guān)鍵業(yè)務(wù)指標(biāo),如訂單數(shù)量、轉(zhuǎn)化率等。
  • 系統(tǒng)資源監(jiān)控:監(jiān)控CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)等系統(tǒng)資源。
  • 設(shè)置合理的警報(bào)閾值:基于業(yè)務(wù)重要性和系統(tǒng)特性設(shè)置警報(bào)閾值。
  • 關(guān)聯(lián)分析:將不同服務(wù)的指標(biāo)關(guān)聯(lián)起來,便于問題根因分析。
  • 日志與指標(biāo)結(jié)合:將日志和指標(biāo)結(jié)合起來,提供更完整的系統(tǒng)視圖。
  • 預(yù)測(cè)性監(jiān)控:使用趨勢(shì)分析預(yù)測(cè)潛在問題,如磁盤空間預(yù)測(cè)用盡時(shí)間。

總結(jié)

本文介紹了SpringBoot中5種核心的服務(wù)可用性保障技術(shù):熔斷器模式、限流技術(shù)、服務(wù)降級(jí)與容錯(cuò)處理、重試機(jī)制以及健康檢查與監(jiān)控。這些技術(shù)不是孤立的,而是相互配合、協(xié)同工作,共同構(gòu)建起應(yīng)用的防御體系。

以上就是SpringBoot中5種服務(wù)可用性保障技術(shù)分享的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot服務(wù)可用性保障技術(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置

    java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置

    本文給大家匯總介紹了2種分別使用新浪和淘寶接口,實(shí)現(xiàn)根據(jù)IP地址獲取詳細(xì)的地理位置的代碼,非常的實(shí)用,有需要的小伙伴可以參考下。
    2016-03-03
  • Java線程中的ThreadLocal類解讀

    Java線程中的ThreadLocal類解讀

    這篇文章主要介紹了Java線程中的ThreadLocal類解讀,ThreadLocal是一個(gè)泛型類,作用是實(shí)現(xiàn)線程隔離,ThreadLocal類型的變量,在每個(gè)線程中都會(huì)對(duì)應(yīng)一個(gè)具體對(duì)象,對(duì)象類型需要在聲明ThreadLocal變量時(shí)指定,需要的朋友可以參考下
    2023-11-11
  • SpringBoot事件發(fā)布與監(jiān)聽超詳細(xì)講解

    SpringBoot事件發(fā)布與監(jiān)聽超詳細(xì)講解

    今天去官網(wǎng)查看spring boot資料時(shí),在特性中看見了系統(tǒng)的事件及監(jiān)聽章節(jié),所以下面這篇文章主要給大家介紹了關(guān)于SpringBoot事件發(fā)布和監(jiān)聽的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • Java SE使用數(shù)組實(shí)現(xiàn)高速數(shù)字轉(zhuǎn)換功能

    Java SE使用數(shù)組實(shí)現(xiàn)高速數(shù)字轉(zhuǎn)換功能

    隨著大數(shù)據(jù)時(shí)代的到來,數(shù)字轉(zhuǎn)換功能變得越來越重要,在Java開發(fā)中,數(shù)字轉(zhuǎn)換功能也是經(jīng)常用到的,下面我們就來學(xué)習(xí)一下如何使用Java SE數(shù)組實(shí)現(xiàn)高速的數(shù)字轉(zhuǎn)換功能吧
    2023-11-11
  • 淺析Mysql中的視圖

    淺析Mysql中的視圖

    這篇文章主要介紹了淺析Mysql中的視圖,視圖是從一個(gè)或者多個(gè)表中導(dǎo)出的表,視圖的行為與表非常相似,在視圖中用戶可以使用SELECT語句查詢數(shù)據(jù),以及使用INSERT、UPDATE和DELETE修改記錄,需要的朋友可以參考下
    2023-05-05
  • 深入講解SpringBoot Actuator是什么

    深入講解SpringBoot Actuator是什么

    Spring Boot Actuator提供了生產(chǎn)上經(jīng)常用到的功能(如健康檢查,審計(jì),指標(biāo)收集,HTTP跟蹤等),幫助我們監(jiān)控和管理Spring Boot應(yīng)用程序。這些功能都可以通過JMX或HTTP端點(diǎn)訪問
    2023-01-01
  • Java通過notify和wait實(shí)現(xiàn)線程間的通信功能

    Java通過notify和wait實(shí)現(xiàn)線程間的通信功能

    在軟件開發(fā)中,線程是實(shí)現(xiàn)并發(fā)執(zhí)行的重要手段,然而,線程之間的協(xié)作與通信卻是開發(fā)者必須重點(diǎn)考慮的挑戰(zhàn)之一,Java作為一種廣泛應(yīng)用于多線程編程的語言,本文將深入探討Java中通過notify和wait實(shí)現(xiàn)線程間通信的機(jī)制,需要的朋友可以參考下
    2024-06-06
  • 基于Java創(chuàng)建XML(無中文亂碼)過程解析

    基于Java創(chuàng)建XML(無中文亂碼)過程解析

    這篇文章主要介紹了基于Java創(chuàng)建XML(無中文亂碼)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(3)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(3)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼

    SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼

    這篇文章主要介紹了SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評(píng)論