一、服務註冊與發現:Nacos

組件定位:微服務架構裏的“服務通訊錄+配置大管家”,是整個服務體系的基礎。

核心價值:主要解決兩個頭疼問題——一是服務間“找誰通話”的問題:服務提供方啓動後會自動把自己的地址信息登記到Nacos上,消費方不用死記硬背對方地址,隨時能查到可用的服務實例;二是配置“散養難管”的問題:把多個服務共用的配置集中放在這裏管,還能按開發、測試、生產等環境分開存,改配置不用挨個服務改。而且它能把這些數據存起來不會丟,從根上解決了服務地址寫死、配置到處藏的麻煩。

1.1 Nacos部署詳解

MySQL表準備

Nacos支持將配置數據持久化到MySQL,需要先創建相關表結構:

-- 創建nacos數據庫
CREATE DATABASE nacos CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 使用nacos官方提供的SQL腳本創建表
-- 腳本位置:nacos/conf/nacos-mysql.sql

配置文件詳解

custom.env文件配置示例:

# 單機模式運行
MODE=standalone
# 使用MySQL作為數據源
SPRING_DATASOURCE_PLATFORM=mysql
# MySQL連接配置
MYSQL_SERVICE_HOST=192.168.150.101
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_DB_NAME=nacos
MYSQL_SERVICE_USER=root
MYSQL_SERVICE_PASSWORD=123456
# 連接池配置
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false

1.2 服務註冊與發現機制

服務提供方 vs 消費方配置差異

雖然雙方都配置了Nacos地址,但實際作用不同:

服務提供方

spring:
  application:
    name: item-service
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848
      discovery:
        # 服務註冊配置
        namespace: public
        group: DEFAULT_GROUP
        # 心跳間隔,默認5秒
        heart-beat-interval: 5000
        # 健康檢查超時時間,默認15秒
        heart-beat-timeout: 15000

服務消費方

spring:
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848
      discovery:
        # 服務發現配置
        server-addr: 192.168.150.101:8848
        # 命名空間隔離
        namespace: public
        # 服務分組
        group: DEFAULT_GROUP

核心區別

  • 提供方:註冊自身實例信息到Nacos
  • 消費方:從Nacos訂閲服務列表,獲取可用實例

二、服務調用:OpenFeign

組件定位:微服務之間的“智能通信秘書”,專門簡化服務間的HTTP調用流程。

核心價值:不用手寫複雜的HTTP請求代碼,只要給接口加幾個註解,就能像調本地方法一樣調用其他服務。它還自帶負載均衡能力(搭配Spring Cloud LoadBalancer),能自動把請求分到不同的服務實例上,避免某一個實例忙不過來。如果配上OKHttp這類工具做連接池優化,還能減少重複建立TCP連接的開銷,既讓代碼好懂好維護,又能提高調用效率。

2.1 負載均衡策略詳解

OpenFeign整合了Ribbon(現為Spring Cloud LoadBalancer)提供負載均衡能力:

三種常用負載均衡策略

1. 輪詢策略(RoundRobin)

# 默認策略,按順序輪流訪問服務實例
spring:
  cloud:
    loadbalancer:
      configurations: round-robin

2. 隨機策略(Random)

spring:
  cloud:
    loadbalancer:
      configurations: random

3. 權重策略(Weighted)

# 根據實例權重分配流量
spring:
  cloud:
    loadbalancer:
      configurations: weighted

自定義負載均衡配置

@Configuration
public class LoadBalancerConfig {
    
    @Bean
    public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment, LoadBalancerClientFactory factory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(factory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

2.2 連接池化思想

為什麼需要連接池?

  • 減少TCP握手開銷:TCP三次握手耗時約1.5RTT
  • 資源複用:避免頻繁創建銷燬連接
  • 連接管理:統一管理連接生命週期

OKHttp連接池配置

feign:
  okhttp:
    enabled: true
    # 連接池配置
    max-connections: 200
    max-connections-per-route: 50
    # 連接超時
    connect-timeout: 3000
    # 讀取超時
    read-timeout: 10000
    # 寫入超時
    write-timeout: 10000

連接池參數調優

@Configuration
public class OkHttpConfig {
    
    @Bean
    public okhttp3.OkHttpClient okHttpClient() {
        return new okhttp3.OkHttpClient.Builder()
                .connectionPool(new ConnectionPool(200, 5, TimeUnit.MINUTES))
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .build();
    }
}

三、API網關:Gateway

組件定位:微服務集羣的“大門衞+流量調度中心”,所有外部請求都得從它這裏進系統。

核心價值:主要幹三件事:一是“指路”,把請求精準轉發到對應的微服務,比如把下單請求轉給訂單服務,支付請求轉給支付服務;二是“安檢”,幫着做登錄鑑權、記錄請求日誌、處理跨域問題,不讓非法請求進來;三是“限流”,遇到突發大流量時能控制請求速度,還能修改請求路徑、加請求頭信息。對前端來説不用記一堆服務地址,對後端來説能把服務藏在網關後面,安全性更有保障。

3.1 網關核心功能詳解

路由配置增強

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/user/**
            - Method=GET,POST
            - Header=X-Request-Id, \d+
            - Query=version, v1
          filters:
            - StripPrefix=1  # 去除路徑前綴
            - AddRequestHeader=X-Gateway-Request, true
            - AddResponseHeader=X-Gateway-Response, true
            - PrefixPath=/api  # 添加路徑前綴

全局過濾器鏈詳解

@Component
public class GlobalFilterChain implements GlobalFilter, Ordered {
    
    private final List<GlobalFilter> filters;
    
    public GlobalFilterChain(List<GlobalFilter> filters) {
        this.filters = filters.stream()
                .sorted(Comparator.comparingInt(Ordered::getOrder))
                .collect(Collectors.toList());
    }
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return Flux.fromIterable(filters)
                .reduce(chain, (currentChain, filter) -> 
                    new GatewayFilterChain() {
                        @Override
                        public Mono<Void> filter(ServerWebExchange exchange) {
                            return filter.filter(exchange, currentChain);
                        }
                    })
                .filter(exchange);
    }
}

3.2 用户信息傳遞機制

ThreadLocal使用詳解

public class UserContext {
    private static final ThreadLocal<Long> USER_CONTEXT = new ThreadLocal<>();
    
    public static void setUserId(Long userId) {
        USER_CONTEXT.set(userId);
    }
    
    public static Long getUserId() {
        return USER_CONTEXT.get();
    }
    
    public static void clear() {
        USER_CONTEXT.remove();
    }
}

攔截器配置

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login", "/register");
    }
}

public class UserInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) {
        String userId = request.getHeader("user-id");
        if (userId != null && !userId.trim().isEmpty()) {
            try {
                UserContext.setUserId(Long.valueOf(userId));
            } catch (NumberFormatException e) {
                // 記錄日誌,但不中斷請求
                log.warn("Invalid user-id header: {}", userId);
            }
        }
        return true;
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request,
                              HttpServletResponse response,
                              Object handler, Exception ex) {
        // 必須清理,防止內存泄漏
        UserContext.clear();
    }
}

四、配置中心:Nacos進階使用

組件定位:基於Nacos升級的“配置動態管理平台”,專治配置重複、改配置要重啓服務的毛病。

核心價值:把多個服務都要用的配置(比如數據庫連接信息)抽出來統一管理,不用每個服務都寫一遍。支持按環境隔離配置,開發環境改配置不會影響生產環境;最關鍵的是配置改完能實時生效,不用重啓服務,比如改個限流閾值、開關參數,立馬就能用。還能監聽配置變化,業務需要動態調參時特別方便。

4.1 配置共享原理

配置加載優先級

Spring Cloud配置加載順序:

  1. bootstrap.yml(最高優先級)
  2. Nacos共享配置(shared-configs
  3. Nacos擴展配置(extension-configs
  4. 應用專屬配置(spring.application.name
  5. application.yml(最低優先級)

多環境配置管理

# bootstrap.yaml
spring:
  application:
    name: order-service
  profiles:
    active: dev  # 環境標識
  cloud:
    nacos:
      config:
        file-extension: yaml
        shared-configs:
          - dataId: shared-jdbc-${spring.profiles.active}.yaml
          - dataId: shared-log-${spring.profiles.active}.yaml
        extension-configs:
          - dataId: ${spring.application.name}-${spring.profiles.active}.yaml
            group: DEFAULT_GROUP
            refresh: true

4.2 配置熱更新原理

@ConfigurationProperties工作原理

@ConfigurationProperties(prefix = "business")
@Data
@Component
@RefreshScope  // 關鍵註解,啓用配置刷新
public class BusinessProperties {
    
    /**
     * 最大數量限制
     * 配置示例:business.max-count=100
     */
    private Integer maxCount = 10;  // 默認值
    
    /**
     * 超時時間(毫秒)
     */
    private Integer timeout = 3000;
    
    /**
     * 是否啓用功能
     */
    private Boolean enabled = true;
}

配置變更監聽機制

@Component
public class ConfigChangeListener {
    
    @Autowired
    private BusinessProperties businessProperties;
    
    @EventListener
    public void handleRefreshEvent(EnvironmentChangeEvent event) {
        // 配置變更時的處理邏輯
        log.info("配置發生變化: {}", event.getKeys());
        
        // 重新加載相關配置
        reloadBusinessConfig();
    }
    
    private void reloadBusinessConfig() {
        log.info("當前配置 - maxCount: {}, timeout: {}", 
                businessProperties.getMaxCount(), 
                businessProperties.getTimeout());
    }
}

五、服務保護:Sentinel

組件定位:微服務的“安全衞士”,專門守護服務不被流量沖垮,保障系統高可用。

核心價值:有三大核心技能:一是限流,比如限制某個接口每秒最多處理100個請求,避免請求太多把服務壓崩;二是熔斷降級,要是某個依賴的服務掛了,不會一直等着它響應,而是快速返回失敗,防止故障像多米諾骨牌一樣擴散;三是線程隔離,給每個依賴服務分配獨立的線程池,就算A服務故障,也不會佔用B服務的資源。支持多種限流和熔斷策略,能精準保護每個服務節點。

5.1 Sentinel核心概念詳解

請求限流(Flow Control)

限流算法對比

算法

特點

適用場景

漏桶算法

恆定速率處理,平滑流量

保護系統不被突發流量沖垮

令牌桶算法

允許突發流量,有彈性

保證系統處理能力的同時允許突發

計數器算法

簡單粗暴,固定窗口

簡單限流場景

配置示例

// 資源定義
@SentinelResource(value = "getUserInfo", 
                  blockHandler = "handleBlock",
                  fallback = "handleFallback")
public UserInfo getUserInfo(Long userId) {
    // 業務邏輯
}

// 限流處理
public UserInfo handleBlock(Long userId, BlockException ex) {
    log.warn("觸發限流保護,userId: {}", userId);
    return UserInfo.defaultUser();
}

// 降級處理
public UserInfo handleFallback(Long userId, Throwable ex) {
    log.error("服務降級,userId: {}", userId, ex);
    return UserInfo.defaultUser();
}

線程隔離(Thread Isolation)

線程池隔離 vs 信號量隔離

# 線程池隔離配置
spring:
  cloud:
    sentinel:
      filter:
        enabled: false
      thread-pool:
        # 核心線程數
        core-size: 20
        # 最大線程數  
        max-size: 50
        # 隊列容量
        queue-capacity: 100
        # 線程存活時間
        keep-alive-time: 60s

信號量隔離配置

// 使用@SentinelResource配置信號量隔離
@SentinelResource(value = "queryOrder",
                  fallback = "queryOrderFallback",
                  blockHandler = "queryOrderBlockHandler",
                  // 信號量隔離
                  execution: 
                    isolation:
                      strategy: SEMAPHORE
                      semaphore:
                        maxConcurrentRequests: 100)
public OrderInfo queryOrder(Long orderId) {
    // 業務邏輯
}

服務熔斷和降級策略

熔斷器三種狀態

  • 關閉狀態:正常處理請求
  • 打開狀態:所有請求被熔斷,直接降級
  • 半開狀態:嘗試放行部分請求,測試服務是否恢復

熔斷策略配置

// 基於響應時間的熔斷
DegradeRule rule = new DegradeRule("resourceName")
    .setGrade(RuleConstant.DEGRADE_GRADE_RT)  // 響應時間模式
    .setCount(100)  // 響應時間閾值(ms)
    .setTimeWindow(10)  // 熔斷時間窗口(s)
    .setRtSlowRequestAmount(5)  // 最小請求數
    .setMinRequestAmount(5);  // 觸發熔斷的最小請求數

// 基於異常比例的熔斷
DegradeRule rule2 = new DegradeRule("resourceName")
    .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)
    .setCount(0.5)  // 異常比例閾值(0.5=50%)
    .setTimeWindow(10)
    .setMinRequestAmount(10);

六、分佈式事務:Seata

組件定位:微服務跨服務操作的“數據一致性管家”,解決多個服務操作時“要麼都成,要麼都敗”的問題。

核心價值:比如下單時,要同時扣減庫存(庫存服務)和扣減餘額(用户服務),這兩個操作必須同時成功或同時失敗,不然就會出現“訂單建好了但庫存沒扣”“錢扣了但訂單沒生成”的爛賬。Seata支持兩種模式:AT模式不用改太多代碼,自動幫你管事務;TCC模式更靈活,適合複雜業務場景。它通過全局事務協調器,統一指揮各個服務的本地事務提交或回滾,保證跨服務操作的數據一致。

6.1 Seata分佈式事務模式

AT模式(自動模式)原理

工作流程

  1. 一階段
  • 解析SQL,生成前後鏡像
  • 執行業務SQL
  • 提交前鏡像到undo_log
  • 本地事務提交
  1. 二階段提交
  • 刪除undo_log記錄
  • 異步清理
  1. 二階段回滾
  • 根據undo_log生成反向SQL
  • 執行回滾操作
  • 刪除undo_log記錄

配置示例

@Service
public class OrderService {
    
    @GlobalTransactional  // 開啓全局事務
    public void createOrder(OrderDTO orderDTO) {
        // 1. 扣減庫存
        stockFeignClient.reduceStock(orderDTO.getSkuId(), orderDTO.getCount());
        
        // 2. 創建訂單
        orderMapper.insert(orderDTO);
        
        // 3. 扣減餘額
        accountFeignClient.reduceBalance(orderDTO.getUserId(), orderDTO.getAmount());
    }
}

TCC模式(手動模式)

Try-Confirm-Cancel三個階段

public interface TccOrderService {
    
    @TwoPhaseBusinessAction(name = "createOrder", commitMethod = "confirm", rollbackMethod = "cancel")
    boolean tryCreateOrder(BusinessActionContext actionContext,
                          @BusinessActionContextParameter(paramName = "orderId") Long orderId,
                          @BusinessActionContextParameter(paramName = "amount") BigDecimal amount);
    
    boolean confirm(BusinessActionContext actionContext);
    
    boolean cancel(BusinessActionContext actionContext);
}

6.2 Seata表結構説明

全局事務表(global_table)

CREATE TABLE `global_table` (
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `status` tinyint(4) NOT NULL,
  `application_id` varchar(32) DEFAULT NULL,
  `transaction_service_group` varchar(32) DEFAULT NULL,
  `transaction_name` varchar(128) DEFAULT NULL,
  `timeout` int(11) DEFAULT NULL,
  `begin_time` bigint(20) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`xid`),
  KEY `idx_status_gmt_modified` (`status`,`gmt_modified`),
  KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

分支事務表(branch_table)

CREATE TABLE `branch_table` (
  `xid` varchar(128) NOT NULL,
  `branch_id` bigint(20) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `resource_group_id` varchar(32) DEFAULT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `branch_type` varchar(8) DEFAULT NULL,
  `status` tinyint(4) DEFAULT NULL,
  `client_id` varchar(64) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`branch_id`),
  KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

undo_log表(每個業務數據庫)

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

七、微服務技術棧整合實踐

7.1 完整的微服務架構

前端/客户端
    ↓
Gateway網關(統一入口、鑑權、限流)
    ↓
微服務集羣
    ├── 用户服務(Nacos註冊 + Config配置)
    ├── 商品服務(Feign調用 + Sentinel保護)  
    ├── 訂單服務(Seata分佈式事務)
    └── 庫存服務(負載均衡 + 熔斷降級)
    ↓
數據層
    ├── MySQL(主從複製)
    ├── Redis(緩存)
    └── Elasticsearch(搜索)

7.2 最佳實踐總結

  1. 服務治理:Nacos實現服務註冊發現和配置管理
  2. 服務通信:OpenFeign + LoadBalancer實現聲明式調用
  3. 流量控制:Gateway統一入口 + Sentinel多層次保護
  4. 數據一致性:Seata AT/TCC模式保障分佈式事務
  5. 可觀測性:整合鏈路追蹤、監控告警體系

通過以上組件的有機結合,可以構建出高可用、可擴展、易維護的微服務架構體系。