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

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

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

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

網(wǎng)絡(luò)的關(guān)口,負(fù)責(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ù)保護(hù)和分布式事務(wù)

1.雪崩問題

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

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

2.服務(wù)保護(hù)

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

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

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

3.分布式事務(wù)

事務(wù)協(xié)調(diào)者(TC):維護(hù)全局和分支事務(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完成之后進(jìn)行事務(wù)的提交,不占用資源,提高了性能

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

?總結(jié)

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

相關(guān)文章

  • Java利用Jackson輕松處理JSON序列化與反序列化

    Java利用Jackson輕松處理JSON序列化與反序列化

    Jackson?是?Java?中最流行的?JSON?處理庫之一,它提供了許多注解來簡化?JSON?的序列化和反序列化過程。這篇文章將介紹一些?Jackson?常用的注解,以幫助您更輕松地處理?JSON?數(shù)據(jù)
    2023-05-05
  • C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    這篇文章主要介紹了C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法,相比普通方法能夠在Windows下簡化很多操作步驟,需要的朋友可以參考下
    2016-04-04
  • Spring Cloud 部署時使用 Kubernetes 作為注冊中心和配置中心的方法

    Spring Cloud 部署時使用 Kubernetes 作為注冊中心和配置中

    Spring Cloud Kubernetes提供了使用Kubernete本地服務(wù)的Spring Cloud通用接口實現(xiàn),這篇文章主要介紹了Spring Cloud 部署時如何使用 Kubernetes 作為注冊中心和配置中心,需要的朋友可以參考下
    2024-05-05
  • SpringBoot集成Druid實現(xiàn)多數(shù)據(jù)源的兩種方式

    SpringBoot集成Druid實現(xiàn)多數(shù)據(jù)源的兩種方式

    這篇文章主要介紹了SpringBoot集成Druid實現(xiàn)多數(shù)據(jù)源的兩種方式,集成com.baomidou的方式和基于AOP手動實現(xiàn)多數(shù)據(jù)源原生的方式,文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • RabbitMQ核心函數(shù)的參數(shù)意義和使用場景分析

    RabbitMQ核心函數(shù)的參數(shù)意義和使用場景分析

    這篇文章主要介紹了RabbitMQ核心函數(shù)的參數(shù)意義和使用場景分析,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-06-06
  • SpringMVC Controller 返回值的可選類型詳解

    SpringMVC Controller 返回值的可選類型詳解

    本篇文章主要介紹了SpringMVC Controller 返回值的可選類型詳解 ,spring mvc 支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void,有興趣的可以了解一下
    2017-05-05
  • IntelliJ IDEA中使用mybatis-generator的示例

    IntelliJ IDEA中使用mybatis-generator的示例

    這篇文章主要介紹了IntelliJ IDEA中使用mybatis-generator,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java泛型繼承原理與用法詳解

    Java泛型繼承原理與用法詳解

    這篇文章主要介紹了Java泛型繼承原理與用法,結(jié)合實例形式分析了java泛型繼承的相關(guān)原理與實現(xiàn)技巧,需要的朋友可以參考下
    2019-07-07
  • Java 抽象類特點總結(jié)

    Java 抽象類特點總結(jié)

    在面向?qū)ο蟮母拍钪?,所有的對象都是通過類來描繪的,但是反過來,并不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類
    2021-10-10
  • JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解

    JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解

    這篇文章主要介紹了JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解,CountDownLatch 類可以設(shè)置一個計數(shù)器,然后通過 countDown 方法來進(jìn)行 減 1 的操作,使用 await 方法等待計數(shù)器不大于 0,然后繼續(xù)執(zhí)行 await 方法 之后的語句,需要的朋友可以參考下
    2024-01-01

最新評論