diff --git a/config/consumer_config.go b/config/consumer_config.go index 737339a0ad195201327eb4fac3445b18eb4bbf26..55082ffe41ad0a38ccbb6c2e788f0b609a8b4ef8 100644 --- a/config/consumer_config.go +++ b/config/consumer_config.go @@ -52,6 +52,7 @@ type ConsumerConfig struct { Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` References map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"` ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf"` + FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" ` } func (*ConsumerConfig) Prefix() string { diff --git a/config/provider_config.go b/config/provider_config.go index a504eea237dc47f66c4ed27d334ce5eea5c87d45..db8abaf73e9609b3f3ac1db68e89a3d66068659b 100644 --- a/config/provider_config.go +++ b/config/provider_config.go @@ -46,6 +46,7 @@ type ProviderConfig struct { Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` Protocols map[string]*ProtocolConfig `yaml:"protocols" json:"protocols,omitempty" property:"protocols"` ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty" property:"protocol_conf" ` + FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf" ` } func (*ProviderConfig) Prefix() string { diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go new file mode 100644 index 0000000000000000000000000000000000000000..0d8d7d2ffd6b7ea5db3831b55fa4dc45ace302c5 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/client.go @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "context" + "fmt" + "os" + "os/signal" + "syscall" + "time" +) + +import ( + "github.com/apache/dubbo-go-hessian2" +) + +import ( + "github.com/apache/dubbo-go/common/logger" + _ "github.com/apache/dubbo-go/common/proxy/proxy_factory" + "github.com/apache/dubbo-go/config" + _ "github.com/apache/dubbo-go/protocol/dubbo" + _ "github.com/apache/dubbo-go/registry/protocol" + + _ "github.com/apache/dubbo-go/filter/impl" + + _ "github.com/apache/dubbo-go/cluster/cluster_impl" + _ "github.com/apache/dubbo-go/cluster/loadbalance" + _ "github.com/apache/dubbo-go/registry/zookeeper" +) + +var ( + survivalTimeout int = 10e9 +) + +// they are necessary: +// export CONF_CONSUMER_FILE_PATH="xxx" +// export APP_LOG_CONF_FILE="xxx" +func main() { + + hessian.RegisterJavaEnum(Gender(MAN)) + hessian.RegisterJavaEnum(Gender(WOMAN)) + hessian.RegisterPOJO(&User{}) + getUserChan := make(chan string, 32) + getErrChan := make(chan string, 32) + getUser1Chan := make(chan string, 32) + + config.Load() + logger.Debugf("[Start to test GetUser]") + for i := 0; i < 32; i++ { + go func() { + user := &User{} + err := userProvider.GetUser(context.TODO(), []interface{}{"A003"}, user) + getUserChan <- fmt.Sprintf("Result: %s ; Error: %v", user.Name, err) + }() + } + time.Sleep(time.Second * 4) + + logger.Debugf("[Start to test GetErr, without error whitelist]") + for i := 0; i < 32; i++ { + go func() { + user := &User{} + err := userProvider.GetErr(context.TODO(), []interface{}{"A003"}, user) + getErrChan <- fmt.Sprintf("Result: %s ; Error: %v", user.Name, err) + }() + } + time.Sleep(time.Second * 4) + + logger.Debugf("[Start to test illegal method GetUser1, with error whitelist]") + for i := 0; i < 32; i++ { + go func() { + user := &User{} + err := userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user) + getUser1Chan <- fmt.Sprintf("Result: %s ; Error: %v", user.Name, err) + }() + } + time.Sleep(time.Second * 4) + for i := 1; i < 32; i++ { + resGot := <-getUserChan + logger.Infof("[GetUser] %v", resGot) + } + for i := 1; i < 32; i++ { + resGot := <-getErrChan + logger.Infof("[GetErr] %v", resGot) + } + for i := 1; i < 32; i++ { + resGot := <-getUser1Chan + logger.Infof("[GetUser1] %v", resGot) + } + //initSignal() +} + +func initSignal() { + signals := make(chan os.Signal, 1) + // It is not possible to block SIGKILL or syscall.SIGSTOP + signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP, + syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) + for { + sig := <-signals + logger.Infof("get signal %s", sig.String()) + switch sig { + case syscall.SIGHUP: + // reload() + default: + go time.AfterFunc(time.Duration(survivalTimeout)*time.Second, func() { + logger.Warnf("app exit now by force...") + os.Exit(1) + }) + + // 瑕佷箞fastFailTimeout鏃堕棿鍐呮墽琛屽畬姣曚笅闈㈢殑閫昏緫鐒跺悗绋嬪簭閫€鍑猴紝瑕佷箞鎵ц涓婇潰鐨勮秴鏃跺嚱鏁扮▼搴忓己琛岄€€鍑� + fmt.Println("app exit now...") + return + } + } +} diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/example_fallback_filter.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/example_fallback_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..0e86988fd787e0df941b62ad038746b412baf314 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/example_fallback_filter.go @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package main + +import ( + "time" +) + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/filter" + "github.com/apache/dubbo-go/filter/impl" + "github.com/apache/dubbo-go/protocol" +) + +const ( + EXAMPLE_FALLBACK_FILTER = "example_fallback" +) + +//This is an example filter that handles result from hystrix filter +//Define your filters and write your service downgrade strategy like this +//TODO: Maybe a base fallback filter can be offered +type ExampleFallbackFilter struct { +} + +func GetExampleFallbackFilter() filter.Filter { + return &ExampleFallbackFilter{} +} + +//The name should be the same as in your config +//Put the filter in front of hystrix filter +func init() { + extension.SetFilter(EXAMPLE_FALLBACK_FILTER, GetExampleFallbackFilter) +} + +func (ff *ExampleFallbackFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + return invoker.Invoke(invocation) + +} +func (ff *ExampleFallbackFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + if err := result.Error(); err != nil { + hystrixError, ok := err.(*impl.HystrixFilterError) + if ok { + if hystrixError.FailByHystrix() { + logger.Debugf("[Example fallback filter]%s get error caused by %s", invocation.MethodName(), hystrixError.Error()) + //Handle the error caused by Hystrix, including circuit breaking, concurrency limit and timeout + //The detailed error source can be got through hystrixError.Error() + //In this example we return a mock result under this circumstance + res := User{ + "MockID", + "MockName", + 55, + time.Now(), + Gender(MAN), + } + *(invocation.Reply().(*User)) = res + result.SetResult(&res) + result.SetError(nil) + } + } + } + //If the error is not caused by hystrix, the result doesn't come from hystrix filter or there's no error, + //we just return it here. + return result +} diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/user.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/user.go new file mode 100644 index 0000000000000000000000000000000000000000..affa5418a701842e890f9e2498c2ef7a769532bd --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/user.go @@ -0,0 +1,149 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "context" + "fmt" + "strconv" + "time" +) + +import ( + hessian "github.com/apache/dubbo-go-hessian2" +) + +import ( + "github.com/apache/dubbo-go/config" +) + +type Gender hessian.JavaEnum + +var ( + userProvider = new(UserProvider) + userProvider1 = new(UserProvider1) + userProvider2 = new(UserProvider2) +) + +func init() { + config.SetConsumerService(userProvider) + config.SetConsumerService(userProvider1) + config.SetConsumerService(userProvider2) +} + +const ( + MAN hessian.JavaEnum = iota + WOMAN +) + +var genderName = map[hessian.JavaEnum]string{ + MAN: "MAN", + WOMAN: "WOMAN", +} + +var genderValue = map[string]hessian.JavaEnum{ + "MAN": MAN, + "WOMAN": WOMAN, +} + +func (g Gender) JavaClassName() string { + return "com.ikurento.user.Gender" +} + +func (g Gender) String() string { + s, ok := genderName[hessian.JavaEnum(g)] + if ok { + return s + } + + return strconv.Itoa(int(g)) +} + +func (g Gender) EnumValue(s string) hessian.JavaEnum { + v, ok := genderValue[s] + if ok { + return v + } + + return hessian.InvalidJavaEnum +} + +type User struct { + // !!! Cannot define lowercase names of variable + Id string + Name string + Age int32 + Time time.Time + Sex Gender // 娉ㄦ剰姝ゅ锛宩ava enum Object <--> go string +} + +func (u User) String() string { + return fmt.Sprintf( + "User{Id:%s, Name:%s, Age:%d, Time:%s, Sex:%s}", + u.Id, u.Name, u.Age, u.Time, u.Sex, + ) +} + +func (User) JavaClassName() string { + return "com.ikurento.user.User" +} + +type UserProvider struct { + GetUsers func(req []interface{}) ([]interface{}, error) + GetErr func(ctx context.Context, req []interface{}, rsp *User) error + GetUser func(ctx context.Context, req []interface{}, rsp *User) error + GetUser0 func(id string, name string) (User, error) + GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error + GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"` + GetUser3 func() error + Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used +} + +func (u *UserProvider) Reference() string { + return "UserProvider" +} + +type UserProvider1 struct { + GetUsers func(req []interface{}) ([]interface{}, error) + GetErr func(ctx context.Context, req []interface{}, rsp *User) error + GetUser func(ctx context.Context, req []interface{}, rsp *User) error + GetUser0 func(id string, name string) (User, error) + GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error + GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"` + GetUser3 func() error + Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used +} + +func (u *UserProvider1) Reference() string { + return "UserProvider1" +} + +type UserProvider2 struct { + GetUsers func(req []interface{}) ([]interface{}, error) + GetErr func(ctx context.Context, req []interface{}, rsp *User) error + GetUser func(ctx context.Context, req []interface{}, rsp *User) error + GetUser0 func(id string, name string) (User, error) + GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error + GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"` + GetUser3 func() error + Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used +} + +func (u *UserProvider2) Reference() string { + return "UserProvider2" +} diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/version.go b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/version.go new file mode 100644 index 0000000000000000000000000000000000000000..c6138584f1ddeab3a4927774f44f9e78a8f08da7 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/app/version.go @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +var ( + Version = "2.6.0" +) diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/bin/load.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/bin/load.sh new file mode 100644 index 0000000000000000000000000000000000000000..07d5d15eac7b7974845e36c3807e7ec55875de65 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/bin/load.sh @@ -0,0 +1,196 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : dubbogo app devops script +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-05-13 02:01 +# FILE : load.sh +# ****************************************************** + +APP_NAME="APPLICATION_NAME" +APP_ARGS="" +SLEEP_INTERVAL=5 +MAX_LIFETIME=4000 + +PROJECT_HOME="" +OS_NAME=`uname` +if [[ ${OS_NAME} != "Windows" ]]; then + PROJECT_HOME=`pwd` + PROJECT_HOME=${PROJECT_HOME}"/" +else + APP_NAME="APPLICATION_NAME.exe" +fi + +export CONF_CONSUMER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE" +export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE" +# export GOTRACEBACK=system +# export GODEBUG=gctrace=1 + +usage() { + echo "Usage: $0 start [conf suffix]" + echo " $0 stop" + echo " $0 term" + echo " $0 restart" + echo " $0 list" + echo " $0 monitor" + echo " $0 crontab" + exit +} + +start() { + arg=$1 + if [ "$arg" = "" ];then + echo "No registry type! Default client.yml!" + else + export CONF_CONSUMER_FILE_PATH=${CONF_CONSUMER_FILE_PATH//\.yml/\_$arg\.yml} + fi + if [ ! -f "${CONF_CONSUMER_FILE_PATH}" ];then + echo $CONF_CONSUMER_FILE_PATH" is not existing!" + return + fi + APP_LOG_PATH=${PROJECT_HOME}"logs/" + mkdir -p ${APP_LOG_PATH} + APP_BIN=${PROJECT_HOME}sbin/${APP_NAME} + chmod u+x ${APP_BIN} + # CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &" + CMD="${APP_BIN}" + eval ${CMD} + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + CUR=`date +%FT%T` + if [ "${PID}" != "" ]; then + for p in ${PID} + do + echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR} + done + fi +} + +stop() { + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + if [ "${PID}" != "" ]; + then + for ps in ${PID} + do + echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")" + kill -2 ${ps} + done + fi +} + + +term() { + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + if [ "${PID}" != "" ]; + then + for ps in ${PID} + do + echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")" + kill -9 ${ps} + done + fi +} + +list() { + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'` + fi + + if [ "${PID}" != "" ]; then + echo "list ${APP_NAME}" + + if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then + echo "index: user, pid, start, duration" + else + echo "index: PID, WINPID, UID, STIME, COMMAND" + fi + idx=0 + for ps in ${PID} + do + echo "${idx}: ${ps}" + ((idx ++)) + done + fi +} + +monitor() { + idx=0 + while true; do + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + if [[ "${PID}" == "" ]]; then + start + idx=0 + fi + + ((LIFE=idx*${SLEEP_INTERVAL})) + echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds." + ((idx ++)) + sleep ${SLEEP_INTERVAL} + done +} + +crontab() { + idx=0 + while true; do + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'` + if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then + PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'` + fi + if [[ "${PID}" == "" ]]; then + start + idx=0 + fi + + ((LIFE=idx*${SLEEP_INTERVAL})) + echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds." + ((idx ++)) + sleep ${SLEEP_INTERVAL} + if [[ ${LIFE} -gt ${MAX_LIFETIME} ]]; then + kill -9 ${PID} + fi + done +} + +opt=$1 +case C"$opt" in + Cstart) + start $2 + ;; + Cstop) + stop + ;; + Cterm) + term + ;; + Crestart) + term + start $2 + ;; + Clist) + list + ;; + Cmonitor) + monitor + ;; + Ccrontab) + crontab + ;; + C*) + usage + ;; +esac + diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/app.properties b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/app.properties new file mode 100644 index 0000000000000000000000000000000000000000..6bbd6db850ceeaf5ff873fee01a3578237cbd557 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/app.properties @@ -0,0 +1,17 @@ +# dubbogo application configure script +# ****************************************************** +# DESC : dubbogo environment variable +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:29 +# FILE : app.properties +# ****************************************************** + +export TARGET_EXEC_NAME="user_info_client" +# BUILD_PACKAGE="dubbogo-examples/user-info/client/app" +export BUILD_PACKAGE="app" + +export TARGET_CONF_FILE="conf/client.yml" +export TARGET_LOG_CONF_FILE="conf/log.yml" diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/build.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..e72418297ad2f0ac6985476b5a8d5e03b9e7584e --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/common/build.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:28 +# FILE : build.sh +# ****************************************************** + +rm -rf target/ + +PROJECT_HOME=`pwd` +TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS} + +TARGET_SBIN_NAME=${TARGET_EXEC_NAME} +version=`cat app/version.go | grep Version | grep -v "Apache" | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'` +if [[ ${GOOS} == "windows" ]]; then + TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe +fi +TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME} +if [[ $PROFILE == "dev" || $PROFILE == "test" ]]; then + # GFLAGS=-gcflags "-N -l" -race -x -v # -x浼氭妸go build鐨勮缁嗚繃绋嬭緭鍑� + # GFLAGS=-gcflags "-N -l" -race -v + # GFLAGS="-gcflags \"-N -l\" -v" + cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd - +else + # -s鍘绘帀绗﹀彿琛紙鐒跺悗panic鏃跺€欑殑stack trace灏辨病鏈変换浣曟枃浠跺悕/琛屽彿淇℃伅浜嗭紝杩欎釜绛変环浜庢櫘閫欳/C++绋嬪簭琚玸trip鐨勬晥鏋滐級锛� + # -w鍘绘帀DWARF璋冭瘯淇℃伅锛屽緱鍒扮殑绋嬪簭灏变笉鑳界敤gdb璋冭瘯浜嗐€�-s鍜�-w涔熷彲浠ュ垎寮€浣跨敤锛屼竴鑸潵璇村鏋滀笉鎵撶畻鐢╣db璋冭瘯锛� + # -w鍩烘湰娌″暐鎹熷け銆�-s鐨勬崯澶卞氨鏈夌偣澶т簡銆� + cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd - +fi + +TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE} + +mkdir -p ${TARGET_FOLDER}/${TAR_NAME} + +SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin +BIN_DIR=${TARGET_FOLDER}/${TAR_NAME} +CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf + +mkdir -p ${SBIN_DIR} +mkdir -p ${CONF_DIR} + +mv ${TARGET_NAME} ${SBIN_DIR} +cp -r assembly/bin ${BIN_DIR} +cd ${BIN_DIR}/bin/ && mv load.sh load_${TARGET_EXEC_NAME}.sh && cd - + +platform=$(uname) +# modify APPLICATION_NAME +if [ ${platform} == "Darwin" ]; then + sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/* +else + sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/* +fi + +# modify TARGET_CONF_FILE +if [ ${platform} == "Darwin" ]; then + sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/* +else + sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/* +fi + +# modify TARGET_LOG_CONF_FILE +if [ ${platform} == "Darwin" ]; then + sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/* +else + sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/* +fi + +cp -r profiles/${PROFILE}/* ${CONF_DIR} + +cd ${TARGET_FOLDER} + +tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/* + diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/dev.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/dev.sh new file mode 100644 index 0000000000000000000000000000000000000000..3373f01b948b708cd7bc1958c9d56a9042c60a68 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/dev.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for dev env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2017-10-18 13:24 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +export PROFILE="dev" + +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/release.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..34867b8b3488778cd76a1dc7802393dcab6b0df0 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/release.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +export PROFILE="release" +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/test.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..1bbbefd1e14e08c16deaf859e2841f4d1fe88e9c --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/linux/test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for test env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +export PROFILE="test" +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/dev.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/dev.sh new file mode 100644 index 0000000000000000000000000000000000000000..b68ac83b6524a6713cd90c4fc5968fe64b1a9545 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/dev.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for dev env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2017-10-18 13:24 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +export PROFILE="dev" + +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/release.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..688288b3b1b989e8af70a3674b34ea8e0668f3b4 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/release.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +export PROFILE="release" +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/test.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..56d6c11ecd6a1dc5984c74b88c10be9239e57428 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/mac/test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for test env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +export PROFILE="test" +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/dev.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/dev.sh new file mode 100644 index 0000000000000000000000000000000000000000..91cf6f23bcbecb26db798469a30529261aabbbb6 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/dev.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for dev env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2017-10-18 13:24 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +export PROFILE="dev" +PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/release.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/release.sh new file mode 100644 index 0000000000000000000000000000000000000000..f317720bd53d9c9e5f8f484b6eb682c9c736af0c --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/release.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for release env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +export PROFILE="release" +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/test.sh b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..7dd2bec5260e647b57a46aaa37acc098babff068 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/assembly/windows/test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# ****************************************************** +# DESC : build script for test env +# AUTHOR : Alex Stocks +# VERSION : 1.0 +# LICENCE : Apache License 2.0 +# EMAIL : alexstocks@foxmail.com +# MOD : 2016-07-12 16:34 +# FILE : test.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +export PROFILE="test" +export PROJECT_HOME=`pwd` + +if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then + . ${PROJECT_HOME}/assembly/common/app.properties +fi + +if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then + sh ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml new file mode 100644 index 0000000000000000000000000000000000000000..5b5003fb2cabde05e7d99e738afd584a635355bd --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/client.yml @@ -0,0 +1,98 @@ +# dubbo client yaml configure file + + +check: true +# client +request_timeout : "3s" +# connect timeout +connect_timeout : "3s" + +# application config +application_config: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "dev" + +registries : + "hangzhouzk": + # 瀵瑰簲java閰嶇疆涓璦ddress灞炴€х殑zookeeper <dubbo:registry address="zookeeper://127.0.0.1:2181"/> + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2181" + username: "" + password: "" + "shanghaizk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2182" + username: "" + password: "" + +references: + "UserProvider": + # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� + registry: "hangzhouzk" + filter: "example_fallback,hystrix_consumer" + protocol : "dubbo" + interface : "com.ikurento.user.UserProvider" + cluster: "failover" + methods : + - name: "GetUser" + retries: 3 + +protocol_conf: + dubbo: + reconnect_interval: 0 + connection_number: 2 + heartbeat_period: "5s" + session_timeout: "20s" + fail_fast_timeout: "5s" + pool_size: 64 + pool_ttl: 600 + getty_session_param: + compress_encoding: false + tcp_no_delay: true + tcp_keep_alive: true + keep_alive_period: "120s" + tcp_r_buf_size: 262144 + tcp_w_buf_size: 65536 + pkg_rq_size: 1024 + pkg_wq_size: 512 + tcp_read_timeout: "1s" + tcp_write_timeout: "5s" + wait_timeout: "1s" + max_msg_len: 10240 + session_name: "client" + +filter_conf: + hystrix: + configs: + "Default": + timeout : 1000 + max_concurrent_requests : 25 + sleep_window : 5000 + error_percent_threshold : 50 + request_volume_threshold: 20 + "userp": + timeout: 2000 + max_concurrent_requests: 512 + sleep_window: 4000 + error_percent_threshold: 35 + request_volume_threshold: 6 + "userp_m": + timeout : 1200 + max_concurrent_requests : 512 + sleep_window : 6000 + error_percent_threshold : 60 + request_volume_threshold: 16 + error_whitelist: [".*exception.*"] + default: "Default" + services: + "com.ikurento.user.UserProvider": + service_config: "userp" + methods: + "GetUser": "userp_m" + "GetUser1": "userp_m" \ No newline at end of file diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml new file mode 100644 index 0000000000000000000000000000000000000000..3ed242d290148743b198e32c5823ad9aae233e8b --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/dev/log.yml @@ -0,0 +1,28 @@ + +level: "debug" +development: true +disableCaller: false +disableStacktrace: false +sampling: +encoding: "console" + +# encoder +encoderConfig: + messageKey: "message" + levelKey: "level" + timeKey: "time" + nameKey: "logger" + callerKey: "caller" + stacktraceKey: "stacktrace" + lineEnding: "" + levelEncoder: "capitalColor" + timeEncoder: "iso8601" + durationEncoder: "seconds" + callerEncoder: "short" + nameEncoder: "" + +outputPaths: + - "stderr" +errorOutputPaths: + - "stderr" +initialFields: diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/release/client.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/release/client.yml new file mode 100644 index 0000000000000000000000000000000000000000..9263f2d01ff5288144876eb14c08060bdb165974 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/release/client.yml @@ -0,0 +1,98 @@ +# dubbo client yaml configure file + + +check: true +# client +request_timeout : "3s" +# connect timeout +connect_timeout : "3s" + +# application config +application_config: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "release" + +registries : + "hangzhouzk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2181" + username: "" + password: "" + "shanghaizk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2182" + username: "" + password: "" + +references: + "UserProvider": + # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� + registry: "hangzhouzk" + filter: "example_fallback,hystrix_consumer" + protocol : "dubbo" +# version: "2.0" +# group: "as" + interface : "com.ikurento.user.UserProvider" + cluster: "failover" + methods : + - name: "GetUser" + retries: 3 + +protocol_conf: + dubbo: + reconnect_interval: 0 + connection_number: 2 + heartbeat_period: "5s" + session_timeout: "20s" + fail_fast_timeout: "5s" + pool_size: 64 + pool_ttl: 600 + getty_session_param: + compress_encoding: false + tcp_no_delay: true + tcp_keep_alive: true + keep_alive_period: "120s" + tcp_r_buf_size: 262144 + tcp_w_buf_size: 65536 + pkg_rq_size: 1024 + pkg_wq_size: 512 + tcp_read_timeout: "1s" + tcp_write_timeout: "5s" + wait_timeout: "1s" + max_msg_len: 10240 + session_name: "client" + +filter_conf: + hystrix: + configs: + "Default": + timeout : 1000 + max_concurrent_requests : 10 + sleep_window : 5000 + error_percent_threshold : 50 + request_volume_threshold: 20 + "userp": + timeout: 1200 + max_concurrent_requests: 8 + sleep_window: 4000 + error_percent_threshold: 45 + request_volume_threshold: 15 + "userp_m": + timeout : 1200 + max_concurrent_requests : 12 + sleep_window : 6000 + error_percent_threshold : 60 + request_volume_threshold: 30 + fallback: "exampleFallback" + default: "Default" + services: + "com.ikurento.user.UserProvider": + service_config: "userp" + methods: + "GetUser": "userp_m" diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/release/log.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/release/log.yml new file mode 100644 index 0000000000000000000000000000000000000000..d8606247b8479ac5054fd2ef70a0af4bca85c4c4 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/release/log.yml @@ -0,0 +1,28 @@ + +level: "warn" +development: true +disableCaller: true +disableStacktrace: true +sampling: +encoding: "console" + +# encoder +encoderConfig: + messageKey: "message" + levelKey: "level" + timeKey: "time" + nameKey: "logger" + callerKey: "caller" + stacktraceKey: "stacktrace" + lineEnding: "" + levelEncoder: "capitalColor" + timeEncoder: "iso8601" + durationEncoder: "seconds" + callerEncoder: "short" + nameEncoder: "" + +outputPaths: + - "stderr" +errorOutputPaths: + - "stderr" +initialFields: diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/test/client.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/test/client.yml new file mode 100644 index 0000000000000000000000000000000000000000..048703b6bb130fbd26f5be88650e950f70355a24 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/test/client.yml @@ -0,0 +1,99 @@ +# dubbo client yaml configure file + + +check: true +# client +request_timeout : "3s" +# connect timeout +connect_timeout : "3s" + +# application config +application_config: + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "test" + +registries : + "hangzhouzk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2181" + username: "" + password: "" + "shanghaizk": + protocol: "zookeeper" + timeout : "3s" + address: "127.0.0.1:2182" + username: "" + password: "" + +references: + "UserProvider": + # 鍙互鎸囧畾澶氫釜registry锛屼娇鐢ㄩ€楀彿闅斿紑;涓嶆寚瀹氶粯璁ゅ悜鎵€鏈夋敞鍐屼腑蹇冩敞鍐� + registry: "hangzhouzk" + filter: "example_fallback,hystrix_consumer" + protocol : "dubbo" +# version: "2.0" +# group: "as" + interface : "com.ikurento.user.UserProvider" + cluster: "failover" + methods : + - name: "GetUser" + retries: 3 + +protocol_conf: + dubbo: + reconnect_interval: 0 + connection_number: 2 + heartbeat_period: "5s" + session_timeout: "20s" + fail_fast_timeout: "5s" + pool_size: 64 + pool_ttl: 600 + getty_session_param: + compress_encoding: false + tcp_no_delay: true + tcp_keep_alive: true + keep_alive_period: "120s" + tcp_r_buf_size: 262144 + tcp_w_buf_size: 65536 + pkg_rq_size: 1024 + pkg_wq_size: 512 + tcp_read_timeout: "1s" + tcp_write_timeout: "5s" + wait_timeout: "1s" + max_msg_len: 10240 + session_name: "client" + +filter_conf: + hystrix: + configs: + "Default": + timeout : 1000 + max_concurrent_requests : 25 + sleep_window : 5000 + error_percent_threshold : 50 + request_volume_threshold: 20 + "userp": + timeout: 2000 + max_concurrent_requests: 512 + sleep_window: 4000 + error_percent_threshold: 35 + request_volume_threshold: 6 + "userp_m": + timeout : 1200 + max_concurrent_requests : 512 + sleep_window : 6000 + error_percent_threshold : 60 + request_volume_threshold: 16 + error_whitelist: [".*exception.*"] + default: "Default" + services: + "com.ikurento.user.UserProvider": + service_config: "userp" + methods: + "GetUser": "userp_m" + "GetUser1": "userp_m" \ No newline at end of file diff --git a/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/test/log.yml b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/test/log.yml new file mode 100644 index 0000000000000000000000000000000000000000..f93d3c7fccadec845059460befb2e0b1076881e2 --- /dev/null +++ b/examples/hystrixfilter/dubbo/with-hystrix-go-client/profiles/test/log.yml @@ -0,0 +1,28 @@ + +level: "info" +development: false +disableCaller: false +disableStacktrace: true +sampling: +encoding: "console" + +# encoder +encoderConfig: + messageKey: "message" + levelKey: "level" + timeKey: "time" + nameKey: "logger" + callerKey: "caller" + stacktraceKey: "stacktrace" + lineEnding: "" + levelEncoder: "capitalColor" + timeEncoder: "iso8601" + durationEncoder: "seconds" + callerEncoder: "short" + nameEncoder: "" + +outputPaths: + - "stderr" +errorOutputPaths: + - "stderr" +initialFields: diff --git a/filter/impl/hystrix_filter.go b/filter/impl/hystrix_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..3fd9f87168616b69d5ec72460767890d6956c154 --- /dev/null +++ b/filter/impl/hystrix_filter.go @@ -0,0 +1,269 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package impl + +import ( + "fmt" + "regexp" + "sync" +) +import ( + "github.com/afex/hystrix-go/hystrix" + perrors "github.com/pkg/errors" + "gopkg.in/yaml.v2" +) +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/filter" + "github.com/apache/dubbo-go/protocol" +) + +const ( + HYSTRIX_CONSUMER = "hystrix_consumer" + HYSTRIX_PROVIDER = "hystrix_provider" + HYSTRIX = "hystrix" +) + +var ( + confConsumer = &HystrixFilterConfig{} + confProvider = &HystrixFilterConfig{} + configLoadMutex = sync.RWMutex{} + consumerConfigOnce sync.Once + providerConfigOnce sync.Once +) + +//The filter in the server end of dubbo-go can't get the invoke result for now, +//this filter ONLY works in CLIENT end (consumer side) temporarily +//Only after the callService logic is integrated into the filter chain of server end can this filter be used, +//which will be done soon +func init() { + extension.SetFilter(HYSTRIX_CONSUMER, GetHystrixFilterConsumer) + extension.SetFilter(HYSTRIX_PROVIDER, GetHystrixFilterProvider) +} + +type HystrixFilterError struct { + err error + failByHystrix bool +} + +func (hfError *HystrixFilterError) Error() string { + return hfError.err.Error() +} + +func (hfError *HystrixFilterError) FailByHystrix() bool { + return hfError.failByHystrix +} +func NewHystrixFilterError(err error, failByHystrix bool) error { + return &HystrixFilterError{ + err: err, + failByHystrix: failByHystrix, + } +} + +type HystrixFilter struct { + COrP bool //true for consumer + res map[string][]*regexp.Regexp + ifNewMap sync.Map +} + +func (hf *HystrixFilter) Invoke(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(invocation) + } + logger.Infof("[Hystrix Filter]Using hystrix filter: %s", cmdName) + var result protocol.Result + _ = hystrix.Do(cmdName, func() error { + result = invoker.Invoke(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 +} + +func (hf *HystrixFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + return result +} +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} +} + +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} +} + +func getConfig(service string, method string, cOrP bool) CommandConfigWithError { + //Find method level config + var conf *HystrixFilterConfig + if cOrP { + conf = confConsumer + } else { + conf = confProvider + } + getConf := conf.Configs[conf.Services[service].Methods[method]] + if getConf != nil { + logger.Infof("[Hystrix Filter]Found method-level config for %s - %s", service, method) + return *getConf + } + //Find service level config + getConf = conf.Configs[conf.Services[service].ServiceConfig] + if getConf != nil { + logger.Infof("[Hystrix Filter]Found service-level config for %s - %s", service, method) + return *getConf + } + //Find default config + getConf = conf.Configs[conf.Default] + if getConf != nil { + logger.Infof("[Hystrix Filter]Found global default config for %s - %s", service, method) + return *getConf + } + getConf = &CommandConfigWithError{} + logger.Infof("[Hystrix Filter]No config found for %s - %s, using default", service, method) + return *getConf + +} + +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 +} +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 +} + +//For sake of dynamic config +//func RefreshHystrix() error { +// conf = &HystrixFilterConfig{} +// hystrix.Flush() +// return initHystrixConfig() +//} + +type CommandConfigWithError struct { + Timeout int `yaml:"timeout"` + MaxConcurrentRequests int `yaml:"max_concurrent_requests"` + RequestVolumeThreshold int `yaml:"request_volume_threshold"` + SleepWindow int `yaml:"sleep_window"` + ErrorPercentThreshold int `yaml:"error_percent_threshold"` + Error []string `yaml:"error_whitelist"` +} + +//Config: +//- Timeout: how long to wait for command to complete, in milliseconds +//- MaxConcurrentRequests: how many commands of the same type can run at the same time +//- RequestVolumeThreshold: the minimum number of requests needed before a circuit can be tripped due to health +//- SleepWindow: how long, in milliseconds, to wait after a circuit opens before testing for recovery +//- ErrorPercentThreshold: it causes circuits to open once the rolling measure of errors exceeds this percent of requests +//See hystrix doc + +type HystrixFilterConfig struct { + Configs map[string]*CommandConfigWithError + Default string + Services map[string]ServiceHystrixConfig +} +type ServiceHystrixConfig struct { + ServiceConfig string `yaml:"service_config"` + Methods map[string]string +} diff --git a/filter/impl/hystrix_filter_test.go b/filter/impl/hystrix_filter_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d3a5183ede25d8a325bb1c73020edddd2ffbc638 --- /dev/null +++ b/filter/impl/hystrix_filter_test.go @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package impl + +import ( + "regexp" + "testing" +) +import ( + "github.com/afex/hystrix-go/hystrix" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) +import ( + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/invocation" +) + +func init() { + mockInitHystrixConfig() +} + +func TestNewHystrixFilterError(t *testing.T) { + get := NewHystrixFilterError(errors.New("test"), true) + assert.True(t, get.(*HystrixFilterError).FailByHystrix()) + assert.Equal(t, "test", get.Error()) +} + +func mockInitHystrixConfig() { + //Mock config + confConsumer = &HystrixFilterConfig{ + make(map[string]*CommandConfigWithError), + "Default", + make(map[string]ServiceHystrixConfig), + } + confConsumer.Configs["Default"] = &CommandConfigWithError{ + Timeout: 1000, + MaxConcurrentRequests: 600, + RequestVolumeThreshold: 5, + SleepWindow: 5000, + ErrorPercentThreshold: 5, + Error: nil, + } + confConsumer.Configs["userp"] = &CommandConfigWithError{ + Timeout: 2000, + MaxConcurrentRequests: 64, + RequestVolumeThreshold: 15, + SleepWindow: 4000, + ErrorPercentThreshold: 45, + Error: nil, + } + confConsumer.Configs["userp_m"] = &CommandConfigWithError{ + Timeout: 1200, + MaxConcurrentRequests: 64, + RequestVolumeThreshold: 5, + SleepWindow: 6000, + ErrorPercentThreshold: 60, + Error: []string{ + "exception", + }, + } + confConsumer.Services["com.ikurento.user.UserProvider"] = ServiceHystrixConfig{ + "userp", + map[string]string{ + "GetUser": "userp_m", + }, + } + +} + +func TestGetHystrixFilter(t *testing.T) { + filterGot := GetHystrixFilterConsumer() + assert.NotNil(t, filterGot) +} + +func TestGetConfig_1(t *testing.T) { + mockInitHystrixConfig() + configGot := getConfig("com.ikurento.user.UserProvider", "GetUser", true) + assert.NotNil(t, configGot) + assert.Equal(t, 1200, configGot.Timeout) + assert.Equal(t, 64, configGot.MaxConcurrentRequests) + assert.Equal(t, 6000, configGot.SleepWindow) + assert.Equal(t, 60, configGot.ErrorPercentThreshold) + assert.Equal(t, 5, configGot.RequestVolumeThreshold) +} + +func TestGetConfig_2(t *testing.T) { + mockInitHystrixConfig() + configGot := getConfig("com.ikurento.user.UserProvider", "GetUser0", true) + assert.NotNil(t, configGot) + assert.Equal(t, 2000, configGot.Timeout) + assert.Equal(t, 64, configGot.MaxConcurrentRequests) + assert.Equal(t, 4000, configGot.SleepWindow) + assert.Equal(t, 45, configGot.ErrorPercentThreshold) + assert.Equal(t, 15, configGot.RequestVolumeThreshold) +} + +func TestGetConfig_3(t *testing.T) { + mockInitHystrixConfig() + //This should use default + configGot := getConfig("Mock.Service", "GetMock", true) + assert.NotNil(t, configGot) + assert.Equal(t, 1000, configGot.Timeout) + assert.Equal(t, 600, configGot.MaxConcurrentRequests) + assert.Equal(t, 5000, configGot.SleepWindow) + assert.Equal(t, 5, configGot.ErrorPercentThreshold) + assert.Equal(t, 5, configGot.RequestVolumeThreshold) +} + +type testMockSuccessInvoker struct { + protocol.BaseInvoker +} + +func (iv *testMockSuccessInvoker) Invoke(invocation protocol.Invocation) protocol.Result { + return &protocol.RPCResult{ + Rest: "Sucess", + Err: nil, + } +} + +type testMockFailInvoker struct { + protocol.BaseInvoker +} + +func (iv *testMockFailInvoker) Invoke(invocation protocol.Invocation) protocol.Result { + return &protocol.RPCResult{ + Err: errors.Errorf("exception"), + } +} + +func TestHystrixFilter_Invoke_Success(t *testing.T) { + hf := &HystrixFilter{} + result := hf.Invoke(&testMockSuccessInvoker{}, &invocation.RPCInvocation{}) + assert.NotNil(t, result) + assert.NoError(t, result.Error()) + assert.NotNil(t, result.Result()) +} + +func TestHystrixFilter_Invoke_Fail(t *testing.T) { + hf := &HystrixFilter{} + result := hf.Invoke(&testMockFailInvoker{}, &invocation.RPCInvocation{}) + assert.NotNil(t, result) + assert.Error(t, result.Error()) +} + +func TestHystricFilter_Invoke_CircuitBreak(t *testing.T) { + mockInitHystrixConfig() + hystrix.Flush() + hf := &HystrixFilter{COrP: true} + resChan := make(chan protocol.Result, 50) + for i := 0; i < 50; i++ { + go func() { + result := hf.Invoke(&testMockFailInvoker{}, &invocation.RPCInvocation{}) + resChan <- result + }() + } + //This can not always pass the test when on travis due to concurrency, you can uncomment the code below and test it locally + + //var lastRest bool + //for i := 0; i < 50; i++ { + // lastRest = (<-resChan).Error().(*HystrixFilterError).FailByHystrix() + //} + //Normally the last result should be true, which means the circuit has been opened + // + //assert.True(t, lastRest) + +} + +func TestHystricFilter_Invoke_CircuitBreak_Omit_Exception(t *testing.T) { + mockInitHystrixConfig() + hystrix.Flush() + reg, _ := regexp.Compile(".*exception.*") + regs := []*regexp.Regexp{reg} + hf := &HystrixFilter{res: map[string][]*regexp.Regexp{"": regs}, COrP: true} + resChan := make(chan protocol.Result, 50) + for i := 0; i < 50; i++ { + go func() { + result := hf.Invoke(&testMockFailInvoker{}, &invocation.RPCInvocation{}) + resChan <- result + }() + } + //This can not always pass the test when on travis due to concurrency, you can uncomment the code below and test it locally + + //time.Sleep(time.Second * 6) + //var lastRest bool + //for i := 0; i < 50; i++ { + // lastRest = (<-resChan).Error().(*HystrixFilterError).FailByHystrix() + //} + // + //assert.False(t, lastRest) + +} + +func TestGetHystrixFilterConsumer(t *testing.T) { + get := GetHystrixFilterConsumer() + assert.NotNil(t, get) + assert.True(t, get.(*HystrixFilter).COrP) +} +func TestGetHystrixFilterProvider(t *testing.T) { + get := GetHystrixFilterProvider() + assert.NotNil(t, get) + assert.False(t, get.(*HystrixFilter).COrP) +} diff --git a/go.mod b/go.mod index 12ab8c15559e2a56da44541727a0abbccebe4f25..20a8fc836788b1b30ca0368574f65f3b54d94d3a 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,7 @@ module github.com/apache/dubbo-go require ( github.com/Workiva/go-datastructures v1.0.50 + github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect github.com/apache/dubbo-go-hessian2 v1.2.5-0.20190731020727-1697039810c8 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect @@ -32,6 +33,7 @@ require ( github.com/pkg/errors v0.8.1 github.com/prometheus/client_golang v1.1.0 // indirect github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec + github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect github.com/soheilhy/cmux v0.1.4 // indirect github.com/stretchr/testify v1.3.0 github.com/tebeka/strftime v0.1.3 // indirect diff --git a/go.sum b/go.sum index 40541db3605afa82a32cc03f376579c884ad2560..4c6eb9b2553042914b00f2cd121277804b896a57 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,8 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIO github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -292,6 +294,8 @@ github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62F github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b h1:VE6r2OwP5gj+Z9aCkSKl3MlmnZbfMAjhvR5T7abKHEo= @@ -421,10 +425,14 @@ github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 h1:N8Bg45zpk/UcpNGnfJt2y/3lRWASHNTUET8owPYCgYI= +github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic= github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= diff --git a/protocol/protocolwrapper/protocol_filter_wrapper_test.go b/protocol/protocolwrapper/protocol_filter_wrapper_test.go index 8a332490f71ead601d151fe5e27390eadcc1cbd8..f6a73d448525da51d9d5578a0d1ec552a1d4128d 100644 --- a/protocol/protocolwrapper/protocol_filter_wrapper_test.go +++ b/protocol/protocolwrapper/protocol_filter_wrapper_test.go @@ -18,6 +18,8 @@ package protocolwrapper import ( + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/filter" "net/url" "testing" ) @@ -30,7 +32,7 @@ import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" - "github.com/apache/dubbo-go/filter/impl" + //"github.com/apache/dubbo-go/filter/impl" "github.com/apache/dubbo-go/protocol" ) @@ -40,7 +42,7 @@ func TestProtocolFilterWrapper_Export(t *testing.T) { u := common.NewURLWithOptions( common.WithParams(url.Values{}), - common.WithParamsValue(constant.SERVICE_FILTER_KEY, impl.ECHO)) + common.WithParamsValue(constant.SERVICE_FILTER_KEY, "echo")) exporter := filtProto.Export(protocol.NewBaseInvoker(*u)) _, ok := exporter.GetInvoker().(*FilterInvoker) assert.True(t, ok) @@ -52,8 +54,35 @@ func TestProtocolFilterWrapper_Refer(t *testing.T) { u := common.NewURLWithOptions( common.WithParams(url.Values{}), - common.WithParamsValue(constant.REFERENCE_FILTER_KEY, impl.ECHO)) + common.WithParamsValue(constant.REFERENCE_FILTER_KEY, "echo")) invoker := filtProto.Refer(*u) _, ok := invoker.(*FilterInvoker) assert.True(t, ok) } + +//the same as echo filter, for test +func init() { + extension.SetFilter("echo", GetFilter) +} + +type EchoFilterForTest struct{} + +func (ef *EchoFilterForTest) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + logger.Infof("invoking echo filter.") + logger.Debugf("%v,%v", invocation.MethodName(), len(invocation.Arguments())) + if invocation.MethodName() == constant.ECHO && len(invocation.Arguments()) == 1 { + return &protocol.RPCResult{ + Rest: invocation.Arguments()[0], + } + } + + return invoker.Invoke(invocation) +} + +func (ef *EchoFilterForTest) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + return result +} + +func GetFilter() filter.Filter { + return &EchoFilterForTest{} +}