From 8129bca60e08b07e09e2972c10b9103f4fed3710 Mon Sep 17 00:00:00 2001 From: "vito.he" <hxmhlt@163.com> Date: Sat, 22 Jun 2019 04:32:26 +0800 Subject: [PATCH] Ftr: new feature implement for config center, config refresh from config center when dubbogo start --- common/config/environment.go | 35 ++- common/config/environment_test.go | 52 ++++ common/constant/key.go | 8 + common/url.go | 9 +- config/application_config.go | 24 +- config/base_config.go | 227 ++++++++++---- config/base_config_test.go | 282 +++++++++++++++--- config/config_center_config.go | 1 - config/config_loader.go | 188 ++---------- config/config_loader_test.go | 34 ++- config/consumer_config.go | 134 +++++++++ config/method_config.go | 36 +++ config/protocol_config.go | 45 +++ config/provider_config.go | 107 +++++++ config/reference_config.go | 40 +-- config/reference_config_test.go | 45 ++- config/registry_config.go | 41 ++- config/service_config.go | 33 +- config/service_config_test.go | 46 ++- config/testdata/consumer_config.yml | 12 +- .../consumer_config_with_configcenter.yml | 39 +++ config/testdata/provider_config.yml | 12 +- config_center/mock_dynamic_config.go | 94 ++++++ config_center/zookeeper/factory.go | 5 +- config_center/zookeeper/impl.go | 58 +++- config_center/zookeeper/impl_test.go | 162 ++++++++++ config_center/zookeeper/listener.go | 6 +- .../dubbo/go-client/profiles/dev/client.yml | 35 +-- .../go-client/profiles/release/client.yml | 24 +- .../dubbo/go-client/profiles/test/client.yml | 24 +- .../dubbo/go-server/profiles/dev/server.yml | 37 ++- .../go-server/profiles/release/server.yml | 31 +- .../dubbo/go-server/profiles/test/server.yml | 31 +- .../with-configcenter-go-client/app/client.go | 146 +++++++++ .../with-configcenter-go-client/app/user.go | 114 +++++++ .../app/version.go | 22 ++ .../assembly/bin/load.sh | 196 ++++++++++++ .../assembly/common/app.properties | 17 ++ .../assembly/common/build.sh | 77 +++++ .../assembly/linux/dev.sh | 29 ++ .../assembly/linux/release.sh | 28 ++ .../assembly/linux/test.sh | 28 ++ .../assembly/mac/dev.sh | 29 ++ .../assembly/mac/release.sh | 27 ++ .../assembly/mac/test.sh | 28 ++ .../assembly/windows/dev.sh | 27 ++ .../assembly/windows/release.sh | 27 ++ .../assembly/windows/test.sh | 27 ++ .../profiles/dev/client.yml | 40 +++ .../profiles/dev/log.yml | 28 ++ .../profiles/release/client.yml | 40 +++ .../profiles/release/log.yml | 28 ++ .../profiles/test/client.yml | 40 +++ .../profiles/test/log.yml | 28 ++ .../with-configcenter-go-server/app/server.go | 89 ++++++ .../with-configcenter-go-server/app/user.go | 195 ++++++++++++ .../app/version.go | 22 ++ .../assembly/bin/load.sh | 144 +++++++++ .../assembly/common/app.properties | 17 ++ .../assembly/common/build.sh | 74 +++++ .../assembly/linux/dev.sh | 29 ++ .../assembly/linux/release.sh | 29 ++ .../assembly/linux/test.sh | 29 ++ .../assembly/mac/dev.sh | 29 ++ .../assembly/mac/release.sh | 29 ++ .../assembly/mac/test.sh | 29 ++ .../assembly/windows/dev.sh | 29 ++ .../assembly/windows/release.sh | 29 ++ .../assembly/windows/test.sh | 29 ++ .../profiles/dev/log.yml | 28 ++ .../profiles/dev/server.yml | 41 +++ .../profiles/release/log.yml | 28 ++ .../profiles/release/server.yml | 41 +++ .../profiles/test/log.yml | 28 ++ .../profiles/test/server.yml | 41 +++ .../jsonrpc/go-client/profiles/dev/client.yml | 14 +- .../go-client/profiles/release/client.yml | 51 +++- .../go-client/profiles/test/client.yml | 50 +++- .../jsonrpc/go-server/profiles/dev/server.yml | 16 +- .../go-server/profiles/release/server.yml | 64 ++-- .../go-server/profiles/test/server.yml | 50 ++-- .../with-configcenter-go-client/app/client.go | 132 ++++++++ .../with-configcenter-go-client/app/user.go | 64 ++++ .../app/version.go | 22 ++ .../assembly/bin/load.sh | 196 ++++++++++++ .../assembly/common/app.properties | 17 ++ .../assembly/common/build.sh | 77 +++++ .../assembly/linux/dev.sh | 29 ++ .../assembly/linux/release.sh | 28 ++ .../assembly/linux/test.sh | 28 ++ .../assembly/mac/dev.sh | 29 ++ .../assembly/mac/release.sh | 27 ++ .../assembly/mac/test.sh | 28 ++ .../assembly/windows/dev.sh | 27 ++ .../assembly/windows/release.sh | 27 ++ .../assembly/windows/test.sh | 27 ++ .../profiles/dev/client.yml | 16 + .../profiles/dev/log.yml | 28 ++ .../profiles/release/client.yml | 16 + .../profiles/release/log.yml | 28 ++ .../profiles/test/client.yml | 16 + .../profiles/test/log.yml | 28 ++ .../with-configcenter-go-server/app/server.go | 78 +++++ .../with-configcenter-go-server/app/user.go | 159 ++++++++++ .../app/version.go | 22 ++ .../assembly/bin/load.sh | 144 +++++++++ .../assembly/common/app.properties | 17 ++ .../assembly/common/build.sh | 74 +++++ .../assembly/linux/dev.sh | 29 ++ .../assembly/linux/release.sh | 29 ++ .../assembly/linux/test.sh | 29 ++ .../assembly/mac/dev.sh | 29 ++ .../assembly/mac/release.sh | 29 ++ .../assembly/mac/test.sh | 29 ++ .../assembly/windows/dev.sh | 29 ++ .../assembly/windows/release.sh | 29 ++ .../assembly/windows/test.sh | 29 ++ .../profiles/dev/log.yml | 28 ++ .../profiles/dev/server.yml | 22 ++ .../profiles/release/log.yml | 28 ++ .../profiles/release/server.yml | 25 ++ .../profiles/test/log.yml | 28 ++ .../profiles/test/server.yml | 25 ++ protocol/jsonrpc/http.go | 2 +- protocol/jsonrpc/server.go | 12 +- remoting/zookeeper/client.go | 2 +- remoting/zookeeper/listener.go | 116 ++++++- 127 files changed, 5514 insertions(+), 656 deletions(-) create mode 100644 common/config/environment_test.go create mode 100644 config/consumer_config.go create mode 100644 config/method_config.go create mode 100644 config/protocol_config.go create mode 100644 config/provider_config.go create mode 100644 config/testdata/consumer_config_with_configcenter.yml create mode 100644 config_center/mock_dynamic_config.go create mode 100644 config_center/zookeeper/impl_test.go create mode 100644 examples/dubbo/with-configcenter-go-client/app/client.go create mode 100644 examples/dubbo/with-configcenter-go-client/app/user.go create mode 100644 examples/dubbo/with-configcenter-go-client/app/version.go create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/bin/load.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/common/app.properties create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/common/build.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/linux/dev.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/linux/release.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/linux/test.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/mac/dev.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/mac/release.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/mac/test.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/windows/dev.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/windows/release.sh create mode 100644 examples/dubbo/with-configcenter-go-client/assembly/windows/test.sh create mode 100644 examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml create mode 100644 examples/dubbo/with-configcenter-go-client/profiles/dev/log.yml create mode 100644 examples/dubbo/with-configcenter-go-client/profiles/release/client.yml create mode 100644 examples/dubbo/with-configcenter-go-client/profiles/release/log.yml create mode 100644 examples/dubbo/with-configcenter-go-client/profiles/test/client.yml create mode 100644 examples/dubbo/with-configcenter-go-client/profiles/test/log.yml create mode 100644 examples/dubbo/with-configcenter-go-server/app/server.go create mode 100644 examples/dubbo/with-configcenter-go-server/app/user.go create mode 100644 examples/dubbo/with-configcenter-go-server/app/version.go create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/bin/load.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/common/app.properties create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/common/build.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/linux/dev.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/linux/release.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/linux/test.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/mac/dev.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/mac/release.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/mac/test.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/windows/dev.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/windows/release.sh create mode 100644 examples/dubbo/with-configcenter-go-server/assembly/windows/test.sh create mode 100644 examples/dubbo/with-configcenter-go-server/profiles/dev/log.yml create mode 100644 examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml create mode 100644 examples/dubbo/with-configcenter-go-server/profiles/release/log.yml create mode 100644 examples/dubbo/with-configcenter-go-server/profiles/release/server.yml create mode 100644 examples/dubbo/with-configcenter-go-server/profiles/test/log.yml create mode 100644 examples/dubbo/with-configcenter-go-server/profiles/test/server.yml create mode 100644 examples/jsonrpc/with-configcenter-go-client/app/client.go create mode 100644 examples/jsonrpc/with-configcenter-go-client/app/user.go create mode 100644 examples/jsonrpc/with-configcenter-go-client/app/version.go create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/common/app.properties create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/common/build.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh create mode 100644 examples/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml create mode 100644 examples/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml create mode 100644 examples/jsonrpc/with-configcenter-go-client/profiles/release/client.yml create mode 100644 examples/jsonrpc/with-configcenter-go-client/profiles/release/log.yml create mode 100644 examples/jsonrpc/with-configcenter-go-client/profiles/test/client.yml create mode 100644 examples/jsonrpc/with-configcenter-go-client/profiles/test/log.yml create mode 100644 examples/jsonrpc/with-configcenter-go-server/app/server.go create mode 100644 examples/jsonrpc/with-configcenter-go-server/app/user.go create mode 100644 examples/jsonrpc/with-configcenter-go-server/app/version.go create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/common/app.properties create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/common/build.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh create mode 100644 examples/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml create mode 100644 examples/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml create mode 100644 examples/jsonrpc/with-configcenter-go-server/profiles/release/log.yml create mode 100644 examples/jsonrpc/with-configcenter-go-server/profiles/release/server.yml create mode 100644 examples/jsonrpc/with-configcenter-go-server/profiles/test/log.yml create mode 100644 examples/jsonrpc/with-configcenter-go-server/profiles/test/server.yml diff --git a/common/config/environment.go b/common/config/environment.go index d92c000a3..7d2f4e598 100644 --- a/common/config/environment.go +++ b/common/config/environment.go @@ -19,6 +19,7 @@ package config import ( "container/list" + "strings" "sync" ) @@ -58,31 +59,45 @@ func (env *Environment) UpdateExternalConfigMap(externalMap map[string]string) { } } -func (env *Environment) Configuration(prefix string) *list.List { +func (env *Environment) Configuration() *list.List { list := list.New() - memConf := newInmemoryConfiguration(prefix) + memConf := newInmemoryConfiguration() memConf.setProperties(env.externalConfigMap) list.PushBack(memConf) return list } type InmemoryConfiguration struct { - prefix string - store sync.Map + store sync.Map } -func newInmemoryConfiguration(prefix string) *InmemoryConfiguration { - return &InmemoryConfiguration{prefix: prefix} +func newInmemoryConfiguration() *InmemoryConfiguration { + return &InmemoryConfiguration{} } func (conf *InmemoryConfiguration) setProperties(p sync.Map) { conf.store = p } -func (conf *InmemoryConfiguration) GetProperty(key string) string { - v, ok := conf.store.Load(conf.prefix + "." + key) +func (conf *InmemoryConfiguration) GetProperty(key string) (bool, string) { + v, ok := conf.store.Load(key) if ok { - return v.(string) + return true, v.(string) } else { - return "" + return false, "" } } + +func (conf *InmemoryConfiguration) GetSubProperty(subKey string) map[string]struct{} { + properties := make(map[string]struct{}) + conf.store.Range(func(key, value interface{}) bool { + if idx := strings.Index(key.(string), subKey); idx >= 0 { + after := key.(string)[idx+len(subKey):] + if i := strings.Index(after, "."); i >= 0 { + properties[after[0:strings.Index(after, ".")]] = struct{}{} + } + + } + return true + }) + return properties +} diff --git a/common/config/environment_test.go b/common/config/environment_test.go new file mode 100644 index 000000000..ab7cafae8 --- /dev/null +++ b/common/config/environment_test.go @@ -0,0 +1,52 @@ +/* + * 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 config + +import ( + "testing" +) +import ( + "github.com/stretchr/testify/assert" +) + +func TestGetEnvInstance(t *testing.T) { + GetEnvInstance() + assert.NotNil(t, instance) +} + +func TestEnvironment_UpdateExternalConfigMap(t *testing.T) { + GetEnvInstance().UpdateExternalConfigMap(map[string]string{"1": "2"}) + v, ok := GetEnvInstance().externalConfigMap.Load("1") + assert.True(t, ok) + assert.Equal(t, "2", v) +} + +func TestEnvironment_ConfigurationAndGetProperty(t *testing.T) { + GetEnvInstance().UpdateExternalConfigMap(map[string]string{"1": "2"}) + list := GetEnvInstance().Configuration() + ok, v := list.Front().Value.(*InmemoryConfiguration).GetProperty("1") + assert.True(t, ok) + assert.Equal(t, "2", v) +} + +func TestInmemoryConfiguration_GetSubProperty(t *testing.T) { + GetEnvInstance().UpdateExternalConfigMap(map[string]string{"123": "2"}) + list := GetEnvInstance().Configuration() + m := list.Front().Value.(*InmemoryConfiguration).GetSubProperty("1") + + assert.Equal(t, struct{}{}, m["123"]) +} diff --git a/common/constant/key.go b/common/constant/key.go index e49ddae72..4392d8034 100644 --- a/common/constant/key.go +++ b/common/constant/key.go @@ -72,3 +72,11 @@ const ( CONFIG_NAMESPACE_KEY = "config.namespace" CONFIG_TIMEOUT_KET = "config.timeout" ) +const ( + RegistryConfigPrefix = "dubbo.registries." + ReferenceConfigPrefix = "dubbo.reference." + ServiceConfigPrefix = "dubbo.service." + ProtocolConfigPrefix = "dubbo.protocols." + ProviderConfigPrefix = "dubbo.provider." + ConsumerConfigPrefix = "dubbo.consumer." +) diff --git a/common/url.go b/common/url.go index 115167ee3..6dbae32e7 100644 --- a/common/url.go +++ b/common/url.go @@ -164,6 +164,13 @@ func NewURL(ctx context.Context, urlString string, opts ...option) (URL, error) } //rawUrlString = "//" + rawUrlString + if strings.Index(rawUrlString, "//") < 0 { + t := URL{baseUrl: baseUrl{ctx: ctx}} + for _, opt := range opts { + opt(&t) + } + rawUrlString = t.Protocol + "://" + rawUrlString + } serviceUrl, err = url.Parse(rawUrlString) if err != nil { return s, perrors.Errorf("url.Parse(url string{%s}), error{%v}", rawUrlString, err) @@ -197,10 +204,10 @@ func NewURL(ctx context.Context, urlString string, opts ...option) (URL, error) // s.Timeout = time.Duration(timeout * 1e6) // timeout unit is millisecond // } //} + //fmt.Println(s.String()) for _, opt := range opts { opt(&s) } - //fmt.Println(s.String()) return s, nil } diff --git a/config/application_config.go b/config/application_config.go index ae9716d2d..af4ffd6ac 100644 --- a/config/application_config.go +++ b/config/application_config.go @@ -17,11 +17,23 @@ package config +import "github.com/apache/dubbo-go/common/constant" + type ApplicationConfig struct { - Organization string `yaml:"organization" json:"organization,omitempty"` - Name string `yaml:"name" json:"name,omitempty"` - Module string `yaml:"module" json:"module,omitempty"` - Version string `yaml:"version" json:"version,omitempty"` - Owner string `yaml:"owner" json:"owner,omitempty"` - Environment string `yaml:"environment" json:"environment,omitempty"` + Organization string `yaml:"organization" json:"organization,omitempty" property:"organization"` + Name string `yaml:"name" json:"name,omitempty" property:"name"` + Module string `yaml:"module" json:"module,omitempty" property:"module"` + Version string `yaml:"version" json:"version,omitempty" property:"version"` + Owner string `yaml:"owner" json:"owner,omitempty" property:"owner"` + Environment string `yaml:"environment" json:"environment,omitempty" property:"environment"` +} + +func (*ApplicationConfig) Prefix() string { + return constant.DUBBO + ".application." +} +func (c *ApplicationConfig) Id() string { + return "" +} +func (c *ApplicationConfig) SetId(id string) { + } diff --git a/config/base_config.go b/config/base_config.go index dc7a2f19a..f15eada0e 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -18,10 +18,8 @@ package config import ( "context" - "github.com/apache/dubbo-go/common/constant" "reflect" "strconv" - "strings" ) import ( perrors "github.com/pkg/errors" @@ -34,24 +32,31 @@ import ( "github.com/apache/dubbo-go/config_center" ) -type baseConfig struct { - ConfigCenterConfig ConfigCenterConfig +type multiConfiger interface { + Prefix() string +} + +type BaseConfig struct { + ConfigCenterConfig *ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` configCenterUrl *common.URL prefix string fatherConfig interface{} } -func (c *baseConfig) startConfigCenter(ctx context.Context) error { - var err error - *c.configCenterUrl, err = common.NewURL(ctx, c.ConfigCenterConfig.Address) +func (c *BaseConfig) startConfigCenter(ctx context.Context) error { + url, err := common.NewURL(ctx, c.ConfigCenterConfig.Address, common.WithProtocol(c.ConfigCenterConfig.Protocol)) + if err != nil { + return err + } + c.configCenterUrl = &url if c.prepareEnvironment() != nil { return perrors.WithMessagef(err, "start config center error!") } - c.fresh() + //c.fresh() return err } -func (c *baseConfig) prepareEnvironment() error { +func (c *BaseConfig) prepareEnvironment() error { factory := extension.GetConfigCenterFactory(c.ConfigCenterConfig.Protocol) dynamicConfig, err := factory.GetDynamicConfiguration(c.configCenterUrl) @@ -72,76 +77,184 @@ func (c *baseConfig) prepareEnvironment() error { return nil } -func (c *baseConfig) fresh() { - configList := config.GetEnvInstance().Configuration(c.Prefix()) - config := configList.Front().Value.(*config.InmemoryConfiguration) - val := reflect.Indirect(reflect.ValueOf(c.fatherConfig)) +func getKeyPrefix(val reflect.Value, id reflect.Value) string { + var prefix string + var idStr string + if id.Kind() == reflect.String { + idStr = id.Interface().(string) + } + + if val.CanAddr() { + prefix = val.Addr().MethodByName("Prefix").Call(nil)[0].String() + } else { + prefix = val.MethodByName("Prefix").Call(nil)[0].String() + } + + if idStr != "" { + return prefix + idStr + "." + } else { + return prefix + } +} + +func setFieldValue(val reflect.Value, id reflect.Value, config *config.InmemoryConfiguration) { for i := 0; i < val.NumField(); i++ { if key := val.Type().Field(i).Tag.Get("property"); key != "-" && key != "" { f := val.Field(i) if f.IsValid() { - value := config.GetProperty(key) - setValue := func(f reflect.Value) { - if f.Kind() == reflect.Int { - x, err := strconv.Atoi(value) - if err != nil { - logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", - val.Type().Name(), val.Type().Field(i).Name, err) - } else { - if !f.OverflowInt(int64(x)) { - f.SetInt(int64(x)) - } else { + setBaseValue := func(f reflect.Value) { + ok, value := config.GetProperty(getKeyPrefix(val, id) + key) + if ok { + if f.Kind() == reflect.Int64 { + x, err := strconv.Atoi(value) + if err != nil { logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", - val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the int64 value {%v} from config center is overflow", int64(x))) + val.Type().Name(), val.Type().Field(i).Name, err) + } else { + if !f.OverflowInt(int64(x)) { + f.SetInt(int64(x)) + } else { + logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", + val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the int64 value {%v} from config center is overflow", int64(x))) + } } + } + if f.Kind() == reflect.String { + f.SetString(value) + } + if f.Kind() == reflect.Bool { + x, err := strconv.ParseBool(value) + if err != nil { + logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", + val.Type().Name(), val.Type().Field(i).Name, err) + } + f.SetBool(x) + } + if f.Kind() == reflect.Float64 { + x, err := strconv.ParseFloat(value, 64) + if err != nil { + logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", + val.Type().Name(), val.Type().Field(i).Name, err) + } else { + if !f.OverflowFloat(x) { + f.SetFloat(x) + } else { + logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", + val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the float64 value {%v} from config center is overflow", x)) + } + } + } } - if f.Kind() == reflect.String { - f.SetString(value) + + } + + setBaseValue(f) + if f.Kind() == reflect.Ptr { + if f.Elem().Kind() == reflect.Struct { + setFieldValue(f.Elem(), reflect.Value{}, config) + } else { + setBaseValue(f.Elem()) } - if f.Kind() == reflect.Bool { - x, err := strconv.ParseBool(value) - if err != nil { - logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", - val.Type().Name(), val.Type().Field(i).Name, err) + } + + if f.Kind() == reflect.Struct { + setFieldValue(f, reflect.Value{}, config) + } + if f.Kind() == reflect.Slice { + for i := 0; i < f.Len(); i++ { + e := f.Index(i) + if e.Kind() == reflect.Ptr { + if e.Elem().Kind() == reflect.Struct { + setFieldValue(e.Elem(), reflect.Value{}, config) + } else { + setBaseValue(e.Elem()) + } } - f.SetBool(x) + } - if f.Kind() == reflect.Float64 { - x, err := strconv.ParseFloat(value, 64) - if err != nil { - logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", - val.Type().Name(), val.Type().Field(i).Name, err) - } else { - if !f.OverflowFloat(x) { - f.SetFloat(x) + + } + if f.Kind() == reflect.Map { + + //initiate config + s := reflect.New(f.Type().Elem().Elem()) + prefix := s.MethodByName("Prefix").Call(nil)[0].String() + m := config.GetSubProperty(prefix) + for k := range m { + f.SetMapIndex(reflect.ValueOf(k), reflect.New(f.Type().Elem().Elem())) + } + //iter := f.MapRange() + + for _, k := range f.MapKeys() { + v := f.MapIndex(k) + if v.Kind() == reflect.Ptr { + if v.Elem().Kind() == reflect.Struct { + setFieldValue(v.Elem(), k, config) } else { - logger.Errorf("Dynamic change the configuration in struct {%v} field {%v} error ,error message is {%v}", - val.Type().Name(), val.Type().Field(i).Name, perrors.Errorf("the float64 value {%v} from config center is overflow", x)) + setBaseValue(v.Elem()) } } + } } - setValue(f) - if f.Kind() == reflect.Ptr { - setValue(f.Elem()) - } + } } } } +func (c *BaseConfig) fresh() { + configList := config.GetEnvInstance().Configuration() + config := configList.Front().Value.(*config.InmemoryConfiguration) -func (c *baseConfig) SetPrefix(prefix string) { - c.prefix = prefix -} -func (c *baseConfig) Prefix() string { - if c.prefix == "" { - return constant.DUBBO + "." + strings.ToLower(strings.Replace(reflect.Indirect(reflect.ValueOf(c.fatherConfig)).Type().Name(), "Config", "", -1)) - } else { - return c.prefix - } + //reflect to init struct + tp := reflect.ValueOf(c.fatherConfig).Elem().Type() + initializeStruct(tp, reflect.ValueOf(c.fatherConfig).Elem()) + + val := reflect.Indirect(reflect.ValueOf(c.fatherConfig)) + setFieldValue(val, reflect.Value{}, config) } -func (c *baseConfig) SetFatherConfig(fatherConfig interface{}) { + +func (c *BaseConfig) SetFatherConfig(fatherConfig interface{}) { c.fatherConfig = fatherConfig } + +func initializeStruct(t reflect.Type, v reflect.Value) { + if v.Kind() == reflect.Struct { + for i := 0; i < v.NumField(); i++ { + f := v.Field(i) + ft := t.Field(i) + + if ft.Tag.Get("property") != "" { + switch ft.Type.Kind() { + case reflect.Map: + if f.IsNil() { + f.Set(reflect.MakeMap(ft.Type)) + } + case reflect.Slice: + if f.IsNil() { + f.Set(reflect.MakeSlice(ft.Type, 0, 0)) + } + case reflect.Chan: + if f.IsNil() { + f.Set(reflect.MakeChan(ft.Type, 0)) + } + case reflect.Struct: + if f.IsNil() { + initializeStruct(ft.Type, f) + } + case reflect.Ptr: + if f.IsNil() { + fv := reflect.New(ft.Type.Elem()) + initializeStruct(ft.Type.Elem(), fv.Elem()) + f.Set(fv) + } + default: + } + } + + } + } + +} diff --git a/config/base_config_test.go b/config/base_config_test.go index efdcb2b29..7676a11d0 100644 --- a/config/base_config_test.go +++ b/config/base_config_test.go @@ -1,60 +1,258 @@ +/* + * 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 config import ( - "github.com/apache/dubbo-go/common/config" - "github.com/stretchr/testify/assert" + "context" + "fmt" + "reflect" "testing" ) +import ( + "github.com/stretchr/testify/assert" +) +import ( + "github.com/apache/dubbo-go/common/config" + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/config_center" +) func Test_refresh(t *testing.T) { - //Id string `required:"true" yaml:"id" json:"id,omitempty"` - //Type string `required:"true" yaml:"type" json:"type,omitempty"` - //TimeoutStr string `yaml:"timeout" default:"5s" json:"timeout,omitempty"` // unit: second - //Group string `yaml:"group" json:"group,omitempty"` - ////for registry - //Address string `yaml:"address" json:"address,omitempty"` - //Username string `yaml:"username" json:"address,omitempty"` - //Password string `yaml:"password" json:"address,omitempty"` - - c := &baseConfig{} + c := &BaseConfig{} mockMap := map[string]string{} - mockMap["dubbo.registry.type"] = "zookeeper" - mockMap["dubbo.registry.timeout"] = "3s" - mockMap["dubbo.registry.group"] = "hangzhou" - mockMap["dubbo.registry.address"] = "zookeeper://172.0.0.1:2181" - mockMap["dubbo.registry.username"] = "admin" - mockMap["dubbo.registry.password"] = "admin" + mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100" + mockMap["dubbo.reference.MockService.MockService.retries"] = "10" + mockMap["dubbo.MockService.MockService.GetUser.retries"] = "10" + mockMap["dubbo.consumer.check"] = "false" + mockMap["dubbo.application.name"] = "dubbo" + config.GetEnvInstance().UpdateExternalConfigMap(mockMap) - father := &RegistryConfig{Type: "1111"} + + father := &ConsumerConfig{ + Check: &[]bool{true}[0], + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registries: map[string]*RegistryConfig{ + //"shanghai_reg1": { + // id: "shanghai_reg1", + // Protocol: "mock", + // TimeoutStr: "2s", + // Group: "shanghai_idc", + // Address: "127.0.0.1:2181", + // Username: "user1", + // Password: "pwd1", + //}, + "shanghai_reg2": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "shanghai_idc", + Address: "127.0.0.2:2181", + Username: "user1", + Password: "pwd1", + }, + "hangzhou_reg1": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "hangzhou_idc", + Address: "127.0.0.3:2181", + Username: "user1", + Password: "pwd1", + }, + "hangzhou_reg2": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "hangzhou_idc", + Address: "127.0.0.4:2181", + Username: "user1", + Password: "pwd1", + }, + }, + References: map[string]*ReferenceConfig{ + "MockService": { + InterfaceName: "MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: 3, + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + InterfaceId: "MockService", + InterfaceName: "MockService", + Name: "GetUser", + Retries: 2, + Loadbalance: "random", + }, + {InterfaceId: "MockService", + InterfaceName: "MockService", + Name: "GetUser1", + Retries: 2, + Loadbalance: "random", + }, + }, + }, + }, + } + c.SetFatherConfig(father) c.fresh() - assert.Equal(t, "zookeeper", father.Type) - assert.Equal(t, "zookeeper", father.Type) + assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol) + assert.Equal(t, int64(10), father.References["MockService"].Retries) + + assert.Equal(t, int64(10), father.References["MockService"].Methods[0].Retries) + assert.Equal(t, &[]bool{false}[0], father.Check) + assert.Equal(t, "dubbo", father.ApplicationConfig.Name) } -func Test_refreshWithPrefix(t *testing.T) { - //Id string `required:"true" yaml:"id" json:"id,omitempty"` - //Type string `required:"true" yaml:"type" json:"type,omitempty"` - //TimeoutStr string `yaml:"timeout" default:"5s" json:"timeout,omitempty"` // unit: second - //Group string `yaml:"group" json:"group,omitempty"` - ////for registry - //Address string `yaml:"address" json:"address,omitempty"` - //Username string `yaml:"username" json:"address,omitempty"` - //Password string `yaml:"password" json:"address,omitempty"` - - c := &baseConfig{} +func Test_refreshProvider(t *testing.T) { + c := &BaseConfig{} mockMap := map[string]string{} - mockMap["dubbo.customRegistry.type"] = "zookeeper" - mockMap["dubbo.customRegistry.timeout"] = "3s" - mockMap["dubbo.customRegistry.group"] = "hangzhou" - mockMap["dubbo.customRegistry.address"] = "zookeeper://172.0.0.1:2181" - mockMap["dubbo.customRegistry.username"] = "admin" - mockMap["dubbo.customRegistry.password"] = "admin" + mockMap["dubbo.registries.shanghai_reg1.protocol"] = "mock100" + mockMap["dubbo.service.MockService.MockService.retries"] = "10" + mockMap["dubbo.MockService.MockService.GetUser.retries"] = "10" + mockMap["dubbo.consumer.check"] = "false" + mockMap["dubbo.application.name"] = "dubbo" + mockMap["dubbo.protocols.jsonrpc1.name"] = "jsonrpc" + mockMap["dubbo.protocols.jsonrpc1.ip"] = "127.0.0.1" + mockMap["dubbo.protocols.jsonrpc1.port"] = "20001" + config.GetEnvInstance().UpdateExternalConfigMap(mockMap) - father := &RegistryConfig{Type: "1111"} - c.SetPrefix("dubbo.customRegistry") + + father := &ProviderConfig{ + ApplicationConfig: &ApplicationConfig{ + Organization: "dubbo_org", + Name: "dubbo", + Module: "module", + Version: "2.6.0", + Owner: "dubbo", + Environment: "test"}, + Registries: map[string]*RegistryConfig{ + //"shanghai_reg1": { + // id: "shanghai_reg1", + // Protocol: "mock", + // TimeoutStr: "2s", + // Group: "shanghai_idc", + // Address: "127.0.0.1:2181", + // Username: "user1", + // Password: "pwd1", + //}, + "shanghai_reg2": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "shanghai_idc", + Address: "127.0.0.2:2181", + Username: "user1", + Password: "pwd1", + }, + "hangzhou_reg1": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "hangzhou_idc", + Address: "127.0.0.3:2181", + Username: "user1", + Password: "pwd1", + }, + "hangzhou_reg2": { + Protocol: "mock", + TimeoutStr: "2s", + Group: "hangzhou_idc", + Address: "127.0.0.4:2181", + Username: "user1", + Password: "pwd1", + }, + }, + Services: map[string]*ServiceConfig{ + "MockService": { + InterfaceName: "MockService", + Protocol: "mock", + Cluster: "failover", + Loadbalance: "random", + Retries: 3, + Group: "huadong_idc", + Version: "1.0.0", + Methods: []*MethodConfig{ + { + InterfaceId: "MockService", + InterfaceName: "MockService", + Name: "GetUser", + Retries: 2, + Loadbalance: "random", + }, + {InterfaceId: "MockService", + InterfaceName: "MockService", + Name: "GetUser1", + Retries: 2, + Loadbalance: "random", + }, + }, + }, + }, + } + c.SetFatherConfig(father) c.fresh() - assert.Equal(t, "zookeeper", father.Type) - assert.Equal(t, "zookeeper", father.Type) + assert.Equal(t, "mock100", father.Registries["shanghai_reg1"].Protocol) + assert.Equal(t, int64(10), father.Services["MockService"].Retries) + + assert.Equal(t, int64(10), father.Services["MockService"].Methods[0].Retries) + assert.Equal(t, "dubbo", father.ApplicationConfig.Name) + assert.Equal(t, "20001", father.Protocols["jsonrpc1"].Port) +} + +func Test_startConfigCenter(t *testing.T) { + + extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory { + return &config_center.MockDynamicConfigurationFactory{} + }) + c := &BaseConfig{ConfigCenterConfig: &ConfigCenterConfig{ + Protocol: "mock", + Address: "172.0.0.1", + Group: "dubbo", + ConfigFile: "mockDubbo.properties", + }} + err := c.startConfigCenter(context.Background()) + assert.NoError(t, err) + b, v := config.GetEnvInstance().Configuration().Front().Value.(*config.InmemoryConfiguration).GetProperty("dubbo.application.organization") + assert.True(t, b) + assert.Equal(t, "ikurento.com", v) +} + +func Test_initializeStruct(t *testing.T) { + consumerConfig := &ConsumerConfig{} + tp := reflect.TypeOf(ConsumerConfig{}) + v := reflect.New(tp) + initializeStruct(tp, v.Elem()) + fmt.Println(reflect.ValueOf(consumerConfig).Elem().Type().String()) + fmt.Println(v.Elem().Type().String()) + reflect.ValueOf(consumerConfig).Elem().Set(v.Elem()) + + assert.Condition(t, func() (success bool) { + return consumerConfig.ApplicationConfig != nil + }) + assert.Condition(t, func() (success bool) { + return consumerConfig.Registries != nil + }) + assert.Condition(t, func() (success bool) { + return consumerConfig.References != nil + }) } diff --git a/config/config_center_config.go b/config/config_center_config.go index 54a034770..47efce126 100644 --- a/config/config_center_config.go +++ b/config/config_center_config.go @@ -30,7 +30,6 @@ type ConfigCenterConfig struct { Group string `default:"dubbo" yaml:"group" json:"group,omitempty"` Username string `yaml:"username" json:"username,omitempty"` Password string `yaml:"password" json:"password,omitempty"` - Check *bool `yaml:"check" json:"check,omitempty"` ConfigFile string `default:"dubbo.properties" yaml:"config_file" json:"config_file,omitempty"` TimeoutStr string `yaml:"timeout" json:"timeout,omitempty"` timeout time.Duration diff --git a/config/config_loader.go b/config/config_loader.go index 7ee88024f..8bbd49cca 100644 --- a/config/config_loader.go +++ b/config/config_loader.go @@ -19,19 +19,11 @@ package config import ( "fmt" - "io/ioutil" "log" "os" - "path" - "strings" "time" ) -import ( - perrors "github.com/pkg/errors" - "gopkg.in/yaml.v2" -) - import ( "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" @@ -47,14 +39,12 @@ var ( // loaded comsumer & provider config from xxx.yml, and log config from xxx.xml // Namely: dubbo.comsumer.xml & dubbo.provider.xml in java dubbo func init() { - var ( confConFile, confProFile string ) confConFile = os.Getenv(constant.CONF_CONSUMER_FILE_PATH) confProFile = os.Getenv(constant.CONF_PROVIDER_FILE_PATH) - if errCon := consumerInit(confConFile); errCon != nil { log.Printf("[consumerInit] %#v", errCon) consumerConfig = nil @@ -65,148 +55,9 @@ func init() { } } -func consumerInit(confConFile string) error { - if confConFile == "" { - return perrors.Errorf("application configure(consumer) file name is nil") - } - - if path.Ext(confConFile) != ".yml" { - return perrors.Errorf("application configure file name{%v} suffix must be .yml", confConFile) - } - - confFileStream, err := ioutil.ReadFile(confConFile) - if err != nil { - return perrors.Errorf("ioutil.ReadFile(file:%s) = error:%v", confConFile, perrors.WithStack(err)) - } - consumerConfig = &ConsumerConfig{} - err = yaml.Unmarshal(confFileStream, consumerConfig) - if err != nil { - return perrors.Errorf("yaml.Unmarshal() = error:%v", perrors.WithStack(err)) - } - - if consumerConfig.RequestTimeout, err = time.ParseDuration(consumerConfig.Request_Timeout); err != nil { - return perrors.WithMessagef(err, "time.ParseDuration(Request_Timeout{%#v})", consumerConfig.Request_Timeout) - } - if consumerConfig.ConnectTimeout, err = time.ParseDuration(consumerConfig.Connect_Timeout); err != nil { - return perrors.WithMessagef(err, "time.ParseDuration(Connect_Timeout{%#v})", consumerConfig.Connect_Timeout) - } - - logger.Debugf("consumer config{%#v}\n", consumerConfig) - return nil -} - -func providerInit(confProFile string) error { - if confProFile == "" { - return perrors.Errorf("application configure(provider) file name is nil") - } - - if path.Ext(confProFile) != ".yml" { - return perrors.Errorf("application configure file name{%v} suffix must be .yml", confProFile) - } - - confFileStream, err := ioutil.ReadFile(confProFile) - if err != nil { - return perrors.Errorf("ioutil.ReadFile(file:%s) = error:%v", confProFile, perrors.WithStack(err)) - } - providerConfig = &ProviderConfig{} - err = yaml.Unmarshal(confFileStream, providerConfig) - if err != nil { - return perrors.Errorf("yaml.Unmarshal() = error:%v", perrors.WithStack(err)) - } - - logger.Debugf("provider config{%#v}\n", providerConfig) - return nil -} - -///////////////////////// -// consumerConfig -///////////////////////// - -type ConsumerConfig struct { - baseConfig - Filter string `yaml:"filter" json:"filter,omitempty"` - // application - ApplicationConfig ApplicationConfig `yaml:"application_config" json:"application_config,omitempty"` - // client - Connect_Timeout string `default:"100ms" yaml:"connect_timeout" json:"connect_timeout,omitempty"` - ConnectTimeout time.Duration - - Request_Timeout string `yaml:"request_timeout" default:"5s" json:"request_timeout,omitempty"` - RequestTimeout time.Duration - ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty"` - Check *bool `yaml:"check" json:"check,omitempty"` - - Registries []RegistryConfig `yaml:"registries" json:"registries,omitempty"` - References []ReferenceConfig `yaml:"references" json:"references,omitempty"` - ConfigCenter ConfigCenterConfig `yaml:"config_center" json:"config_center,omitempty"` - ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty"` -} - -type ReferenceConfigTmp struct { - Service string `required:"true" yaml:"service" json:"service,omitempty"` - Registries []RegistryConfig `required:"true" yaml:"registries" json:"registries,omitempty"` - URLs []map[string]string -} - -func SetConsumerConfig(c ConsumerConfig) { - consumerConfig = &c -} -func GetConsumerConfig() ConsumerConfig { - if consumerConfig == nil { - logger.Warnf("consumerConfig is nil!") - return ConsumerConfig{} - } - return *consumerConfig -} - -///////////////////////// -// providerConfig -///////////////////////// - -type ProviderConfig struct { - Filter string `yaml:"filter" json:"filter,omitempty"` - ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty"` - - ApplicationConfig ApplicationConfig `yaml:"application_config" json:"application_config,omitempty"` - Registries []RegistryConfig `yaml:"registries" json:"registries,omitempty"` - Services []ServiceConfig `yaml:"services" json:"services,omitempty"` - Protocols []ProtocolConfig `yaml:"protocols" json:"protocols,omitempty"` - ProtocolConf interface{} `yaml:"protocol_conf" json:"protocol_conf,omitempty"` -} - -func SetProviderConfig(p ProviderConfig) { - providerConfig = &p -} -func GetProviderConfig() ProviderConfig { - if providerConfig == nil { - logger.Warnf("providerConfig is nil!") - return ProviderConfig{} - } - return *providerConfig -} - -type ProtocolConfig struct { - Name string `required:"true" yaml:"name" json:"name,omitempty"` - Ip string `required:"true" yaml:"ip" json:"ip,omitempty"` - Port string `required:"true" yaml:"port" json:"port,omitempty"` - ContextPath string `required:"true" yaml:"contextPath" json:"contextPath,omitempty"` -} - -func loadProtocol(protocolsIds string, protocols []ProtocolConfig) []ProtocolConfig { - returnProtocols := []ProtocolConfig{} - for _, v := range strings.Split(protocolsIds, ",") { - for _, prot := range protocols { - if v == prot.Name { - returnProtocols = append(returnProtocols, prot) - } - } - - } - return returnProtocols -} - // Dubbo Init func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { + var refMap map[string]*ReferenceConfig var srvMap map[string]*ServiceConfig @@ -214,20 +65,20 @@ func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { if consumerConfig == nil { logger.Warnf("consumerConfig is nil!") } else { + if err := configCenterRefreshConsumer(); err != nil { + logger.Errorf("[consumer config center refresh] %#v", err) + } refMap = make(map[string]*ReferenceConfig) - length := len(consumerConfig.References) - for index := 0; index < length; index++ { - con := &consumerConfig.References[index] - rpcService := GetConsumerService(con.InterfaceName) + for _, ref := range consumerConfig.References { + rpcService := GetConsumerService(ref.InterfaceName) if rpcService == nil { - logger.Warnf("%s is not exsist!", con.InterfaceName) + logger.Warnf("%s is not exsist!", ref.InterfaceName) continue } - con.Refer() - con.Implement(rpcService) - refMap[con.InterfaceName] = con + ref.Refer() + ref.Implement(rpcService) + refMap[ref.InterfaceName] = ref } - //wait for invoker is available, if wait over default 3s, then panic var count int checkok := true @@ -263,20 +114,21 @@ func Load() (map[string]*ReferenceConfig, map[string]*ServiceConfig) { if providerConfig == nil { logger.Warnf("providerConfig is nil!") } else { + if err := configCenterRefreshProvider(); err != nil { + logger.Errorf("[provider config center refresh] %#v", err) + } srvMap = make(map[string]*ServiceConfig) - length := len(providerConfig.Services) - for index := 0; index < length; index++ { - pro := &providerConfig.Services[index] - rpcService := GetProviderService(pro.InterfaceName) + for _, svs := range providerConfig.Services { + rpcService := GetProviderService(svs.InterfaceName) if rpcService == nil { - logger.Warnf("%s is not exsist!", pro.InterfaceName) + logger.Warnf("%s is not exsist!", svs.InterfaceName) continue } - pro.Implement(rpcService) - if err := pro.Export(); err != nil { - panic(fmt.Sprintf("service %s export failed! ", pro.InterfaceName)) + svs.Implement(rpcService) + if err := svs.Export(); err != nil { + panic(fmt.Sprintf("service %s export failed! ", svs.InterfaceName)) } - srvMap[pro.InterfaceName] = pro + srvMap[svs.InterfaceName] = svs } } diff --git a/config/config_loader_test.go b/config/config_loader_test.go index 7c3343fd3..2cdc6f2ed 100644 --- a/config/config_loader_test.go +++ b/config/config_loader_test.go @@ -31,6 +31,7 @@ import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/extension" "github.com/apache/dubbo-go/common/proxy/proxy_factory" + "github.com/apache/dubbo-go/config_center" ) func TestConfigLoader(t *testing.T) { @@ -65,7 +66,6 @@ func TestLoad(t *testing.T) { extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) extension.SetProxyFactory("default", proxy_factory.NewDefaultProxyFactory) - consumerConfig.References[0].Registries = []ConfigRegistry{"shanghai_reg1"} refConfigs, svcConfigs := Load() assert.NotEqual(t, 0, len(refConfigs)) @@ -77,3 +77,35 @@ func TestLoad(t *testing.T) { consumerConfig = nil providerConfig = nil } + +func TestConfigLoaderWithConfigCenter(t *testing.T) { + extension.SetConfigCenterFactory("mock", func() config_center.DynamicConfigurationFactory { + return &config_center.MockDynamicConfigurationFactory{} + }) + + conPath, err := filepath.Abs("./testdata/consumer_config_with_configcenter.yml") + assert.NoError(t, err) + proPath, err := filepath.Abs("./testdata/provider_config.yml") + assert.NoError(t, err) + + assert.Nil(t, consumerConfig) + assert.Equal(t, ConsumerConfig{}, GetConsumerConfig()) + assert.Nil(t, providerConfig) + assert.Equal(t, ProviderConfig{}, GetProviderConfig()) + + err = consumerInit(conPath) + configCenterRefreshConsumer() + assert.NoError(t, err) + err = providerInit(proPath) + configCenterRefreshProvider() + assert.NoError(t, err) + + assert.NotNil(t, consumerConfig) + assert.NotEqual(t, ConsumerConfig{}, GetConsumerConfig()) + assert.NotNil(t, providerConfig) + assert.NotEqual(t, ProviderConfig{}, GetProviderConfig()) + + assert.Equal(t, "BDTService", consumerConfig.ApplicationConfig.Name) + assert.Equal(t, "127.0.0.1:2181", consumerConfig.Registries["hangzhouzk"].Address) + +} diff --git a/config/consumer_config.go b/config/consumer_config.go new file mode 100644 index 000000000..5d3aec18e --- /dev/null +++ b/config/consumer_config.go @@ -0,0 +1,134 @@ +/* + * 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 config + +import ( + "context" + "io/ioutil" + "path" + "time" +) +import ( + perrors "github.com/pkg/errors" + "gopkg.in/yaml.v2" +) +import ( + "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" +) + +///////////////////////// +// consumerConfig +///////////////////////// + +type ConsumerConfig struct { + BaseConfig `yaml:",inline"` + Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` + // application + ApplicationConfig *ApplicationConfig `yaml:"application_config" json:"application_config,omitempty" property:"application_config"` + // client + Connect_Timeout string `default:"100ms" yaml:"connect_timeout" json:"connect_timeout,omitempty" property:"connect_timeout"` + ConnectTimeout time.Duration + + Request_Timeout string `yaml:"request_timeout" default:"5s" json:"request_timeout,omitempty" property:"request_timeout"` + RequestTimeout time.Duration + ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` + Check *bool `yaml:"check" json:"check,omitempty" property:"check"` + + 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"` +} + +func (*ConsumerConfig) Prefix() string { + return constant.ConsumerConfigPrefix +} + +func SetConsumerConfig(c ConsumerConfig) { + consumerConfig = &c +} +func GetConsumerConfig() ConsumerConfig { + if consumerConfig == nil { + logger.Warnf("consumerConfig is nil!") + return ConsumerConfig{} + } + return *consumerConfig +} + +func consumerInit(confConFile string) error { + if confConFile == "" { + return perrors.Errorf("application configure(consumer) file name is nil") + } + + if path.Ext(confConFile) != ".yml" { + return perrors.Errorf("application configure file name{%v} suffix must be .yml", confConFile) + } + + confFileStream, err := ioutil.ReadFile(confConFile) + if err != nil { + return perrors.Errorf("ioutil.ReadFile(file:%s) = error:%v", confConFile, perrors.WithStack(err)) + } + consumerConfig = &ConsumerConfig{} + err = yaml.Unmarshal(confFileStream, consumerConfig) + if err != nil { + return perrors.Errorf("yaml.Unmarshal() = error:%v", perrors.WithStack(err)) + } + + //set method interfaceId & interfaceName + for k, v := range consumerConfig.References { + //set id for reference + for _, n := range consumerConfig.References[k].Methods { + n.InterfaceName = v.InterfaceName + n.InterfaceId = k + } + } + if consumerConfig.Request_Timeout != "" { + if consumerConfig.RequestTimeout, err = time.ParseDuration(consumerConfig.Request_Timeout); err != nil { + return perrors.WithMessagef(err, "time.ParseDuration(Request_Timeout{%#v})", consumerConfig.Request_Timeout) + } + } + if consumerConfig.Connect_Timeout != "" { + if consumerConfig.ConnectTimeout, err = time.ParseDuration(consumerConfig.Connect_Timeout); err != nil { + return perrors.WithMessagef(err, "time.ParseDuration(Connect_Timeout{%#v})", consumerConfig.Connect_Timeout) + } + } + logger.Debugf("consumer config{%#v}\n", consumerConfig) + return nil +} + +func configCenterRefreshConsumer() error { + //fresh it + var err error + if consumerConfig.ConfigCenterConfig != nil { + consumerConfig.SetFatherConfig(consumerConfig) + if err := consumerConfig.startConfigCenter(context.Background()); err != nil { + return perrors.Errorf("start config center error , error message is {%v}", perrors.WithStack(err)) + } + consumerConfig.fresh() + } + if consumerConfig.Request_Timeout != "" { + if consumerConfig.RequestTimeout, err = time.ParseDuration(consumerConfig.Request_Timeout); err != nil { + return perrors.WithMessagef(err, "time.ParseDuration(Request_Timeout{%#v})", consumerConfig.Request_Timeout) + } + } + if consumerConfig.Connect_Timeout != "" { + if consumerConfig.ConnectTimeout, err = time.ParseDuration(consumerConfig.Connect_Timeout); err != nil { + return perrors.WithMessagef(err, "time.ParseDuration(Connect_Timeout{%#v})", consumerConfig.Connect_Timeout) + } + } + return err +} diff --git a/config/method_config.go b/config/method_config.go new file mode 100644 index 000000000..99cf0d134 --- /dev/null +++ b/config/method_config.go @@ -0,0 +1,36 @@ +/* + * 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 config + +import "github.com/apache/dubbo-go/common/constant" + +type MethodConfig struct { + InterfaceId string + InterfaceName string + Name string `yaml:"name" json:"name,omitempty" property:"name"` + Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` + Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + Weight int64 `yaml:"weight" json:"weight,omitempty" property:"weight"` +} + +func (c *MethodConfig) Prefix() string { + if c.InterfaceId != "" { + return constant.DUBBO + "." + c.InterfaceName + "." + c.InterfaceId + "." + c.Name + "." + } else { + return constant.DUBBO + "." + c.InterfaceName + "." + c.Name + "." + } +} diff --git a/config/protocol_config.go b/config/protocol_config.go new file mode 100644 index 000000000..ad0503090 --- /dev/null +++ b/config/protocol_config.go @@ -0,0 +1,45 @@ +/* + * 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 config + +import ( + "github.com/apache/dubbo-go/common/constant" + "strings" +) + +type ProtocolConfig struct { + Name string `required:"true" yaml:"name" json:"name,omitempty" property:"name"` + Ip string `required:"true" yaml:"ip" json:"ip,omitempty" property:"ip"` + Port string `required:"true" yaml:"port" json:"port,omitempty" property:"port"` +} + +func (c *ProtocolConfig) Prefix() string { + return constant.ProtocolConfigPrefix +} + +func loadProtocol(protocolsIds string, protocols map[string]*ProtocolConfig) []*ProtocolConfig { + returnProtocols := []*ProtocolConfig{} + for _, v := range strings.Split(protocolsIds, ",") { + for _, prot := range protocols { + if v == prot.Name { + returnProtocols = append(returnProtocols, prot) + } + } + + } + return returnProtocols +} diff --git a/config/provider_config.go b/config/provider_config.go new file mode 100644 index 000000000..558d60e67 --- /dev/null +++ b/config/provider_config.go @@ -0,0 +1,107 @@ +/* + * 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 config + +import ( + "context" + "github.com/apache/dubbo-go/common/constant" + "io/ioutil" + "path" +) + +import ( + perrors "github.com/pkg/errors" + "gopkg.in/yaml.v2" +) +import ( + "github.com/apache/dubbo-go/common/logger" +) + +///////////////////////// +// providerConfig +///////////////////////// + +type ProviderConfig struct { + BaseConfig `yaml:",inline"` + Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` + ProxyFactory string `yaml:"proxy_factory" default:"default" json:"proxy_factory,omitempty" property:"proxy_factory"` + + ApplicationConfig *ApplicationConfig `yaml:"application_config" json:"application_config,omitempty" property:"application_config"` + Registries map[string]*RegistryConfig `yaml:"registries" json:"registries,omitempty" property:"registries"` + 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" ` +} + +func (*ProviderConfig) Prefix() string { + return constant.ProviderConfigPrefix +} + +func SetProviderConfig(p ProviderConfig) { + providerConfig = &p +} +func GetProviderConfig() ProviderConfig { + if providerConfig == nil { + logger.Warnf("providerConfig is nil!") + return ProviderConfig{} + } + return *providerConfig +} + +func providerInit(confProFile string) error { + if confProFile == "" { + return perrors.Errorf("application configure(provider) file name is nil") + } + + if path.Ext(confProFile) != ".yml" { + return perrors.Errorf("application configure file name{%v} suffix must be .yml", confProFile) + } + + confFileStream, err := ioutil.ReadFile(confProFile) + if err != nil { + return perrors.Errorf("ioutil.ReadFile(file:%s) = error:%v", confProFile, perrors.WithStack(err)) + } + providerConfig = &ProviderConfig{} + err = yaml.Unmarshal(confFileStream, providerConfig) + if err != nil { + return perrors.Errorf("yaml.Unmarshal() = error:%v", perrors.WithStack(err)) + } + + //set method interfaceId & interfaceName + for k, v := range providerConfig.Services { + //set id for reference + for _, n := range providerConfig.Services[k].Methods { + n.InterfaceName = v.InterfaceName + n.InterfaceId = k + } + } + + logger.Debugf("provider config{%#v}\n", providerConfig) + return nil +} + +func configCenterRefreshProvider() error { + //fresh it + if providerConfig.ConfigCenterConfig != nil { + providerConfig.fatherConfig = providerConfig + if err := providerConfig.startConfigCenter(context.Background()); err != nil { + return perrors.Errorf("start config center error , error message is {%v}", perrors.WithStack(err)) + } + providerConfig.fresh() + } + return nil +} diff --git a/config/reference_config.go b/config/reference_config.go index e0c93b3e5..480f7749f 100644 --- a/config/reference_config.go +++ b/config/reference_config.go @@ -38,25 +38,25 @@ import ( type ReferenceConfig struct { context context.Context pxy *proxy.Proxy - InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty"` - Check *bool `yaml:"check" json:"check,omitempty"` - Url string `yaml:"url" json:"url,omitempty"` - Filter string `yaml:"filter" json:"filter,omitempty"` - Protocol string `yaml:"protocol" json:"protocol,omitempty"` - Registries []ConfigRegistry `required:"true" yaml:"registries" json:"registries,omitempty"` - Cluster string `yaml:"cluster" json:"cluster,omitempty"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty"` - Retries int64 `yaml:"retries" json:"retries,omitempty"` - Group string `yaml:"group" json:"group,omitempty"` - Version string `yaml:"version" json:"version,omitempty"` - Methods []struct { - Name string `yaml:"name" json:"name,omitempty"` - Retries int64 `yaml:"retries" json:"retries,omitempty"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty"` - } `yaml:"methods" json:"methods,omitempty"` - async bool `yaml:"async" json:"async,omitempty"` - invoker protocol.Invoker - urls []*common.URL + InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"` + Check *bool `yaml:"check" json:"check,omitempty" property:"check"` + Url string `yaml:"url" json:"url,omitempty" property:"url"` + Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` + Protocol string `yaml:"protocol" json:"protocol,omitempty" property:"protocol"` + //Registries []ConfigRegistry `required:"true" yaml:"registries" json:"registries,omitempty" property:"registries"` + Cluster string `yaml:"cluster" json:"cluster,omitempty" property:"cluster"` + Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` + Group string `yaml:"group" json:"group,omitempty" property:"group"` + Version string `yaml:"version" json:"version,omitempty" property:"version"` + Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` + async bool `yaml:"async" json:"async,omitempty" property:"async"` + invoker protocol.Invoker + urls []*common.URL +} + +func (c *ReferenceConfig) Prefix() string { + return constant.ReferenceConfigPrefix + c.InterfaceName + "." } type ConfigRegistry string @@ -102,7 +102,7 @@ func (refconfig *ReferenceConfig) Refer() { } } else { //2. assemble SubURL from register center's configuration模式 - refconfig.urls = loadRegistries(refconfig.Registries, consumerConfig.Registries, common.CONSUMER) + refconfig.urls = loadRegistries(consumerConfig.Registries, common.CONSUMER) //set url to regUrls for _, regUrl := range refconfig.urls { diff --git a/config/reference_config_test.go b/config/reference_config_test.go index fc5836056..16b23c86d 100644 --- a/config/reference_config_test.go +++ b/config/reference_config_test.go @@ -37,44 +37,40 @@ var regProtocol protocol.Protocol func doInit() { consumerConfig = &ConsumerConfig{ - ApplicationConfig: ApplicationConfig{ + ApplicationConfig: &ApplicationConfig{ Organization: "dubbo_org", Name: "dubbo", Module: "module", Version: "2.6.0", Owner: "dubbo", Environment: "test"}, - Registries: []RegistryConfig{ - { - Id: "shanghai_reg1", - Type: "mock", + Registries: map[string]*RegistryConfig{ + "shanghai_reg1": { + Protocol: "mock", TimeoutStr: "2s", Group: "shanghai_idc", Address: "127.0.0.1:2181", Username: "user1", Password: "pwd1", }, - { - Id: "shanghai_reg2", - Type: "mock", + "shanghai_reg2": { + Protocol: "mock", TimeoutStr: "2s", Group: "shanghai_idc", Address: "127.0.0.2:2181", Username: "user1", Password: "pwd1", }, - { - Id: "hangzhou_reg1", - Type: "mock", + "hangzhou_reg1": { + Protocol: "mock", TimeoutStr: "2s", Group: "hangzhou_idc", Address: "127.0.0.3:2181", Username: "user1", Password: "pwd1", }, - { - Id: "hangzhou_reg2", - Type: "mock", + "hangzhou_reg2": { + Protocol: "mock", TimeoutStr: "2s", Group: "hangzhou_idc", Address: "127.0.0.4:2181", @@ -82,21 +78,16 @@ func doInit() { Password: "pwd1", }, }, - References: []ReferenceConfig{ - { + References: map[string]*ReferenceConfig{ + "MockService": { InterfaceName: "MockService", Protocol: "mock", - Registries: []ConfigRegistry{"shanghai_reg1", "shanghai_reg2", "hangzhou_reg1", "hangzhou_reg2"}, Cluster: "failover", Loadbalance: "random", Retries: 3, Group: "huadong_idc", Version: "1.0.0", - Methods: []struct { - Name string `yaml:"name" json:"name,omitempty"` - Retries int64 `yaml:"retries" json:"retries,omitempty"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty"` - }{ + Methods: []*MethodConfig{ { Name: "GetUser", Retries: 2, @@ -130,7 +121,6 @@ func Test_Refer(t *testing.T) { doInit() extension.SetProtocol("registry", GetProtocol) extension.SetCluster("registryAware", cluster_impl.NewRegistryAwareCluster) - consumerConfig.References[0].Registries = []ConfigRegistry{"shanghai_reg1"} for _, reference := range consumerConfig.References { reference.Refer() @@ -142,7 +132,8 @@ func Test_Refer(t *testing.T) { func Test_ReferP2P(t *testing.T) { doInit() extension.SetProtocol("dubbo", GetProtocol) - consumerConfig.References[0].Url = "dubbo://127.0.0.1:20000" + m := consumerConfig.References["MockService"] + m.Url = "dubbo://127.0.0.1:20000" for _, reference := range consumerConfig.References { reference.Refer() @@ -154,7 +145,8 @@ func Test_ReferP2P(t *testing.T) { func Test_ReferMultiP2P(t *testing.T) { doInit() extension.SetProtocol("dubbo", GetProtocol) - consumerConfig.References[0].Url = "dubbo://127.0.0.1:20000;dubbo://127.0.0.2:20000" + m := consumerConfig.References["MockService"] + m.Url = "dubbo://127.0.0.1:20000;dubbo://127.0.0.2:20000" for _, reference := range consumerConfig.References { reference.Refer() @@ -168,7 +160,8 @@ func Test_ReferMultiP2PWithReg(t *testing.T) { doInit() extension.SetProtocol("dubbo", GetProtocol) extension.SetProtocol("registry", GetProtocol) - consumerConfig.References[0].Url = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000" + m := consumerConfig.References["MockService"] + m.Url = "dubbo://127.0.0.1:20000;registry://127.0.0.2:20000" for _, reference := range consumerConfig.References { reference.Refer() diff --git a/config/registry_config.go b/config/registry_config.go index a4bc27551..9d7f5e754 100644 --- a/config/registry_config.go +++ b/config/registry_config.go @@ -30,8 +30,7 @@ import ( ) type RegistryConfig struct { - Id string `required:"true" yaml:"id" json:"id,omitempty"` - Type string `required:"true" yaml:"type" json:"type,omitempty" property:"type"` + Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` TimeoutStr string `yaml:"timeout" default:"5s" json:"timeout,omitempty" property:"timeout"` // unit: second Group string `yaml:"group" json:"group,omitempty" property:"group"` //for registry @@ -40,30 +39,30 @@ type RegistryConfig struct { Password string `yaml:"password" json:"address,omitempty" property:"password"` } -func loadRegistries(registriesIds []ConfigRegistry, registries []RegistryConfig, roleType common.RoleType) []*common.URL { - var urls []*common.URL - for _, registry := range registriesIds { - for _, registryConf := range registries { - if string(registry) == registryConf.Id { +func (*RegistryConfig) Prefix() string { + return constant.RegistryConfigPrefix +} - url, err := common.NewURL( - context.TODO(), - constant.REGISTRY_PROTOCOL+"://"+registryConf.Address, - common.WithParams(registryConf.getUrlMap(roleType)), - common.WithUsername(registryConf.Username), - common.WithPassword(registryConf.Password), - ) +func loadRegistries(registries map[string]*RegistryConfig, roleType common.RoleType) []*common.URL { + var urls []*common.URL + for k, registryConf := range registries { - if err != nil { - logger.Errorf("The registry id:%s url is invalid ,and will skip the registry, error: %#v", registryConf.Id, err) - } else { - urls = append(urls, &url) - } + url, err := common.NewURL( + context.TODO(), + constant.REGISTRY_PROTOCOL+"://"+registryConf.Address, + common.WithParams(registryConf.getUrlMap(roleType)), + common.WithUsername(registryConf.Username), + common.WithPassword(registryConf.Password), + ) - } + if err != nil { + logger.Errorf("The registry id:%s url is invalid ,and will skip the registry, error: %#v", k, err) + } else { + urls = append(urls, &url) } } + return urls } @@ -71,7 +70,7 @@ func (regconfig *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values urlMap := url.Values{} urlMap.Set(constant.GROUP_KEY, regconfig.Group) urlMap.Set(constant.ROLE_KEY, strconv.Itoa(int(roleType))) - urlMap.Set(constant.REGISTRY_KEY, regconfig.Type) + urlMap.Set(constant.REGISTRY_KEY, regconfig.Protocol) urlMap.Set(constant.REGISTRY_TIMEOUT_KEY, regconfig.TimeoutStr) return urlMap diff --git a/config/service_config.go b/config/service_config.go index 9db0f99fa..4d59f8981 100644 --- a/config/service_config.go +++ b/config/service_config.go @@ -41,22 +41,17 @@ import ( type ServiceConfig struct { context context.Context - Filter string `yaml:"filter" json:"filter,omitempty"` - Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"` //multi protocol support, split by ',' - InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty"` - Registries []ConfigRegistry `required:"true" yaml:"registries" json:"registries,omitempty"` - Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty"` - Loadbalance string `default:"random" yaml:"loadbalance" json:"loadbalance,omitempty"` - Group string `yaml:"group" json:"group,omitempty"` - Version string `yaml:"version" json:"version,omitempty"` - Methods []struct { - Name string `yaml:"name" json:"name,omitempty"` - Retries int64 `yaml:"retries" json:"retries,omitempty"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty"` - Weight int64 `yaml:"weight" json:"weight,omitempty"` - } `yaml:"methods" json:"methods,omitempty"` - Warmup string `yaml:"warmup" json:"warmup,omitempty"` - Retries int64 `yaml:"retries" json:"retries,omitempty"` + Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` + Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty" property:"protocol"` //multi protocol support, split by ',' + InterfaceName string `required:"true" yaml:"interface" json:"interface,omitempty" property:"interface"` + Registries []ConfigRegistry `required:"true" yaml:"registries" json:"registries,omitempty" property:"registries"` + Cluster string `default:"failover" yaml:"cluster" json:"cluster,omitempty" property:"cluster"` + Loadbalance string `default:"random" yaml:"loadbalance" json:"loadbalance,omitempty" property:"loadbalance"` + Group string `yaml:"group" json:"group,omitempty" property:"group"` + Version string `yaml:"version" json:"version,omitempty" property:"version" ` + Methods []*MethodConfig `yaml:"methods" json:"methods,omitempty" property:"methods"` + Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"` + Retries int64 `yaml:"retries" json:"retries,omitempty" property:"retries"` unexported *atomic.Bool exported *atomic.Bool rpcService common.RPCService @@ -65,6 +60,10 @@ type ServiceConfig struct { cacheMutex sync.Mutex } +func (c *ServiceConfig) Prefix() string { + return constant.ServiceConfigPrefix + c.InterfaceName + "." +} + func NewServiceConfig() *ServiceConfig { return &ServiceConfig{ unexported: atomic.NewBool(false), @@ -87,7 +86,7 @@ func (srvconfig *ServiceConfig) Export() error { return nil } - regUrls := loadRegistries(srvconfig.Registries, providerConfig.Registries, common.PROVIDER) + regUrls := loadRegistries(providerConfig.Registries, common.PROVIDER) urlMap := srvconfig.getUrlMap() for _, proto := range loadProtocol(srvconfig.Protocol, providerConfig.Protocols) { diff --git a/config/service_config_test.go b/config/service_config_test.go index 77cbbff38..b618085bd 100644 --- a/config/service_config_test.go +++ b/config/service_config_test.go @@ -31,44 +31,40 @@ import ( func doinit() { providerConfig = &ProviderConfig{ - ApplicationConfig: ApplicationConfig{ + ApplicationConfig: &ApplicationConfig{ Organization: "dubbo_org", Name: "dubbo", Module: "module", Version: "2.6.0", Owner: "dubbo", Environment: "test"}, - Registries: []RegistryConfig{ - { - Id: "shanghai_reg1", - Type: "mock", + Registries: map[string]*RegistryConfig{ + "shanghai_reg1": { + Protocol: "mock", TimeoutStr: "2s", Group: "shanghai_idc", Address: "127.0.0.1:2181", Username: "user1", Password: "pwd1", }, - { - Id: "shanghai_reg2", - Type: "mock", + "shanghai_reg2": { + Protocol: "mock", TimeoutStr: "2s", Group: "shanghai_idc", Address: "127.0.0.2:2181", Username: "user1", Password: "pwd1", }, - { - Id: "hangzhou_reg1", - Type: "mock", + "hangzhou_reg1": { + Protocol: "mock", TimeoutStr: "2s", Group: "hangzhou_idc", Address: "127.0.0.3:2181", Username: "user1", Password: "pwd1", }, - { - Id: "hangzhou_reg2", - Type: "mock", + "hangzhou_reg2": { + Protocol: "mock", TimeoutStr: "2s", Group: "hangzhou_idc", Address: "127.0.0.4:2181", @@ -76,8 +72,8 @@ func doinit() { Password: "pwd1", }, }, - Services: []ServiceConfig{ - { + Services: map[string]*ServiceConfig{ + "MockService": { InterfaceName: "MockService", Protocol: "mock", Registries: []ConfigRegistry{"shanghai_reg1", "shanghai_reg2", "hangzhou_reg1", "hangzhou_reg2"}, @@ -86,12 +82,7 @@ func doinit() { Retries: 3, Group: "huadong_idc", Version: "1.0.0", - Methods: []struct { - Name string `yaml:"name" json:"name,omitempty"` - Retries int64 `yaml:"retries" json:"retries,omitempty"` - Loadbalance string `yaml:"loadbalance" json:"loadbalance,omitempty"` - Weight int64 `yaml:"weight" json:"weight,omitempty"` - }{ + Methods: []*MethodConfig{ { Name: "GetUser", Retries: 2, @@ -107,12 +98,11 @@ func doinit() { }, }, }, - Protocols: []ProtocolConfig{ - { - Name: "mock", - Ip: "127.0.0.1", - Port: "20000", - ContextPath: "/xxx", + Protocols: map[string]*ProtocolConfig{ + "mock": { + Name: "mock", + Ip: "127.0.0.1", + Port: "20000", }, }, } diff --git a/config/testdata/consumer_config.yml b/config/testdata/consumer_config.yml index 9095c44d4..2d8287853 100644 --- a/config/testdata/consumer_config.yml +++ b/config/testdata/consumer_config.yml @@ -17,14 +17,16 @@ application_config: environment : "dev" registries : - - id: "hangzhouzk" + + "hangzhouzk": + id: "hangzhouzk" type: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" + "shanghaizk": + id: "shanghaizk" type: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" @@ -32,9 +34,7 @@ registries : password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" + "UserProvider": filter: "" protocol : "dubbo" interface : "com.ikurento.user.UserProvider" diff --git a/config/testdata/consumer_config_with_configcenter.yml b/config/testdata/consumer_config_with_configcenter.yml new file mode 100644 index 000000000..acaed2ade --- /dev/null +++ b/config/testdata/consumer_config_with_configcenter.yml @@ -0,0 +1,39 @@ +# dubbo client yaml configure file + +config_center: + protocol: "mock" + address: "127.0.0.1" +references: + "UserProvider": + filter: "" + protocol : "dubbo" + interface : "com.ikurento.user.UserProvider" + url: "dubbo://127.0.0.1:20000" + 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: 1024 + session_name: "client" diff --git a/config/testdata/provider_config.yml b/config/testdata/provider_config.yml index b02384798..56d658e95 100644 --- a/config/testdata/provider_config.yml +++ b/config/testdata/provider_config.yml @@ -11,14 +11,13 @@ application_config: environment : "dev" registries : - - id: "hangzhouzk" + "hangzhouzk": type: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" + "shanghaizk": type: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" @@ -27,9 +26,7 @@ registries : services: - - registries: - - "hangzhouzk" - - "shanghaizk" + "UserProvider": filter: "" protocol : "dubbo" # equivalent to interface of dubbo.xml @@ -43,7 +40,8 @@ services: loadbalance: "random" protocols: - - name: "dubbo" + "dubbo": + name: "dubbo" # while using dubbo protocol, ip cannot is 127.0.0.1, because client of java-dubbo will get 'connection refuse' ip : "127.0.0.1" port : 20000 diff --git a/config_center/mock_dynamic_config.go b/config_center/mock_dynamic_config.go new file mode 100644 index 000000000..610817e18 --- /dev/null +++ b/config_center/mock_dynamic_config.go @@ -0,0 +1,94 @@ +/* + * 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 config_center + +import ( + "sync" +) +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/remoting" +) + +type MockDynamicConfigurationFactory struct { +} + +var once sync.Once +var dynamicConfiguration *mockDynamicConfiguration + +func (f *MockDynamicConfigurationFactory) GetDynamicConfiguration(url *common.URL) (DynamicConfiguration, error) { + var err error + once.Do(func() { + dynamicConfiguration = &mockDynamicConfiguration{} + dynamicConfiguration.SetParser(&DefaultConfigurationParser{}) + dynamicConfiguration.content = ` + dubbo.consumer.request_timeout=5s + dubbo.consumer.connect_timeout=5s + dubbo.application.organization=ikurento.com + dubbo.application.name=BDTService + dubbo.application.module=dubbogo user-info server + dubbo.application.version=0.0.1 + dubbo.application.owner=ZX + dubbo.application.environment=dev + dubbo.registries.hangzhouzk.protocol=zookeeper + dubbo.registries.hangzhouzk.timeout=3s + dubbo.registries.hangzhouzk.address=127.0.0.1:2181 + dubbo.registries.shanghaizk.protocol=zookeeper + dubbo.registries.shanghaizk.timeout=3s + dubbo.registries.shanghaizk.address=127.0.0.1:2182 + dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo + dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider + dubbo.service.com.ikurento.user.UserProvider.loadbalance=random + dubbo.service.com.ikurento.user.UserProvider.warmup=100 + dubbo.service.com.ikurento.user.UserProvider.cluster=failover + dubbo.protocols.jsonrpc1.name=jsonrpc + dubbo.protocols.jsonrpc1.ip=127.0.0.1 + dubbo.protocols.jsonrpc1.port=20001 +` + }) + return dynamicConfiguration, err + +} + +type mockDynamicConfiguration struct { + parser ConfigurationParser + content string +} + +func (c *mockDynamicConfiguration) AddListener(key string, listener remoting.ConfigurationListener, opions ...Option) { +} + +func (c *mockDynamicConfiguration) RemoveListener(key string, listener remoting.ConfigurationListener, opions ...Option) { +} + +func (c *mockDynamicConfiguration) GetConfig(key string, opts ...Option) (string, error) { + + return c.content, nil +} + +//For zookeeper, getConfig and getConfigs have the same meaning. +func (c *mockDynamicConfiguration) GetConfigs(key string, opts ...Option) (string, error) { + return c.GetConfig(key, opts...) +} + +func (c *mockDynamicConfiguration) Parser() ConfigurationParser { + return c.parser +} +func (c *mockDynamicConfiguration) SetParser(p ConfigurationParser) { + c.parser = p +} diff --git a/config_center/zookeeper/factory.go b/config_center/zookeeper/factory.go index 29eb3a346..c1c7e27b1 100644 --- a/config_center/zookeeper/factory.go +++ b/config_center/zookeeper/factory.go @@ -40,8 +40,11 @@ func (f *zookeeperDynamicConfigurationFactory) GetDynamicConfiguration(url *comm var err error once.Do(func() { dynamicConfiguration, err = newZookeeperDynamicConfiguration(url) - dynamicConfiguration.SetParser(&config_center.DefaultConfigurationParser{}) }) + if err != nil { + return nil, err + } + dynamicConfiguration.SetParser(&config_center.DefaultConfigurationParser{}) return dynamicConfiguration, err } diff --git a/config_center/zookeeper/impl.go b/config_center/zookeeper/impl.go index a45d3f6b0..00982a97c 100644 --- a/config_center/zookeeper/impl.go +++ b/config_center/zookeeper/impl.go @@ -18,8 +18,10 @@ package zookeeper import ( + "github.com/samuel/go-zookeeper/zk" "strings" "sync" + "time" ) import ( perrors "github.com/pkg/errors" @@ -64,10 +66,39 @@ func newZookeeperDynamicConfiguration(url *common.URL) (*zookeeperDynamicConfigu c.listener = zookeeper.NewZkEventListener(c.client) c.cacheListener = NewCacheListener(c.rootPath) + + err = c.client.Create(c.rootPath) + c.listener.ListenServiceEvent(c.rootPath, c.cacheListener) return c, nil } +func newMockZookeeperDynamicConfiguration(url *common.URL, opts ...zookeeper.Option) (*zk.TestCluster, *zookeeperDynamicConfiguration, error) { + c := &zookeeperDynamicConfiguration{ + url: url, + rootPath: "/" + url.GetParam(constant.CONFIG_NAMESPACE_KEY, config_center.DEFAULT_GROUP) + "/config", + } + var ( + tc *zk.TestCluster + err error + ) + tc, c.client, _, err = zookeeper.NewMockZookeeperClient("test", 15*time.Second, opts...) + if err != nil { + logger.Errorf("mock zookeeper client start error ,error message is %v", err) + return tc, c, err + } + c.wg.Add(1) + go zookeeper.HandleClientRestart(c) + + c.listener = zookeeper.NewZkEventListener(c.client) + c.cacheListener = NewCacheListener(c.rootPath) + + err = c.client.Create(c.rootPath) + go c.listener.ListenServiceEvent(c.rootPath, c.cacheListener) + return tc, c, nil + +} + func (c *zookeeperDynamicConfiguration) AddListener(key string, listener remoting.ConfigurationListener, opions ...config_center.Option) { c.cacheListener.AddListener(key, listener) } @@ -77,31 +108,34 @@ func (c *zookeeperDynamicConfiguration) RemoveListener(key string, listener remo } func (c *zookeeperDynamicConfiguration) GetConfig(key string, opts ...config_center.Option) (string, error) { - /** - * when group is not null, we are getting startup configs from Config Center, for example: - * group=dubbo, key=dubbo.properties - */ + opions := &config_center.Options{} for _, opt := range opts { opt(opions) } - + /** + * when group is not null, we are getting startup configs from Config Center, for example: + * group=dubbo, key=dubbo.properties + */ if opions.Group != "" { key = opions.Group + "/" + key + } else { + + /** + * when group is null, we are fetching governance rules, for example: + * 1. key=org.apache.dubbo.DemoService.configurators + * 2. key = org.apache.dubbo.DemoService.condition-router + */ + i := strings.LastIndex(key, ".") + key = key[0:i] + "/" + key[i+1:] } - /** - * when group is null, we are fetching governance rules, for example: - * 1. key=org.apache.dubbo.DemoService.configurators - * 2. key = org.apache.dubbo.DemoService.condition-router - */ - i := strings.LastIndex(key, ".") - key = key[0:i] + "/" + key[i+1:] content, _, err := c.client.GetContent(c.rootPath + "/" + key) if err != nil { return "", perrors.WithStack(err) } else { return string(content), nil } + } //For zookeeper, getConfig and getConfigs have the same meaning. diff --git a/config_center/zookeeper/impl_test.go b/config_center/zookeeper/impl_test.go new file mode 100644 index 000000000..f3ca1c744 --- /dev/null +++ b/config_center/zookeeper/impl_test.go @@ -0,0 +1,162 @@ +/* + * 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 zookeeper + +import ( + "context" + "fmt" + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/config_center" + "github.com/apache/dubbo-go/remoting" + "github.com/samuel/go-zookeeper/zk" + "github.com/stretchr/testify/assert" + "sync" + "testing" +) + +func initZkData(group string, t *testing.T) (*zk.TestCluster, *zookeeperDynamicConfiguration) { + regurl, _ := common.NewURL(context.TODO(), "registry://127.0.0.1:1111") + ts, reg, err := newMockZookeeperDynamicConfiguration(®url) + reg.SetParser(&config_center.DefaultConfigurationParser{}) + + assert.NoError(t, err) + + data := ` + dubbo.consumer.request_timeout=5s + dubbo.consumer.connect_timeout=5s + dubbo.application.organization=ikurento.com + dubbo.application.name=BDTService + dubbo.application.module=dubbogo user-info server + dubbo.application.version=0.0.1 + dubbo.application.owner=ZX + dubbo.application.environment=dev + dubbo.registries.hangzhouzk.protocol=zookeeper + dubbo.registries.hangzhouzk.timeout=3s + dubbo.registries.hangzhouzk.address=127.0.0.1:2181 + dubbo.registries.shanghaizk.protocol=zookeeper + dubbo.registries.shanghaizk.timeout=3s + dubbo.registries.shanghaizk.address=127.0.0.1:2182 + dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo + dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider + dubbo.service.com.ikurento.user.UserProvider.loadbalance=random + dubbo.service.com.ikurento.user.UserProvider.warmup=100 + dubbo.service.com.ikurento.user.UserProvider.cluster=failover +` + if group != "" { + err = reg.client.Create(reg.rootPath + "/dubbo/dubbo.properties") + assert.NoError(t, err) + + _, err = reg.client.Conn.Set(reg.rootPath+"/dubbo/dubbo.properties", []byte(data), 0) + assert.NoError(t, err) + } else { + err = reg.client.Create(reg.rootPath + "/dubbo.properties") + assert.NoError(t, err) + + _, err = reg.client.Conn.Set(reg.rootPath+"/dubbo.properties", []byte(data), 0) + assert.NoError(t, err) + } + + return ts, reg +} +func Test_GetConfig(t *testing.T) { + ts, reg := initZkData("dubbo", t) + defer ts.Stop() + configs, err := reg.GetConfig("dubbo.properties", config_center.WithGroup("dubbo")) + assert.NoError(t, err) + m, err := reg.Parser().Parse(configs) + assert.NoError(t, err) + assert.Equal(t, "5s", m["dubbo.consumer.request_timeout"]) +} + +func Test_AddListener(t *testing.T) { + ts, reg := initZkData("", t) + defer ts.Stop() + listener := &mockDataListener{} + reg.AddListener("dubbo.properties", listener) + listener.wg.Add(1) + data := ` + dubbo.consumer.request_timeout=3s + dubbo.consumer.connect_timeout=5s + dubbo.application.organization=ikurento.com + dubbo.application.name=BDTService + dubbo.application.module=dubbogo user-info server + dubbo.application.version=0.0.1 + dubbo.application.owner=ZX + dubbo.application.environment=dev + dubbo.registries.hangzhouzk.protocol=zookeeper + dubbo.registries.hangzhouzk.timeout=3s + dubbo.registries.hangzhouzk.address=127.0.0.1:2181 + dubbo.registries.shanghaizk.protocol=zookeeper + dubbo.registries.shanghaizk.timeout=3s + dubbo.registries.shanghaizk.address=127.0.0.1:2182 + dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo + dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider + dubbo.service.com.ikurento.user.UserProvider.loadbalance=random + dubbo.service.com.ikurento.user.UserProvider.warmup=100 + dubbo.service.com.ikurento.user.UserProvider.cluster=failover +` + _, err := reg.client.Conn.Set(reg.rootPath+"/dubbo.properties", []byte(data), 1) + assert.NoError(t, err) + listener.wg.Wait() + assert.Equal(t, "dubbo.properties", listener.event) +} + +func Test_RemoveListener(t *testing.T) { + ts, reg := initZkData("", t) + defer ts.Stop() + listener := &mockDataListener{} + reg.AddListener("dubbo.properties", listener) + listener.wg.Add(1) + data := ` + dubbo.consumer.request_timeout=3s + dubbo.consumer.connect_timeout=5s + dubbo.application.organization=ikurento.com + dubbo.application.name=BDTService + dubbo.application.module=dubbogo user-info server + dubbo.application.version=0.0.1 + dubbo.application.owner=ZX + dubbo.application.environment=dev + dubbo.registries.hangzhouzk.protocol=zookeeper + dubbo.registries.hangzhouzk.timeout=3s + dubbo.registries.hangzhouzk.address=127.0.0.1:2181 + dubbo.registries.shanghaizk.protocol=zookeeper + dubbo.registries.shanghaizk.timeout=3s + dubbo.registries.shanghaizk.address=127.0.0.1:2182 + dubbo.service.com.ikurento.user.UserProvider.protocol=dubbo + dubbo.service.com.ikurento.user.UserProvider.interface=com.ikurento.user.UserProvider + dubbo.service.com.ikurento.user.UserProvider.loadbalance=random + dubbo.service.com.ikurento.user.UserProvider.warmup=100 + dubbo.service.com.ikurento.user.UserProvider.cluster=failover +` + reg.RemoveListener("dubbo.properties", listener) + listener.wg.Done() + _, err := reg.client.Conn.Set(reg.rootPath+"/dubbo.properties", []byte(data), 1) + assert.NoError(t, err) + listener.wg.Wait() + assert.Equal(t, "", listener.event) +} + +type mockDataListener struct { + wg sync.WaitGroup + event string +} + +func (l *mockDataListener) Process(configType *remoting.ConfigChangeEvent) { + fmt.Println("process!!!!!") + l.wg.Done() + l.event = configType.Key +} diff --git a/config_center/zookeeper/listener.go b/config_center/zookeeper/listener.go index 0188e8af2..b746c34ba 100644 --- a/config_center/zookeeper/listener.go +++ b/config_center/zookeeper/listener.go @@ -18,7 +18,6 @@ package zookeeper import ( - "fmt" "strings" "sync" ) @@ -53,7 +52,10 @@ func (l *CacheListener) RemoveListener(key string, listener remoting.Configurati } func (l *CacheListener) DataChange(event remoting.Event) bool { - fmt.Println(event) + if event.Content == "" { + //meanings new node + return true + } key := l.pathToKey(event.Path) if key != "" { if listeners, ok := l.keyListeners.Load(key); ok { diff --git a/examples/dubbo/go-client/profiles/dev/client.yml b/examples/dubbo/go-client/profiles/dev/client.yml index 3fcbd2cb1..8e991a5e7 100644 --- a/examples/dubbo/go-client/profiles/dev/client.yml +++ b/examples/dubbo/go-client/profiles/dev/client.yml @@ -1,41 +1,38 @@ # dubbo client yaml configure file + +check: true # client -request_timeout : "100ms" +request_timeout : "3s" # connect timeout -connect_timeout : "100ms" -check: true +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" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "dev" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" - + "UserProvider": protocol : "dubbo" - # url: "dubbo://127.0.0.1:20000" interface : "com.ikurento.user.UserProvider" cluster: "failover" methods : diff --git a/examples/dubbo/go-client/profiles/release/client.yml b/examples/dubbo/go-client/profiles/release/client.yml index 998f232fc..f35325529 100644 --- a/examples/dubbo/go-client/profiles/release/client.yml +++ b/examples/dubbo/go-client/profiles/release/client.yml @@ -1,10 +1,12 @@ # dubbo client yaml configure file + +check: true # client -request_timeout : "100ms" +request_timeout : "3s" # connect timeout -connect_timeout : "100ms" -check: true +connect_timeout : "3s" + # application config application_config: organization : "ikurento.com" @@ -12,28 +14,24 @@ application_config: module : "dubbogo user-info client" version : "0.0.1" owner : "ZX" - environment : "dev" + environment : "release" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" - + "UserProvider": protocol : "dubbo" interface : "com.ikurento.user.UserProvider" cluster: "failover" diff --git a/examples/dubbo/go-client/profiles/test/client.yml b/examples/dubbo/go-client/profiles/test/client.yml index 998f232fc..b9b9d0735 100644 --- a/examples/dubbo/go-client/profiles/test/client.yml +++ b/examples/dubbo/go-client/profiles/test/client.yml @@ -1,10 +1,12 @@ # dubbo client yaml configure file + +check: true # client -request_timeout : "100ms" +request_timeout : "3s" # connect timeout -connect_timeout : "100ms" -check: true +connect_timeout : "3s" + # application config application_config: organization : "ikurento.com" @@ -12,28 +14,24 @@ application_config: module : "dubbogo user-info client" version : "0.0.1" owner : "ZX" - environment : "dev" + environment : "test" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" - + "UserProvider": protocol : "dubbo" interface : "com.ikurento.user.UserProvider" cluster: "failover" diff --git a/examples/dubbo/go-server/profiles/dev/server.yml b/examples/dubbo/go-server/profiles/dev/server.yml index 619f2ddca..78b21624a 100644 --- a/examples/dubbo/go-server/profiles/dev/server.yml +++ b/examples/dubbo/go-server/profiles/dev/server.yml @@ -1,24 +1,24 @@ # dubbo server yaml configure file + # application config application_config: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "dev" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "dev" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" @@ -26,11 +26,9 @@ registries : services: - - registries: - - "hangzhouzk" - - "shanghaizk" + "UserProvider": protocol : "dubbo" - # 相当于dubbo.xml中的interface + # 相当于dubbo.xml中的interface interface : "com.ikurento.user.UserProvider" loadbalance: "random" warmup: "100" @@ -41,12 +39,11 @@ services: loadbalance: "random" protocols: - - name: "dubbo" + "dubbo1": + name: "dubbo" # ip : "127.0.0.1" - port : 20000 - #- name: "jsonrpc" - # ip: "127.0.0.1" - # port: 20001 + port: 20000 + protocol_conf: dubbo: diff --git a/examples/dubbo/go-server/profiles/release/server.yml b/examples/dubbo/go-server/profiles/release/server.yml index c4d98eb74..9c9ad5c15 100644 --- a/examples/dubbo/go-server/profiles/release/server.yml +++ b/examples/dubbo/go-server/profiles/release/server.yml @@ -1,5 +1,6 @@ # dubbo server yaml configure file + # application config application_config: organization : "ikurento.com" @@ -7,18 +8,17 @@ application_config: module : "dubbogo user-info server" version : "0.0.1" owner : "ZX" - environment : "dev" + environment : "release" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" @@ -26,9 +26,7 @@ registries : services: - - registries: - - "hangzhouzk" - - "shanghaizk" + "UserProvider": protocol : "dubbo" # 相当于dubbo.xml中的interface interface : "com.ikurento.user.UserProvider" @@ -36,17 +34,16 @@ services: warmup: "100" cluster: "failover" methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + - name: "GetUser" + retries: 1 + loadbalance: "random" protocols: - - name: "dubbo" + "dubbo1": + name: "dubbo" # ip : "127.0.0.1" - port : 20000 - #- name: "jsonrpc" - # ip: "127.0.0.1" - # port: 20001 + port: 20000 + protocol_conf: dubbo: diff --git a/examples/dubbo/go-server/profiles/test/server.yml b/examples/dubbo/go-server/profiles/test/server.yml index c4d98eb74..69d68279d 100644 --- a/examples/dubbo/go-server/profiles/test/server.yml +++ b/examples/dubbo/go-server/profiles/test/server.yml @@ -1,5 +1,6 @@ # dubbo server yaml configure file + # application config application_config: organization : "ikurento.com" @@ -7,18 +8,17 @@ application_config: module : "dubbogo user-info server" version : "0.0.1" owner : "ZX" - environment : "dev" + environment : "test" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" @@ -26,9 +26,7 @@ registries : services: - - registries: - - "hangzhouzk" - - "shanghaizk" + "UserProvider": protocol : "dubbo" # 相当于dubbo.xml中的interface interface : "com.ikurento.user.UserProvider" @@ -36,17 +34,16 @@ services: warmup: "100" cluster: "failover" methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + - name: "GetUser" + retries: 1 + loadbalance: "random" protocols: - - name: "dubbo" + "dubbo1": + name: "dubbo" # ip : "127.0.0.1" - port : 20000 - #- name: "jsonrpc" - # ip: "127.0.0.1" - # port: 20001 + port: 20000 + protocol_conf: dubbo: diff --git a/examples/dubbo/with-configcenter-go-client/app/client.go b/examples/dubbo/with-configcenter-go-client/app/client.go new file mode 100644 index 000000000..a842e7bee --- /dev/null +++ b/examples/dubbo/with-configcenter-go-client/app/client.go @@ -0,0 +1,146 @@ +/* + * 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/dubbogo/hessian2" +) + +import ( + _ "github.com/apache/dubbo-go/cluster/cluster_impl" + _ "github.com/apache/dubbo-go/cluster/loadbalance" + "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/config_center/zookeeper" + _ "github.com/apache/dubbo-go/filter/impl" + _ "github.com/apache/dubbo-go/protocol/dubbo" + _ "github.com/apache/dubbo-go/registry/protocol" + _ "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{}) + + conMap, _ := config.Load() + if conMap == nil { + panic("conMap is nil") + } + + println("\n\n\necho") + res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK") + if err != nil { + panic(err) + } + println("res: %v\n", res) + + time.Sleep(3e9) + + println("\n\n\nstart to test dubbo") + user := &User{} + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user) + if err != nil { + panic(err) + } + println("response result: %v", user) + + println("\n\n\nstart to test dubbo - GetUser0") + ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0("A003", "Moorse") + if err != nil { + panic(err) + } + println("response result: %v", ret) + + println("\n\n\nstart to test dubbo - GetUsers") + ret1, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUsers([]interface{}{[]interface{}{"A002", "A003"}}) + if err != nil { + panic(err) + } + println("response result: %v", ret1) + + println("\n\n\nstart to test dubbo - getUser2") + user = &User{} + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user) + if err != nil { + println("getUser - error: %v", err) + } else { + println("response result: %v", user) + } + + println("\n\n\nstart to test dubbo - getErr") + user = &User{} + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetErr(context.TODO(), []interface{}{"A003"}, user) + if err != nil { + println("getErr - error: %v", err) + } + + println("\n\n\nstart to test dubbo illegal method") + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user) + if err != nil { + panic(err) + } + + 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 + } + } +} + +func println(format string, args ...interface{}) { + fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...) +} diff --git a/examples/dubbo/with-configcenter-go-client/app/user.go b/examples/dubbo/with-configcenter-go-client/app/user.go new file mode 100644 index 000000000..59e105109 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-client/app/user.go @@ -0,0 +1,114 @@ +/* + * 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/dubbogo/hessian2" +) + +import ( + "github.com/apache/dubbo-go/config" +) + +type Gender hessian.JavaEnum + +func init() { + config.SetConsumerService(new(UserProvider)) +} + +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 // 注意此处,java 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"` + Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used +} + +func (u *UserProvider) Service() string { + return "com.ikurento.user.UserProvider" +} + +func (u *UserProvider) Version() string { + return "" +} diff --git a/examples/dubbo/with-configcenter-go-client/app/version.go b/examples/dubbo/with-configcenter-go-client/app/version.go new file mode 100644 index 000000000..c6138584f --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/bin/load.sh b/examples/dubbo/with-configcenter-go-client/assembly/bin/load.sh new file mode 100644 index 000000000..07d5d15ea --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/common/app.properties b/examples/dubbo/with-configcenter-go-client/assembly/common/app.properties new file mode 100644 index 000000000..6bbd6db85 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/common/build.sh b/examples/dubbo/with-configcenter-go-client/assembly/common/build.sh new file mode 100644 index 000000000..e72418297 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/C++程序被strip的效果), + # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试, + # -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/dubbo/with-configcenter-go-client/assembly/linux/dev.sh b/examples/dubbo/with-configcenter-go-client/assembly/linux/dev.sh new file mode 100644 index 000000000..3373f01b9 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/linux/release.sh b/examples/dubbo/with-configcenter-go-client/assembly/linux/release.sh new file mode 100644 index 000000000..34867b8b3 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/linux/test.sh b/examples/dubbo/with-configcenter-go-client/assembly/linux/test.sh new file mode 100644 index 000000000..1bbbefd1e --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/mac/dev.sh b/examples/dubbo/with-configcenter-go-client/assembly/mac/dev.sh new file mode 100644 index 000000000..b68ac83b6 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/mac/release.sh b/examples/dubbo/with-configcenter-go-client/assembly/mac/release.sh new file mode 100644 index 000000000..688288b3b --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/mac/test.sh b/examples/dubbo/with-configcenter-go-client/assembly/mac/test.sh new file mode 100644 index 000000000..56d6c11ec --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/windows/dev.sh b/examples/dubbo/with-configcenter-go-client/assembly/windows/dev.sh new file mode 100644 index 000000000..91cf6f23b --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/windows/release.sh b/examples/dubbo/with-configcenter-go-client/assembly/windows/release.sh new file mode 100644 index 000000000..f317720bd --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/assembly/windows/test.sh b/examples/dubbo/with-configcenter-go-client/assembly/windows/test.sh new file mode 100644 index 000000000..7dd2bec52 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/profiles/dev/client.yml b/examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml new file mode 100644 index 000000000..c809041f1 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-client/profiles/dev/client.yml @@ -0,0 +1,40 @@ +# dubbo client yaml configure file + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.client.properties" + +references: + "UserProvider": + 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" diff --git a/examples/dubbo/with-configcenter-go-client/profiles/dev/log.yml b/examples/dubbo/with-configcenter-go-client/profiles/dev/log.yml new file mode 100644 index 000000000..59fa4279a --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/profiles/release/client.yml b/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml new file mode 100644 index 000000000..c809041f1 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-client/profiles/release/client.yml @@ -0,0 +1,40 @@ +# dubbo client yaml configure file + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.client.properties" + +references: + "UserProvider": + 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" diff --git a/examples/dubbo/with-configcenter-go-client/profiles/release/log.yml b/examples/dubbo/with-configcenter-go-client/profiles/release/log.yml new file mode 100644 index 000000000..e0514be02 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/dubbo/with-configcenter-go-client/profiles/test/client.yml b/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml new file mode 100644 index 000000000..c809041f1 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-client/profiles/test/client.yml @@ -0,0 +1,40 @@ +# dubbo client yaml configure file + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.client.properties" + +references: + "UserProvider": + 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" diff --git a/examples/dubbo/with-configcenter-go-client/profiles/test/log.yml b/examples/dubbo/with-configcenter-go-client/profiles/test/log.yml new file mode 100644 index 000000000..baee0b724 --- /dev/null +++ b/examples/dubbo/with-configcenter-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/examples/dubbo/with-configcenter-go-server/app/server.go b/examples/dubbo/with-configcenter-go-server/app/server.go new file mode 100644 index 000000000..7522f6204 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/app/server.go @@ -0,0 +1,89 @@ +/* + * 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 ( + "fmt" + "os" + "os/signal" + "syscall" + "time" +) + +import ( + hessian "github.com/dubbogo/hessian2" +) + +import ( + _ "github.com/apache/dubbo-go/cluster/cluster_impl" + _ "github.com/apache/dubbo-go/cluster/loadbalance" + "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/config_center/zookeeper" + _ "github.com/apache/dubbo-go/filter/impl" + _ "github.com/apache/dubbo-go/protocol/dubbo" + _ "github.com/apache/dubbo-go/registry/protocol" + _ "github.com/apache/dubbo-go/registry/zookeeper" +) + +var ( + survivalTimeout = int(3e9) +) + +// they are necessary: +// export CONF_PROVIDER_FILE_PATH="xxx" +// export APP_LOG_CONF_FILE="xxx" +func main() { + + // ------for hessian2------ + hessian.RegisterJavaEnum(Gender(MAN)) + hessian.RegisterJavaEnum(Gender(WOMAN)) + hessian.RegisterPOJO(&User{}) + // ------------ + + _, proMap := config.Load() + if proMap == nil { + panic("proMap is nil") + } + + 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(float64(survivalTimeout)*float64(time.Second)), func() { + logger.Warnf("app exit now by force...") + os.Exit(1) + }) + + // 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出 + fmt.Println("provider app exit now...") + return + } + } +} diff --git a/examples/dubbo/with-configcenter-go-server/app/user.go b/examples/dubbo/with-configcenter-go-server/app/user.go new file mode 100644 index 000000000..e4400cc27 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/app/user.go @@ -0,0 +1,195 @@ +/* + * 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 ( + perrors "github.com/pkg/errors" +) + +import ( + "github.com/apache/dubbo-go/config" + hessian "github.com/dubbogo/hessian2" +) + +type Gender hessian.JavaEnum + +func init() { + config.SetProviderService(new(UserProvider)) +} + +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 // 注意此处,java enum Object <--> go string + } + + UserProvider struct { + user map[string]User + } +) + +var ( + DefaultUser = User{ + Id: "0", Name: "Alex Stocks", Age: 31, + Sex: Gender(MAN), + } + + userMap = UserProvider{user: make(map[string]User)} +) + +func init() { + userMap.user["A000"] = DefaultUser + userMap.user["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, Sex: Gender(MAN)} + userMap.user["A002"] = User{Id: "002", Name: "Lily", Age: 20, Sex: Gender(WOMAN)} + userMap.user["A003"] = User{Id: "113", Name: "Moorse", Age: 30, Sex: Gender(WOMAN)} + for k, v := range userMap.user { + v.Time = time.Now() + userMap.user[k] = v + } +} + +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 (u User) JavaClassName() string { + return "com.ikurento.user.User" +} + +func (u *UserProvider) getUser(userId string) (*User, error) { + if user, ok := userMap.user[userId]; ok { + return &user, nil + } + + return nil, fmt.Errorf("invalid user id:%s", userId) +} + +func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error { + var ( + err error + user *User + ) + + println("req:%#v", req) + user, err = u.getUser(req[0].(string)) + if err == nil { + *rsp = *user + println("rsp:%#v", rsp) + } + return err +} + +func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error { + return hessian.NewThrowable("exception") +} + +func (u *UserProvider) GetUser0(id string, name string) (User, error) { + var err error + + println("id:%s, name:%s", id, name) + user, err := u.getUser(id) + if err != nil { + return User{}, err + } + if user.Name != name { + return User{}, perrors.New("name is not " + user.Name) + } + return *user, err +} + +func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) { + var err error + + println("req:%s", req) + t := req[0].([]interface{}) + user, err := u.getUser(t[0].(string)) + if err != nil { + return nil, err + } + println("user:%v", user) + user1, err := u.getUser(t[1].(string)) + if err != nil { + return nil, err + } + println("user1:%v", user1) + + return []interface{}{user, user1}, err +} + +func (u *UserProvider) Service() string { + return "com.ikurento.user.UserProvider" +} + +func (u *UserProvider) Version() string { + return "" +} + +func println(format string, args ...interface{}) { + fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...) +} diff --git a/examples/dubbo/with-configcenter-go-server/app/version.go b/examples/dubbo/with-configcenter-go-server/app/version.go new file mode 100644 index 000000000..c6138584f --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/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/dubbo/with-configcenter-go-server/assembly/bin/load.sh b/examples/dubbo/with-configcenter-go-server/assembly/bin/load.sh new file mode 100644 index 000000000..47fc5e38d --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/bin/load.sh @@ -0,0 +1,144 @@ +#!/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="" + + +PROJECT_HOME="" +OS_NAME=`uname` +if [[ ${OS_NAME} != "Windows" ]]; then + PROJECT_HOME=`pwd` + PROJECT_HOME=${PROJECT_HOME}"/" +fi + +export CONF_PROVIDER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE" +export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE" + +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 server.yml!" + else + export CONF_PROVIDER_FILE_PATH=${CONF_PROVIDER_FILE_PATH//\.yml/\_$arg\.yml} + fi + if [ ! -f "${CONF_PROVIDER_FILE_PATH}" ];then + echo $CONF_PROVIDER_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 +} + +opt=$1 +case C"$opt" in + Cstart) + start $2 + ;; + Cstop) + stop + ;; + Cterm) + term + ;; + Crestart) + term + start $2 + ;; + Clist) + list + ;; + C*) + usage + ;; +esac + diff --git a/examples/dubbo/with-configcenter-go-server/assembly/common/app.properties b/examples/dubbo/with-configcenter-go-server/assembly/common/app.properties new file mode 100644 index 000000000..dffb755b0 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/common/app.properties @@ -0,0 +1,17 @@ +# dubbogo application configure script +# ****************************************************** +# DESC : application 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 +# ****************************************************** + +TARGET_EXEC_NAME="user_info_server" +# BUILD_PACKAGE="dubbogo-examples/user-info/server/app" +BUILD_PACKAGE="app" + +TARGET_CONF_FILE="conf/server.yml" +TARGET_LOG_CONF_FILE="conf/log.yml" diff --git a/examples/dubbo/with-configcenter-go-server/assembly/common/build.sh b/examples/dubbo/with-configcenter-go-server/assembly/common/build.sh new file mode 100644 index 000000000..15ac904f7 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/common/build.sh @@ -0,0 +1,74 @@ +#!/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 = "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} && go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd - +else + # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果), + # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试, + # -w基本没啥损失。-s的损失就有点大了。 + cd ${BUILD_PACKAGE} && 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} +# modify APPLICATION_NAME +# OS=`uname` +# if [[ $OS=="Darwin" ]]; then +if [ "$(uname)" == "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 [ "$(uname)" == "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 [ "$(uname)" == "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/dubbo/with-configcenter-go-server/assembly/linux/dev.sh b/examples/dubbo/with-configcenter-go-server/assembly/linux/dev.sh new file mode 100644 index 000000000..55886f09f --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/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 : 2018-06-24 17:32 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/linux/release.sh b/examples/dubbo/with-configcenter-go-server/assembly/linux/release.sh new file mode 100644 index 000000000..9772ad961 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/linux/release.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +PROFILE=release + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/linux/test.sh b/examples/dubbo/with-configcenter-go-server/assembly/linux/test.sh new file mode 100644 index 000000000..2fc4a9886 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/linux/test.sh @@ -0,0 +1,29 @@ +#!/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 + +PROFILE=test + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/mac/dev.sh b/examples/dubbo/with-configcenter-go-server/assembly/mac/dev.sh new file mode 100644 index 000000000..5dfa78490 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/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 : 2018-06-24 17:32 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/mac/release.sh b/examples/dubbo/with-configcenter-go-server/assembly/mac/release.sh new file mode 100644 index 000000000..1ec21c7b5 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/mac/release.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=release + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/mac/test.sh b/examples/dubbo/with-configcenter-go-server/assembly/mac/test.sh new file mode 100644 index 000000000..d34914c7d --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/mac/test.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=test + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi + diff --git a/examples/dubbo/with-configcenter-go-server/assembly/windows/dev.sh b/examples/dubbo/with-configcenter-go-server/assembly/windows/dev.sh new file mode 100644 index 000000000..97fbb6f69 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/windows/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 : 2018-06-24 17:34 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/windows/release.sh b/examples/dubbo/with-configcenter-go-server/assembly/windows/release.sh new file mode 100644 index 000000000..782cb10c7 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/windows/release.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +PROFILE=release + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/assembly/windows/test.sh b/examples/dubbo/with-configcenter-go-server/assembly/windows/test.sh new file mode 100644 index 000000000..2037ddecf --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/assembly/windows/test.sh @@ -0,0 +1,29 @@ +#!/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 + +PROFILE=test + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/dubbo/with-configcenter-go-server/profiles/dev/log.yml b/examples/dubbo/with-configcenter-go-server/profiles/dev/log.yml new file mode 100644 index 000000000..59fa4279a --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/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/dubbo/with-configcenter-go-server/profiles/dev/server.yml b/examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml new file mode 100644 index 000000000..05f758592 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/profiles/dev/server.yml @@ -0,0 +1,41 @@ +# dubbo server yaml configure file + + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.properties" + +services: + "UserProvider": + protocol : "dubbo" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +protocol_conf: + dubbo: + session_number: 700 + fail_fast_timeout: "5s" + session_timeout: "20s" + 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: 1024 + session_name: "server" diff --git a/examples/dubbo/with-configcenter-go-server/profiles/release/log.yml b/examples/dubbo/with-configcenter-go-server/profiles/release/log.yml new file mode 100644 index 000000000..e0514be02 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/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/dubbo/with-configcenter-go-server/profiles/release/server.yml b/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml new file mode 100644 index 000000000..05f758592 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/profiles/release/server.yml @@ -0,0 +1,41 @@ +# dubbo server yaml configure file + + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.properties" + +services: + "UserProvider": + protocol : "dubbo" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +protocol_conf: + dubbo: + session_number: 700 + fail_fast_timeout: "5s" + session_timeout: "20s" + 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: 1024 + session_name: "server" diff --git a/examples/dubbo/with-configcenter-go-server/profiles/test/log.yml b/examples/dubbo/with-configcenter-go-server/profiles/test/log.yml new file mode 100644 index 000000000..baee0b724 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/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/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml b/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml new file mode 100644 index 000000000..05f758592 --- /dev/null +++ b/examples/dubbo/with-configcenter-go-server/profiles/test/server.yml @@ -0,0 +1,41 @@ +# dubbo server yaml configure file + + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.properties" + +services: + "UserProvider": + protocol : "dubbo" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +protocol_conf: + dubbo: + session_number: 700 + fail_fast_timeout: "5s" + session_timeout: "20s" + 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: 1024 + session_name: "server" diff --git a/examples/jsonrpc/go-client/profiles/dev/client.yml b/examples/jsonrpc/go-client/profiles/dev/client.yml index 020adc5e6..e6feab42f 100644 --- a/examples/jsonrpc/go-client/profiles/dev/client.yml +++ b/examples/jsonrpc/go-client/profiles/dev/client.yml @@ -16,25 +16,21 @@ application_config: environment : "dev" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" - + "UserProvider": protocol : "jsonrpc" interface : "com.ikurento.user.UserProvider" cluster: "failover" diff --git a/examples/jsonrpc/go-client/profiles/release/client.yml b/examples/jsonrpc/go-client/profiles/release/client.yml index 3e3bd63f5..1ce7237cd 100644 --- a/examples/jsonrpc/go-client/profiles/release/client.yml +++ b/examples/jsonrpc/go-client/profiles/release/client.yml @@ -1,6 +1,5 @@ # dubbo client yaml configure file - check: true # client request_timeout : "3s" @@ -9,36 +8,56 @@ 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" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "release" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" - + "UserProvider": protocol : "jsonrpc" 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" diff --git a/examples/jsonrpc/go-client/profiles/test/client.yml b/examples/jsonrpc/go-client/profiles/test/client.yml index e79f7f47f..59119ddfe 100644 --- a/examples/jsonrpc/go-client/profiles/test/client.yml +++ b/examples/jsonrpc/go-client/profiles/test/client.yml @@ -8,36 +8,56 @@ 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" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info client" + version : "0.0.1" + owner : "ZX" + environment : "test" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" references: - - registries : - - "hangzhouzk" - - "shanghaizk" - + "UserProvider": protocol : "jsonrpc" 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" diff --git a/examples/jsonrpc/go-server/profiles/dev/server.yml b/examples/jsonrpc/go-server/profiles/dev/server.yml index 0175847a6..94e92dcc6 100644 --- a/examples/jsonrpc/go-server/profiles/dev/server.yml +++ b/examples/jsonrpc/go-server/profiles/dev/server.yml @@ -10,15 +10,14 @@ application_config: environment : "dev" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" @@ -26,9 +25,7 @@ registries : services: - - registries: - - "hangzhouzk" - - "shanghaizk" + "UserProvider": protocol : "jsonrpc" # 相当于dubbo.xml中的interface interface : "com.ikurento.user.UserProvider" @@ -44,7 +41,8 @@ protocols: #- name: "dubbo" # ip : "127.0.0.1" # port : 20000 - - name: "jsonrpc" + "jsonrpc1": + name: "jsonrpc" ip: "127.0.0.1" port: 20001 diff --git a/examples/jsonrpc/go-server/profiles/release/server.yml b/examples/jsonrpc/go-server/profiles/release/server.yml index 3c70e8248..f1f503eb0 100644 --- a/examples/jsonrpc/go-server/profiles/release/server.yml +++ b/examples/jsonrpc/go-server/profiles/release/server.yml @@ -2,49 +2,47 @@ # application config application_config: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "dev" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "release" registries : -- id: "hangzhouzk" - type: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2181" - username: "" - password: "" - -- id: "shanghaizk" - type: "zookeeper" - timeout : "3s" - address: "127.0.0.1:2182" - username: "" - password: "" + "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: "" services: - - registries: - - "hangzhouzk" - - "shanghaizk" - protocol : "jsonrpc" - # 相当于dubbo.xml中的interface - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + "UserProvider": + protocol : "jsonrpc" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" protocols: #- name: "dubbo" # ip : "127.0.0.1" # port : 20000 - - name: "jsonrpc" + "jsonrpc1": + name: "jsonrpc" ip: "127.0.0.1" port: 20001 diff --git a/examples/jsonrpc/go-server/profiles/test/server.yml b/examples/jsonrpc/go-server/profiles/test/server.yml index a8ad5746b..e8d7135a8 100644 --- a/examples/jsonrpc/go-server/profiles/test/server.yml +++ b/examples/jsonrpc/go-server/profiles/test/server.yml @@ -2,47 +2,47 @@ # application config application_config: - organization : "ikurento.com" - name : "BDTService" - module : "dubbogo user-info server" - version : "0.0.1" - owner : "ZX" - environment : "dev" + organization : "ikurento.com" + name : "BDTService" + module : "dubbogo user-info server" + version : "0.0.1" + owner : "ZX" + environment : "test" registries : - - id: "hangzhouzk" - type: "zookeeper" + "hangzhouzk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2181" username: "" password: "" - - - id: "shanghaizk" - type: "zookeeper" + "shanghaizk": + protocol: "zookeeper" timeout : "3s" address: "127.0.0.1:2182" username: "" password: "" + services: - - registries: - - "hangzhouzk" - - "shanghaizk" - protocol : "jsonrpc" - # 相当于dubbo.xml中的interface - interface : "com.ikurento.user.UserProvider" - loadbalance: "random" - warmup: "100" - cluster: "failover" - methods: - - name: "GetUser" - retries: 1 - loadbalance: "random" + "UserProvider": + protocol : "jsonrpc" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" protocols: #- name: "dubbo" # ip : "127.0.0.1" # port : 20000 - - name: "jsonrpc" + "jsonrpc1": + name: "jsonrpc" ip: "127.0.0.1" port: 20001 + diff --git a/examples/jsonrpc/with-configcenter-go-client/app/client.go b/examples/jsonrpc/with-configcenter-go-client/app/client.go new file mode 100644 index 000000000..1255c674c --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-client/app/client.go @@ -0,0 +1,132 @@ +/* + * 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/cluster/cluster_impl" + _ "github.com/apache/dubbo-go/cluster/loadbalance" + "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/config_center/zookeeper" + _ "github.com/apache/dubbo-go/filter/impl" + _ "github.com/apache/dubbo-go/protocol/jsonrpc" + _ "github.com/apache/dubbo-go/registry/protocol" + _ "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() { + + conMap, _ := config.Load() + if conMap == nil { + panic("conMap is nil") + } + + println("\n\n\necho") + res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK") + if err != nil { + println("echo - error: %v", err) + } else { + println("res: %v", res) + } + + time.Sleep(3e9) + + println("\n\n\nstart to test jsonrpc") + user := &JsonRPCUser{} + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user) + if err != nil { + panic(err) + } + println("response result: %v", user) + + println("\n\n\nstart to test jsonrpc - GetUser0") + ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0("A003", "Moorse") + if err != nil { + panic(err) + } + println("response result: %v", ret) + + println("\n\n\nstart to test jsonrpc - GetUsers") + ret1, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUsers([]interface{}{[]interface{}{"A002", "A003"}}) + if err != nil { + panic(err) + } + println("response result: %v", ret1) + + println("\n\n\nstart to test jsonrpc - getUser") + user = &JsonRPCUser{} + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user) + if err != nil { + println("getUser - error: %v", err) + } else { + println("response result: %v", user) + } + + println("\n\n\nstart to test jsonrpc illegal method") + err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user) + if err != nil { + panic(err) + } + + 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 + } + } +} + +func println(format string, args ...interface{}) { + fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...) +} diff --git a/examples/jsonrpc/with-configcenter-go-client/app/user.go b/examples/jsonrpc/with-configcenter-go-client/app/user.go new file mode 100644 index 000000000..6e2a97081 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-client/app/user.go @@ -0,0 +1,64 @@ +/* + * 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" + "time" +) + +import ( + "github.com/apache/dubbo-go/config" +) + +func init() { + config.SetConsumerService(new(UserProvider)) +} + +type JsonRPCUser struct { + ID string `json:"id"` + Name string `json:"name"` + Age int64 `json:"age"` + Time int64 `json:"time"` + Sex string `json:"sex"` +} + +func (u JsonRPCUser) String() string { + return fmt.Sprintf( + "User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}", + u.ID, u.Name, u.Age, time.Unix(u.Time, 0).Format("2006-01-02 15:04:05.99999"), u.Sex, + ) +} + +type UserProvider struct { + GetUsers func(req []interface{}) ([]JsonRPCUser, error) + GetUser func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error + GetUser0 func(id string, name string) (JsonRPCUser, error) + GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error + GetUser2 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error `dubbo:"getUser"` + Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used +} + +func (u *UserProvider) Service() string { + return "com.ikurento.user.UserProvider" +} + +func (u *UserProvider) Version() string { + return "" +} diff --git a/examples/jsonrpc/with-configcenter-go-client/app/version.go b/examples/jsonrpc/with-configcenter-go-client/app/version.go new file mode 100644 index 000000000..c6138584f --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/bin/load.sh new file mode 100644 index 000000000..07d5d15ea --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/common/app.properties b/examples/jsonrpc/with-configcenter-go-client/assembly/common/app.properties new file mode 100644 index 000000000..6bbd6db85 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/common/build.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/common/build.sh new file mode 100644 index 000000000..06b212db6 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/C++程序被strip的效果), + # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试, + # -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/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/linux/dev.sh new file mode 100644 index 000000000..3373f01b9 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/linux/release.sh new file mode 100644 index 000000000..34867b8b3 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/linux/test.sh new file mode 100644 index 000000000..1bbbefd1e --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/mac/dev.sh new file mode 100644 index 000000000..b68ac83b6 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/mac/release.sh new file mode 100644 index 000000000..688288b3b --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/mac/test.sh new file mode 100644 index 000000000..56d6c11ec --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/windows/dev.sh new file mode 100644 index 000000000..91cf6f23b --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/windows/release.sh new file mode 100644 index 000000000..f317720bd --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh b/examples/jsonrpc/with-configcenter-go-client/assembly/windows/test.sh new file mode 100644 index 000000000..7dd2bec52 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml b/examples/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml new file mode 100644 index 000000000..3770f52b8 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-client/profiles/dev/client.yml @@ -0,0 +1,16 @@ +# dubbo client yaml configure file + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.client.properties" + +references: + "UserProvider": + protocol : "jsonrpc" + interface : "com.ikurento.user.UserProvider" + cluster: "failover" + methods : + - name: "GetUser" + retries: 3 diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml b/examples/jsonrpc/with-configcenter-go-client/profiles/dev/log.yml new file mode 100644 index 000000000..59fa4279a --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/profiles/release/client.yml b/examples/jsonrpc/with-configcenter-go-client/profiles/release/client.yml new file mode 100644 index 000000000..3770f52b8 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-client/profiles/release/client.yml @@ -0,0 +1,16 @@ +# dubbo client yaml configure file + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.client.properties" + +references: + "UserProvider": + protocol : "jsonrpc" + interface : "com.ikurento.user.UserProvider" + cluster: "failover" + methods : + - name: "GetUser" + retries: 3 diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/release/log.yml b/examples/jsonrpc/with-configcenter-go-client/profiles/release/log.yml new file mode 100644 index 000000000..e0514be02 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/jsonrpc/with-configcenter-go-client/profiles/test/client.yml b/examples/jsonrpc/with-configcenter-go-client/profiles/test/client.yml new file mode 100644 index 000000000..3770f52b8 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-client/profiles/test/client.yml @@ -0,0 +1,16 @@ +# dubbo client yaml configure file + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.client.properties" + +references: + "UserProvider": + protocol : "jsonrpc" + interface : "com.ikurento.user.UserProvider" + cluster: "failover" + methods : + - name: "GetUser" + retries: 3 diff --git a/examples/jsonrpc/with-configcenter-go-client/profiles/test/log.yml b/examples/jsonrpc/with-configcenter-go-client/profiles/test/log.yml new file mode 100644 index 000000000..baee0b724 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-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/examples/jsonrpc/with-configcenter-go-server/app/server.go b/examples/jsonrpc/with-configcenter-go-server/app/server.go new file mode 100644 index 000000000..9433059e4 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/app/server.go @@ -0,0 +1,78 @@ +/* + * 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 ( + "fmt" + "os" + "os/signal" + "syscall" + "time" +) + +import ( + _ "github.com/apache/dubbo-go/cluster/cluster_impl" + _ "github.com/apache/dubbo-go/cluster/loadbalance" + "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/config_center/zookeeper" + _ "github.com/apache/dubbo-go/filter/impl" + _ "github.com/apache/dubbo-go/protocol/jsonrpc" + _ "github.com/apache/dubbo-go/registry/protocol" + _ "github.com/apache/dubbo-go/registry/zookeeper" +) + +var ( + survivalTimeout = int(3e9) +) + +// they are necessary: +// export CONF_PROVIDER_FILE_PATH="xxx" +// export APP_LOG_CONF_FILE="xxx" +func main() { + _, proMap := config.Load() + if proMap == nil { + panic("proMap is nil") + } + + 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(float64(survivalTimeout)*float64(time.Second)), func() { + logger.Warnf("app exit now by force...") + os.Exit(1) + }) + + // 要么fastFailTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出 + fmt.Println("provider app exit now...") + return + } + } +} diff --git a/examples/jsonrpc/with-configcenter-go-server/app/user.go b/examples/jsonrpc/with-configcenter-go-server/app/user.go new file mode 100644 index 000000000..fbe6f3339 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/app/user.go @@ -0,0 +1,159 @@ +/* + * 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" + "time" +) + +import ( + perrors "github.com/pkg/errors" +) + +import ( + "github.com/apache/dubbo-go/config" +) + +type Gender int + +func init() { + config.SetProviderService(new(UserProvider)) +} + +const ( + MAN = iota + WOMAN +) + +var genderStrings = [...]string{ + "MAN", + "WOMAN", +} + +func (g Gender) String() string { + return genderStrings[g] +} + +type ( + User struct { + Id string `json:"id"` + Name string `json:"name"` + Age int `json:"age"` + sex Gender + Birth int `json:"time"` + Sex string `json:"sex"` + } + + UserProvider struct { + user map[string]User + } +) + +var ( + DefaultUser = User{ + Id: "0", Name: "Alex Stocks", Age: 31, + // Birth: int(time.Date(1985, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()), + Birth: int(time.Date(1985, 11, 24, 15, 15, 0, 0, time.Local).Unix()), + sex: Gender(MAN), + } + + userMap = UserProvider{user: make(map[string]User)} +) + +func init() { + DefaultUser.Sex = DefaultUser.sex.String() + userMap.user["A000"] = DefaultUser + userMap.user["A001"] = User{Id: "001", Name: "ZhangSheng", Age: 18, sex: MAN} + userMap.user["A002"] = User{Id: "002", Name: "Lily", Age: 20, sex: WOMAN} + userMap.user["A003"] = User{Id: "113", Name: "Moorse", Age: 30, sex: MAN} + for k, v := range userMap.user { + v.Birth = int(time.Now().AddDate(-1*v.Age, 0, 0).Unix()) + v.Sex = userMap.user[k].sex.String() + userMap.user[k] = v + } +} + +func (u *UserProvider) getUser(userId string) (*User, error) { + if user, ok := userMap.user[userId]; ok { + return &user, nil + } + + return nil, fmt.Errorf("invalid user id:%s", userId) +} + +func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error { + var ( + err error + user *User + ) + + println("req:%#v", req) + user, err = u.getUser(req[0].(string)) + if err == nil { + *rsp = *user + println("rsp:%#v", rsp) + } + return err +} + +func (u *UserProvider) GetUser0(id string, name string) (User, error) { + var err error + + println("id:%s, name:%s", id, name) + user, err := u.getUser(id) + if err != nil { + return User{}, err + } + if user.Name != name { + return User{}, perrors.New("name is not " + user.Name) + } + return *user, err +} + +func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) { + var err error + + println("req:%s", req) + t := req[0].([]interface{}) + user, err := u.getUser(t[0].(string)) + if err != nil { + return nil, err + } + println("user:%v", user) + user1, err := u.getUser(t[1].(string)) + if err != nil { + return nil, err + } + println("user1:%v", user1) + + return []User{*user, *user1}, err +} + +func (u *UserProvider) Service() string { + return "com.ikurento.user.UserProvider" +} + +func (u *UserProvider) Version() string { + return "" +} + +func println(format string, args ...interface{}) { + fmt.Printf("\033[32;40m"+format+"\033[0m\n", args...) +} diff --git a/examples/jsonrpc/with-configcenter-go-server/app/version.go b/examples/jsonrpc/with-configcenter-go-server/app/version.go new file mode 100644 index 000000000..c6138584f --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/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/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh new file mode 100644 index 000000000..47fc5e38d --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/bin/load.sh @@ -0,0 +1,144 @@ +#!/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="" + + +PROJECT_HOME="" +OS_NAME=`uname` +if [[ ${OS_NAME} != "Windows" ]]; then + PROJECT_HOME=`pwd` + PROJECT_HOME=${PROJECT_HOME}"/" +fi + +export CONF_PROVIDER_FILE_PATH=${PROJECT_HOME}"TARGET_CONF_FILE" +export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE" + +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 server.yml!" + else + export CONF_PROVIDER_FILE_PATH=${CONF_PROVIDER_FILE_PATH//\.yml/\_$arg\.yml} + fi + if [ ! -f "${CONF_PROVIDER_FILE_PATH}" ];then + echo $CONF_PROVIDER_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 +} + +opt=$1 +case C"$opt" in + Cstart) + start $2 + ;; + Cstop) + stop + ;; + Cterm) + term + ;; + Crestart) + term + start $2 + ;; + Clist) + list + ;; + C*) + usage + ;; +esac + diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/common/app.properties b/examples/jsonrpc/with-configcenter-go-server/assembly/common/app.properties new file mode 100644 index 000000000..dffb755b0 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/common/app.properties @@ -0,0 +1,17 @@ +# dubbogo application configure script +# ****************************************************** +# DESC : application 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 +# ****************************************************** + +TARGET_EXEC_NAME="user_info_server" +# BUILD_PACKAGE="dubbogo-examples/user-info/server/app" +BUILD_PACKAGE="app" + +TARGET_CONF_FILE="conf/server.yml" +TARGET_LOG_CONF_FILE="conf/log.yml" diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/common/build.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/common/build.sh new file mode 100644 index 000000000..15ac904f7 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/common/build.sh @@ -0,0 +1,74 @@ +#!/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 = "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} && go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd - +else + # -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果), + # -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试, + # -w基本没啥损失。-s的损失就有点大了。 + cd ${BUILD_PACKAGE} && 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} +# modify APPLICATION_NAME +# OS=`uname` +# if [[ $OS=="Darwin" ]]; then +if [ "$(uname)" == "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 [ "$(uname)" == "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 [ "$(uname)" == "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/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/linux/dev.sh new file mode 100644 index 000000000..55886f09f --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/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 : 2018-06-24 17:32 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh new file mode 100644 index 000000000..9772ad961 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/linux/release.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=linux +export GOARCH=amd64 + +PROFILE=release + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh new file mode 100644 index 000000000..2fc4a9886 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/linux/test.sh @@ -0,0 +1,29 @@ +#!/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 + +PROFILE=test + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/mac/dev.sh new file mode 100644 index 000000000..5dfa78490 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/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 : 2018-06-24 17:32 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh new file mode 100644 index 000000000..1ec21c7b5 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/mac/release.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=release + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh new file mode 100644 index 000000000..d34914c7d --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/mac/test.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + +set -e + +export GOOS=darwin +export GOARCH=amd64 + +PROFILE=test + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi + diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/windows/dev.sh new file mode 100644 index 000000000..97fbb6f69 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/windows/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 : 2018-06-24 17:34 +# FILE : dev.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh new file mode 100644 index 000000000..782cb10c7 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/windows/release.sh @@ -0,0 +1,29 @@ +#!/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:25 +# FILE : release.sh +# ****************************************************** + + +set -e + +export GOOS=windows +export GOARCH=amd64 + +PROFILE=release + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh b/examples/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh new file mode 100644 index 000000000..2037ddecf --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/assembly/windows/test.sh @@ -0,0 +1,29 @@ +#!/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 + +PROFILE=test + +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 +. ${PROJECT_HOME}/assembly/common/build.sh +fi diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml b/examples/jsonrpc/with-configcenter-go-server/profiles/dev/log.yml new file mode 100644 index 000000000..59fa4279a --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/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/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml b/examples/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml new file mode 100644 index 000000000..5c2a2fe2c --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/profiles/dev/server.yml @@ -0,0 +1,22 @@ +# dubbo server yaml configure file + +# application config + +services: + "UserProvider": + protocol : "jsonrpc" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.properties" diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/release/log.yml b/examples/jsonrpc/with-configcenter-go-server/profiles/release/log.yml new file mode 100644 index 000000000..e0514be02 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/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/jsonrpc/with-configcenter-go-server/profiles/release/server.yml b/examples/jsonrpc/with-configcenter-go-server/profiles/release/server.yml new file mode 100644 index 000000000..82c9fa66a --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/profiles/release/server.yml @@ -0,0 +1,25 @@ +# dubbo server yaml configure file + +# application config + +services: + "UserProvider": + protocol : "jsonrpc" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.properties" + + + diff --git a/examples/jsonrpc/with-configcenter-go-server/profiles/test/log.yml b/examples/jsonrpc/with-configcenter-go-server/profiles/test/log.yml new file mode 100644 index 000000000..baee0b724 --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/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/examples/jsonrpc/with-configcenter-go-server/profiles/test/server.yml b/examples/jsonrpc/with-configcenter-go-server/profiles/test/server.yml new file mode 100644 index 000000000..82c9fa66a --- /dev/null +++ b/examples/jsonrpc/with-configcenter-go-server/profiles/test/server.yml @@ -0,0 +1,25 @@ +# dubbo server yaml configure file + +# application config + +services: + "UserProvider": + protocol : "jsonrpc" + # 相当于dubbo.xml中的interface + interface : "com.ikurento.user.UserProvider" + loadbalance: "random" + warmup: "100" + cluster: "failover" + methods: + - name: "GetUser" + retries: 1 + loadbalance: "random" + +config_center: + protocol: "zookeeper" + address: "127.0.0.1:2181" + group: "dubbo" + config_file: "dubbo.properties" + + + diff --git a/protocol/jsonrpc/http.go b/protocol/jsonrpc/http.go index af65db04b..ffb218da3 100644 --- a/protocol/jsonrpc/http.go +++ b/protocol/jsonrpc/http.go @@ -110,7 +110,7 @@ func (c *HTTPClient) NewRequest(service common.URL, method string, args interfac func (c *HTTPClient) Call(ctx context.Context, service common.URL, req *Request, rsp interface{}) error { // header httpHeader := http.Header{} - httpHeader.Set("Content-Type", "application/json") + httpHeader.Set("Content-Protocol", "application/json") httpHeader.Set("Accept", "application/json") reqTimeout := c.options.HTTPTimeout diff --git a/protocol/jsonrpc/server.go b/protocol/jsonrpc/server.go index a7643dc21..fb8bc4e68 100644 --- a/protocol/jsonrpc/server.go +++ b/protocol/jsonrpc/server.go @@ -100,7 +100,7 @@ func (s *Server) handlePkg(conn net.Conn) { ContentLength: int64(len(body)), Body: ioutil.NopCloser(bytes.NewReader(body)), } - rsp.Header.Del("Content-Type") + rsp.Header.Del("Content-Protocol") rsp.Header.Del("Content-Length") rsp.Header.Del("Timeout") @@ -139,10 +139,10 @@ func (s *Server) handlePkg(conn net.Conn) { reqHeader["HttpMethod"] = r.Method httpTimeout := s.timeout - contentType := reqHeader["Content-Type"] + contentType := reqHeader["Content-Protocol"] if contentType != "application/json" && contentType != "application/json-rpc" { setTimeout(conn, httpTimeout) - r.Header.Set("Content-Type", "text/plain") + r.Header.Set("Content-Protocol", "text/plain") if errRsp := sendErrorResp(r.Header, []byte(perrors.WithStack(err).Error())); errRsp != nil { logger.Warnf("sendErrorResp(header:%#v, error:%v) = error:%s", r.Header, perrors.WithStack(err), errRsp) @@ -258,7 +258,7 @@ func serveRequest(ctx context.Context, ContentLength: int64(len(body)), Body: ioutil.NopCloser(bytes.NewReader(body)), } - rsp.Header.Del("Content-Type") + rsp.Header.Del("Content-Protocol") rsp.Header.Del("Content-Length") rsp.Header.Del("Timeout") for k, v := range header { @@ -282,7 +282,7 @@ func serveRequest(ctx context.Context, ContentLength: int64(len(body)), Body: ioutil.NopCloser(bytes.NewReader(body)), } - rsp.Header.Del("Content-Type") + rsp.Header.Del("Content-Protocol") rsp.Header.Del("Content-Length") rsp.Header.Del("Timeout") for k, v := range header { @@ -418,7 +418,7 @@ func serveRequest(ctx context.Context, ContentLength: int64(len(rspStream)), Body: ioutil.NopCloser(bytes.NewReader(rspStream)), } - delete(header, "Content-Type") + delete(header, "Content-Protocol") delete(header, "Content-Length") delete(header, "Timeout") for k, v := range header { diff --git a/remoting/zookeeper/client.go b/remoting/zookeeper/client.go index 2ef5f7aeb..d1d5f9900 100644 --- a/remoting/zookeeper/client.go +++ b/remoting/zookeeper/client.go @@ -543,7 +543,7 @@ func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) { } z.Unlock() if err != nil { - logger.Errorf("zkClient{%s}.ExistsW(path{%s}) = error{%v}.", z.name, zkPath, perrors.WithStack(err)) + logger.Warnf("zkClient{%s}.ExistsW(path{%s}) = error{%v}.", z.name, zkPath, perrors.WithStack(err)) return nil, perrors.WithMessagef(err, "zk.ExistsW(path:%s)", zkPath) } if !exist { diff --git a/remoting/zookeeper/listener.go b/remoting/zookeeper/listener.go index dcb0c308f..089092d23 100644 --- a/remoting/zookeeper/listener.go +++ b/remoting/zookeeper/listener.go @@ -29,7 +29,6 @@ import ( ) import ( - "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/remoting" ) @@ -50,14 +49,14 @@ func NewZkEventListener(client *ZookeeperClient) *ZkEventListener { func (l *ZkEventListener) SetClient(client *ZookeeperClient) { l.client = client } -func (l *ZkEventListener) listenServiceNodeEvent(zkPath string, listener ...remoting.DataListener) bool { +func (l *ZkEventListener) ListenServiceNodeEvent(zkPath string, listener ...remoting.DataListener) bool { l.wg.Add(1) defer l.wg.Done() var zkEvent zk.Event for { keyEventCh, err := l.client.ExistW(zkPath) if err != nil { - logger.Errorf("existW{key:%s} = error{%v}", zkPath, err) + logger.Warnf("existW{key:%s} = error{%v}", zkPath, err) return false } @@ -125,13 +124,14 @@ func (l *ZkEventListener) handleZkNodeEvent(zkPath string, children []string, li if err != nil { logger.Errorf("Get new node path {%v} 's content error,message is {%v}", newNode, perrors.WithStack(err)) } + if !listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.Add, Content: string(content)}) { continue } // listen l service node go func(node string) { logger.Infof("delete zkNode{%s}", node) - if l.listenServiceNodeEvent(node, listener) { + if l.ListenServiceNodeEvent(node, listener) { logger.Infof("delete content{%s}", n) listener.DataChange(remoting.Event{Path: zkPath, Action: remoting.Del}) } @@ -176,7 +176,7 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi if MaxFailTimes <= failTimes { failTimes = MaxFailTimes } - logger.Errorf("listenDirEvent(path{%s}) = error{%v}", zkPath, err) + logger.Warnf("listenDirEvent(path{%s}) = error{%v}", zkPath, err) // clear the event channel CLEAR: for { @@ -203,7 +203,32 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi } } failTimes = 0 + for _, c := range children { + + // listen l service node + dubboPath := path.Join(zkPath, c) + content, _, err := l.client.Conn.Get(dubboPath) + if err != nil { + logger.Errorf("Get new node path {%v} 's content error,message is {%v}", dubboPath, perrors.WithStack(err)) + } + logger.Infof("Get children!{%s}", dubboPath) + if !listener.DataChange(remoting.Event{Path: dubboPath, Action: remoting.Add, Content: string(content)}) { + continue + } + logger.Infof("listen dubbo service key{%s}", dubboPath) + go func(zkPath string) { + if l.ListenServiceNodeEvent(dubboPath) { + listener.DataChange(remoting.Event{Path: dubboPath, Action: remoting.Del}) + } + logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath) + }(dubboPath) + //liten sub path recursive + go func(zkPath string, listener remoting.DataListener) { + l.listenDirEvent(zkPath, listener) + logger.Warnf("listenDirEvent(zkPath{%s}) goroutine exit now", zkPath) + }(dubboPath, listener) + } select { case zkEvent = <-childEventCh: logger.Warnf("get a zookeeper zkEvent{type:%s, server:%s, path:%s, state:%d-%s, err:%s}", @@ -219,20 +244,80 @@ func (l *ZkEventListener) listenDirEvent(zkPath string, listener remoting.DataLi } } +// +//func (l *ZkEventListener) listenFileEvent(zkPath string, listener remoting.DataListener) { +// l.wg.Add(1) +// defer l.wg.Done() +// +// var ( +// failTimes int +// event chan struct{} +// zkEvent zk.Event +// ) +// event = make(chan struct{}, 4) +// defer close(event) +// for { +// // get current children for a zkPath +// content,_, eventCh, err := l.client.Conn.GetW(zkPath) +// if err != nil { +// failTimes++ +// if MaxFailTimes <= failTimes { +// failTimes = MaxFailTimes +// } +// logger.Errorf("listenFileEvent(path{%s}) = error{%v}", zkPath, err) +// // clear the event channel +// CLEAR: +// for { +// select { +// case <-event: +// default: +// break CLEAR +// } +// } +// l.client.RegisterEvent(zkPath, &event) +// select { +// case <-time.After(timeSecondDuration(failTimes * ConnDelay)): +// l.client.UnregisterEvent(zkPath, &event) +// continue +// case <-l.client.Done(): +// l.client.UnregisterEvent(zkPath, &event) +// logger.Warnf("client.done(), listen(path{%s}) goroutine exit now...", zkPath) +// return +// case <-event: +// logger.Infof("get zk.EventNodeDataChange notify event") +// l.client.UnregisterEvent(zkPath, &event) +// l.handleZkNodeEvent(zkPath, nil, listener) +// continue +// } +// } +// failTimes = 0 +// +// select { +// case zkEvent = <-eventCh: +// logger.Warnf("get a zookeeper zkEvent{type:%s, server:%s, path:%s, state:%d-%s, err:%s}", +// zkEvent.Type.String(), zkEvent.Server, zkEvent.Path, zkEvent.State, StateToString(zkEvent.State), zkEvent.Err) +// +// l.handleZkNodeEvent(zkEvent.Path, children, listener) +// case <-l.client.Done(): +// logger.Warnf("client.done(), listen(path{%s}) goroutine exit now...", zkPath) +// return +// } +// } +//} + func timeSecondDuration(sec int) time.Duration { return time.Duration(sec) * time.Second } // this func is invoked by ZkConsumerRegistry::Registe/ZkConsumerRegistry::get/ZkConsumerRegistry::getListener -// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> listenServiceNodeEvent +// registry.go:Listen -> listenServiceEvent -> listenDirEvent -> ListenServiceNodeEvent // | -// --------> listenServiceNodeEvent +// --------> ListenServiceNodeEvent func (l *ZkEventListener) ListenServiceEvent(zkPath string, listener remoting.DataListener) { var ( - err error - dubboPath string - children []string - serviceURL common.URL + err error + dubboPath string + children []string ) l.pathMapLock.Lock() @@ -251,7 +336,7 @@ func (l *ZkEventListener) ListenServiceEvent(zkPath string, listener remoting.Da children, err = l.client.GetChildren(zkPath) if err != nil { children = nil - logger.Errorf("fail to get children of zk path{%s}", zkPath) + logger.Warnf("fail to get children of zk path{%s}", zkPath) } for _, c := range children { @@ -266,13 +351,12 @@ func (l *ZkEventListener) ListenServiceEvent(zkPath string, listener remoting.Da continue } logger.Infof("listen dubbo service key{%s}", dubboPath) - go func(zkPath string, serviceURL common.URL) { - if l.listenServiceNodeEvent(dubboPath) { - logger.Debugf("delete serviceUrl{%s}", serviceURL) + go func(zkPath string) { + if l.ListenServiceNodeEvent(dubboPath) { listener.DataChange(remoting.Event{Path: dubboPath, Action: remoting.Del}) } logger.Warnf("listenSelf(zk path{%s}) goroutine exit now", zkPath) - }(dubboPath, serviceURL) + }(dubboPath) } logger.Infof("listen dubbo path{%s}", zkPath) -- GitLab