dubbo.apache.org/dubbo-go/v3@v3.1.1/filter/xds/cb/filter.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package cb 19 20 import ( 21 "context" 22 ) 23 24 import ( 25 "github.com/dubbogo/gost/log/logger" 26 ) 27 28 import ( 29 "dubbo.apache.org/dubbo-go/v3/common" 30 "dubbo.apache.org/dubbo-go/v3/common/constant" 31 "dubbo.apache.org/dubbo-go/v3/common/extension" 32 "dubbo.apache.org/dubbo-go/v3/filter" 33 "dubbo.apache.org/dubbo-go/v3/protocol" 34 "dubbo.apache.org/dubbo-go/v3/remoting/xds" 35 "dubbo.apache.org/dubbo-go/v3/xds/client" 36 "dubbo.apache.org/dubbo-go/v3/xds/client/resource" 37 ) 38 39 // this should be executed before users set their own Tracer 40 func init() { 41 extension.SetFilter(constant.XdsCircuitBreakerKey, newCircuitBreakerFilter) 42 } 43 44 // if you wish to using opentracing, please add the this filter into your filter attribute in your configure file. 45 // notice that this could be used in both client-side and server-side. 46 type circuitBreakerFilter struct { 47 client xds.XDSWrapperClient 48 } 49 50 func (cb *circuitBreakerFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { 51 url := invoker.GetURL() 52 rejectedExeHandler := url.GetParam(constant.DefaultKey, constant.DefaultKey) 53 clusterUpdate, err := cb.getClusterUpdate(url) 54 if err != nil { 55 logger.Errorf("xds circuitBreakerFilter get request counter fail", err) 56 return nil 57 } 58 counter := client.GetClusterRequestsCounter(clusterUpdate.ClusterName, clusterUpdate.EDSServiceName) 59 if err := counter.StartRequest(*clusterUpdate.MaxRequests); err != nil { 60 rejectedExecutionHandler, err := extension.GetRejectedExecutionHandler(rejectedExeHandler) 61 if err != nil { 62 logger.Warn(err) 63 } else { 64 return rejectedExecutionHandler.RejectedExecution(url, invocation) 65 } 66 } 67 return invoker.Invoke(ctx, invocation) 68 } 69 70 func (cb *circuitBreakerFilter) OnResponse(ctx context.Context, result protocol.Result, 71 invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { 72 url := invoker.GetURL() 73 clusterUpdate, err := cb.getClusterUpdate(url) 74 if err != nil { 75 logger.Errorf("xds circuitBreakerFilter get request counter fail", err) 76 return nil 77 } 78 counter := client.GetClusterRequestsCounter(clusterUpdate.ClusterName, clusterUpdate.EDSServiceName) 79 counter.EndRequest() 80 return result 81 } 82 83 var circuitBreakerFilterInstance filter.Filter 84 85 func newCircuitBreakerFilter() filter.Filter { 86 if circuitBreakerFilterInstance == nil { 87 circuitBreakerFilterInstance = &circuitBreakerFilter{ 88 client: xds.GetXDSWrappedClient(), 89 } 90 } 91 return circuitBreakerFilterInstance 92 } 93 94 func (cb *circuitBreakerFilter) getClusterUpdate(url *common.URL) (resource.ClusterUpdate, error) { 95 hostAddr, err := cb.client.GetHostAddrByServiceUniqueKey(common.GetSubscribeName(url)) 96 if err != nil { 97 logger.Errorf("xds circuitBreakerFilter get GetHostAddrByServiceUniqueKey fail", err) 98 return resource.ClusterUpdate{}, err 99 } 100 clusterUpdate := cb.client.GetClusterUpdateIgnoreVersion(hostAddr) 101 return clusterUpdate, nil 102 }