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

Spring Cloud 網(wǎng)關(guān)服務(wù) zuul  動(dòng)態(tài)路由的實(shí)現(xiàn)方法

 更新時(shí)間:2019年10月31日 08:48:19   作者:程序員你大爺  
網(wǎng)關(guān)服務(wù)是流量的唯一入口。不能隨便停服務(wù)。所以動(dòng)態(tài)路由就顯得尤為必要。這篇文章主要介紹了Spring Cloud 網(wǎng)關(guān)服務(wù) zuul 三 動(dòng)態(tài)路由的相關(guān)知識(shí),需要的朋友可以參考下

zuul動(dòng)態(tài)路由

網(wǎng)關(guān)服務(wù)是流量的唯一入口。不能隨便停服務(wù)。所以動(dòng)態(tài)路由就顯得尤為必要。

數(shù)據(jù)庫(kù)動(dòng)態(tài)路由基于事件刷新機(jī)制熱修改zuul的路由屬性。

DiscoveryClientRouteLocator

可以看到DiscoveryClientRouteLocator 是默認(rèn)的刷新的核心處理類(lèi)。

//重新加載路由信息方法 protected方法。需要子方法重新方法。
protected LinkedHashMap<String, ZuulRoute> locateRoutes()

//觸發(fā)刷新的方法 RefreshableRouteLocator 接口
 public void refresh() {
   this.doRefresh();
 }

而這倆個(gè)方法都是繼承與SimpleRouteLocator 類(lèi),并進(jìn)行了重新操作。其實(shí)官方的方法注釋說(shuō)明了。如果需要?jiǎng)討B(tài)讀取加載映射關(guān)系。則需要子類(lèi)重寫(xiě)這倆個(gè)方法。

進(jìn)行具體的實(shí)現(xiàn)

首先pom jar包導(dǎo)入 需要連接mysql 數(shù)據(jù)庫(kù)  

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
  </dependency>

  <!-- jdbc -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
  </dependency>

路由實(shí)體 ZuulRouteEntity

package com.xian.cloud.entity;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * <Description> 路由實(shí)體類(lèi)
 *
 * @author xianliru@100tal.com
 * @version 1.0
 * @createDate 2019/10/30 15:00
 */
@Data
public class ZuulRouteEntity implements Serializable {
 private static final long serialVersionUID = 1L;

 /**
  * router Id
  */
 private Integer id;
 /**
  * 路由路徑
  */
 private String path;
 /**
  * 服務(wù)名稱(chēng)
  */
 private String serviceId;
 /**
  * url代理
  */
 private String url;
 /**
  * 轉(zhuǎn)發(fā)去掉前綴
  */
 private String stripPrefix;
 /**
  * 是否重試
  */
 private String retryable;
 /**
  * 是否啟用
  */
 private String enabled;
 /**
  * 敏感請(qǐng)求頭
  */
 private String sensitiveheadersList;
 /**
  * 創(chuàng)建時(shí)間
  */
 private Date createTime;
 /**
  * 更新時(shí)間
  */
 private Date updateTime;
 /**
  * 刪除標(biāo)識(shí)(0-正常,1-刪除)
  */
 private String delFlag;
}

新建DiscoveryRouteLocator 類(lèi) 父類(lèi) 接口 都不變化

package com.xian.cloud.router;


import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.xian.cloud.entity.ZuulRoute;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <Description>
 *
 * @author xianliru@100tal.com
 * @version 1.0
 * @createDate 2019/10/30 18:57
 */
@Slf4j
public class DiscoveryRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

 private ZuulProperties properties;

 private JdbcTemplate jdbcTemplate;

 public DiscoveryRouteLocator(String servletPath, ZuulProperties properties, JdbcTemplate jdbcTemplate) {
  super(servletPath, properties);
  this.properties = properties;
  this.jdbcTemplate = jdbcTemplate;
  log.info("servletPath:{}",servletPath);
 }

 @Override
 public void refresh() {
  doRefresh();
 }

 @Override
 protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
  LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<String, ZuulProperties.ZuulRoute>();
  //從配置文件中加載路由信息
  routesMap.putAll(super.locateRoutes());
  //自定義加載路由信息
  routesMap.putAll(getRouteList());
  //優(yōu)化一下配置
  LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
  for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
   String path = entry.getKey();
   // Prepend with slash if not already present.
   if (!path.startsWith("/")) {
    path = "/" + path;
   }
   if (StringUtils.hasText(this.properties.getPrefix())) {
    path = this.properties.getPrefix() + path;
    if (!path.startsWith("/")) {
     path = "/" + path;
    }
   }
   values.put(path, entry.getValue());
  }
  return values;
 }

 /**
  * 從數(shù)據(jù)庫(kù)讀取zuul路由規(guī)則
  * @return
  */
 private LinkedHashMap<String, ZuulProperties.ZuulRoute> getRouteList() {
  LinkedHashMap<String, ZuulProperties.ZuulRoute> zuulRoutes = new LinkedHashMap<>();
  List<ZuulRoute> sysZuulRoutes = jdbcTemplate.query("select * from sys_zuul_route where del_flag = 0", new BeanPropertyRowMapper<>(ZuulRoute.class));

  for (ZuulRoute route: sysZuulRoutes) {

   // 為空跳過(guò)
   if (Strings.isNullOrEmpty(route.getPath()) && Strings.isNullOrEmpty(route.getUrl())) {
    continue;
   }

   ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
   try {
    zuulRoute.setId(route.getServiceId());
    zuulRoute.setPath(route.getPath());
    zuulRoute.setServiceId(route.getServiceId());
    zuulRoute.setRetryable(Objects.equals("0", route.getRetryable()) ? Boolean.FALSE : Boolean.TRUE);
    zuulRoute.setStripPrefix(Objects.equals("0", route.getStripPrefix()) ? Boolean.FALSE : Boolean.TRUE);
    zuulRoute.setUrl(route.getUrl());
    List<String> sensitiveHeadersList = Arrays.asList(route.getSensitiveheadersList().split(","));
    if (sensitiveHeadersList != null) {
     Set<String> sensitiveHeaderSet = Sets.newHashSet();
     sensitiveHeadersList.forEach(sensitiveHeader -> sensitiveHeaderSet.add(sensitiveHeader));
     zuulRoute.setSensitiveHeaders(sensitiveHeaderSet);
     zuulRoute.setCustomSensitiveHeaders(true);
    }
   } catch (Exception e) {
    log.error("數(shù)據(jù)庫(kù)加載配置異常", e);
   }
   log.info("自定義的路由配置,path:{},serviceId:{}", zuulRoute.getPath(), zuulRoute.getServiceId());
   zuulRoutes.put(zuulRoute.getPath(), zuulRoute);

  }
  return zuulRoutes;
 }
}


我們還需要一個(gè)事件的生產(chǎn)者 和 消費(fèi)者 直接圖方便 集成到一個(gè)類(lèi)中

package com.xian.cloud.event;

import com.xian.cloud.router.DiscoveryRouteLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;

/**
 * <Description> 路由刷新事件發(fā)布,與事件監(jiān)聽(tīng)者
 *
 * @author xianliru@100tal.com
 * @version 1.0
 * @createDate 2019/10/30 15:27
 */
@Service
public class RefreshRouteService implements ApplicationListener<ApplicationEvent> {

 @Autowired
 private ZuulHandlerMapping zuulHandlerMapping;

 private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();

 @Autowired
 ApplicationEventPublisher publisher;

 @Autowired
 private DiscoveryRouteLocator dynamicRouteLocator;

 /**
  * 動(dòng)態(tài)路由實(shí)現(xiàn) 調(diào)用refreshRoute() 發(fā)布刷新路由事件
  */
 public void refreshRoute() {
  RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(dynamicRouteLocator);
  publisher.publishEvent(routesRefreshedEvent);
 }

 /**
  * 事件監(jiān)聽(tīng)者。監(jiān)控檢測(cè)事件刷新
  * @param event
  */
 @Override
 public void onApplicationEvent(ApplicationEvent event) {
  if(event instanceof ContextRefreshedEvent || event instanceof RefreshScopeRefreshedEvent || event instanceof RoutesRefreshedEvent){
   //主動(dòng)手動(dòng)刷新。上下文刷新,配置屬性刷新
   zuulHandlerMapping.setDirty(true);
  }else if(event instanceof HeartbeatEvent){
   //心跳觸發(fā),將本地映射關(guān)系。關(guān)聯(lián)到遠(yuǎn)程服務(wù)上
   HeartbeatEvent heartbeatEvent = (HeartbeatEvent)event;
   if(heartbeatMonitor.update(heartbeatEvent.getValue())){
    zuulHandlerMapping.setDirty(true);
   }
  }
 }
}

對(duì)外提供觸發(fā)接口

package com.xian.cloud.controller;
import com.xian.cloud.event.RefreshRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <Description> 手動(dòng)刷新對(duì)外接口
 *
 * @author xianliru@100tal.com
 * @version 1.0
 * @createDate 2019/10/30 20:23
 */
@RestController
public class RefreshController {
 @Autowired
 private RefreshRouteService refreshRouteService;
 @GetMapping("/refresh")
 public String refresh() {
  refreshRouteService.refreshRoute();
  return "refresh";
 }
}

數(shù)據(jù)庫(kù)表結(jié)構(gòu)

CREATE TABLE `sys_zuul_route` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'router Id',
 `path` varchar(255) NOT NULL COMMENT '路由路徑',
 `service_id` varchar(255) NOT NULL COMMENT '服務(wù)名稱(chēng)',
 `url` varchar(255) DEFAULT NULL COMMENT 'url代理',
 `strip_prefix` char(1) DEFAULT '1' COMMENT '轉(zhuǎn)發(fā)去掉前綴',
 `retryable` char(1) DEFAULT '1' COMMENT '是否重試',
 `enabled` char(1) DEFAULT '1' COMMENT '是否啟用',
 `sensitiveHeaders_list` varchar(255) DEFAULT NULL COMMENT '敏感請(qǐng)求頭',
 `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
 `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間',
 `del_flag` char(1) DEFAULT '0' COMMENT '刪除標(biāo)識(shí)(0-正常,1-刪除)',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='動(dòng)態(tài)路由配置表'

將配置文件client 消費(fèi)者服務(wù) 路由配置注釋掉。設(shè)置數(shù)據(jù)源。從數(shù)據(jù)庫(kù)中讀取

啟動(dòng)服務(wù)打印日志

2019-10-30 20:49:39.946  INFO 63449 --- [TaskScheduler-1] c.xian.cloud.router.DynamicRouteLocator  : 添加數(shù)據(jù)庫(kù)自定義的路由配置,path:/client/**,serviceId:cloud-discovery-client
2019-10-30 20:49:40.397  INFO 63449 --- [TaskScheduler-1] c.xian.cloud.router.DynamicRouteLocator  : 添加數(shù)據(jù)庫(kù)自定義的路由配置,path:/client/**,serviceId:cloud-discovery-client
postman 請(qǐng)求client 接口 看看是否能轉(zhuǎn)發(fā)成功

基于zuul 動(dòng)態(tài)網(wǎng)關(guān)路由完成。

總結(jié)

以上所述是小編給大家介紹的Spring Cloud 網(wǎng)關(guān)服務(wù) zuul  動(dòng)態(tài)路由的實(shí)現(xiàn)方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • SpringBoot整合canal實(shí)現(xiàn)數(shù)據(jù)同步的示例代碼

    SpringBoot整合canal實(shí)現(xiàn)數(shù)據(jù)同步的示例代碼

    本文主要介紹了SpringBoot整合canal實(shí)現(xiàn)數(shù)據(jù)同步,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • java 實(shí)現(xiàn)發(fā)短信功能---騰訊云短信

    java 實(shí)現(xiàn)發(fā)短信功能---騰訊云短信

    如今發(fā)短信功能已經(jīng)成為互聯(lián)網(wǎng)公司的標(biāo)配,接下來(lái)通過(guò)本文給大家介紹java 實(shí)現(xiàn)發(fā)短信功能---騰訊云短信 ,需要的朋友可以參考下
    2019-08-08
  • java 重定義數(shù)組的實(shí)現(xiàn)方法(與VB的ReDim相像)

    java 重定義數(shù)組的實(shí)現(xiàn)方法(與VB的ReDim相像)

    java 重定義數(shù)組的實(shí)現(xiàn)方法(與VB的ReDim相像),需要的朋友可以參考一下
    2013-04-04
  • 使用java + selenium + OpenCV破解網(wǎng)易易盾滑動(dòng)驗(yàn)證碼的示例

    使用java + selenium + OpenCV破解網(wǎng)易易盾滑動(dòng)驗(yàn)證碼的示例

    這篇文章主要介紹了使用java + selenium + OpenCV破解網(wǎng)易易盾滑動(dòng)驗(yàn)證碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Springboot中攔截GET請(qǐng)求獲取請(qǐng)求參數(shù)驗(yàn)證合法性核心方法

    Springboot中攔截GET請(qǐng)求獲取請(qǐng)求參數(shù)驗(yàn)證合法性核心方法

    這篇文章主要介紹了Springboot中攔截GET請(qǐng)求獲取請(qǐng)求參數(shù)驗(yàn)證合法性,在Springboot中創(chuàng)建攔截器攔截所有GET類(lèi)型請(qǐng)求,獲取請(qǐng)求參數(shù)驗(yàn)證內(nèi)容合法性防止SQL注入,這種方法適用攔截get類(lèi)型請(qǐng)求,需要的朋友可以參考下
    2023-08-08
  • Java并發(fā)編程示例(七):守護(hù)線(xiàn)程的創(chuàng)建和運(yùn)行

    Java并發(fā)編程示例(七):守護(hù)線(xiàn)程的創(chuàng)建和運(yùn)行

    這篇文章主要介紹了Java并發(fā)編程示例(七):守護(hù)線(xiàn)程的創(chuàng)建和運(yùn)行,在本節(jié)示例中,我們將創(chuàng)建兩個(gè)線(xiàn)程,一個(gè)是普通線(xiàn)程,向隊(duì)列中寫(xiě)入事件,另外一個(gè)是守護(hù)線(xiàn)程,清除隊(duì)列中的事件,需要的朋友可以參考下
    2014-12-12
  • SpringBoot中使用spring-retry 解決失敗重試調(diào)用

    SpringBoot中使用spring-retry 解決失敗重試調(diào)用

    本文主要介紹了SpringBoot中使用spring-retry 解決失敗重試調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java實(shí)現(xiàn)Treap樹(shù)的示例代碼

    Java實(shí)現(xiàn)Treap樹(shù)的示例代碼

    本文主要介紹了Java實(shí)現(xiàn)Treap樹(shù)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • springboot中使用redis并且執(zhí)行調(diào)試lua腳本

    springboot中使用redis并且執(zhí)行調(diào)試lua腳本

    今天有個(gè)項(xiàng)目需要使用redis,并且有使用腳本的需求,本文主要介紹了springboot中使用redis并且執(zhí)行調(diào)試lua腳本,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • IDEA如何設(shè)置忽略git提交的文件

    IDEA如何設(shè)置忽略git提交的文件

    這篇文章主要介紹了IDEA如何設(shè)置忽略git提交的文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評(píng)論

嵊泗县| 台南市| 鄂温| 长治县| 哈巴河县| 湄潭县| 宣化县| 沾化县| 五原县| 灵川县| 剑川县| 策勒县| 台中市| 奉节县| 上思县| 新绛县| 阳泉市| 昭觉县| 中宁县| 会理县| 苏州市| 福清市| 时尚| 洛隆县| 老河口市| 铜鼓县| 苏尼特左旗| 汝城县| 河源市| 高清| 会东县| 太保市| 阿尔山市| 旬阳县| 阿拉善右旗| 琼中| 衡阳县| 鸡泽县| 重庆市| 玛沁县| 砀山县|