From 27bb050a9d7c55f39258565c4779749ffe597954 Mon Sep 17 00:00:00 2001 From: chuntaojun Date: Fri, 19 Nov 2021 02:09:54 +0800 Subject: [PATCH] fix: fix FeignClient proxy problem --- .../{bootstrap.yml => application.yml} | 16 - .../src/main/resources/polaris.yml | 381 +++++++----------- .../{bootstrap.yml => application.yml} | 16 - .../feign/PolarisFeignBeanPostProcessor.java | 5 +- .../tencent/cloud/feign/PluggableFeign.java | 2 +- 5 files changed, 148 insertions(+), 272 deletions(-) rename spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/{bootstrap.yml => application.yml} (53%) rename spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/{bootstrap.yml => application.yml} (53%) diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/application.yml similarity index 53% rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/application.yml index 32f2eb16c..78a6fbe2b 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/application.yml @@ -12,8 +12,6 @@ global: timeout: 5s feign: - hystrix: - enabled: true #在Feign中开启Hystrix compression: request: enabled: false #是否对请求进行GZIP压缩 @@ -22,19 +20,5 @@ feign: response: enabled: false #是否对响应进行GZIP压缩 -ribbon: - polaris: - enabled: true - # 同一实例最大重试次数,不包括首次调用 - MaxAutoRetries: 1 - # 重试其他实例的最大重试次数,不包括首次所选的server - MaxAutoRetriesNextServer: 2 - # 是否所有操作都进行重试 - OkToRetryOnAllOperations: false - ConnectionTimeout: 1000 - ReadTimeout: 1000 - eager-load: - enabled: on - serivceB: url: http://localhost:48081 \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml index 39d33bd6a..7ccb9ece0 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/polaris.yml @@ -1,287 +1,194 @@ -#描述:全局配置项 global: - #描述系统相关配置 + #描述: 系统相关配置 system: - #描述:SDK运行模式 - #类型:enum - #范围:0(直连模式,SDK直接对接server); 1(代理模式,SDK只对接agent, 通过agent进行server的对接) - #默认值:0 - mode: 0 - #服务发现集群 + #描述: 服务发现集群 discoverCluster: namespace: Polaris service: polaris.discover - #可选:服务刷新间隔 - refreshInterval: 10m - #健康检查集群 + #描述: 服务刷新间隔 + refreshInterval: 1m + #描述: 是否使用埋点地址作为服务发现集群 + sameAsBuiltin: true + #描述: 系统服务使用的路由链 + routers: + - metadataRouter + - nearbyBasedRouter + #描述: 系统服务使用的负载均衡方式 + lbPolicy: weightedRandom + #描述: 健康检查集群 healthCheckCluster: namespace: Polaris service: polaris.healthcheck - #可选:服务刷新间隔 - refreshInterval: 10m - #监控上报集群 + refreshInterval: 1m + sameAsBuiltin: true + routers: + - metadataRouter + - nearbyBasedRouter + lbPolicy: ringHash + #描述: 监控上报集群 monitorCluster: namespace: Polaris service: polaris.monitor - #可选:服务刷新间隔 - refreshInterval: 10m + refreshInterval: 1m + sameAsBuiltin: false + routers: + - metadataRouter + - nearbyBasedRouter + lbPolicy: ringHash + #描述: SDK流程数据缓存配置 + flowCache: + enable: true + name: simpleCache + expireInterval: 60s + #描述: SDK api调用相关配置 api: - #描述:api超时时间 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1ms:...] - #默认值:1s + #描述: api超时时间 timeout: 5s - #描述:上报间隔 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1ms:...] - #默认值:10m + #描述: 客户端给服务端定时上报自身信息的间隔 reportInterval: 10m - #描述:API因为网络原因调用失败后的重试次数 - #类型:int - #范围:[0:...] - #默认值:5 - maxRetryTimes: 5 - #描述:重试间隔 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1s:...] - #默认值:1s - retryInterval: 1s - #描述:对接polaris server的相关配置 + #描述: api因为网络原因调用失败后的最大重试次数 + maxRetryTimes: 1 + #描述: 2次重试之间的重试间隔 + retryInterval: 500ms + #描述: 对接北极星服务端的相关配置 serverConnector: - #描述:访问server的连接协议,SDK会根据协议名称会加载对应的插件 - #类型:string - #范围:已注册的连接器插件名 - #默认值:grpc + #描述:默认服务端埋点接入地址 + addresses: + - 127.0.0.1:8091 + #描述: 访问server的连接协议,SDK会根据协议名称会加载对应的插件 protocol: grpc - #描述:发起连接后的连接超时时间 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1ms:...] - #默认值:200ms + #描述: 发起连接后的连接超时时间 connectTimeout: 500ms - #描述:远程请求超时时间 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1ms:...] - #默认值:1s + #描述: 与服务端发起远程请求超时时间 messageTimeout: 5s - #描述:连接空闲时间,长连接模式下,当连接空闲超过一定时间后,SDK会主动释放连接 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1ms:...] - #默认值:1s - connectionIdleTimeout: 1s - #描述:首次请求的任务队列长度,当用户发起首次服务访问请求时,SDK会对任务进行队列调度并连接server,当积压的任务数超过队列长度后,SDK会直接拒绝首次请求的发起。 - #类型:int - #范围:[0:...] - #默认值:1000 - requestQueueSize: 1000 - #描述:server节点的切换周期,为了使得server的压力能够均衡,SDK会定期针对最新的节点列表进行重新计算自己当前应该连接的节点,假如和当前不一致,则进行切换 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1m:...] - #默认值:10m + #描述: 连接空闲时间(以最后一次消息交互时间来算),长连接模式下,当连接空闲超过一定时间后,SDK会主动释放连接 + connectionIdleTimeout: 60s + #描述: server节点的切换周期,为了使得server的压力能够均衡,SDK会定期切换目标服务端节点 serverSwitchInterval: 10m - plugin: - grpc: - #描述:GRPC客户端单次最大链路接收报文 - #类型:int - #范围:(0:524288000] - maxCallRecvMsgSize: 52428800 - #统计上报设置 + #描述:重连间隔时间 + reconnectInterval: 500ms + #描述: 监控及日志数据上报相关配置 statReporter: - #描述:是否将统计信息上报至monitor - #类型:bool - #默认值:true - enable: true - #描述:启用的统计上报插件类型 - #类型:list - #范围:已经注册的统计上报插件的名字 - #默认值:stat2Monitor(将信息上报至monitor服务) - chain: - - stat2Monitor - - serviceCache - #描述:统计上报插件配置 + #描述: 是否启用上报 + enable: false plugin: - stat2Monitor: - #描述:每次上报多长一段时间的统计信息 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1m:...] - metricsReportWindow: 1m - #描述:将一段时间内的统计信息分为多少个基本单元收集 - #类型:int - #范围:[1:...] - #默认值:12 - metricsNumBuckets: 12 - serviceCache: - #描述:上报缓存信息的周期 - reportInterval: 3m -#描述:主调端配置 + pushgatewayConfig: + #描述: 上报给prometheus pushgateway的任务名称 + jobName: "defaultJob" + #描述: pushgateway的服务名称 + serviceName: "polaris.monitor" + #描述: 上报给pushgateway的时间间隔 + pushInterval: 10 +#描述: 主调端配置 consumer: - #描述:本地缓存相关配置 + #描述: 本地服务缓存相关配置 localCache: - #描述:缓存类型 - #类型:string - #范围:已注册的本地缓存插件名 - #默认值:inmemory(基于本机内存的缓存策略) + #描述: 缓存插件名 type: inmemory - #描述:服务过期淘汰时间 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1m:...] - #默认值:24h + #描述: 是否启用服务数据缓存 + serviceExpireEnable: true + #描述: 服务过期淘汰时间 serviceExpireTime: 24h - #描述:服务定期刷新周期 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1s:...] - #默认值:2s + #描述: 服务定期同步刷新周期 serviceRefreshInterval: 2s - #描述:服务缓存持久化目录,SDK在实例数据更新后,按照服务维度将数据持久化到磁盘 - #类型:string - #格式:本机磁盘目录路径,支持$HOME变量 - #默认值:$HOME/polaris/backup + #描述: 是否启用服务数据文件缓存 + persistEnable: true + #描述: 服务缓存持久化目录,SDK在实例数据更新后,按照服务维度将数据持久化到磁盘 persistDir: ./polaris/backup - #描述:缓存写盘失败的最大重试次数 - #类型:int - #范围:[1:...] - #默认值:5 - persistMaxWriteRetry: 5 - #描述:缓存从磁盘读取失败的最大重试次数 - #类型:int - #范围:[1:...] - #默认值:1 - persistMaxReadRetry: 1 - #描述:缓存读写磁盘的重试间隔 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1ms:...] - #默认值:1s - persistRetryInterval: 1s - #描述:服务路由相关配置 + #描述: 缓存写盘失败的最大重试次数 + persistMaxWriteRetry: 1 + #描述: 缓存从磁盘读取失败的最大重试次数 + persistMaxReadRetry: 0 + #描述: 缓存读写磁盘的重试间隔 + persistRetryInterval: 500ms + #描述: 服务路由相关配置 serviceRouter: - # 服务路由链 + #描述: 前置路由链 + beforeChain: + # 隔离路由 + - isolatedRouter + #描述: 服务路由链 chain: - # 基于主调和被调服务规则的路由策略(默认的路由策略) + # 元数据路由 + - metadataRouter + # 规则路由 - ruleBasedRouter - # 就近路由策略 + # 就近路由 - nearbyBasedRouter + #描述: 后置路由链 + afterChain: + # 兜底(全死全活)路由 + - recoverRouter #描述:服务路由插件的配置 plugin: + metadataRouter: + #描述: 元数据路由降级策略。none(不降级), all(降级返回所有的节点), others(降级返回其他节点) + metadataFailOverType: none nearbyBasedRouter: - #描述:就近路由的最小匹配级别 - #类型:string - #范围:region(大区)、zone(区域)、campus(园区) - #默认值:zone + #描述: 就近路由的最小匹配级别。region(大区)、zone(区域)、campus(园区) matchLevel: zone - ruleBasedRouter: { } - recoverRouter: - #至少应该返回多少比率的实例,如果不填,默认0%,即全死全活 - percentOfMinInstances: 0 - #是否开启全死全活,默认开启 - enableRecoverAll: true + #描述: 最大匹配级别 + maxMatchLevel: all + #描述: 强制就近 + strictNearby: false + #描述: 全部实例不健康时是否降级其他地域 + enableDegradeByUnhealthyPercent: false + #描述: 达到降级标准的不健康实例百分比 + unhealthyPercentToDegrade: 100 + #描述: 是否通过上报方式获取地域信息 + enableReportLocalAddress: false #描述:负载均衡相关配置 loadbalancer: - #描述:负载均衡类型 - #范围:已注册的负载均衡插件名 - #默认值:权重随机负载均衡 + #描述: 负载均衡类型(已注册的负载均衡插件名) type: weightedRandom - plugin: - #描述:虚拟节点的数量 - #类型:int - #默认值:500 - ringHash: - vnodeCount: 500 - #描述:节点熔断相关配置 circuitBreaker: - #描述:是否启用节点熔断功能 - #类型:bool - #默认值:true + #描述: 是否启用本地节点熔断功能 enable: true - #描述:实例定时熔断检测周期 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[100ms:...] - #默认值:30s - checkPeriod: 100ms - #描述:熔断器半开后最大允许的请求数 - #类型:int - #范围:[3:...] - #默认值:10 - requestCountAfterHalfOpen: 10 - #描述:熔断器打开后,多久后转换为半开状态 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1s:...] - #默认值:30s - sleepWindow: 60s - #描述:熔断器半开到关闭所必须的最少成功请求数 - #类型:int - #范围:[1:requestCountAfterHalfOpen] - #默认值:8 - successCountAfterHalfOpen: 8 - #描述:熔断器半开到关闭的统计周期 - #类型:string - #范围:[10s:...] - #默认值:60s - recoverWindow: 60s - #描述:熔断器半开到关闭的统计滑桶数 - #类型:int - #范围:[1:...] - #默认值:10 - recoverNumBuckets: 10 - #描述:熔断策略,SDK会根据策略名称加载对应的熔断器插件 - #类型:list - #范围:已注册的熔断器插件名 - #默认值:基于周期连续错误数熔断(errorCount)、以及基于周期错误率的熔断策略(errorRate) + #描述: 故障检测周期,根据周期内故障进行熔断 + checkPeriod: 1m + #描述: 首次熔断时间,后续熔断时间=重试次数*sleepWindow + sleepWindow: 30s + #描述: 熔断器半开后最大允许的请求数 + requestCountAfterHalfOpen: 3 + #描述: 熔断器半开到关闭所必须的最少成功请求数 + successCountAfterHalfOpen: 3 + #描述:熔断策略,SDK会根据策略名称加载对应的熔断器插件(已注册的熔断器插件名) chain: - errorCount - errorRate - #描述:熔断插件配置 + #描述: 熔断插件配置 plugin: #描述:基于周期连续错误数熔断策略配置 errorCount: - #描述:触发连续错误熔断的阈值 - #类型:int - #范围:[1:...] - #默认值:10 - continuousErrorThreshold: 1 - #描述:连续错误数的最小统计单元数量 - #类型:int - #范围:[1:...] - #默认值:10 - metricNumBuckets: 1 - #描述:连续失败的统计周期 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[10ms:...] - #默认值:1m - metricStatTimeWindow: 100ms + #描述: 触发连续错误熔断的阈值 + continuousErrorThreshold: 10 #描述:基于周期错误率的熔断策略配置 errorRate: - #描述:触发错误率熔断的阈值 - #类型:double - #范围:(0:1] - #默认值:0.5 - errorRateThreshold: 0.01 - #描述:错误率熔断的最小统计单元数量 - #类型:int - #范围:[1:...] - #默认值:5 + #描述:触发错误率熔断的阈值百分比 + errorRateThreshold: 1 + #描述: 错误率熔断的滑窗数量 metricNumBuckets: 5 - #描述:错误率熔断的统计周期 - #类型:string - #格式:^\d+(ms|s|m|h)$ - #范围:[1s:...] - #默认值:1m - metricStatTimeWindow: 1s - #描述:触发错误率熔断的最低请求阈值 - #类型:int - #范围:(0:...] - #默认值:10 - requestVolumeThreshold: 1 + #描述: 触发错误率熔断的最低请求阈值 + requestVolumeThreshold: 10 + #描述:主动探测相关配置 + outlierDetection: + #描述:何时开启主动探测。never(永不开启),on_recover(恢复时才开启主动探测),always(一直开启主动探测) + when: never + #描述:主动探测周期 + checkPeriod: 30s + #描述:主动探测插件链 + chain: + - http + - tcp + - udp +# 被调方配置 +provider: + # 限流配置 + rateLimit: + # 是否开启限流功能 + enable: true + # 限流本地存在的最大窗口限制 + maxWindowCount: 10000000 + # 超过最大窗口限制时的策略。pass(放通), reject(限流) + fallbackOnExceedWindowCount: pass \ No newline at end of file diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/application.yml similarity index 53% rename from spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml rename to spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/application.yml index eedf3e1ee..68a96039d 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-b/src/main/resources/application.yml @@ -12,8 +12,6 @@ global: timeout: 5s feign: - hystrix: - enabled: true #在Feign中开启Hystrix compression: request: enabled: false #是否对请求进行GZIP压缩 @@ -22,19 +20,5 @@ feign: response: enabled: false #是否对响应进行GZIP压缩 -ribbon: - polaris: - enabled: true - # 同一实例最大重试次数,不包括首次调用 - MaxAutoRetries: 1 - # 重试其他实例的最大重试次数,不包括首次所选的server - MaxAutoRetriesNextServer: 2 - # 是否所有操作都进行重试 - OkToRetryOnAllOperations: false - ConnectionTimeout: 1000 - ReadTimeout: 1000 - eager-load: - enabled: on - serivceB: url: http://localhost:48081 \ No newline at end of file diff --git a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java index 73052df87..3d03524b4 100644 --- a/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java +++ b/spring-cloud-tencent-starters/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java @@ -27,6 +27,7 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; +import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLoadBalancerClient; /** * Wrap Spring Bean and decorating proxy for Feign Client. @@ -51,8 +52,8 @@ public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFac private Object wrapper(Object bean) { if (isNeedWrap(bean)) { - if (bean instanceof FeignBlockingLoadBalancerClient) { - FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean; + if (bean instanceof RetryableFeignBlockingLoadBalancerClient) { + RetryableFeignBlockingLoadBalancerClient client = (RetryableFeignBlockingLoadBalancerClient) bean; return new PolarisFeignBlockingLoadBalancerClient(createPolarisFeignClient(client.getDelegate()), factory.getBean(BlockingLoadBalancerClient.class), factory.getBean(LoadBalancerProperties.class), diff --git a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java index 1ff90a6a5..06a8adf65 100644 --- a/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java +++ b/spring-cloud-tencent-starters/spring-cloud-tencent-feign/src/main/java/com/tencent/cloud/feign/PluggableFeign.java @@ -110,7 +110,7 @@ public class PluggableFeign { if (void.class != fallback) { fallbackInstance = getFallbackInstanceFromContext(beanName, "fallback", fallback, target.type()); - return new PluggableFeignInvocationHandler(target, dispatch, (FallbackFactory) fallbackInstance, pluggableFeignPlugins); + return new PluggableFeignInvocationHandler(target, dispatch, new FallbackFactory.Default(fallbackInstance), pluggableFeignPlugins); } if (void.class != fallbackFactory) {