精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何利用Gateway搭建網(wǎng)關(guān)服務(wù)?

jf_78858299 ? 來源:csdn ? 作者:海·是倒過來的天 ? 2023-01-21 16:06 ? 次閱讀

網(wǎng)關(guān)作為微服務(wù)中非常重要的一部分,是必須要掌握的;本文記錄一下我是如何使用Gateway搭建網(wǎng)關(guān)服務(wù)及實現(xiàn)動態(tài)路由的,幫助大家學(xué)習(xí)如何快速搭建一個網(wǎng)關(guān)服務(wù),了解路由相關(guān)配置,鑒權(quán)的流程及業(yè)務(wù)處理,有興趣的一定看到最后,非常適合沒接觸過網(wǎng)關(guān)服務(wù)的同學(xué)當(dāng)作入門教程

搭建服務(wù)

框架

SpringBoot 2.1

<parent>
   <groupId>org.springframework.bootgroupId>
   <artifactId>spring-boot-starter-parentartifactId>
   <version>2.1.0.RELEASEversion>
parent>

Spring-cloud-gateway-core

<dependency>
   <groupId>org.springframework.cloudgroupId>
   <artifactId>spring-cloud-gateway-coreartifactId>
dependency>

common-lang3

<dependency>
   <groupId>org.apache.commonsgroupId>
   <artifactId>commons-lang3artifactId>
dependency>

路由配置

網(wǎng)關(guān)作為請求統(tǒng)一入口,路由就相當(dāng)于是每個業(yè)務(wù)系統(tǒng)的入口,通過路由規(guī)則則可以匹配到對應(yīng)微服務(wù)的入口,將請求命中到對應(yīng)的業(yè)務(wù)系統(tǒng)中

server:
  port: 8080
 
spring:
  cloud:
    gateway:
      enabled: true
      routes:
      - id: demo-server
        uri: http://localhost:8081
        predicates:
        - Path=/demo-server/**
        filters:
          - StripPrefix= 1

routes

圖片

解讀配置

現(xiàn)在有一個服務(wù)demo-server部署在本機,地址和端口127.0.0.1:8081,所以路由配置uri為http://localhost:8081

使用網(wǎng)關(guān)服務(wù)路由到此服務(wù),predicates -Path=/demo-server/**,網(wǎng)關(guān)服務(wù)的端口為8080,啟動網(wǎng)關(guān)服務(wù),訪問localhost:8080/demo-server,路由斷言就會將請求路由到demo-server

直接訪問demo-server的接口localhost:8081/api/test,通過網(wǎng)關(guān)的訪問地址則為localhost:8080/demo-server/api/test,predicates配置將請求斷言到此路由,filters-StripPrefix=1代表將地址中/后的第一個截取,所以demo-server就截取掉了

使用gateway通過配置文件即可完成路由的配置,非常方便,我們只要充分的了解配置項的含義及規(guī)則就可以了;但是這些配置如果要修改則需要重啟服務(wù),重啟網(wǎng)關(guān)服務(wù)會導(dǎo)致整個系統(tǒng)不可用,這一點是無法接受的,下面介紹如何通過Nacos實現(xiàn)動態(tài)路由

動態(tài)路由

使用nacos結(jié)合gateway-server實現(xiàn)動態(tài)路由,我們需要先部署一個nacos服務(wù),可以使用docker部署或下載源碼在本地啟動,具體操作可以參考官方文檔即可

Nacos配置
  • groupId: 使用網(wǎng)關(guān)服務(wù)名稱即可
  • dataId: routes
  • 配置格式:json
[{
      "id": "xxx-server",
      "order": 1, #優(yōu)先級
      "predicates": [{ #路由斷言
          "args": {
              "pattern": "/xxx-server/**"
          },
          "name": "Path"
      }],
      "filters":[{ #過濾規(guī)則
          "args": {
              "parts": 0 #k8s服務(wù)內(nèi)部訪問容器為http://xxx-server/xxx-server的話,配置0即可
          },
          "name": "StripPrefix" #截取的開始索引
      }],
      "uri": "http://localhost:8080/xxx-server" #目標(biāo)地址
  }]

json格式配置項與yaml中對應(yīng),需要了解配置在json中的寫法

比對一下json配置與yaml配置
{
    "id":"demo-server",
    "predicates":[
        {
            "args":{
                "pattern":"/demo-server/**"
            },
            "name":"Path"
        }
    ],
    "filters":[
        {
            "args":{
                "parts":1
            },
            "name":"StripPrefix"
        }
    ],
    "uri":"http://localhost:8081"
}
spring:
  cloud:
    gateway:
      enabled: true
      routes:
      - id: demo-server
        uri: http://localhost:8081
        predicates:
        - Path=/demo-server/**
        filters:
          - StripPrefix= 1
代碼實現(xiàn)

Nacos實現(xiàn)動態(tài)路由的方式核心就是通過Nacos配置監(jiān)聽,配置發(fā)生改變后執(zhí)行網(wǎng)關(guān)相關(guān)api創(chuàng)建路由

圖片

@Component
public class NacosDynamicRouteService implements ApplicationEventPublisherAware {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(NacosDynamicRouteService.class);
 
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
 
    private ApplicationEventPublisher applicationEventPublisher;
 
    /** 路由id */
    private static List<String> routeIds = Lists.newArrayList();
 
    /**
     * 監(jiān)聽nacos路由配置,動態(tài)改變路由
     * @param configInfo
     */
    @NacosConfigListener(dataId = "routes", groupId = "gateway-server")
    public void routeConfigListener(String configInfo) {
        clearRoute();
        try {
            List gatewayRouteDefinitions = JSON.parseArray(configInfo, RouteDefinition.class);
            for (RouteDefinition routeDefinition : gatewayRouteDefinitions) {
                addRoute(routeDefinition);
            }
            publish();
            LOGGER.info("Dynamic Routing Publish Success");
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } 
    }
    /**
     * 清空路由
     */
    private void clearRoute() {
        for (String id : routeIds) {
            routeDefinitionWriter.delete(Mono.just(id)).subscribe();
        }
        routeIds.clear();
    }
 
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
    /**
     * 添加路由
     * 
     * @param definition
     */
    private void addRoute(RouteDefinition definition) {
        try {
            routeDefinitionWriter.save(Mono.just(definition)).subscribe();
            routeIds.add(definition.getId());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }
    /**
     * 發(fā)布路由、使路由生效
     */
    private void publish() {
        this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this.routeDefinitionWriter));
    }
}

過濾器

gateway提供GlobalFilter及Ordered兩個接口用來定義過濾器,我們自定義過濾器只需要實現(xiàn)這個兩個接口即可

  • GlobalFilter filter() 實現(xiàn)過濾器業(yè)務(wù)
  • Ordered getOrder() 定義過濾器執(zhí)行順序

通常一個網(wǎng)關(guān)服務(wù)的過濾主要包含 鑒權(quán)(是否登錄、是否黑名單、是否免登錄接口...) 限流(ip限流等等)功能,我們今天簡單介紹鑒權(quán)過濾器的流程實現(xiàn)

鑒權(quán)過濾器

需要實現(xiàn)鑒權(quán)過濾器,我們先得了解登錄及鑒權(quán)流程,如下圖所示

由圖可知,我們鑒權(quán)過濾核心就是驗證token是否有效,所以我們網(wǎng)關(guān)服務(wù)需要與業(yè)務(wù)系統(tǒng)在同一個redis庫,先給網(wǎng)關(guān)添加redis依賴及配置

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redis-reactiveartifactId>
dependency>
spring:
  redis:
    host: redis-server
    port: 6379
    password:
    database: 0

代碼實現(xiàn)

  1. 定義過濾器AuthFilter
  2. 獲取請求對象 從請求頭或參數(shù)或cookie中獲取token(支持多種方式傳token對于客戶端更加友好,比如部分web下載請求會新建一個頁面,在請求頭中傳token處理起來比較麻煩)
  3. 沒有token,返回401
  4. 有token,查詢redis是否有效
  5. 無效則返回401,有效則完成驗證放行
  6. 重置token過期時間、添加內(nèi)部請求頭信息方便業(yè)務(wù)系統(tǒng)權(quán)限處理
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    private static final String TOKEN_HEADER_KEY = "auth_token";
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.獲取請求對象
        ServerHttpRequest request = exchange.getRequest();
        // 2.獲取token
        String token = getToken(request);
        ServerHttpResponse response = exchange.getResponse();
        if (StringUtils.isBlank(token)) {
            // 3.token為空 返回401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // 4.驗證token是否有效
        String userId = getUserIdByToken(token);
        if (StringUtils.isBlank(userId)) {
            // 5.token無效 返回401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // token有效,后續(xù)業(yè)務(wù)處理
        // 從寫請求頭,方便業(yè)務(wù)系統(tǒng)從請求頭獲取用戶id進行權(quán)限相關(guān)處理
        ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
        request = builder.header("user_id", userId).build();
        // 延長緩存過期時間-token緩存用戶如果一直在操作就會一直重置過期
        // 這樣避免用戶操作過程中突然過期影響業(yè)務(wù)操作及體驗,只有用戶操作間隔時間大于緩存過期時間才會過期
        resetTokenExpirationTime(token, userId);
        // 完成驗證
        return chain.filter(exchange);
    }
 
    @Override
    public int getOrder() {
        // 優(yōu)先級 越小越優(yōu)先
        return 0;
    }
 
    /**
     * 從redis中獲取用戶id
     * 在登錄操作時候 登陸成功會生成一個token, redis得key為auth_token:token 值為用戶id
     *
     * @param token
     * @return
     */
    private String getUserIdByToken(String token) {
        String redisKey = String.join(":", "auth_token", token);
        return redisTemplate.opsForValue().get(redisKey);
    }
 
    /**
     * 重置token過期時間
     *
     * @param token
     * @param userId
     */
    private void resetTokenExpirationTime(String token, String userId) {
        String redisKey = String.join(":", "auth_token", token);
        redisTemplate.opsForValue().set(redisKey, userId, 2, TimeUnit.HOURS);
    }
 
    /**
     * 獲取token
     *
     * @param request
     * @return
     */
    private static String getToken(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        // 從請求頭獲取token
        String token = headers.getFirst(TOKEN_HEADER_KEY);
        if (StringUtils.isBlank(token)) {
            // 請求頭無token則從url獲取token
            token = request.getQueryParams().getFirst(TOKEN_HEADER_KEY);
        }
        if (StringUtils.isBlank(token)) {
            // 請求頭和url都沒有token則從cookies獲取
            HttpCookie cookie = request.getCookies().getFirst(TOKEN_HEADER_KEY);
            if (cookie != null) {
                token = cookie.getValue();
            }
        }
        return token;
    }
}

總結(jié)

Gateway通過配置項可以實現(xiàn)路由功能,整合Nacos及配置監(jiān)聽可以實現(xiàn)動態(tài)路由,實現(xiàn)GlobalFilter,Ordered兩個接口可以快速實現(xiàn)一個過濾器,文中也詳細(xì)的介紹了登錄后的請求鑒權(quán)流程。

來源:https://blog.csdn.net/qq_31587111/article/details/122731977

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 網(wǎng)關(guān)
    +關(guān)注

    關(guān)注

    9

    文章

    4306

    瀏覽量

    50945
  • 路由
    +關(guān)注

    關(guān)注

    0

    文章

    277

    瀏覽量

    41778
  • Gateway
    +關(guān)注

    關(guān)注

    1

    文章

    16

    瀏覽量

    7880
收藏 人收藏

    評論

    相關(guān)推薦

    如何使用Gateway搭建網(wǎng)關(guān)服務(wù)及實現(xiàn)動態(tài)路由

    本文記錄一下我是如何使用Gateway搭建網(wǎng)關(guān)服務(wù)及實現(xiàn)動態(tài)路由的,幫助大家學(xué)習(xí)如何快速搭建一個網(wǎng)關(guān)服務(wù)
    的頭像 發(fā)表于 09-23 15:15 ?1768次閱讀

    #硬聲創(chuàng)作季 14-JAVAEE實戰(zhàn)項目課程—CAT安裝使用-GateWay網(wǎng)關(guān)服務(wù)搭建

    網(wǎng)關(guān)JAVA編程語言Gate網(wǎng)關(guān)設(shè)備
    Mr_haohao
    發(fā)布于 :2022年09月05日 07:17:38

    cc2530和linux gateway之間的通信網(wǎng)關(guān)端的服務(wù)都沒有正常啟動是什么原因?

    點。我希望通過中心節(jié)點去控制端節(jié)點。另外在網(wǎng)關(guān)端我安裝了Z-Stack_Linux_Gateway-1.0.1,即TI的gateway上的SDK,現(xiàn)在我遇到了些問題: 網(wǎng)關(guān)上運行zig
    發(fā)表于 08-14 07:43

    Thing***oard之Gateway使用示例有哪些

    Thing***oard之Gateway使用示例國慶期間西安陰雨綿綿,閑來無事,把thing***orad運行搭建起來,體驗了一把。總體來講CE版本還是很棒的,提供了物聯(lián)網(wǎng)平臺該有的基礎(chǔ)能力
    發(fā)表于 07-12 07:51

    服務(wù)網(wǎng)關(guān)gateway的相關(guān)資料推薦

    目錄微服務(wù)網(wǎng)關(guān) gateway 概述[路由器網(wǎng)關(guān) Zuul 概述]嵌入式 Zuul 反向代理微服務(wù)網(wǎng)關(guān) gateway 概述1、想象一下一個
    發(fā)表于 12-23 08:19

    [魯班貓創(chuàng)意氛圍賽]項目提交:本地LoRaWAN網(wǎng)關(guān)

    chirpstack-gateway-bridge 橋接器,橋接集中器與服務(wù)器之間的通訊 chirpstack 服務(wù)器,用來管理集中器,設(shè)備等角色,并管理數(shù)據(jù),設(shè)備描述等,相關(guān)數(shù)據(jù)保存在數(shù)據(jù)庫里 當(dāng)前
    發(fā)表于 05-13 16:11

    利用Gateway實現(xiàn)上位機監(jiān)控

    前言此技術(shù)文件用于介紹觸控大師的Gateway Server(網(wǎng)關(guān)服務(wù))的設(shè)定與使用方式。用戶可以通過這個功能來實現(xiàn)上位機局域網(wǎng)遠(yuǎn)程監(jiān)控的功能。特點􀁺提供 1 個以太
    發(fā)表于 11-29 16:00 ?0次下載
    <b class='flag-5'>利用</b><b class='flag-5'>Gateway</b>實現(xiàn)上位機監(jiān)控

    六、利用ESP32搭建網(wǎng)絡(luò)服務(wù)器(一)

    六、利用ESP32搭建網(wǎng)絡(luò)服務(wù)器(一)歡迎使用Markdown編輯器新的改變功能快捷鍵合理的創(chuàng)建標(biāo)題,有助于目錄的生成如何改變文本的樣式插入鏈接與圖片如何插入一段漂亮的代碼片生成一個適合你的列表創(chuàng)建
    發(fā)表于 12-29 19:00 ?3次下載
    六、<b class='flag-5'>利用</b>ESP32<b class='flag-5'>搭建網(wǎng)絡(luò)服務(wù)</b>器(一)

    網(wǎng)站搭建時該如何選擇租用服務(wù)

    搭建網(wǎng)站的時候是必須要用到服務(wù)器。服務(wù)器分很多種,有用來開發(fā)游戲叫游戲服務(wù)器,用來存放數(shù)據(jù)叫數(shù)據(jù)庫服務(wù)器,有應(yīng)用
    發(fā)表于 03-14 09:44 ?888次閱讀

    Dubbo Gateway基于Java的Dubbo網(wǎng)關(guān)實現(xiàn)

    ./oschina_soft/dubbo-gateway.zip
    發(fā)表于 06-14 10:28 ?3次下載
    Dubbo <b class='flag-5'>Gateway</b>基于Java的Dubbo<b class='flag-5'>網(wǎng)關(guān)</b>實現(xiàn)

    Spring Cloud Gateway服務(wù)網(wǎng)關(guān)的部署與使用詳細(xì)教程

    Gateway 網(wǎng)關(guān)搭建: 3、Spring Cloud Gateway 配置項的說明: 4、Gateway 集成 nacos 注冊中心
    的頭像 發(fā)表于 10-11 17:46 ?1720次閱讀

    如何使用Gateway搭建網(wǎng)關(guān)服務(wù)及實現(xiàn)動態(tài)路由?

    網(wǎng)關(guān)作為請求統(tǒng)一入口,路由就相當(dāng)于是每個業(yè)務(wù)系統(tǒng)的入口,通過路由規(guī)則則可以匹配到對應(yīng)微服務(wù)的入口,將請求命中到對應(yīng)的業(yè)務(wù)系統(tǒng)中
    的頭像 發(fā)表于 11-15 10:12 ?1452次閱讀

    新品速遞 | 虹科CAN FD轉(zhuǎn)LAN網(wǎng)關(guān):PCAN-Ethernet Gateway FD DR

    PCAN-Ethernet Gateway FD DR網(wǎng)關(guān)可以通過IP網(wǎng)絡(luò)訪問傳統(tǒng)CAN總線或CAN FD總線。
    的頭像 發(fā)表于 11-03 17:43 ?1346次閱讀
    新品速遞 | 虹科CAN FD轉(zhuǎn)LAN<b class='flag-5'>網(wǎng)關(guān)</b>:PCAN-Ethernet <b class='flag-5'>Gateway</b> FD DR

    網(wǎng)關(guān)GateWay的基本概念和使用詳解

    SpringCloudGateway網(wǎng)關(guān)是所有微服務(wù)的統(tǒng)一入口。
    的頭像 發(fā)表于 08-08 09:39 ?2195次閱讀
    <b class='flag-5'>網(wǎng)關(guān)</b><b class='flag-5'>GateWay</b>的基本概念和使用詳解

    Spring Cloud Gateway網(wǎng)關(guān)框架

    Spring Cloud Gateway網(wǎng)關(guān)框架 本軟件微服務(wù)架構(gòu)中采用Spring Cloud Gateway網(wǎng)關(guān)控制框架,Spring
    的頭像 發(fā)表于 08-22 09:58 ?430次閱讀
    Spring Cloud <b class='flag-5'>Gateway</b><b class='flag-5'>網(wǎng)關(guān)</b>框架