[ 
https://issues.apache.org/jira/browse/SCB-941?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16633259#comment-16633259
 ] 

ASF GitHub Bot commented on SCB-941:
------------------------------------

little-cui closed pull request #452: SCB-941 Add an example of multiple 
datacenters discovery
URL: https://github.com/apache/incubator-servicecomb-service-center/pull/452
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/README.md b/README.md
index 2e1e7001..d7302b92 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 Apache ServiceComb (incubating) Service-Center is a Restful based 
service-registry that provides micro-services discovery and micro-service 
management. It is based on Open API format and provides features like 
service-discovery, fault-tolerance, dynamic routing, notify subscription and 
scalable by design. It has high performance cache design and separate entity 
management for micro-services and their instances. It provides out of box 
support for metrics and tracing. It has a web portal to manage the 
micro-services.  
 
 ## Features
- - **Open API**: API doc(Open API format) management for microservice
+ - **[`Open API`](/server/core/swagger/v4.yaml)**: API doc(Open API format) 
management for microservice
  - **Metadata**: Metadata management for both microservice and microservice 
instance
  - **Dependency**: Microservice dependency management
  - **Seperated**: Seperated microservice and microservice instance entity 
management
@@ -12,12 +12,13 @@ Apache ServiceComb (incubating) Service-Center is a Restful 
based service-regist
  - **Security**: White and back list configuration for service discovery
  - **Discovery**: Support query instance by criteria 
  - **Subscribe**: Use web socket to notify client about instance change events
- - **Portal**: Awesome  [web portal](/frontend)
+ - **[`Portal`](/frontend)**: Awesome web portal
  - **Fault tolerance**: Multiple fault tolerance mechanism and design in the 
architecture
  - **Performance**: Performance/Caching design
- - **Metrics**: Able to expose Prometheus metric API automatically
- - **Tracing**: Able to report tracing data to Zipkin server
- - **Multi Datacenter**: Additional layer of abstraction to clusters deployed 
in multiple datacenters
+ - **[`Metrics`](/docs/integration-grafana.md)**: Able to expose Prometheus 
metric API automatically
+ - **[`Tracing`](/docs/tracing.md)**: Able to report tracing data to Zipkin 
server
+ - **[`Multi Datacenter`](/docs/multidcs.md)**: Additional layer of 
abstraction to clusters deployed in multiple datacenters
+ - **[`Dynmaic Plug-in`](/docs/plugin.md)**: Able to load custom 
authentication, tls and other dynamic libraries
  
 ## Documentation
 
diff --git a/docs/README.md b/docs/README.md
index 51a5ce20..b94d0ab3 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -6,7 +6,7 @@
 
 - [Api 
Documentation](https://rawcdn.githack.com/ServiceComb/service-center/master/docs/api-docs.html),
 Swagger 
[`v4`](/server/core/swagger/v4.yaml)|[`v3`](/server/core/swagger/v3.yaml)
-- [Plug-in Extension](/server/plugin/README.md)
+- [Plug-in Extension](/docs/plugin.md)
 - [Command Line Client](/scctl/README.md)
 
 #### [Docker Image Guide](/scripts/docker) 
@@ -23,6 +23,8 @@ Swagger 
[`v4`](/server/core/swagger/v4.yaml)|[`v3`](/server/core/swagger/v3.yaml
 - [In Kubernetes Cluster](/examples/infrastructures/k8s)
 - [In VMs](/docs/sc-cluster.md)
 - [Deploy with TLS](/docs/security-tls.md)
+- [Multiple Datacenters](/docs/multidcs.md)
+- [Access Distinct Kubernetes clusters](/docs/aggregate.md)
 
 #### Monitoring Service-Center
 
diff --git a/docs/aggregate.md b/docs/aggregate.md
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/kubeclusters.PNG b/docs/kubeclusters.PNG
new file mode 100644
index 00000000..de1f8398
Binary files /dev/null and b/docs/kubeclusters.PNG differ
diff --git a/docs/multidcs.PNG b/docs/multidcs.PNG
new file mode 100644
index 00000000..f5678a60
Binary files /dev/null and b/docs/multidcs.PNG differ
diff --git a/docs/multidcs.md b/docs/multidcs.md
new file mode 100644
index 00000000..ecba0eac
--- /dev/null
+++ b/docs/multidcs.md
@@ -0,0 +1,126 @@
+Multiple Datacenters
+-------
+
+## ServiceCenter Aggregate Architecture
+
+Now, service center has supported multiple datacenters deployment. 
+Its architecture likes below.
+
+![architecture](/docs/multidcs.PNG)
+
+As shown in the figure, we deploy an SC(Service-Center) cluster independently 
under each DC(datacenter).
+Each SC cluster manages the micro-service instances under the DC under which 
it belongs, and the DCs are
+isolated from each other. Another implementation of the discovery plug-in, 
`Service-Center Aggregate` service, can
+access multiple SC instances and periodically pull up micro-service instance 
information so that if some
+micro-services can request aggregate, cross-DCs can be implemented using the 
same API as SC cluster.
+
+## Quick Start
+
+Let's assume you want to install 2 clusters of Service-Center in different DCs 
with following details.
+
+| Cluster | Datacenter  | Address     |  
+| :-----: | :---------: | :---------: |  
+| sc-1    | dc-1        | 10.12.0.1   |   
+| sc-2    | dc-2        | 10.12.0.2   | 
+
+you can follow [this](/docs/sc-cluster.md) guide to install Service-Center in 
cluster mode. After that,
+we can deploy a Service-Center Aggregate service now. 
+
+##### Start Service-Center Aggregate
+
+Edit the configuration of the ip/port on which SC aggregate will run, we 
assume you launch it at 10.12.0.3.
+```bash
+vi conf/app.conf
+# Replace the below values
+httpaddr = 10.12.0.3
+discovery_plugin = servicecenter
+registry_plugin = buildin
+self_register = 0
+manager_cluster = "sc-1=http://10.12.0.1:30100,sc-2=http://10.12.0.2:30100";
+
+# Start the Service-center
+./service-center
+```
+
+Note: Please don't run start.sh as it will also start the etcd.
+
+##### Confirm the service is OK
+
+We recommend that you use [`scctl`](/scctl/README.md), and using
+[`cluster command`](/scctl/pkg/plugin/README.md#cluster-options)
+which makes it very convenient to verify OK.
+
+```bash
+scctl --addr http://10.12.0.3:30100 get cluster
+#   CLUSTER |        ENDPOINTS         
+# +---------+-------------------------+
+#   sc-1    | http://10.12.0.1:30100  
+#   sc-2    | http://10.12.0.2:30100
+```
+
+## Example
+
+Here we show an example of multiple datacenters access, where we use an 
+[`example`](https://github.com/go-chassis/go-chassis/tree/master/examples/discovery)
+of the [`go-chassis`](https://github.com/go-chassis/go-chassis) project, 
assuming that below.
+
+| Microservice | Datacenter  | Address     |  
+| :-----:      | :---------: | :---------: |  
+| Client       | dc-1        | 10.12.0.4   |   
+| Server       | dc-2        | 10.12.0.5   |
+
+##### Start Server
+
+Edit the configuration of the ip/port on which Server will register.
+```
+vi examples/discovery/server/conf/chassis.yaml
+```
+Replace the below values
+```yaml
+cse:
+  service:
+    registry:
+      type: servicecenter
+      address: http://10.12.0.2:30100 # the address of SC in dc-2
+```
+
+Run the Server
+```bash
+go run examples/discovery/server/main.go
+```
+##### Start Client
+
+Edit the configuration of the ip/port on which Client will register and 
discover.
+```bash
+vi examples/discovery/client/conf/chassis.yaml
+```
+Replace the below values
+```yaml
+cse:
+  service:
+    registry:
+      registrator:
+        type: servicecenter
+        address: http://10.12.0.1:30100 # the address of SC in dc-1
+      serviceDiscovery:
+        type: servicecenter
+        address: http://10.12.0.3:30100 # the address of SC Aggregate
+```
+
+Run the Client
+```bash
+go run examples/discovery/client/main.go
+```
+
+##### Confirm the multiple datacenters discovery is OK
+
+Since client is not a service, we check its running log.
+```
+2018-09-29 10:30:25.556 +08:00 INFO registry/bootstrap.go:69 Register [Client] 
success
+...
+2018-09-29 10:30:25.566 +08:00 WARN servicecenter/servicecenter.go:324 
55c783c5c38e11e8951f0a58ac00011d Get instances from remote, key: default Server
+2018-09-29 10:30:25.566 +08:00 INFO client/client_manager.go:86 Create client 
for highway:Server:127.0.0.1:8082
+...
+2018/09/29 10:30:25 AddEmploy ------------------------------ 
employList:<name:"One" phone:"15989351111" > 
+```
+
diff --git a/server/plugin/README.md b/docs/plugin.md
similarity index 65%
rename from server/plugin/README.md
rename to docs/plugin.md
index 5ca70cff..8041df3e 100644
--- a/server/plugin/README.md
+++ b/docs/plugin.md
@@ -6,13 +6,13 @@
 1. All plugin interface files are in [infra](/server/infra) package
 
 ## Plug-in names
-1. auth, Customize authentication of service-center.
-1. uuid, Customize micro-service/instance id format.
-1. auditlog, Customize audit log for any change done to the service-center.
-1. cipher, Customize encryption and decryption of TLS certificate private key 
password.
-1. quota, Customize quota for instance registry.
-1. tracing, Customize tracing data reporter.
-1. tls, Customize loading the tls certificates in server
+1. **auth**: Customize authentication of service-center.
+1. **uuid**: Customize micro-service/instance id format.
+1. **auditlog**: Customize audit log for any change done to the service-center.
+1. **cipher**: Customize encryption and decryption of TLS certificate private 
key password.
+1. **quota**: Customize quota for instance registry.
+1. **tracing**: Customize tracing data reporter.
+1. **tls**: Customize loading the tls certificates in server
 
 ## Example: an authentication plug-in
 
diff --git a/server/plugin/pkg/tracing/buildin/README.md b/docs/tracing.md
similarity index 90%
rename from server/plugin/pkg/tracing/buildin/README.md
rename to docs/tracing.md
index 140203e5..e6c7c19d 100644
--- a/server/plugin/pkg/tracing/buildin/README.md
+++ b/docs/tracing.md
@@ -7,7 +7,7 @@ trace_plugin='buildin' # or empty
 
 ## To zipkin server
 
-[zipkin](/docs/tracing-server.PNG)
+![zipkin](/docs/tracing-server.PNG)
 
 ### Add the zipkin server endpoint
 ```
@@ -21,7 +21,7 @@ export TRACING_SERVER_ADDRESS=http://127.0.0.1:9411 # zipkin 
server endpoint
 
 ## To file
 
-[file](/docs/tracing-file.PNG)
+![file](/docs/tracing-file.PNG)
 
 ### Customize the path of trace data file
 ```
diff --git a/examples/infrastructures/k8s/service-center/templates/rbac.yaml 
b/examples/infrastructures/k8s/service-center/templates/rbac.yaml
index fa1a0e9e..ab34413d 100644
--- a/examples/infrastructures/k8s/service-center/templates/rbac.yaml
+++ b/examples/infrastructures/k8s/service-center/templates/rbac.yaml
@@ -1,4 +1,4 @@
-{{- if eq .Values.sc.discovery.type "k8s" -}}
+{{- if or (eq .Values.sc.discovery.type "k8s") (eq .Values.sc.discovery.type 
"aggregate") -}}
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
diff --git a/server/plugin/pkg/discovery/cache_kv.go 
b/server/plugin/pkg/discovery/cache_kv.go
index ff8c6424..b9981cfc 100644
--- a/server/plugin/pkg/discovery/cache_kv.go
+++ b/server/plugin/pkg/discovery/cache_kv.go
@@ -108,20 +108,27 @@ func (c *KvCache) getPrefixKey(arr *[]*KeyValue, prefix 
string) (count int) {
                return 0
        }
 
-       tmp := make([]*KeyValue, 0, len(keysRef))
+       // TODO support sort option
+       if arr == nil {
+               for key := range keysRef {
+                       if n := c.getPrefixKey(nil, key); n > 0 {
+                               count += n
+                               continue
+                       }
+                       count++
+               }
+               return
+       }
+
        for key, val := range keysRef {
                if n := c.getPrefixKey(arr, key); n > 0 {
                        count += n
                        continue
                }
-               tmp = append(tmp, val)
+               *arr = append(*arr, val)
                count++
        }
-       if arr != nil {
-               // TODO support sort option
-               *arr = append(*arr, tmp...)
-       }
-       return count
+       return
 }
 
 func (c *KvCache) addPrefixKey(key string, val *KeyValue) {
diff --git a/server/plugin/pkg/discovery/cache_test.go 
b/server/plugin/pkg/discovery/cache_test.go
index 741784b4..2ff70157 100644
--- a/server/plugin/pkg/discovery/cache_test.go
+++ b/server/plugin/pkg/discovery/cache_test.go
@@ -130,3 +130,32 @@ func TestKvCache_Get(t *testing.T) {
                }
        }
 }
+
+func BenchmarkKvCache_GetAll1(b *testing.B) {
+       c := NewKvCache("test", Configure())
+       c.Put("/a/b/c/d/e/1", &KeyValue{Version: 1})
+       c.Put("/a/b/c/d/e/2", &KeyValue{Version: 2})
+       c.Put("/a/b/d/d/f/3", &KeyValue{Version: 3})
+       c.Put("/a/b/e/d/g/4", &KeyValue{Version: 4})
+       b.ResetTimer()
+       for i := 0; i < b.N; i++ {
+               _ = c.GetAll(nil)
+       }
+       b.ReportAllocs()
+       // 1000000            1269 ns/op               0 B/op          0 
allocs/op
+}
+
+func BenchmarkKvCache_GetAll2(b *testing.B) {
+       c := NewKvCache("test", Configure())
+       c.Put("/a/b/c/d/e/1", &KeyValue{Version: 1})
+       c.Put("/a/b/c/d/e/2", &KeyValue{Version: 2})
+       c.Put("/a/b/d/d/f/3", &KeyValue{Version: 3})
+       c.Put("/a/b/e/d/g/4", &KeyValue{Version: 4})
+       b.ResetTimer()
+       var arr []*KeyValue
+       for i := 0; i < b.N; i++ {
+               _ = c.GetAll(&arr)
+       }
+       b.ReportAllocs()
+       // 1000000            2784 ns/op             173 B/op          0 
allocs/op
+}
diff --git a/server/plugin/pkg/discovery/cacher_test.go 
b/server/plugin/pkg/discovery/cacher_test.go
new file mode 100644
index 00000000..d534a900
--- /dev/null
+++ b/server/plugin/pkg/discovery/cacher_test.go
@@ -0,0 +1,60 @@
+// 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 discovery
+
+import (
+       
"github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+       "testing"
+)
+
+func TestNewCommonCacher(t *testing.T) {
+       var e KvEvent
+       cfg := Configure()
+       cache := NewKvCache("test", cfg)
+       cacher := NewCommonCacher(cfg, cache)
+
+       if cacher.Cache() != cache {
+               t.Fatalf("TestNewCommonCacher failed")
+       }
+       select {
+       case <-cacher.Ready():
+               t.Fatalf("TestNewCommonCacher failed")
+       default:
+               cacher.Run()
+       }
+       select {
+       case <-cacher.Ready():
+       default:
+               t.Fatalf("TestNewCommonCacher failed")
+       }
+
+       cacher.Notify(proto.EVT_CREATE, "/a", &KeyValue{Version: 1})
+       if e.Type == proto.EVT_CREATE || cache.Get("/a").Version != 1 {
+               t.Fatalf("TestNewCommonCacher failed")
+       }
+       cfg.WithEventFunc(func(evt KvEvent) {
+               e = evt
+       })
+       cacher.Notify(proto.EVT_CREATE, "/a", &KeyValue{Version: 1})
+       if e.Type != proto.EVT_CREATE || cache.Get("/a").Version != 1 {
+               t.Fatalf("TestNewCommonCacher failed")
+       }
+       cacher.Notify(proto.EVT_DELETE, "/a", &KeyValue{Version: 1})
+       if e.Type != proto.EVT_DELETE || cache.Get("/a") != nil {
+               t.Fatalf("TestNewCommonCacher failed")
+       }
+       cacher.Stop()
+}
diff --git a/server/plugin/pkg/discovery/types.go 
b/server/plugin/pkg/discovery/types.go
index 0c7c9bfc..aeed4744 100644
--- a/server/plugin/pkg/discovery/types.go
+++ b/server/plugin/pkg/discovery/types.go
@@ -64,7 +64,7 @@ type KeyValue struct {
 
 func (kv *KeyValue) String() string {
        b, _ := json.Marshal(kv.Value)
-       return fmt.Sprintf("{key: '%s', value: '%s', version: %d}",
+       return fmt.Sprintf("{key: '%s', value: %s, version: %d}",
                util.BytesToStringWithNoCopy(kv.Key), 
util.BytesToStringWithNoCopy(b), kv.Version)
 }
 
diff --git a/server/plugin/pkg/discovery/types_test.go 
b/server/plugin/pkg/discovery/types_test.go
index 5d54c5b4..69dd8b88 100644
--- a/server/plugin/pkg/discovery/types_test.go
+++ b/server/plugin/pkg/discovery/types_test.go
@@ -34,4 +34,9 @@ func TestTypes(t *testing.T) {
        if TypeError.String() != "TypeError" {
                t.Fatalf("TestTypes failed")
        }
+
+       var kv KeyValue
+       if kv.String() != "{key: '', value: null, version: 0}" {
+               t.Fatalf("TestTypes failed, %v", kv.String())
+       }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Support multiple datacenter deployment
> --------------------------------------
>
>                 Key: SCB-941
>                 URL: https://issues.apache.org/jira/browse/SCB-941
>             Project: Apache ServiceComb
>          Issue Type: New Feature
>          Components: Service-Center
>            Reporter: little-cui
>            Assignee: little-cui
>            Priority: Major
>             Fix For: service-center-1.1.0
>
>




--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to