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

Java使用Gateway自定義負(fù)載均衡過(guò)濾器

 更新時(shí)間:2020年07月06日 10:13:16   作者:愛(ài)唱歌的Coder  
這篇文章主要介紹了Java使用Gateway自定義負(fù)載均衡過(guò)濾器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

背景

最近項(xiàng)目中需要上傳視頻文件,由于視頻文件可能會(huì)比較大,但是我們應(yīng)用服務(wù)器tomcat設(shè)置單次只支持的100M,因此決定開(kāi)發(fā)一個(gè)分片上傳接口。
把大文件分成若干個(gè)小文件上傳。所有文件上傳完成后通過(guò)唯一標(biāo)示進(jìn)行合并文件。
我們的開(kāi)發(fā)人員很快完成了開(kāi)發(fā),并在單元測(cè)試中表現(xiàn)無(wú)誤。上傳代碼到測(cè)試環(huán)境,喔嚯?。?!出錯(cuò)了。
經(jīng)過(guò)一段時(shí)間的辛苦排查終于發(fā)現(xiàn)問(wèn)題,測(cè)試環(huán)境多實(shí)例,分片上傳的接口會(huì)被路由到不同的實(shí)例,導(dǎo)致上傳后的分片文件在不同的機(jī)器,那么也就無(wú)法被合并。
知道了原因就好解決,經(jīng)過(guò)一系列的過(guò)程最終決定修改網(wǎng)關(guān)把uuid相同的請(qǐng)求路由到相同的實(shí)例上,這樣就不會(huì)出錯(cuò)了!

準(zhǔn)備

由于是公司代碼不方便透露,現(xiàn)使用本地測(cè)試代碼。
準(zhǔn)備:Eureka注冊(cè)中心,Gateway網(wǎng)關(guān),測(cè)試微服務(wù)

啟動(dòng)后服務(wù)如下兩個(gè)測(cè)試的微服務(wù),一個(gè)網(wǎng)關(guān)服務(wù)

gateway版本

<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>

此處就說(shuō)下我網(wǎng)關(guān)的配置。

#網(wǎng)關(guān)名
spring.cloud.gateway.routes[0].id=route-my-service-id
#網(wǎng)關(guān)uri,lb代表負(fù)載均衡,后面是服務(wù)名,必須要和微服務(wù)名一致,不能錯(cuò),錯(cuò)了肯定不能路由
spring.cloud.gateway.routes[0].uri=lb://my-service-id
#斷言,配置的路徑
spring.cloud.gateway.routes[0].predicates[0]=Path=/my-service-id/v3/**
#截取uri前面兩個(gè)位置的
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=2

分析

想要修改路由就要知道gateway是如何把我們的請(qǐng)求路由到各個(gè)微服務(wù)的實(shí)例上的。

gateway其實(shí)無(wú)非就是不同的過(guò)濾器,然后對(duì)請(qǐng)求進(jìn)行處理,和zuul類(lèi)似。gateway自帶了很多過(guò)濾器。過(guò)濾器分為兩種:

1、GlobalFilter 。顧名思義,全局過(guò)濾器,所有請(qǐng)求都會(huì)走的過(guò)濾器。常見(jiàn)的自帶過(guò)濾器LoadBalancerClientFilter(負(fù)載均衡過(guò)濾器,后面我們就是修改這個(gè)地方)。

2、GatewayFilter。網(wǎng)關(guān)過(guò)濾器,該過(guò)濾器可以指定過(guò)濾的條件,只有達(dá)到了條件的才進(jìn)入該過(guò)濾器。

如果想知道自帶有哪些配置,我們可以查看gateway的自動(dòng)注入類(lèi)GatewayAutoConfiguration。

/**
 * @author Spencer Gibb
 */
@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class,
		WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayLoadBalancerClientAutoConfiguration.class,
		GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {

	@Bean
	public StringToZonedDateTimeConverter stringToZonedDateTimeConverter() {
		return new StringToZonedDateTimeConverter();
	}

	@Bean
	public RouteLocatorBuilder routeLocatorBuilder(
			ConfigurableApplicationContext context) {
		return new RouteLocatorBuilder(context);
	}

	@Bean
	@ConditionalOnMissingBean
	public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(
			GatewayProperties properties) {
		return new PropertiesRouteDefinitionLocator(properties);
	}
省略.......

然后查看負(fù)載均衡配置。
GatewayLoadBalancerClientAutoConfiguration

/**
 * @author Spencer Gibb
 */
@Configuration
@ConditionalOnClass({ LoadBalancerClient.class, RibbonAutoConfiguration.class,
		DispatcherHandler.class })
@AutoConfigureAfter(RibbonAutoConfiguration.class)
@EnableConfigurationProperties(LoadBalancerProperties.class)
public class GatewayLoadBalancerClientAutoConfiguration {

	// GlobalFilter beans

	//負(fù)載均衡
	@Bean
	@ConditionalOnBean(LoadBalancerClient.class)
	@ConditionalOnMissingBean(LoadBalancerClientFilter.class)
	public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client,
			LoadBalancerProperties properties) {
		return new LoadBalancerClientFilter(client, properties);
	}

}

進(jìn)入LoadBalancerClientFilter,其實(shí)就是一個(gè)GlobalFilter。
調(diào)試代碼試一試呢?發(fā)現(xiàn)果然要走。(此處圖片中應(yīng)該是my-service-id)。


最終被路由到這個(gè)地方,負(fù)載均衡使用的是ribbon,關(guān)于ribbon暫時(shí)不討論。


重點(diǎn)在這兒,通過(guò)現(xiàn)在的uri選擇到具體的uri。而這個(gè)方法恰恰是一個(gè)protected方法,我們可以重寫(xiě)該方法加上我們自己的業(yè)務(wù)邏輯。

protected ServiceInstance choose(ServerWebExchange exchange) {
		return loadBalancer.choose(
				((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost());
	}

實(shí)現(xiàn)

重寫(xiě)LoadBalancerClientFilter中的choose方法,實(shí)現(xiàn)自定義邏輯

/**
 * @Description 自定義負(fù)載均衡
 * @Author Singh
 * @Date 2020-07-02 10:36
 * @Version
 **/
public class CustomLoadBalancerClientFilter extends LoadBalancerClientFilter implements BeanPostProcessor {

  private final DiscoveryClient discoveryClient;

  private final List<IChooseRule> chooseRules;

  public CustomLoadBalancerClientFilter(LoadBalancerClient loadBalancer,
                     LoadBalancerProperties properties,
                     DiscoveryClient discoveryClient) {
    super(loadBalancer, properties);
    this.discoveryClient = discoveryClient;
    this.chooseRules = new ArrayList<>();
    chooseRules.add(new EngineeringChooseRule());
  }

  protected ServiceInstance choose(ServerWebExchange exchange) {
    if(!CollectionUtils.isEmpty(chooseRules)){
      Iterator<IChooseRule> iChooseRuleIterator = chooseRules.iterator();
      while (iChooseRuleIterator.hasNext()){
        IChooseRule chooseRule = iChooseRuleIterator.next();
        ServiceInstance choose = chooseRule.choose(exchange,discoveryClient);
        if(choose != null){
          return choose;
        }
      }
    }
    return loadBalancer.choose(
        ((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost());
  }
}

定義通用選擇實(shí)例規(guī)則

/**
 * @Description 自定義選擇實(shí)例規(guī)則
 * @Author Singh
 * @Date 2020-07-02 11:03
 * @Version
 **/
public interface IChooseRule {

  /**
   * 返回null那么使用gateway默認(rèn)的負(fù)載均衡策略
   * @param exchange
   * @param discoveryClient
   * @return
   */
  ServiceInstance choose(ServerWebExchange exchange, DiscoveryClient discoveryClient);

}

實(shí)現(xiàn)自定義路由策略

/**
 * @Description 微服務(wù)負(fù)載均衡策略
 * @Author Singh
 * @Date 2020-07-02 11:10
 * @Version
 **/
public class EngineeringChooseRule implements IChooseRule {

  @Override
  public ServiceInstance choose(ServerWebExchange exchange, DiscoveryClient discoveryClient) {
    URI originalUrl = (URI) exchange.getAttributes().get(GATEWAY_REQUEST_URL_ATTR);
    String instancesId = originalUrl.getHost();
    if(instancesId.equals("my-service-id")){
      if(originalUrl.getPath().contains("/files/upload")){
        try{
          List<ServiceInstance> instances = discoveryClient.getInstances(instancesId);
          MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
          String uuid = queryParams.get("uuid").get(0);
          int hash = uuid.hashCode() >>> 16 ;
          int index = hash % instances.size();
          return instances.get(index);
        }catch (Exception e){
          //do nothing
        }
      }
    }

    return null;
  }
}

最后注入自定義負(fù)載均衡過(guò)濾器。

/**
 * @Description
 * @Author Singh
 * @Date 2020-07-01 17:57
 * @Version
 **/
@Configuration
public class GetawayConfig {

//  @Bean
//  public RouteLocator routeLocator(RouteLocatorBuilder builder) {
//    //lb://hjhn-engineering/files/upload
//    return builder.routes()
//        .route(r ->r.path("/**").filters(
//                    f -> f.stripPrefix(2).filters(new EngineeringGatewayFilter())
//                ).uri("lb://hjhn-engineering")
//        ) .build();
//  }

  @Bean
  public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client,
                               LoadBalancerProperties properties,
                              DiscoveryClient discoveryClient) {
      return new CustomLoadBalancerClientFilter(client, properties,discoveryClient);
  }

}

如此,相同uuid的請(qǐng)求就可以通過(guò)hash取模路由到相同的機(jī)器上了,當(dāng)然這樣還是存在問(wèn)題,比如多添加一個(gè)實(shí)例,或者掛了一個(gè)實(shí)例,掛之前有一個(gè)請(qǐng)求到A,掛之后可能到B,因?yàn)榇藭r(shí)取模就不同了,還是會(huì)到不同請(qǐng)求。但是這種情況很少發(fā)生,所以暫時(shí)不考慮。

或許有hash槽的方式可以解決一點(diǎn)問(wèn)題,后續(xù)研究!?。。。?/p>

到此這篇關(guān)于Java使用Gateway自定義負(fù)載均衡過(guò)濾器的文章就介紹到這了,更多相關(guān)Java 自定義負(fù)載均衡過(guò)濾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解java設(shè)計(jì)模式之六大原則

    詳解java設(shè)計(jì)模式之六大原則

    這篇文章主要介紹了java設(shè)計(jì)模式之六大原則,對(duì)設(shè)計(jì)模式感興趣的同學(xué),可以參考下
    2021-05-05
  • Eclipse查看開(kāi)發(fā)包jar里源代碼的方法

    Eclipse查看開(kāi)發(fā)包jar里源代碼的方法

    這篇文章主要介紹了Eclipse查看開(kāi)發(fā)包jar里源代碼的方法的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • 使用java寫(xiě)的矩陣乘法實(shí)例(Strassen算法)

    使用java寫(xiě)的矩陣乘法實(shí)例(Strassen算法)

    這篇文章主要給大家介紹了關(guān)于如何使用java寫(xiě)的矩陣乘法(Strassen算法)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • MyBatis中多對(duì)一和一對(duì)多數(shù)據(jù)的處理方法

    MyBatis中多對(duì)一和一對(duì)多數(shù)據(jù)的處理方法

    這篇文章主要介紹了MyBatis中多對(duì)一和一對(duì)多數(shù)據(jù)的處理,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • Mac系統(tǒng)搭建JDK及JMETER過(guò)程解析

    Mac系統(tǒng)搭建JDK及JMETER過(guò)程解析

    這篇文章主要介紹了Mac系統(tǒng)搭建JDK及JMETER過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java Arrays.AsList原理及用法實(shí)例

    Java Arrays.AsList原理及用法實(shí)例

    這篇文章主要介紹了Java Arrays.AsList原理及用法實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringSecurity概念及整合ssm框架的示例詳解

    SpringSecurity概念及整合ssm框架的示例詳解

    用戶(hù)登錄系統(tǒng)時(shí)我們協(xié)助?SpringSecurity?把用戶(hù)對(duì)應(yīng)的角色、權(quán)限組裝好,同時(shí)把各個(gè)資源所要求的權(quán)限信息設(shè)定好,剩下的“登錄驗(yàn)證”、“權(quán)限驗(yàn)證”等等工作都交給SpringSecurity,對(duì)SpringSecurity整合ssm框架相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • Spring?Boot?中的?Native?SQL基本概念及使用方法

    Spring?Boot?中的?Native?SQL基本概念及使用方法

    在本文中,我們介紹了 Spring Boot 中的 Native SQL,以及如何使用 JdbcTemplate 和 NamedParameterJdbcTemplate 來(lái)執(zhí)行自定義的 SQL 查詢(xún)或更新語(yǔ)句,需要的朋友跟隨小編一起看看吧
    2023-07-07
  • SpringBoot中Shiro緩存使用Redis、Ehcache的方法

    SpringBoot中Shiro緩存使用Redis、Ehcache的方法

    這篇文章主要介紹了SpringBoot中Shiro緩存使用Redis、Ehcache的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 為什么說(shuō)HashMap線(xiàn)程不安全

    為什么說(shuō)HashMap線(xiàn)程不安全

    本文主要介紹了為什么說(shuō)HashMap線(xiàn)程不安全,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評(píng)論