IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

聊聊dubbo-go的HystrixFilter

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

本文主要研究一下dubbo-go的HystrixFilter

HystrixFilter

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

// HystrixFilter ...
type HystrixFilter struct {
    COrP     bool //true for consumer
    res      map[string][]*regexp.Regexp
    ifNewMap sync.Map
}

  • HystrixFilter定义了COrP、res、ifNewMap属性

Invoke

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

// Invoke ...
func (hf *HystrixFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
    cmdName := fmt.Sprintf("%s&method=%s", invoker.GetUrl().Key(), invocation.MethodName())

    // Do the configuration if the circuit breaker is created for the first time
    if _, load := hf.ifNewMap.LoadOrStore(cmdName, true); !load {
        configLoadMutex.Lock()
        filterConf := getConfig(invoker.GetUrl().Service(), invocation.MethodName(), hf.COrP)
        for _, ptn := range filterConf.Error {
            reg, err := regexp.Compile(ptn)
            if err != nil {
                logger.Warnf("[Hystrix Filter]Errors occurred parsing error omit regexp: %s, %v", ptn, err)
            } else {
                if hf.res == nil {
                    hf.res = make(map[string][]*regexp.Regexp)
                }
                hf.res[invocation.MethodName()] = append(hf.res[invocation.MethodName()], reg)
            }
        }
        hystrix.ConfigureCommand(cmdName, hystrix.CommandConfig{
            Timeout:                filterConf.Timeout,
            MaxConcurrentRequests:  filterConf.MaxConcurrentRequests,
            SleepWindow:            filterConf.SleepWindow,
            ErrorPercentThreshold:  filterConf.ErrorPercentThreshold,
            RequestVolumeThreshold: filterConf.RequestVolumeThreshold,
        })
        configLoadMutex.Unlock()
    }
    configLoadMutex.RLock()
    _, _, err := hystrix.GetCircuit(cmdName)
    configLoadMutex.RUnlock()
    if err != nil {
        logger.Errorf("[Hystrix Filter]Errors occurred getting circuit for %s , will invoke without hystrix, error is: ", cmdName, err)
        return invoker.Invoke(ctx, invocation)
    }
    logger.Infof("[Hystrix Filter]Using hystrix filter: %s", cmdName)
    var result protocol.Result
    _ = hystrix.Do(cmdName, func() error {
        result = invoker.Invoke(ctx, invocation)
        err := result.Error()
        if err != nil {
            result.SetError(NewHystrixFilterError(err, false))
            for _, reg := range hf.res[invocation.MethodName()] {
                if reg.MatchString(err.Error()) {
                    logger.Debugf("[Hystrix Filter]Error in invocation but omitted in circuit breaker: %v; %s", err, cmdName)
                    return nil
                }
            }
        }
        return err
    }, func(err error) error {
        //Return error and if it is caused by hystrix logic, so that it can be handled by previous filters.
        _, ok := err.(hystrix.CircuitError)
        logger.Debugf("[Hystrix Filter]Hystrix health check counted, error is: %v, failed by hystrix: %v; %s", err, ok, cmdName)
        result = &protocol.RPCResult{}
        result.SetResult(nil)
        result.SetError(NewHystrixFilterError(err, ok))
        return err
    })
    return result
}

  • Invoke方法首先通过hf.ifNewMap.LoadOrStore判断该cmdName的circuit breaker是否已经创建,还没有创建的话,会通过getConfig获取filterConf,给指定的invocation.MethodName()创建reg,之后通过hystrix.ConfigureCommand进行配置;之后通过hystrix.GetCircuit(cmdName)获取circuit,然后执行hystrix.Do,在该func里头执行invoker.Invoke(ctx, invocation)

OnResponse

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

// OnResponse ...
func (hf *HystrixFilter) OnResponse(ctx context.Context, result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
    return result
}

  • OnResponse方法目前直接返回result

GetHystrixFilterConsumer

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

// GetHystrixFilterConsumer ...
func GetHystrixFilterConsumer() filter.Filter {
    //When first called, load the config in
    consumerConfigOnce.Do(func() {
        if err := initHystrixConfigConsumer(); err != nil {
            logger.Warnf("[Hystrix Filter]Config load failed for consumer, error is: %v , will use default", err)
        }
    })
    return &HystrixFilter{COrP: true}
}

  • GetHystrixFilterConsumer创建的HystrixFilter的COrP属性为true

GetHystrixFilterProvider

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

// GetHystrixFilterProvider ...
func GetHystrixFilterProvider() filter.Filter {
    providerConfigOnce.Do(func() {
        if err := initHystrixConfigProvider(); err != nil {
            logger.Warnf("[Hystrix Filter]Config load failed for provider, error is: %v , will use default", err)
        }
    })
    return &HystrixFilter{COrP: false}
}

  • GetHystrixFilterProvider创建的HystrixFilter的COrP属性为false

initHystrixConfigConsumer

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

func initHystrixConfigConsumer() error {
    if config.GetConsumerConfig().FilterConf == nil {
        return perrors.Errorf("no config for hystrix")
    }
    filterConfig := config.GetConsumerConfig().FilterConf.(map[interface{}]interface{})[HYSTRIX]
    if filterConfig == nil {
        return perrors.Errorf("no config for hystrix")
    }
    hystrixConfByte, err := yaml.Marshal(filterConfig)
    if err != nil {
        return err
    }
    err = yaml.Unmarshal(hystrixConfByte, confConsumer)
    if err != nil {
        return err
    }
    return nil
}

  • initHystrixConfigConsumer会根据config.GetConsumerConfig().FilterConf的filterConfig来创建confConsumer

initHystrixConfigProvider

dubbo-go-v1.4.2/filter/filter_impl/hystrix_filter.go

func initHystrixConfigProvider() error {
    if config.GetProviderConfig().FilterConf == nil {
        return perrors.Errorf("no config for hystrix")
    }
    filterConfig := config.GetConsumerConfig().FilterConf.(map[interface{}]interface{})[HYSTRIX]
    if filterConfig == nil {
        return perrors.Errorf("no config for hystrix")
    }
    hystrixConfByte, err := yaml.Marshal(filterConfig)
    if err != nil {
        return err
    }
    err = yaml.Unmarshal(hystrixConfByte, confProvider)
    if err != nil {
        return err
    }
    return nil
}

  • initHystrixConfigProvider方法根据filterConfig来创建confProvider

小结

HystrixFilter的Invoke方法首先通过hf.ifNewMap.LoadOrStore判断该cmdName的circuit breaker是否已经创建,还没有创建的话,会通过getConfig获取filterConf,给指定的invocation.MethodName()创建reg,之后通过hystrix.ConfigureCommand进行配置;之后通过hystrix.GetCircuit(cmdName)获取circuit,然后执行hystrix.Do,在该func里头执行invoker.Invoke(ctx, invocation)

doc

  • hystrix_filter

文章永久链接:https://tech.souyunku.com/?p=25960


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(97) 打赏



未经允许不得转载:搜云库技术团队 » 聊聊dubbo-go的HystrixFilter

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367