最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringCloud之網(wǎng)關(guān)、服務(wù)保護和分布式事務(wù)詳解

 更新時間:2025年09月17日 15:39:12   作者:l_tian_tian_  
網(wǎng)關(guān)負責(zé)路由、身份驗證及用戶ID傳遞,配置管理支持熱更新與動態(tài)路由,服務(wù)保護通過限流、隔離、熔斷防止雪崩,分布式事務(wù)采用XA模式強一致性或AT模式高性能但控制復(fù)雜

一、網(wǎng)關(guān)

網(wǎng)絡(luò)的關(guān)口,負責(zé)請求的路由、轉(zhuǎn)發(fā)、身份驗證

server:
  port: 8080
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.96.129:8848
    gateway:
      routes:
        - id: item-service
          uri: lb://item-service
          predicates:
            - Path=/items/**,/search/**
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/addresses/**,/users/**
        - id: cart-service
          uri: lb://cart-service
          predicates:
            - Path=/carts/**
        - id: trade-service
          uri: lb://trade-service
          predicates:
            - Path=/orders/**
  application:
    name: hm-gateway

二、網(wǎng)關(guān)登錄校驗

自定義過濾器:

package com.hmall.gateway.filters;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        System.out.println("GlobalFilter pre階段 執(zhí)行了");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

微服務(wù)項目網(wǎng)關(guān):

package com.hmall.gateway.filters;

import com.hmall.common.exception.UnauthorizedException;
import com.hmall.gateway.config.AuthProperties;
import com.hmall.gateway.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;


@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    //不需要處理的請求路徑
    public final AuthProperties authProperties;
    public final JwtTool jwtTool;
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //獲得請求頭
        ServerHttpRequest request = exchange.getRequest();
        //放行不需要攔截的請求
        //路徑合法,需要放行
        if (isUnique(request.getPath().toString())){
            //合法,放行
            return chain.filter(exchange);
        }

        //判斷令牌是否合法
        String token=null;
        Long userId=null;
        List<String> authorization = request.getHeaders().get("authorization");
        if (authorization != null && authorization.size() > 0) {
            token = authorization.get(0);
        }

        try {
            userId = jwtTool.parseToken(token);

        }
        catch (UnauthorizedException e) {
            //401 未登錄、未授權(quán)
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        //TODO 保存用戶id到請求頭,實現(xiàn)多個微服務(wù)間用戶id的共享
        String userInfo = userId.toString();
        ServerWebExchange swe=exchange.mutate().request(builder -> builder.header("user-info", userInfo)).build();
        //System.out.println(userId);
        //放行
        return chain.filter(swe);
    }

    @Override
    public int getOrder() {
        return 0;
    }


    private boolean isUnique(String path) {
        for (String excludePath : authProperties.getExcludePaths()) {
            if (antPathMatcher.match(excludePath, path)) {
                return true;
            }
        }
        return false;
    }
}
server:
  port: 8080
spring:
  application:
    name: hm-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.96.129:8848
    gateway:
      routes:
        - id: item-service
          uri: lb://item-service
          predicates:
            - Path=/items/**,/search/**
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/addresses/**,/users/**
        - id: cart-service
          uri: lb://cart-service
          predicates:
            - Path=/carts/**
        - id: trade-service
          uri: lb://trade-service
          predicates:
            - Path=/orders/**
        - id: pay-service
          uri: lb://pay-service
          predicates:
            - Path=/pay-orders/**
hm:
  jwt:
    location: classpath:hmall.jks
    alias: hmall
    password: hmall123
    tokenTTL: 30m
  auth:
    excludePaths:
      - /search/**
      - /users/login
      - /items/**
      - /hi

網(wǎng)關(guān)傳遞用戶:將用戶的id保存在請求頭當(dāng)中,通過統(tǒng)一攔截處理,獲取用戶的id,放入ThreadLocal當(dāng)中;請求完成,清理ThreadLocal,實現(xiàn)用戶id從網(wǎng)關(guān)到各個項目模塊的傳遞

OpenFeign傳遞用戶:OpenFeign中提供了一個攔截器接口,所有由OpenFeign發(fā)起的請求都會先調(diào)用攔截器處理請求,在攔截處理過程中,我們將ThreadLocal中的用戶id放入OpenFeign的請求頭當(dāng)中,其他微服務(wù)攔截處理的過程中獲得用戶id并放入線程當(dāng)中

三、配置管理

1.拉取共享配置

2.加入相關(guān)依賴

        <!--nacos配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>


        <!--讀取bootstrap文件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

3.配置熱更新

(1)nacos中要有一個與微服務(wù)名有關(guān)的配置文件

(2)微服務(wù)中要以特定方式讀取需要熱更新的配置屬性

package com.hmall.cart.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties(prefix = "hm.cart")
public class MaxCommodityConfig {
    private Integer maxCommodity;
}

4.動態(tài)路由

package com.hmall.gateway.routes;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Executor;

@Component
@RequiredArgsConstructor
public class DynamicRounterLoader {
    private final NacosConfigManager nacosConfigManager;

    private final RouteDefinitionWriter writer;

    private final String dataId="gateway-routes.json";

    private final String group="DEFAULT_GROUP";

    //記錄路由的id
    private HashSet<String> set=new HashSet<String>();


    //在Bean初始化之后執(zhí)行
    @PostConstruct
    public void initRoutesConfigListener() throws NacosException {

        //拉取配置并更新配置
        String configInfo = nacosConfigManager.getConfigService().getConfigAndSignListener(dataId, group, 5000, new Listener() {

            @Override
            public Executor getExecutor() {
                return null;
            }

            @Override
            public void receiveConfigInfo(String configInfo) {

                //路由表更新,更新監(jiān)聽器
                System.out.println(configInfo+"監(jiān)聽器更新執(zhí)行了");
                updateRouters(configInfo);

            }
        });


        System.out.println(configInfo+"監(jiān)聽器更新了");
        //第一次啟動,更新監(jiān)聽器
        updateRouters(configInfo);





    }

    private void updateRouters(String configInfo) {
        //將json數(shù)據(jù)轉(zhuǎn)換為實體類
        List<RouteDefinition> routeDefinitionList = JSONUtil.toList(configInfo, RouteDefinition.class);

        //刪除原來的路由表
        for (String id : set) {
            writer.delete(Mono.just(id)).subscribe();
        }
        set.clear();
        //添加新的路由表并記錄id
        for (RouteDefinition routeDefinition : routeDefinitionList) {
            writer.save(Mono.just(routeDefinition)).subscribe();
            set.add(routeDefinition.getId());
        }

    }


}

將yaml配置轉(zhuǎn)換為json配置:

[
    {
        "id": "item",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/items/**", "_genkey_1":"/search/**"}
        }],
        "filters": [],
        "uri": "lb://item-service"
    },
    {
        "id": "cart",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/carts/**"}
        }],
        "filters": [],
        "uri": "lb://cart-service"
    },
    {
        "id": "user",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/users/**", "_genkey_1":"/addresses/**"}
        }],
        "filters": [],
        "uri": "lb://user-service"
    },
    {
        "id": "trade",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/orders/**"}
        }],
        "filters": [],
        "uri": "lb://trade-service"
    },
    {
        "id": "pay",
        "predicates": [{
            "name": "Path",
            "args": {"_genkey_0":"/pay-orders/**"}
        }],
        "filters": [],
        "uri": "lb://pay-service"
    }
]

三、服務(wù)保護和分布式事務(wù)

1.雪崩問題

微服務(wù)調(diào)用鏈路中的某個服務(wù)故障,引起整個鏈路中的所有微服務(wù)都不可用

解決方案:保證代碼的健壯性、保證網(wǎng)絡(luò)的暢通、能應(yīng)對高并發(fā)請求

2.服務(wù)保護

請求限流:限制訪問服務(wù)器的并發(fā)量,避免服務(wù)因流量激增出現(xiàn)故障

線程隔離:模擬船艙隔板的防水原理。通過限定每個業(yè)務(wù)能使用的線程數(shù)量而將故障業(yè)務(wù)隔離,避免故障擴散

服務(wù)熔斷:由斷路器統(tǒng)計請求的異常比例或慢調(diào)用比例,如果超出閾值則會熔斷業(yè)務(wù),則攔截該接口請求

3.分布式事務(wù)

事務(wù)協(xié)調(diào)者(TC):維護全局和分支事務(wù)的狀態(tài),協(xié)調(diào)全局事務(wù)提交和回滾

事務(wù)管理器(TM):定義全局事務(wù)范圍、開始全局事務(wù)、提交或回滾全局事務(wù)

資源管理器(RM):管理分支事務(wù),與TC交談以注冊分支事務(wù)和報告分支事務(wù)狀態(tài)

  • XA模式:

優(yōu)點:事務(wù)的強一致性,滿足ACID原則?,常用數(shù)據(jù)庫都支持,實現(xiàn)簡單,并且沒有代碼侵入

缺點:因為一階段需要鎖定數(shù)據(jù)庫資源,等待二階段結(jié)束才釋放,性能較差?,依賴關(guān)系型數(shù)據(jù)庫實現(xiàn)事務(wù)?

  • AT模式:

優(yōu)點:滿足ACID原則?,常用數(shù)據(jù)庫都支持,實現(xiàn)簡單,并且沒有代碼侵入,單個RM完成之后進行事務(wù)的提交,不占用資源,提高了性能

缺點:難以實現(xiàn)復(fù)的事務(wù)控制,如特定隔離級別;當(dāng)事務(wù)的隔離級別過低時會出現(xiàn)臟讀、不可重復(fù)讀、幻讀問題

?總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java向數(shù)據(jù)庫中插入數(shù)據(jù)后獲取自增ID的常用方法

    Java向數(shù)據(jù)庫中插入數(shù)據(jù)后獲取自增ID的常用方法

    有時候因為新增的需求需要獲取剛剛新增的數(shù)據(jù)的自增的主鍵ID,下面這篇文章主要給大家介紹了關(guān)于Java向數(shù)據(jù)庫中插入數(shù)據(jù)后獲取自增ID的常用方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • java開發(fā)命名規(guī)范總結(jié)

    java開發(fā)命名規(guī)范總結(jié)

    包名的書寫規(guī)范 (Package)推薦使用公司或機構(gòu)的頂級域名為包名的前綴,目的是保證各公司/機構(gòu)內(nèi)所使用的包名的唯一性。包名全部為小寫字母,且具有實際的區(qū)分意義
    2013-10-10
  • Kafka Java Producer代碼實例詳解

    Kafka Java Producer代碼實例詳解

    這篇文章主要介紹了Kafka Java Producer代碼實例詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • 解析Java線程編程中的線程安全與synchronized的使用

    解析Java線程編程中的線程安全與synchronized的使用

    這篇文章主要介紹了Java線程編程中的線程安全與synchronized的使用,synchronized多線程使用時一定要注意線程之間的沖突問題,需要的朋友可以參考下
    2015-12-12
  • springboot?注解方式批量插入數(shù)據(jù)的實現(xiàn)

    springboot?注解方式批量插入數(shù)據(jù)的實現(xiàn)

    一次請求需要往數(shù)據(jù)庫插入多條數(shù)據(jù)時,可以節(jié)省大量時間,本文主要介紹了springboot?注解方式批量插入數(shù)據(jù),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Spring詳細解讀事務(wù)管理

    Spring詳細解讀事務(wù)管理

    Spring事務(wù)的本質(zhì)就是對數(shù)據(jù)庫事務(wù)的支持,沒有數(shù)據(jù)庫事務(wù),Spring是無法提供事務(wù)功能的。Spring只提供統(tǒng)一的事務(wù)管理接口,具體實現(xiàn)都是由數(shù)據(jù)庫自己實現(xiàn)的,Spring會在事務(wù)開始時,根據(jù)當(dāng)前設(shè)置的隔離級別,調(diào)整數(shù)據(jù)庫的隔離級別,由此保持一致
    2022-04-04
  • SpringBoot+Quartz實現(xiàn)定時任務(wù)的代碼模版分享

    SpringBoot+Quartz實現(xiàn)定時任務(wù)的代碼模版分享

    quartz?是一款開源且豐富特性的Java?任務(wù)調(diào)度庫,用于實現(xiàn)任務(wù)調(diào)度和定時任務(wù),本文主要和大家分享一個SpringBoot整合Quartz實現(xiàn)定時任務(wù)的代碼模版,需要的可以參考一下
    2023-06-06
  • Java?Stream流語法示例詳解

    Java?Stream流語法示例詳解

    這篇文章主要為大家詳細介紹了Java的Stream流,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 你知道怎么用Spring的三級緩存解決循環(huán)依賴嗎

    你知道怎么用Spring的三級緩存解決循環(huán)依賴嗎

    這篇文章主要為大家詳細介紹了Spring的三級緩存解決循環(huán)依賴,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • java語言中封裝類代碼示例

    java語言中封裝類代碼示例

    這篇文章主要介紹了java語言中封裝類,涉及相關(guān)代碼示例及結(jié)果分析,以及封裝的好處簡單介紹,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01

最新評論

准格尔旗| 庐江县| 宁陕县| 丹东市| 博野县| 富裕县| 云南省| 将乐县| 谷城县| 都江堰市| 收藏| 滦平县| 阿巴嘎旗| 井冈山市| 安康市| 潞西市| 康乐县| 北辰区| 通州区| 富宁县| 临高县| 萍乡市| 安达市| 长治县| 南华县| 孝昌县| 嫩江县| 江门市| 昌都县| 遂平县| 甘泉县| 长垣县| 九台市| 黔江区| 大化| 台东县| 仙桃市| 盐山县| 宜章县| 锦州市| 巩留县|