diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..cb96f044b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,21 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+## In what area(s)?
+
+
+
+> /area runtime
+> /area operator
+> /area placement
+> /area docs
+> /area test-and-release
+
+## Describe the feature
+
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 000000000..73ca425dc
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,28 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Java CI with Maven
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ - name: Build with Maven
+ run: mvn clean install -DskipTests -B -V
+ && sh ./tools/check_format.sh
+ && mvn clean test
+ - name: Codecov
+ uses: codecov/codecov-action@v1
diff --git a/.travis.yml b/.travis.yml
index cb53cacfe..e8363e468 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,8 @@
language: java
sudo: false
+dist: trusty
+
jdk:
- oraclejdk8
@@ -12,4 +14,4 @@ script:
- sh ./tools/check_format.sh
after_success:
-- bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
+- bash <(curl -s https://codecov.io/bash)
diff --git a/README.md b/README.md
index c37c604a2..e589ab84e 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
# SOFARegistry
-[![Build Status](https://travis-ci.com/alipay/sofa-registry.svg?branch=master)](https://travis-ci.com/alipay/sofa-registry)
+[![Java CI with Maven](https://github.com/sofastack/sofa-registry/actions/workflows/maven.yml/badge.svg)](https://github.com/sofastack/sofa-registry/actions/workflows/maven.yml)
![license](https://img.shields.io/badge/license-Apache--2.0-green.svg)
-[![Coverage Status](https://codecov.io/gh/alipay/sofa-registry/branch/master/graph/badge.svg)](https://codecov.io/gh/alipay/sofa-registry)
-![maven](https://img.shields.io/github/release/alipay/sofa-registry.svg)
+[![Coverage Status](https://codecov.io/gh/alipay/sofa-registry/branch/master/graph/badge.svg)](https://codecov.io/gh/sofastack/sofa-registry)
+![maven](https://img.shields.io/github/release/sofastack/sofa-registry.svg)
SOFARegistry 是蚂蚁金服开源的一个生产级、高时效、高可用的服务注册中心。SOFARegistry 最早源自于淘宝的 ConfigServer,十年来,随着蚂蚁金服的业务发展,注册中心架构已经演进至第五代。目前 SOFARegistry 不仅全面服务于蚂蚁金服的自有业务,还随着蚂蚁金融科技服务众多合作伙伴,同时也兼容开源生态。SOFARegistry 采用 AP 架构,支持秒级时效性推送,同时采用分层架构支持无限水平扩展。
-## 功能特性
+## 功能特性
- 支持服务发布与服务订阅
- 支持服务变更时的主动推送
diff --git a/client/all/pom.xml b/client/all/pom.xml
index 9ab6a12dd..e39f2d502 100644
--- a/client/all/pom.xml
+++ b/client/all/pom.xml
@@ -6,7 +6,7 @@
com.alipay.sofa
registry-client-all
- 5.2.0-SNAPSHOT
+ 5.4.5
${project.groupId}:${project.artifactId}
http://github.com/alipay/sofa-registry
@@ -56,7 +56,7 @@
3.3.6
1.5.2
1.0.12
- 4.1.25.Final
+ 4.1.42.Final
1.7.21
../../
diff --git a/client/api/pom.xml b/client/api/pom.xml
index b4f43b84b..996a538c0 100644
--- a/client/api/pom.xml
+++ b/client/api/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-client-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/client/impl/pom.xml b/client/impl/pom.xml
index e9a54b4c5..769c95d4a 100644
--- a/client/impl/pom.xml
+++ b/client/impl/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-client-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/DefaultRegistryClientTest.java b/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/DefaultRegistryClientTest.java
index 183ebb4ec..aba3677dc 100644
--- a/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/DefaultRegistryClientTest.java
+++ b/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/DefaultRegistryClientTest.java
@@ -16,6 +16,17 @@
*/
package com.alipay.sofa.registry.client.provider;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import com.alipay.sofa.registry.client.api.ConfigDataObserver;
import com.alipay.sofa.registry.client.api.Configurator;
import com.alipay.sofa.registry.client.api.Publisher;
@@ -31,16 +42,6 @@
import com.alipay.sofa.registry.core.model.PublisherRegister;
import com.alipay.sofa.registry.core.model.ScopeEnum;
import com.alipay.sofa.registry.core.model.SubscriberRegister;
-import org.junit.After;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
/**
* The type Default registry client test.
@@ -89,7 +90,7 @@ public void registerPublisher() throws InterruptedException {
defaultPublisher.republish("republish test");
- Thread.sleep(500L);
+ Thread.sleep(2000L);
// register success when republish
assertTrue(defaultPublisher.isRegistered());
}
@@ -111,7 +112,7 @@ public void handleData(String dataId, UserData data) {
assertNotNull(subscriber);
assertEquals(dataId, subscriber.getDataId());
- Thread.sleep(500L);
+ Thread.sleep(2000L);
RegisterCache registerCache = registryClient.getRegisterCache();
@@ -142,7 +143,7 @@ public void handleData(String dataId, ConfigData configData) {
assertNotNull(configurator);
assertEquals(dataId, configurator.getDataId());
- Thread.sleep(500L);
+ Thread.sleep(2000L);
RegisterCache registerCache = registryClient.getRegisterCache();
@@ -164,7 +165,7 @@ public void unregisterSinglePublisherTest() throws InterruptedException {
int unregisterCount = registryClient.unregister(dataId, null, RegistryType.PUBLISHER);
assertEquals(1, unregisterCount);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
Publisher temp = registryClient.getRegisterCache().getPublisherByRegistId(
publisher.getRegistId());
@@ -185,7 +186,7 @@ public void unregisterSingleSubscriberTest() throws InterruptedException {
int unregisterCount = registryClient.unregister(dataId, null, RegistryType.SUBSCRIBER);
assertEquals(1, unregisterCount);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
Subscriber temp = registryClient.getRegisterCache().getSubscriberByRegistId(
subscriber.getRegistId());
@@ -206,7 +207,7 @@ public void unregisterSingleConfiguratorTest() throws InterruptedException {
int unregisterCount = registryClient.unregister(dataId, null, RegistryType.CONFIGURATOR);
assertEquals(1, unregisterCount);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
Subscriber temp = registryClient.getRegisterCache().getSubscriberByRegistId(
configurator.getRegistId());
@@ -236,13 +237,13 @@ public void unregisterMultiTest() throws InterruptedException {
Subscriber subscriber2 = registryClient.register(subscriberRegistration2);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
// 2. unregister publisher
int unregisterCount = registryClient.unregister(dataId, null, RegistryType.PUBLISHER);
assertEquals(2, unregisterCount);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
// 3. check publisher register cache
RegisterCache registerCache = registryClient.getRegisterCache();
@@ -256,7 +257,7 @@ public void unregisterMultiTest() throws InterruptedException {
unregisterCount = registryClient.unregister(dataId, null, RegistryType.SUBSCRIBER);
assertEquals(2, unregisterCount);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
// 5. check subscriber register cache
Subscriber tempSub = registerCache.getSubscriberByRegistId(subscriber1.getRegistId());
diff --git a/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/RegisterOrderTest.java b/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/RegisterOrderTest.java
index 90117a8aa..2e23dd731 100644
--- a/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/RegisterOrderTest.java
+++ b/client/impl/src/test/java/com/alipay/sofa/registry/client/provider/RegisterOrderTest.java
@@ -16,6 +16,20 @@
*/
package com.alipay.sofa.registry.client.provider;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import com.alipay.sofa.registry.client.api.Publisher;
import com.alipay.sofa.registry.client.api.Subscriber;
import com.alipay.sofa.registry.client.api.SubscriberDataObserver;
@@ -26,19 +40,6 @@
import com.alipay.sofa.registry.core.model.DataBox;
import com.alipay.sofa.registry.core.model.PublisherRegister;
import com.alipay.sofa.registry.core.model.SubscriberRegister;
-import org.junit.After;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
/**
*
@@ -126,7 +127,7 @@ public void publishAndUnregister() throws InterruptedException {
// step 1
Publisher publisher = registryClient.register(new PublisherRegistration(dataId), data);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
String registId = publisher.getRegistId();
PublisherRegister publisherRegister = mockServer.queryPubliser(registId);
@@ -137,7 +138,7 @@ public void publishAndUnregister() throws InterruptedException {
// step 2
publisher.unregister();
- Thread.sleep(500L);
+ Thread.sleep(2000L);
assertNull(mockServer.queryPubliser(registId));
@@ -151,7 +152,7 @@ public void publishAndRefused() throws InterruptedException {
// step 1
Publisher publisher = registryClient.register(new PublisherRegistration(data), data);
- Thread.sleep(500L);
+ Thread.sleep(2000L);
String registId = publisher.getRegistId();
PublisherRegister publisherRegister = mockServer.queryPubliser(registId);
@@ -182,7 +183,7 @@ public void handleData(String dataId, UserData data) {
Subscriber subscriber = registryClient.register(new SubscriberRegistration(dataId,
dataObserver));
- Thread.sleep(500L);
+ Thread.sleep(2000L);
String registId = subscriber.getRegistId();
SubscriberRegister subscriberRegister = mockServer.querySubscriber(registId);
@@ -191,7 +192,7 @@ public void handleData(String dataId, UserData data) {
// step 2
subscriber.unregister();
- Thread.sleep(500L);
+ Thread.sleep(2000L);
assertNull(mockServer.queryPubliser(registId));
@@ -211,7 +212,7 @@ public void handleData(String dataId, UserData data) {
Subscriber subscriber = registryClient.register(new SubscriberRegistration(
"subscribeAndRefused", dataObserver));
- Thread.sleep(500L);
+ Thread.sleep(2000L);
String registId = subscriber.getRegistId();
SubscriberRegister subscriberRegister = mockServer.querySubscriber(registId);
diff --git a/client/log/pom.xml b/client/log/pom.xml
index b41fb3f47..546462dbb 100644
--- a/client/log/pom.xml
+++ b/client/log/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-client-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/client/pom.xml b/client/pom.xml
index ea36b1f84..1bef3c48c 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -7,7 +7,7 @@
com.alipay.sofa
registry-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
diff --git a/core/pom.xml b/core/pom.xml
index e01707058..39b8e57ba 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/pom.xml b/pom.xml
index 8d1e42280..8d0e95d58 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,11 +2,11 @@
+
4.0.0
-
com.alipay.sofa
registry-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
pom
${project.groupId}:${project.artifactId}
@@ -59,7 +59,7 @@
1.8
1.8
UTF-8
- 1.5.2
+ 1.6.2
2.6
18.0
1.0.12
@@ -67,24 +67,30 @@
5.0.2
${junit.version}.2
1.0.2
- 3.3.6
- 4.1.25.Final
+ 3.3.8
+ 4.1.42.Final
2.26
3.5.1
1.7.21
1.5.2
1.10.19
1.6.6
- 1.2.4
+ 1.3.5.Alpha1
4.0.2
2.4
- 9.4.12.v20180830
+ 9.4.19.v20190610
+ 6.4.6
${user.dir}
-Dnetwork_interface_denylist=docker0
+
+ org.slf4j
+ jul-to-slf4j
+ 1.7.9
+
org.springframework.boot
spring-boot-starter-parent
@@ -307,6 +313,12 @@
${metrics.version}
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
junit
@@ -332,6 +344,11 @@
${powermock.version}
test
+
+ org.rocksdb
+ rocksdbjni
+ ${rocksdbjni.version}
+
@@ -396,6 +413,9 @@
org.apache.maven.plugins
maven-surefire-plugin
2.21.0
+
+ once
+
org.jacoco
diff --git a/server/common/model/pom.xml b/server/common/model/pom.xml
index d87c55c92..49734dd14 100644
--- a/server/common/model/pom.xml
+++ b/server/common/model/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-common
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/CommonResponse.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/CommonResponse.java
index e85455adf..72f7d5591 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/CommonResponse.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/CommonResponse.java
@@ -108,4 +108,16 @@ public String getMessage() {
public void setMessage(String message) {
this.message = message;
}
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("CommonResponse{");
+ sb.append("success=").append(success);
+ sb.append(", message='").append(message).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/DatumSnapshotRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/DatumSnapshotRequest.java
new file mode 100644
index 000000000..0b517fa61
--- /dev/null
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/DatumSnapshotRequest.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.alipay.sofa.registry.common.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.alipay.sofa.registry.common.model.store.Publisher;
+
+/**
+ *
+ * @author shangyu.wh
+ * @version $Id: DatumSnapshotRequest.java, v 0.1 2019-05-30 11:09 shangyu.wh Exp $
+ */
+public class DatumSnapshotRequest implements Serializable {
+
+ private static final long serialVersionUID = 2193212935059863551L;
+
+ private final String connectId;
+
+ private final String dataServerIp;
+
+ private final List publishers;
+
+ public DatumSnapshotRequest(String connectId, String dataServerIp, List publishers) {
+ this.connectId = connectId;
+ this.dataServerIp = dataServerIp;
+ this.publishers = publishers;
+ }
+
+ /**
+ * Getter method for property connectId.
+ *
+ * @return property value of connectId
+ */
+ public String getConnectId() {
+ return connectId;
+ }
+
+ /**
+ * Getter method for property dataServerIp.
+ *
+ * @return property value of dataServerIp
+ */
+ public String getDataServerIp() {
+ return dataServerIp;
+ }
+
+ /**
+ * Getter method for property publishers.
+ *
+ * @return property value of publishers
+ */
+ public List getPublishers() {
+ return publishers;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("DatumSnapshotRequest{");
+ sb.append("connectId='").append(connectId).append('\'');
+ sb.append(", dataServerIp='").append(dataServerIp).append('\'');
+ sb.append(", publishers.size=").append(publishers.size());
+ sb.append('}');
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/PublisherDigestUtil.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/PublisherDigestUtil.java
new file mode 100644
index 000000000..67ad72236
--- /dev/null
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/PublisherDigestUtil.java
@@ -0,0 +1,50 @@
+/*
+ * 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 com.alipay.sofa.registry.common.model;
+
+import java.util.Collection;
+
+import com.alipay.sofa.registry.common.model.store.Publisher;
+
+/**
+ *
+ * @author kezhu.wukz
+ * @author shangyu.wh
+ * @version $Id: PublisherDigestUtil.java, v 0.1 2019-05-30 20:58 shangyu.wh Exp $
+ */
+public class PublisherDigestUtil {
+
+ public static long getDigestValueSum(Collection publishers) {
+ long digest = 0L;
+ if (publishers != null && !publishers.isEmpty()) {
+ for (Publisher publisher : publishers) {
+ digest += getDigestValue(publisher);
+ }
+ }
+ return digest;
+ }
+
+ public static long getDigestValue(Publisher publisher) {
+ String registerId = publisher.getRegisterId();
+ Long version = publisher.getVersion();
+ long registerTimestamp = publisher.getRegisterTimestamp();
+ long result = registerId != null ? registerId.hashCode() : 0;
+ result = 31 * result + (version != null ? version.hashCode() : 0);
+ result = 31 * result + (int) (registerTimestamp ^ (registerTimestamp >>> 32));
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/RenewDatumRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/RenewDatumRequest.java
new file mode 100644
index 000000000..603c40fb3
--- /dev/null
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/RenewDatumRequest.java
@@ -0,0 +1,82 @@
+/*
+ * 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 com.alipay.sofa.registry.common.model;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author shangyu.wh
+ * @author kezhu.wukz
+ * @version $Id: RenewRequest.java, v 0.1 2019-05-30 10:58 shangyu.wh Exp $
+ */
+public class RenewDatumRequest implements Serializable {
+
+ private static final long serialVersionUID = 683097441984338311L;
+
+ private final String connectId;
+
+ private final String dataServerIP;
+
+ private final String digestSum;
+
+ public RenewDatumRequest(String connectId, String dataServerIP, String digestSum) {
+ this.connectId = connectId;
+ this.dataServerIP = dataServerIP;
+ this.digestSum = digestSum;
+ }
+
+ /**
+ * Getter method for property connectId.
+ *
+ * @return property value of connectId
+ */
+ public String getConnectId() {
+ return connectId;
+ }
+
+ /**
+ * Getter method for property dataServerIP.
+ *
+ * @return property value of dataServerIP
+ */
+ public String getDataServerIP() {
+ return dataServerIP;
+ }
+
+ /**
+ * Getter method for property digestSum.
+ *
+ * @return property value of digestSum
+ */
+ public String getDigestSum() {
+ return digestSum;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("RenewDatumRequest{");
+ sb.append("connectId='").append(connectId).append('\'');
+ sb.append(", dataServerIP='").append(dataServerIP).append('\'');
+ sb.append(", digestSum='").append(digestSum).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ServerDataBox.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ServerDataBox.java
index 75dc51877..f65d8b942 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ServerDataBox.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/ServerDataBox.java
@@ -16,8 +16,6 @@
*/
package com.alipay.sofa.registry.common.model;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -25,6 +23,8 @@
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
/**
*
* @author zhuoyu.sjw
@@ -93,7 +93,7 @@ public Object getObject() {
* @throws ClassNotFoundException the class not found exception
*/
public Object extract() throws IOException, ClassNotFoundException {
- if (isInBytes()) {
+ if (object == null && isInBytes()) {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
if (serialization != SERIALIZED_BY_JAVA) {
throw new IOException("Unsupported serialization type: " + serialization);
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/constants/ValueConstants.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/constants/ValueConstants.java
index bd6f20409..cd0ed73d1 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/constants/ValueConstants.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/constants/ValueConstants.java
@@ -23,37 +23,61 @@
*/
public class ValueConstants {
+ /**
+ * connectId: sourceAddress_targetAddress
+ */
+ public static final String CONNECT_ID_SPLIT = "_";
+
/**
* The constant DEFAULT_GROUP.
*/
- public static final String DEFAULT_GROUP = "DEFAULT_GROUP";
+ public static final String DEFAULT_GROUP = "DEFAULT_GROUP";
/**
* The constant DEFAULT_ZONE.
*/
- public static final String DEFAULT_ZONE = "DEFAULT_ZONE";
+ public static final String DEFAULT_ZONE = "DEFAULT_ZONE";
- public static final String DEFAULT_INSTANCE_ID = "DEFAULT_INSTANCE_ID";
+ public static final String DEFAULT_INSTANCE_ID = "DEFAULT_INSTANCE_ID";
/**
* The constant DEFAULT_DATA_CENTER.
*/
- public static final String DEFAULT_DATA_CENTER = "DefaultDataCenter";
+ public static final String DEFAULT_DATA_CENTER = "DefaultDataCenter";
+
+ public static final long DEFAULT_NO_DATUM_VERSION = 1L;
+
+ private static final Integer SYSTEM_RAFT_PORT = Integer
+ .getInteger("RAFT_SERVER_PORT");
+
+ public static final int RAFT_SERVER_PORT = SYSTEM_RAFT_PORT != null ? SYSTEM_RAFT_PORT
+ : 9614;
- public static final long DEFAULT_NO_DATUM_VERSION = 1L;
+ private static final String SYSTEM_RAFT_GROUP = System
+ .getProperty("RAFT_SERVER_GROUP");
- private static final Integer SYSTEM_RAFT_PORT = Integer
- .getInteger("RAFT_SERVER_PORT");
+ public static final String RAFT_SERVER_GROUP = SYSTEM_RAFT_GROUP != null ? SYSTEM_RAFT_GROUP
+ : "RegistryGroup";
- public static final int RAFT_SERVER_PORT = SYSTEM_RAFT_PORT != null ? SYSTEM_RAFT_PORT
- : 9614;
+ public static final String STOP_PUSH_DATA_SWITCH_DATA_ID = "session.stop.push.data.switch#@#9600#@#CONFIG";
- private static final String SYSTEM_RAFT_GROUP = System
- .getProperty("RAFT_SERVER_GROUP");
+ public static final String BLACK_LIST_DATA_ID = "session.blacklist.data#@#9600#@#CONFIG";
- public static final String RAFT_SERVER_GROUP = SYSTEM_RAFT_GROUP != null ? SYSTEM_RAFT_GROUP
- : "RegistryGroup";
+ public static final String ENABLE_DATA_RENEW_SNAPSHOT = "session.enable.datum.renew.switch#@#9600#@#CONFIG";
- public static final String STOP_PUSH_DATA_SWITCH_DATA_ID = "session.stop.push.data.switch#@#9600#@#CONFIG";
+ public static final String ENABLE_DATA_DATUM_EXPIRE = "data.enable.datum.expire.switch#@#9600#@#CONFIG";
+
+ public static final String LOGGER_NAME_RENEW = "RENEW-LOGGER";
+
+ /**
+ * switch key for dataId sensitive is disable or not
+ */
+ public static final String DISABLE_DATA_ID_CASE_SENSITIVE_SWITCH = "disable.dataId.case.sensitive";
+ /**
+ * switch for dataId sensitive is disable or not, default value is false which means dataId is case sensitive
+ */
+ public static final Boolean DISABLE_DATA_ID_CASE_SENSITIVE = Boolean
+ .valueOf(System
+ .getProperty(DISABLE_DATA_ID_CASE_SENSITIVE_SWITCH));
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/Datum.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/Datum.java
index 61044ea8f..80d0b9e0c 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/Datum.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/Datum.java
@@ -16,13 +16,14 @@
*/
package com.alipay.sofa.registry.common.model.dataserver;
-import com.alipay.sofa.registry.common.model.store.Publisher;
-import com.alipay.sofa.registry.common.model.store.WordCache;
-
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import com.alipay.sofa.registry.common.model.store.Publisher;
+import com.alipay.sofa.registry.common.model.store.WordCache;
+import com.alipay.sofa.registry.util.DatumVersionUtil;
+
/**
* datum store in dataserver
*
@@ -61,7 +62,7 @@ public Datum() {
* @param dataCenter
*/
public Datum(String dataInfoId, String dataCenter) {
- this.dataInfoId = dataInfoId;
+ this.dataInfoId = WordCache.getInstance().getWordCache(dataInfoId);
this.dataCenter = WordCache.getInstance().getWordCache(dataCenter);
updateVersion();
}
@@ -96,7 +97,7 @@ public Datum(Publisher publisher, String dataCenter, long version) {
}
public void updateVersion() {
- this.version = System.currentTimeMillis();
+ this.version = DatumVersionUtil.nextId();
}
/**
@@ -243,7 +244,7 @@ public void setContainsUnPub(boolean containsUnPub) {
this.containsUnPub = containsUnPub;
}
- public static Datum processDatum(Datum datum) {
+ public static Datum internDatum(Datum datum) {
datum.setDataCenter(datum.getDataCenter());
datum.setDataInfoId(datum.getDataInfoId());
datum.setDataId(datum.getDataId());
@@ -252,7 +253,13 @@ public static Datum processDatum(Datum datum) {
Map pubMap = datum.getPubMap();
if (pubMap != null && !pubMap.isEmpty()) {
- pubMap.forEach((registerId, publisher) -> Publisher.processPublisher(publisher));
+ pubMap.forEach((registerId, publisher) -> {
+ // let registerId == pub.getRegisterId in every , for reducing old gen memory
+ // because this Datum is put into Memory directly, by DatumCache.coverDatum
+ publisher.setRegisterId(registerId);
+ // change publisher word cache
+ Publisher.internPublisher(publisher);
+ });
}
return datum;
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/SessionServerRegisterRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/SessionServerRegisterRequest.java
index 16f00f56b..b852aa3ef 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/SessionServerRegisterRequest.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/SessionServerRegisterRequest.java
@@ -30,16 +30,16 @@ public class SessionServerRegisterRequest implements Serializable {
private String processId;
- private Set clientHosts;
+ private Set connectIds;
/**
* constructor
* @param processId
- * @param clientHosts
+ * @param connectIds
*/
- public SessionServerRegisterRequest(String processId, Set clientHosts) {
+ public SessionServerRegisterRequest(String processId, Set connectIds) {
this.processId = processId;
- this.clientHosts = clientHosts;
+ this.connectIds = connectIds;
}
/**
@@ -61,17 +61,17 @@ public void setProcessId(String processId) {
}
/**
- * Getter method for property clientHosts.
+ * Getter method for property connectIds.
*
- * @return property value of clientHosts
+ * @return property value of connectIds
*/
- public Set getClientHosts() {
- return clientHosts;
+ public Set getConnectIds() {
+ return connectIds;
}
@Override
public String toString() {
return new StringBuilder("[SessionServerRegisterRequest] processId=")
- .append(this.processId).append(", clientHosts=").append(this.clientHosts).toString();
+ .append(this.processId).append(", connectIds=").append(this.connectIds).toString();
}
}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/UnPublishDataRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/UnPublishDataRequest.java
index cfa8554ac..33fbdbf0c 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/UnPublishDataRequest.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/dataserver/UnPublishDataRequest.java
@@ -34,12 +34,6 @@ public class UnPublishDataRequest implements Serializable {
private long registerTimestamp;
- /**
- * constructor
- */
- public UnPublishDataRequest() {
- }
-
/**
* construtor
* @param dataInfoId
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/ConfigureLoadbalanceRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/ConfigureLoadbalanceRequest.java
new file mode 100644
index 000000000..b430b16fb
--- /dev/null
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/ConfigureLoadbalanceRequest.java
@@ -0,0 +1,41 @@
+/*
+ * 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 com.alipay.sofa.registry.common.model.metaserver;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author xiangxu
+ * @version : LoadbalanceConfig.java, v 0.1 2020年05月29日 10:19 上午 xiangxu Exp $
+ */
+public class ConfigureLoadbalanceRequest implements Serializable {
+ private int maxConnections;
+
+ public ConfigureLoadbalanceRequest(int maxConnections) {
+ this.maxConnections = maxConnections;
+ }
+
+ public int getMaxConnections() {
+ return maxConnections;
+ }
+
+ public void setMaxConnections(int maxConnections) {
+ this.maxConnections = maxConnections;
+ }
+
+}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/DataNode.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/DataNode.java
index ca3bba378..e5e623f63 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/DataNode.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/DataNode.java
@@ -213,10 +213,6 @@ public void setRegistrationTimestamp(long registrationTimestamp) {
public String toString() {
final StringBuilder sb = new StringBuilder("DataNode{");
sb.append("ip=").append(getIp());
- sb.append(", dataCenter='").append(dataCenter).append('\'');
- sb.append(", regionId='").append(regionId).append('\'');
- sb.append(", nodeStatus=").append(nodeStatus);
- sb.append(", registrationTimestamp=").append(registrationTimestamp);
sb.append('}');
return sb.toString();
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/GetLoadbalanceMetricsRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/GetLoadbalanceMetricsRequest.java
new file mode 100644
index 000000000..ad781aff8
--- /dev/null
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/GetLoadbalanceMetricsRequest.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.alipay.sofa.registry.common.model.metaserver;
+
+import java.io.Serializable;
+
+/**
+ * @author xiangxu
+ * @version : SessionLoadbalanceMetrics.java, v 0.1 2020年05月27日 11:13 上午 xiangxu Exp $
+ */
+public class GetLoadbalanceMetricsRequest implements Serializable {
+}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/LoadbalanceMetrics.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/LoadbalanceMetrics.java
new file mode 100644
index 000000000..42a31a8b6
--- /dev/null
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/LoadbalanceMetrics.java
@@ -0,0 +1,38 @@
+/*
+ * 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 com.alipay.sofa.registry.common.model.metaserver;
+
+import java.io.Serializable;
+
+/**
+ * @author xiangxu
+ * @version : LoadbalanceMetrics.java, v 0.1 2020年05月27日 2:29 下午 xiangxu Exp $
+ */
+public class LoadbalanceMetrics implements Serializable {
+ private int connectionCount;
+
+ public LoadbalanceMetrics() {
+ }
+
+ public int getConnectionCount() {
+ return connectionCount;
+ }
+
+ public void setConnectionCount(int connectionCount) {
+ this.connectionCount = connectionCount;
+ }
+}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/MetaNode.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/MetaNode.java
index 6adf2457c..01d107cb0 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/MetaNode.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/MetaNode.java
@@ -131,10 +131,7 @@ public void setRegionId(String regionId) {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("MetaNode{");
- sb.append("nodeUrl=").append(getIp());
- sb.append(", dataCenter='").append(dataCenter).append('\'');
- sb.append(", regionId='").append(regionId).append('\'');
- sb.append(", nodeStatus=").append(nodeStatus);
+ sb.append("ip=").append(getIp());
sb.append('}');
return sb.toString();
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/NotifyProvideDataChange.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/NotifyProvideDataChange.java
index ad14df8f0..3fa7f078c 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/NotifyProvideDataChange.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/NotifyProvideDataChange.java
@@ -17,6 +17,10 @@
package com.alipay.sofa.registry.common.model.metaserver;
import java.io.Serializable;
+import java.util.Set;
+
+import com.alipay.sofa.registry.common.model.Node.NodeType;
+import com.google.common.collect.Sets;
/**
*
@@ -25,11 +29,13 @@
*/
public class NotifyProvideDataChange implements Serializable {
- private String dataInfoId;
+ private String dataInfoId;
+
+ private Long version;
- private Long version;
+ private DataOperator dataOperator;
- private DataOperator dataOperator;
+ private Set nodeTypes;
/**
* constructor
@@ -38,9 +44,15 @@ public class NotifyProvideDataChange implements Serializable {
* @param dataOperator
*/
public NotifyProvideDataChange(String dataInfoId, Long version, DataOperator dataOperator) {
+ this(dataInfoId, version, dataOperator, Sets.newHashSet(NodeType.SESSION));
+ }
+
+ public NotifyProvideDataChange(String dataInfoId, Long version, DataOperator dataOperator,
+ Set nodeTypes) {
this.dataInfoId = dataInfoId;
this.version = version;
this.dataOperator = dataOperator;
+ this.nodeTypes = nodeTypes;
}
/**
@@ -97,12 +109,31 @@ public void setDataOperator(DataOperator dataOperator) {
this.dataOperator = dataOperator;
}
+ /**
+ * Getter method for property nodeType.
+ *
+ * @return property value of nodeType
+ */
+ public Set getNodeTypes() {
+ return nodeTypes;
+ }
+
+ /**
+ * Setter method for property nodeType.
+ *
+ * @param nodeTypes value to be assigned to property nodeType
+ */
+ public void setNodeTypes(Set nodeTypes) {
+ this.nodeTypes = nodeTypes;
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("NotifyProvideDataChange{");
sb.append("dataInfoId='").append(dataInfoId).append('\'');
sb.append(", version=").append(version);
sb.append(", dataOperator=").append(dataOperator);
+ sb.append(", nodeTypes=").append(nodeTypes);
sb.append('}');
return sb.toString();
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/ReNewNodesRequest.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/RenewNodesRequest.java
similarity index 92%
rename from server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/ReNewNodesRequest.java
rename to server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/RenewNodesRequest.java
index 50485e65c..0794e5152 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/ReNewNodesRequest.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/RenewNodesRequest.java
@@ -16,16 +16,16 @@
*/
package com.alipay.sofa.registry.common.model.metaserver;
-import com.alipay.sofa.registry.common.model.Node;
-
import java.io.Serializable;
+import com.alipay.sofa.registry.common.model.Node;
+
/**
*
* @author shangyu.wh
* @version $Id: RenewNodesRequest.java, v 0.1 2018-03-30 19:51 shangyu.wh Exp $
*/
-public class ReNewNodesRequest implements Serializable {
+public class RenewNodesRequest implements Serializable {
private int duration;
@@ -35,7 +35,7 @@ public class ReNewNodesRequest implements Serializable {
* constructor
* @param node
*/
- public ReNewNodesRequest(T node) {
+ public RenewNodesRequest(T node) {
this.node = node;
}
@@ -68,7 +68,7 @@ public T getNode() {
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder("ReNewNodesRequest{");
+ final StringBuilder sb = new StringBuilder("RenewNodesRequest{");
sb.append("duration=").append(duration);
sb.append(", node=").append(node);
sb.append('}');
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/SessionNode.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/SessionNode.java
index d6beeaf67..8c9a3487e 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/SessionNode.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/metaserver/SessionNode.java
@@ -55,6 +55,14 @@ public URL getNodeUrl() {
return nodeUrl;
}
+ /**
+ * get ip address from nodeUrl
+ * @return
+ */
+ public String getIp() {
+ return nodeUrl == null ? "" : nodeUrl.getIpAddress();
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -167,10 +175,7 @@ public void setNodeStatus(NodeStatus nodeStatus) {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("SessionNode{");
- sb.append("nodeUrl=").append(nodeUrl);
- sb.append(", regionId='").append(regionId).append('\'');
- sb.append(", name='").append(name).append('\'');
- sb.append(", nodeStatus=").append(nodeStatus);
+ sb.append("ip=").append(getIp());
sb.append('}');
return sb.toString();
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java
index 7c4983356..e2de744bc 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/BaseInfo.java
@@ -16,12 +16,12 @@
*/
package com.alipay.sofa.registry.common.model.store;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
/**
*
* @author shangyu.wh
@@ -51,6 +51,8 @@ public abstract class BaseInfo implements Serializable, StoreData {
private URL sourceAddress;
+ private URL targetAddress;
+
private ClientVersion clientVersion;
private String group;
@@ -136,7 +138,7 @@ public String getProcessId() {
* @param processId value to be assigned to property processId
*/
public void setProcessId(String processId) {
- this.processId = processId;
+ this.processId = WordCache.getInstance().getWordCache(processId);
}
/**
@@ -175,6 +177,24 @@ public void setSourceAddress(URL sourceAddress) {
this.sourceAddress = sourceAddress;
}
+ /**
+ * Getter method for property targetAddress.
+ *
+ * @return property value of targetAddress
+ */
+ public URL getTargetAddress() {
+ return targetAddress;
+ }
+
+ /**
+ * Setter method for property targetAddress.
+ *
+ * @param targetAddress value to be assigned to property targetAddress
+ */
+ public void setTargetAddress(URL targetAddress) {
+ this.targetAddress = targetAddress;
+ }
+
/**
* Getter method for property attributes.
*
@@ -193,7 +213,7 @@ public void setAttributes(Map attributes) {
Map newAttributes = new HashMap<>();
if (attributes != null && !attributes.isEmpty()) {
attributes.forEach((key, value) -> newAttributes
- .put(WordCache.getInstance().getWordCache(key), value));
+ .put(key, value));
}
this.attributes = newAttributes;
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/DataInfo.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/DataInfo.java
index f519b44b0..02e5ee7f2 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/DataInfo.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/DataInfo.java
@@ -16,6 +16,8 @@
*/
package com.alipay.sofa.registry.common.model.store;
+import com.alipay.sofa.registry.common.model.constants.ValueConstants;
+
import java.io.Serializable;
/**
@@ -61,7 +63,11 @@ public static String toDataInfoId(String dataId, String instanceId, String dataT
if (dataId == null || dataId.isEmpty()) {
throw new IllegalArgumentException("error dataId:" + dataId);
}
- buf.append(dataId);
+ if (ValueConstants.DISABLE_DATA_ID_CASE_SENSITIVE) {
+ buf.append(dataId.toUpperCase());
+ } else {
+ buf.append(dataId);
+ }
if (instanceId == null || instanceId.isEmpty()) {
throw new IllegalArgumentException("error instanceId:" + instanceId);
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Publisher.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Publisher.java
index 8ecd7566b..a216732aa 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Publisher.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Publisher.java
@@ -16,12 +16,12 @@
*/
package com.alipay.sofa.registry.common.model.store;
+import java.util.List;
+
import com.alipay.sofa.registry.common.model.PublishType;
import com.alipay.sofa.registry.common.model.ServerDataBox;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.List;
-
/**
*
* @author shangyu.wh
@@ -90,8 +90,8 @@ protected String getOtherInfo() {
* @param publisher
* @return
*/
- public static Publisher processPublisher(Publisher publisher) {
-
+ public static Publisher internPublisher(Publisher publisher) {
+ publisher.setRegisterId(publisher.getRegisterId());
publisher.setDataInfoId(publisher.getDataInfoId());
publisher.setInstanceId(publisher.getInstanceId());
publisher.setGroup(publisher.getGroup());
@@ -101,13 +101,6 @@ public static Publisher processPublisher(Publisher publisher) {
publisher.setProcessId(publisher.getProcessId());
publisher.setAppName(publisher.getAppName());
- if (publisher.getSourceAddress() != null) {
- publisher.setSourceAddress(new URL(publisher.getSourceAddress().getIpAddress(),
- publisher.getSourceAddress().getPort()));
- }
-
- publisher.setAttributes(publisher.getAttributes());
-
return publisher;
}
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java
index 1ec2d9a66..5746a45f8 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/StoreData.java
@@ -27,7 +27,7 @@ public interface StoreData {
* DataType enum
*/
enum DataType {
- SUBSCRIBER, PUBLISHER, WATCHER, UNPUBLISHER
+ SUBSCRIBER, PUBLISHER, WATCHER, UN_PUBLISHER
}
/**
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java
index 2f0b8b78d..3d9b532b7 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Subscriber.java
@@ -16,13 +16,14 @@
*/
package com.alipay.sofa.registry.common.model.store;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import com.alipay.sofa.registry.common.model.ElementType;
+import com.alipay.sofa.registry.common.model.constants.ValueConstants;
import com.alipay.sofa.registry.core.model.ScopeEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
*
* @author shangyu.wh
@@ -31,16 +32,16 @@
public class Subscriber extends BaseInfo {
/** UID */
- private static final long serialVersionUID = 98433360274932292L;
+ private static final long serialVersionUID = 98433360274932292L;
/** */
- private ScopeEnum scope;
+ private ScopeEnum scope;
/** */
- private ElementType elementType;
+ private ElementType elementType;
/**
- * all dataCenter push dataInfo version
+ * last push context
*/
- private Map lastPushVersions = new ConcurrentHashMap<>();
+ private Map lastPushContexts = new ConcurrentHashMap<>();
/**
* Getter method for property scope.
@@ -71,7 +72,11 @@ public ElementType getElementType() {
*/
public boolean checkVersion(String dataCenter, Long version) {
- Long oldVersion = lastPushVersions.get(dataCenter);
+ PushContext lastPushContext = lastPushContexts.get(dataCenter);
+ if (lastPushContext == null) {
+ return version != null;
+ }
+ Long oldVersion = lastPushContext.pushVersion;
if (oldVersion == null) {
return version != null;
} else {
@@ -88,15 +93,26 @@ public boolean checkVersion(String dataCenter, Long version) {
* @return
*/
public void checkAndUpdateVersion(String dataCenter, Long version) {
+ checkAndUpdateVersion(dataCenter, version, -1);
+ }
+
+ /**
+ * check version input greater or equal to current version
+ * @param version
+ * @return
+ */
+ public void checkAndUpdateVersion(String dataCenter, Long version, int pubCount) {
while (true) {
- Long oldVersion = lastPushVersions.putIfAbsent(dataCenter, version);
+ PushContext pushContext = new PushContext(version, pubCount);
+ PushContext oldPushContext = lastPushContexts.putIfAbsent(dataCenter, pushContext);
// Add firstly
- if (oldVersion == null) {
+ if (oldPushContext == null) {
break;
} else {
- if (version > oldVersion) {
- if (lastPushVersions.replace(dataCenter, oldVersion, version)) {
+ if (oldPushContext.pushVersion == null
+ || (pushContext.pushVersion != null && pushContext.pushVersion > oldPushContext.pushVersion)) {
+ if (lastPushContexts.replace(dataCenter, oldPushContext, pushContext)) {
break;
}
} else {
@@ -106,6 +122,23 @@ public void checkAndUpdateVersion(String dataCenter, Long version) {
}
}
+ /**
+ * If the pushed data is empty, check the last push, for avoid continuous empty datum push
+ */
+ public boolean allowPush(String dataCenter, int pubCount) {
+ boolean allowPush = true;
+ // condition of no push:
+ // 1. last push count is 0 and this time is also 0
+ // 2. last push is a valid push (version > 1)
+ if (pubCount == 0) {
+ PushContext pushContext = lastPushContexts.get(dataCenter);
+ allowPush = !(pushContext != null && pushContext.pushPubCount == 0
+ //last push is a valid push
+ && pushContext.pushVersion != null && pushContext.pushVersion > ValueConstants.DEFAULT_NO_DATUM_VERSION);
+ }
+ return allowPush;
+ }
+
/**
* Setter method for property elementType.
*
@@ -126,28 +159,10 @@ protected String getOtherInfo() {
final StringBuilder sb = new StringBuilder("scope=");
sb.append(scope).append(",");
sb.append("elementType=").append(elementType).append(",");
- sb.append("lastPushVersion=").append(lastPushVersions);
+ sb.append("pushVersion=").append(lastPushContexts);
return sb.toString();
}
- /**
- * Getter method for property lastPushVersions.
- *
- * @return property value of lastPushVersions
- */
- public Map getLastPushVersions() {
- return lastPushVersions;
- }
-
- /**
- * Setter method for property lastPushVersions .
- *
- * @param lastPushVersions value to be assigned to property lastPushVersions
- */
- public void setLastPushVersions(Map lastPushVersions) {
- this.lastPushVersions = lastPushVersions;
- }
-
/**
* @see Object#toString()
*/
@@ -156,9 +171,57 @@ public String toString() {
final StringBuilder sb = new StringBuilder("Subscriber{");
sb.append("scope=").append(scope);
sb.append(", elementType=").append(elementType);
- sb.append(", lastPushVersions=").append(lastPushVersions);
+ sb.append(", lastPushContexts=").append(lastPushContexts);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
+
+ /**
+ * change subscriber word cache
+ * @param subscriber
+ * @return
+ */
+ public static Subscriber internSubscriber(Subscriber subscriber) {
+ subscriber.setRegisterId(subscriber.getRegisterId());
+ subscriber.setDataInfoId(subscriber.getDataInfoId());
+ subscriber.setInstanceId(subscriber.getInstanceId());
+ subscriber.setGroup(subscriber.getGroup());
+ subscriber.setDataId(subscriber.getDataId());
+ subscriber.setClientId(subscriber.getClientId());
+ subscriber.setCell(subscriber.getCell());
+ subscriber.setProcessId(subscriber.getProcessId());
+ subscriber.setAppName(subscriber.getAppName());
+
+ return subscriber;
+ }
+
+ static class PushContext {
+ /**
+ * last pushed dataInfo version
+ */
+ private Long pushVersion;
+
+ /**
+ * push pushed dataInfo pubCount
+ */
+ private int pushPubCount;
+
+ public PushContext(Long pushVersion, int pushPubCount) {
+ this.pushVersion = pushVersion;
+ this.pushPubCount = pushPubCount;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PushContext{");
+ sb.append("pushVersion=").append(pushVersion);
+ sb.append(", pushPubCount=").append(pushPubCount);
+ sb.append('}');
+ return sb.toString();
+ }
+ }
}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java
index 6ffa610f9..f369d5e4e 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/Watcher.java
@@ -27,4 +27,23 @@ public class Watcher extends BaseInfo {
public DataType getDataType() {
return DataType.WATCHER;
}
+
+ /**
+ * change watcher word cache
+ * @param watcher
+ * @return
+ */
+ public static Watcher internWatcher(Watcher watcher) {
+ watcher.setRegisterId(watcher.getRegisterId());
+ watcher.setDataInfoId(watcher.getDataInfoId());
+ watcher.setInstanceId(watcher.getInstanceId());
+ watcher.setGroup(watcher.getGroup());
+ watcher.setDataId(watcher.getDataId());
+ watcher.setClientId(watcher.getClientId());
+ watcher.setCell(watcher.getCell());
+ watcher.setProcessId(watcher.getProcessId());
+ watcher.setAppName(watcher.getAppName());
+
+ return watcher;
+ }
}
\ No newline at end of file
diff --git a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/WordCache.java b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/WordCache.java
index 2734c8ac0..f00e3c938 100644
--- a/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/WordCache.java
+++ b/server/common/model/src/main/java/com/alipay/sofa/registry/common/model/store/WordCache.java
@@ -16,7 +16,8 @@
*/
package com.alipay.sofa.registry.common.model.store;
-import java.util.concurrent.ConcurrentHashMap;
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
/**
*
@@ -45,7 +46,7 @@ public static WordCache getInstance() {
/**
* word cache map
*/
- private ConcurrentHashMap map = new ConcurrentHashMap<>();
+ private Interner interners = Interners.newWeakInterner();
/**
*
@@ -56,8 +57,7 @@ public String getWordCache(String s) {
if (s == null) {
return null;
}
- String oldValue = map.putIfAbsent(s, s);
- return oldValue == null ? s : oldValue;
+ return interners.intern(s);
}
}
\ No newline at end of file
diff --git a/server/common/pom.xml b/server/common/pom.xml
index 9027270dc..40b568ca7 100644
--- a/server/common/pom.xml
+++ b/server/common/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-server-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/common/util/pom.xml b/server/common/util/pom.xml
index 827af0b6e..fd262ae30 100644
--- a/server/common/util/pom.xml
+++ b/server/common/util/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-common
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/ReporterUtils.java b/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/ReporterUtils.java
index fb5f24e36..7cc79bc33 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/ReporterUtils.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/ReporterUtils.java
@@ -16,12 +16,13 @@
*/
package com.alipay.sofa.registry.metrics;
+import java.util.concurrent.TimeUnit;
+
import com.alipay.sofa.registry.log.Logger;
+import com.alipay.sofa.registry.log.LoggerFactory;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Slf4jReporter;
-import java.util.concurrent.TimeUnit;
-
/**
*
* @author shangyu.wh
@@ -29,6 +30,8 @@
*/
public class ReporterUtils {
+ private static final Logger METRIC_LOGGER = LoggerFactory.getLogger("REGISTRY-METRICS");
+
/**
* start slf4j reporter
* @param period
@@ -46,4 +49,13 @@ public static void startSlf4jReporter(long period, MetricRegistry registry, Logg
}
}
+
+ /**
+ * start slf4j reporter
+ * @param period
+ * @param registry
+ */
+ public static void startSlf4jReporter(long period, MetricRegistry registry) {
+ startSlf4jReporter(period, registry, METRIC_LOGGER);
+ }
}
\ No newline at end of file
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/TaskMetrics.java b/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/TaskMetrics.java
index ae0ec816c..4408046de 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/TaskMetrics.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/metrics/TaskMetrics.java
@@ -18,7 +18,13 @@
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
+import com.google.common.collect.Sets;
+import io.netty.util.internal.ConcurrentSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
/**
@@ -29,6 +35,7 @@
public class TaskMetrics {
private final MetricRegistry metrics;
+ private final Set executorNames = Sets.newConcurrentHashSet();
private TaskMetrics() {
this.metrics = new MetricRegistry();
@@ -53,21 +60,45 @@ public MetricRegistry getMetricRegistry() {
}
public void registerThreadExecutor(String executorName, ThreadPoolExecutor executor) {
+ executorNames.add(executorName);
metrics.register(MetricRegistry.name(executorName, "queue"),
- (Gauge) () -> executor.getQueue().size());
+ (Gauge) () -> executor.getQueue().size());
metrics.register(MetricRegistry.name(executorName, "current"),
- (Gauge) executor::getPoolSize);
+ (Gauge) executor::getPoolSize);
metrics.register(MetricRegistry.name(executorName, "active"),
- (Gauge) executor::getActiveCount);
+ (Gauge) executor::getActiveCount);
metrics.register(MetricRegistry.name(executorName, "completed"),
- (Gauge) executor::getCompletedTaskCount);
+ (Gauge) executor::getCompletedTaskCount);
metrics.register(MetricRegistry.name(executorName, "task"),
- (Gauge) executor::getTaskCount);
+ (Gauge) executor::getTaskCount);
+ }
+
+ public Set getExecutorNames() {
+ return executorNames;
+ }
+ public String metricsString() {
+ final String SYMBOLIC = " └─ ";
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n").append("ExecutorMetrics").append(" >>>>>>>>");
+ sb.append("\n");
+ for (String executorName : getExecutorNames()) {
+ MetricRegistry metricRegistry = getMetricRegistry();
+ Map map = metricRegistry
+ .getGauges((name, value) -> name.startsWith(executorName));
+
+ sb.append(SYMBOLIC).append(executorName);
+ map.forEach((key, gauge) -> {
+ String name = key.substring(executorName.length() + 1);
+ sb.append(", ").append(name).append(":").append(gauge.getValue());
+ });
+ sb.append("\n");
+ }
+ return sb.toString();
}
}
\ No newline at end of file
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/DefaultTaskListenerManager.java b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/DefaultTaskListenerManager.java
index 8e6b23077..a0aa07b2f 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/DefaultTaskListenerManager.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/DefaultTaskListenerManager.java
@@ -16,33 +16,35 @@
*/
package com.alipay.sofa.registry.task.listener;
-import java.util.ArrayList;
import java.util.Collection;
+import com.alipay.sofa.registry.task.listener.TaskEvent.TaskType;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
/**
* @author xuanbei
* @since 2018/12/28
*/
public class DefaultTaskListenerManager implements TaskListenerManager {
- private Collection taskListeners = new ArrayList<>();
+
+ private Multimap taskListeners = ArrayListMultimap.create();
@Override
- public Collection getTaskListeners() {
+ public Multimap getTaskListeners() {
return taskListeners;
}
@Override
public void addTaskListener(TaskListener taskListener) {
- taskListeners.add(taskListener);
+ taskListeners.put(taskListener.support(), taskListener);
}
@Override
public void sendTaskEvent(TaskEvent taskEvent) {
-
+ Collection taskListeners = this.taskListeners.get(taskEvent.getTaskType());
for (TaskListener taskListener : taskListeners) {
- if (taskListener.support(taskEvent)) {
- taskListener.handleEvent(taskEvent);
- }
+ taskListener.handleEvent(taskEvent);
}
}
}
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskEvent.java b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskEvent.java
index 16f1abcc3..a46f40f8d 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskEvent.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskEvent.java
@@ -16,10 +16,11 @@
*/
package com.alipay.sofa.registry.task.listener;
-import com.alipay.sofa.registry.task.TaskClosure;
-
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.alipay.sofa.registry.task.TaskClosure;
/**
*
@@ -30,33 +31,41 @@ public class TaskEvent {
public enum TaskType {
//Session task
- SUBSCRIBER_REGISTER_FETCH_TASK("SubscriberRegisterFetchTask"), SUBSCRIBER_PUSH_EMPTY_TASK(
- "SubscriberPushEmptyTask"), WATCHER_REGISTER_FETCH_TASK(
- "WatcherRegisterFetchTask"), DATA_CHANGE_FETCH_TASK(
- "DataChangeFetchTask"), DATA_PUSH_TASK(
- "DataPushTask"), DATA_CHANGE_FETCH_CLOUD_TASK(
- "DataChangeFetchCloudTask"), RECEIVED_DATA_MULTI_PUSH_TASK(
- "ReceivedDataMultiPushTask"), RECEIVED_DATA_CONFIG_PUSH_TASK(
- "ReceivedDataConfigPushTask"), CANCEL_DATA_TASK(
- "CancelDataTask"), SYNC_PUBLISHER_TASK(
- "SyncPublisherTask"), SYNC_SUBSCRIBER_TASK(
- "SyncSubscriberTask"), SESSION_REGISTER_DATA_TASK(
- "SessionRegisterDataTask"), PROVIDE_DATA_CHANGE_FETCH_TASK(
- "ProvideDataChangeFetchTask"),
-
- SUBSCRIBER_MULTI_FETCH_TASK("SubscriberMultiFetchTask"),
+ SUBSCRIBER_REGISTER_FETCH_TASK("SubscriberRegisterFetchTask"), //
+ SUBSCRIBER_PUSH_EMPTY_TASK("SubscriberPushEmptyTask"), //
+ WATCHER_REGISTER_FETCH_TASK("WatcherRegisterFetchTask"), //
+ DATA_CHANGE_FETCH_TASK("DataChangeFetchTask"), //
+ DATA_PUSH_TASK("DataPushTask"), //
+ DATA_CHANGE_FETCH_CLOUD_TASK("DataChangeFetchCloudTask"), //
+ RECEIVED_DATA_MULTI_PUSH_TASK("ReceivedDataMultiPushTask"), //
+ RECEIVED_DATA_CONFIG_PUSH_TASK("ReceivedDataConfigPushTask"), //
+ CANCEL_DATA_TASK("CancelDataTask"), //
+ SYNC_PUBLISHER_TASK("SyncPublisherTask"), //
+ SYNC_UNPUBLISHER_TASK("SyncUnPublisherTask"), //
+ SYNC_SUBSCRIBER_TASK("SyncSubscriberTask"), //
+ SYNC_UNSUBSCRIBER_TASK("SyncUnSubscriberTask"), //
+ SESSION_REGISTER_DATA_TASK("SessionRegisterDataTask"), //
+ PROVIDE_DATA_CHANGE_FETCH_TASK("ProvideDataChangeFetchTask"), //
+ SUBSCRIBER_MULTI_FETCH_TASK("SubscriberMultiFetchTask"), //
+ PUBLISH_DATA_TASK("PublishDataTask"), //
+ UN_PUBLISH_DATA_TASK("UnPublishDataTask"), //
+ RENEW_DATUM_TASK("RenewDatumTask"), //
+ DATUM_SNAPSHOT_TASK("DatumSnapshotTask"), //
//Session Adapter task
- USER_DATA_ELEMENT_PUSH_TASK("UserDataElementPushTask"), USER_DATA_ELEMENT_MULTI_PUSH_TASK(
- "UserDataElementMultiPushTask"),
+ USER_DATA_ELEMENT_PUSH_TASK("UserDataElementPushTask"), //
+ USER_DATA_ELEMENT_MULTI_PUSH_TASK("UserDataElementMultiPushTask"), //
//MetaServer task
- SESSION_NODE_CHANGE_PUSH_TASK("SessionNodeChangePushTask"), DATA_NODE_CHANGE_PUSH_TASK(
- "DataNodeChangePushTask"), RECEIVE_STATUS_CONFIRM_NOTIFY_TASK(
- "ReceiveStatusConfirmNotifyTask"), PERSISTENCE_DATA_CHANGE_NOTIFY_TASK(
- "PersistenceDataChangeNotifyTask");
+ SESSION_NODE_CHANGE_PUSH_TASK("SessionNodeChangePushTask"), //
+ DATA_NODE_CHANGE_PUSH_TASK("DataNodeChangePushTask"), //
+ RECEIVE_STATUS_CONFIRM_NOTIFY_TASK("ReceiveStatusConfirmNotifyTask"), //
+ PERSISTENCE_DATA_CHANGE_NOTIFY_TASK("PersistenceDataChangeNotifyTask"), //
+ ;
- private String name;
+ private String name;
+
+ private AtomicInteger nextId = new AtomicInteger(0);
TaskType(String name) {
this.name = name;
@@ -75,7 +84,11 @@ public String getName() {
private long createTime;
- private final Map attributes = new ConcurrentHashMap();
+ private TaskClosure taskClosure;
+
+ private final String taskId;
+
+ private final Map attributes = new ConcurrentHashMap();
/**
* constructor
@@ -84,18 +97,27 @@ public String getName() {
public TaskEvent(TaskType taskType) {
this.taskType = taskType;
this.createTime = System.currentTimeMillis();
+ this.taskId = String.format("%s-%s-%s", taskType.name, this.createTime,
+ taskType.nextId.getAndIncrement());
}
- private TaskClosure taskClosure;
-
/**
* constructor
* @param eventObj
* @param taskType
*/
public TaskEvent(Object eventObj, TaskType taskType) {
+ this(taskType);
this.eventObj = eventObj;
- this.taskType = taskType;
+ }
+
+ /**
+ * Getter method for property taskId.
+ *
+ * @return property value of taskId
+ */
+ public String getTaskId() {
+ return taskId;
}
/**
@@ -195,7 +217,12 @@ public long getCreateTime() {
@Override
public String toString() {
- return "TaskEvent{" + "eventObj=" + eventObj + ", sendTimeStamp=" + sendTimeStamp
- + ", attributes=" + attributes + '}';
+ final StringBuilder sb = new StringBuilder("TaskEvent{");
+ sb.append("eventObj=").append(eventObj);
+ sb.append(", sendTimeStamp=").append(sendTimeStamp);
+ sb.append(", attributes=").append(attributes);
+ sb.append(", taskId='").append(taskId).append('\'');
+ sb.append('}');
+ return sb.toString();
}
}
\ No newline at end of file
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListener.java b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListener.java
index 547d3b154..5601031eb 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListener.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListener.java
@@ -16,6 +16,8 @@
*/
package com.alipay.sofa.registry.task.listener;
+import com.alipay.sofa.registry.task.listener.TaskEvent.TaskType;
+
/**
*
* @author shangyu.wh
@@ -26,10 +28,9 @@ public interface TaskListener {
/**
* com.alipay.sofa.registry.server.meta.listener type check
*
- * @param event
- * @return true or false。
+ * @return type
*/
- boolean support(TaskEvent event);
+ TaskType support();
/**
* event execute
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListenerManager.java b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListenerManager.java
index dc19c661d..58be148f8 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListenerManager.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/task/listener/TaskListenerManager.java
@@ -16,7 +16,8 @@
*/
package com.alipay.sofa.registry.task.listener;
-import java.util.Collection;
+import com.alipay.sofa.registry.task.listener.TaskEvent.TaskType;
+import com.google.common.collect.Multimap;
/**
*
@@ -29,7 +30,7 @@ public interface TaskListenerManager {
*
* @return
*/
- Collection getTaskListeners();
+ Multimap getTaskListeners();
/**
*
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimer.java b/server/common/util/src/main/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimer.java
index f6cd4d206..7119a88a8 100644
--- a/server/common/util/src/main/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimer.java
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimer.java
@@ -16,45 +16,66 @@
*/
package com.alipay.sofa.registry.timer;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timeout;
-import io.netty.util.TimerTask;
-
import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timeout;
+import io.netty.util.TimerTask;
+
/**
* based on HashedWheelTimer, add function: exec TimerTask async
*
- * @author kezhu.wukz
+ * @author kezhu.wukz
* @version $Id: AsyncHashedWheelTimer.java, v 0.1 2019-01-11 10:54 AM kezhu.wukz Exp $
*/
public class AsyncHashedWheelTimer extends HashedWheelTimer {
/** */
- private final Executor executor;
+ protected final Executor executor;
/** */
- private final TaskFailedCallback taskFailedCallback;
+ protected final TaskFailedCallback taskFailedCallback;
/**
- *
* @param threadFactory
* @param tickDuration
* @param unit
* @param ticksPerWheel
+ * @param threadSize
+ * @param queueSize
* @param asyncThreadFactory
*/
public AsyncHashedWheelTimer(ThreadFactory threadFactory, long tickDuration, TimeUnit unit,
- int ticksPerWheel, ThreadFactory asyncThreadFactory,
+ int ticksPerWheel, int threadSize, int queueSize,
+ ThreadFactory asyncThreadFactory,
TaskFailedCallback taskFailedCallback) {
super(threadFactory, tickDuration, unit, ticksPerWheel);
- this.executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
- new SynchronousQueue<>(), asyncThreadFactory);
+ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(threadSize, threadSize,
+ 300L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(queueSize), asyncThreadFactory);
+ threadPoolExecutor.allowCoreThreadTimeOut(true);
+ this.executor = threadPoolExecutor;
+ this.taskFailedCallback = taskFailedCallback;
+ }
+
+ /**
+ *
+ * @param threadFactory
+ * @param tickDuration
+ * @param unit
+ * @param ticksPerWheel
+ * @param asyncExecutor
+ */
+ public AsyncHashedWheelTimer(ThreadFactory threadFactory, long tickDuration, TimeUnit unit,
+ int ticksPerWheel, Executor asyncExecutor,
+ TaskFailedCallback taskFailedCallback) {
+ super(threadFactory, tickDuration, unit, ticksPerWheel);
+
+ this.executor = asyncExecutor;
this.taskFailedCallback = taskFailedCallback;
}
@@ -85,14 +106,14 @@ public AsyncTimerTask(TimerTask timerTask) {
/**
*/
@Override
- public void run(Timeout timeout) throws Exception {
+ public void run(Timeout timeout) {
this.timeout = timeout;
try {
AsyncHashedWheelTimer.this.executor.execute(this);
} catch (RejectedExecutionException e) {
taskFailedCallback.executionRejected(e);
} catch (Throwable e) {
- taskFailedCallback.executionRejected(e);
+ taskFailedCallback.executionFailed(e);
}
}
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/timer/RecycleAsyncHashedWheelTimer.java b/server/common/util/src/main/java/com/alipay/sofa/registry/timer/RecycleAsyncHashedWheelTimer.java
new file mode 100644
index 000000000..fb3a0bd63
--- /dev/null
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/timer/RecycleAsyncHashedWheelTimer.java
@@ -0,0 +1,125 @@
+/*
+ * 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 com.alipay.sofa.registry.timer;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BooleanSupplier;
+
+import io.netty.util.Timeout;
+import io.netty.util.TimerTask;
+
+/**
+ *
+ * @author kezhu.wukz
+ * @version $Id: RecycleAsyncHashedWheelTimer.java, v 0.1 2019-07-27 10:54 kezhu.wukz Exp $
+ */
+public class RecycleAsyncHashedWheelTimer extends AsyncHashedWheelTimer {
+
+ public RecycleAsyncHashedWheelTimer(ThreadFactory threadFactory, long tickDuration,
+ TimeUnit unit, int ticksPerWheel, int threadSize,
+ int queueSize, ThreadFactory asyncThreadFactory,
+ TaskFailedCallback taskFailedCallback) {
+ super(threadFactory, tickDuration, unit, ticksPerWheel, threadSize, queueSize,
+ asyncThreadFactory, taskFailedCallback);
+ }
+
+ public RecycleAsyncHashedWheelTimer(ThreadFactory threadFactory, long tickDuration,
+ TimeUnit unit, int ticksPerWheel, Executor asyncExecutor,
+ TaskFailedCallback taskFailedCallback) {
+ super(threadFactory, tickDuration, unit, ticksPerWheel, asyncExecutor, taskFailedCallback);
+ }
+
+ public Timeout newTimeout(TimerTask task, long firstDelay, long recycleDelay, TimeUnit unit,
+ BooleanSupplier checkCondition) {
+
+ return super.newTimeout(
+ new RecycleAsyncTimerTask(task, recycleDelay, unit, checkCondition), firstDelay, unit);
+ }
+
+ public Timeout newTimeout(TimerTask task, long recycleDelay, TimeUnit unit,
+ BooleanSupplier checkCondition) {
+
+ return super
+ .newTimeout(new RecycleAsyncTimerTask(task, recycleDelay, unit, checkCondition),
+ recycleDelay, unit);
+ }
+
+ /**
+ *
+ */
+ class RecycleAsyncTimerTask implements TimerTask, Runnable {
+ /** */
+ private final TimerTask timerTask;
+
+ private final long recycleDelay;
+
+ private final TimeUnit delayUnit;
+
+ private final BooleanSupplier checkCondition;
+
+ /** */
+ private Timeout timeout;
+
+ /**
+ * @param timerTask
+ */
+ public RecycleAsyncTimerTask(TimerTask timerTask, long recycleDelay, TimeUnit unit,
+ BooleanSupplier checkCondition) {
+ super();
+ this.timerTask = timerTask;
+ this.recycleDelay = recycleDelay;
+ this.delayUnit = unit;
+ this.checkCondition = checkCondition;
+ }
+
+ /**
+ */
+ @Override
+ public void run(Timeout timeout) {
+ this.timeout = timeout;
+ try {
+ RecycleAsyncHashedWheelTimer.super.executor.execute(this);
+ } catch (RejectedExecutionException e) {
+ taskFailedCallback.executionRejected(e);
+ } catch (Throwable e) {
+ taskFailedCallback.executionFailed(e);
+ }
+ }
+
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ try {
+ this.timerTask.run(this.timeout);
+ } catch (Throwable e) {
+ taskFailedCallback.executionFailed(e);
+ } finally {
+ if (checkCondition.getAsBoolean()) {
+ RecycleAsyncHashedWheelTimer.this.newTimeout(timerTask, recycleDelay,
+ delayUnit, checkCondition);
+ }
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/server/common/util/src/main/java/com/alipay/sofa/registry/util/DatumVersionUtil.java b/server/common/util/src/main/java/com/alipay/sofa/registry/util/DatumVersionUtil.java
new file mode 100644
index 000000000..78112433b
--- /dev/null
+++ b/server/common/util/src/main/java/com/alipay/sofa/registry/util/DatumVersionUtil.java
@@ -0,0 +1,79 @@
+/*
+ * 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 com.alipay.sofa.registry.util;
+
+/**
+ * generates ID: 49 bit millisecond timestamp + 15 bit incremental ID
+ *
+ * refer to: https://github.com/twitter/snowflake
+ *
+ * @author kezhu.wukz
+ * @version $Id: DatumVersionUtil.java, v 0.1 2019-07-04 22:05 kezhu.wukz Exp $
+ */
+public class DatumVersionUtil {
+
+ private static long sequence = 0L;
+
+ /** Tue Jan 01 00:00:00 CST 2019 */
+ private static long twepoch = 1546272000000L;
+
+ private static long sequenceBits = 15L;
+ private static long timestampLeftShift = sequenceBits;
+ private static long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+ private static long lastTimestamp = -1L;
+
+ public synchronized static long nextId() {
+ long timestamp = timeGen();
+
+ if (timestamp < lastTimestamp) {
+ throw new RuntimeException(String.format(
+ "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp
+ - timestamp));
+ }
+
+ if (lastTimestamp == timestamp) {
+ sequence = (sequence + 1) & sequenceMask;
+ if (sequence == 0) {
+ timestamp = untilNextMillis(lastTimestamp);
+ }
+ } else {
+ sequence = 0L;
+ }
+
+ lastTimestamp = timestamp;
+
+ return ((timestamp - twepoch) << timestampLeftShift) | sequence;
+ }
+
+ public static long getRealTimestamp(long id) {
+ return (id >> timestampLeftShift) + twepoch;
+ }
+
+ private static long untilNextMillis(long lastTimestamp) {
+ long timestamp = timeGen();
+ while (timestamp <= lastTimestamp) {
+ timestamp = timeGen();
+ }
+ return timestamp;
+ }
+
+ private static long timeGen() {
+ return System.currentTimeMillis();
+ }
+
+}
\ No newline at end of file
diff --git a/server/common/util/src/test/java/com/alipay/sofa/registry/task/listener/TaskListenerTest.java b/server/common/util/src/test/java/com/alipay/sofa/registry/task/listener/TaskListenerTest.java
index 9443f5d44..1e7d0acd5 100644
--- a/server/common/util/src/test/java/com/alipay/sofa/registry/task/listener/TaskListenerTest.java
+++ b/server/common/util/src/test/java/com/alipay/sofa/registry/task/listener/TaskListenerTest.java
@@ -16,13 +16,15 @@
*/
package com.alipay.sofa.registry.task.listener;
+import static com.alipay.sofa.registry.task.listener.TaskEvent.TaskType.CANCEL_DATA_TASK;
+import static com.alipay.sofa.registry.task.listener.TaskEvent.TaskType.DATA_PUSH_TASK;
+import static com.alipay.sofa.registry.task.listener.TaskEvent.TaskType.WATCHER_REGISTER_FETCH_TASK;
+
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
-import static com.alipay.sofa.registry.task.listener.TaskEvent.TaskType.CANCEL_DATA_TASK;
-import static com.alipay.sofa.registry.task.listener.TaskEvent.TaskType.DATA_PUSH_TASK;
-import static com.alipay.sofa.registry.task.listener.TaskEvent.TaskType.WATCHER_REGISTER_FETCH_TASK;
+import com.alipay.sofa.registry.task.listener.TaskEvent.TaskType;
/**
* @author xuanbei
@@ -65,8 +67,8 @@ public void doTest() {
private static class DataPushTaskListener implements TaskListener {
@Override
- public boolean support(TaskEvent event) {
- return DATA_PUSH_TASK.equals(event.getTaskType());
+ public TaskType support() {
+ return DATA_PUSH_TASK;
}
@Override
@@ -77,8 +79,8 @@ public void handleEvent(TaskEvent event) {
private static class CancelDataTaskListener implements TaskListener {
@Override
- public boolean support(TaskEvent event) {
- return TaskEvent.TaskType.CANCEL_DATA_TASK.equals(event.getTaskType());
+ public TaskType support() {
+ return TaskType.CANCEL_DATA_TASK;
}
@Override
@@ -89,8 +91,8 @@ public void handleEvent(TaskEvent event) {
private static class WatcherRegisterFetchTaskListener implements TaskListener {
@Override
- public boolean support(TaskEvent event) {
- return TaskEvent.TaskType.WATCHER_REGISTER_FETCH_TASK.equals(event.getTaskType());
+ public TaskType support() {
+ return TaskType.WATCHER_REGISTER_FETCH_TASK;
}
@Override
diff --git a/server/common/util/src/test/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimerTest.java b/server/common/util/src/test/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimerTest.java
index 11b63f53b..dbabd7faf 100644
--- a/server/common/util/src/test/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimerTest.java
+++ b/server/common/util/src/test/java/com/alipay/sofa/registry/timer/AsyncHashedWheelTimerTest.java
@@ -16,13 +16,15 @@
*/
package com.alipay.sofa.registry.timer;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import io.netty.util.Timer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
import org.junit.Assert;
import org.junit.Test;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+import io.netty.util.Timer;
/**
* @author xuanbei
@@ -40,7 +42,7 @@ public void doTest() throws InterruptedException {
ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder();
threadFactoryBuilder.setDaemon(true);
final Timer timer = new AsyncHashedWheelTimer(threadFactoryBuilder.setNameFormat(
- "AsyncHashedWheelTimerTest").build(), 50, TimeUnit.MILLISECONDS, 10,
+ "AsyncHashedWheelTimerTest").build(), 50, TimeUnit.MILLISECONDS, 10, 5, 10,
threadFactoryBuilder.setNameFormat("Registry-DataNodeServiceImpl-WheelExecutor-%d")
.build(), new AsyncHashedWheelTimer.TaskFailedCallback() {
@Override
diff --git a/server/consistency/pom.xml b/server/consistency/pom.xml
index 7e8855042..af9efc807 100644
--- a/server/consistency/pom.xml
+++ b/server/consistency/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-server-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/consistency/src/main/java/com/alipay/sofa/registry/consistency/hash/ConsistentHash.java b/server/consistency/src/main/java/com/alipay/sofa/registry/consistency/hash/ConsistentHash.java
index 3c6949236..fdcbd2ad6 100644
--- a/server/consistency/src/main/java/com/alipay/sofa/registry/consistency/hash/ConsistentHash.java
+++ b/server/consistency/src/main/java/com/alipay/sofa/registry/consistency/hash/ConsistentHash.java
@@ -148,4 +148,59 @@ public List getNUniqueNodesFor(Object key, int n) {
}
return list;
}
+
+ /**
+ * This returns the closest n unique nodes in order for the object.
+ *
+ * This will return a list that has all nodes if n > number of nodes.
+ *
+ * @param key the key
+ * @param n the n
+ * @param disasterList disaster region name
+ * @return the n unique nodes for
+ */
+ public List getNUniqueNodesFor(Object key, int n, List disasterList) {
+ if (circle.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ if (n > realNodes.size()) {
+ n = realNodes.size();
+ }
+
+ List disasters = disasterList != null && !disasterList.isEmpty() ? disasterList
+ : new ArrayList<>();
+ List list = new ArrayList<>(n);
+ int hash = hashFunction.hash(key);
+ for (int i = 0; i < n; i++) {
+ if (!circle.containsKey(hash)) {
+ // go to next element.
+ SortedMap tailMap = circle.tailMap(hash);
+ hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
+ }
+ T candidate = circle.get(hash);
+ if (!list.contains(candidate)) {
+
+ while (!disasters.isEmpty() && !disasters.contains(candidate.getNodeName())) {
+ hash++;
+ if (!circle.containsKey(hash)) {
+ // go to next element.
+ SortedMap tailMap = circle.tailMap(hash);
+ hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
+ }
+ candidate = circle.get(hash);
+ }
+ list.add(candidate);
+ if (!disasters.isEmpty()) {
+ disasters.remove(candidate.getNodeName());
+ }
+
+ } else {
+ i--; // try again.
+ }
+ // find the next element in the circle
+ hash++;
+ }
+ return list;
+ }
}
diff --git a/server/distribution/data/conf/application.properties b/server/distribution/data/conf/application.properties
index f5ed68c49..28027cb25 100644
--- a/server/distribution/data/conf/application.properties
+++ b/server/distribution/data/conf/application.properties
@@ -1,3 +1,2 @@
nodes.metaNode=DefaultDataCenter:localhost
-nodes.localDataCenter=DefaultDataCenter
-data.server.numberOfReplicas=1
\ No newline at end of file
+nodes.localDataCenter=DefaultDataCenter
\ No newline at end of file
diff --git a/server/distribution/data/distribution-data.xml b/server/distribution/data/distribution-data.xml
index b6a029b0e..630e83144 100644
--- a/server/distribution/data/distribution-data.xml
+++ b/server/distribution/data/distribution-data.xml
@@ -22,17 +22,17 @@
- /
+ ./
registry-data.jar
- /conf
+ ./conf
logback-spring.xml
- /
+ ./
version_${project.version}
diff --git a/server/distribution/data/pom.xml b/server/distribution/data/pom.xml
index 12bbdfe43..00219e935 100644
--- a/server/distribution/data/pom.xml
+++ b/server/distribution/data/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-distribution
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/distribution/integration/conf/application.properties.example b/server/distribution/integration/conf/application.properties.example
index 3ecb93291..513b6c425 100644
--- a/server/distribution/integration/conf/application.properties.example
+++ b/server/distribution/integration/conf/application.properties.example
@@ -42,9 +42,9 @@ session.server.printTask.fixedDelay=30000
session.server.schedulerCheckVersionTimeout=3
session.server.schedulerCheckVersionFirstDelay=3
session.server.schedulerCheckVersionExpBackOffBound=10
-session.server.schedulerHeartbeatTimeout=30
-session.server.schedulerHeartbeatFirstDelay=30
-session.server.schedulerHeartbeatExpBackOffBound=10
+session.server.schedulerHeartbeatTimeout=3
+session.server.schedulerHeartbeatFirstDelay=3
+session.server.schedulerHeartbeatExpBackOffBound=1
session.server.schedulerFetchDataTimeout=3
session.server.schedulerFetchDataFirstDelay=3
session.server.schedulerFetchDataExpBackOffBound=10
diff --git a/server/distribution/integration/distribution-integration.xml b/server/distribution/integration/distribution-integration.xml
index effdaf0fd..305504f53 100644
--- a/server/distribution/integration/distribution-integration.xml
+++ b/server/distribution/integration/distribution-integration.xml
@@ -22,17 +22,17 @@
- /
+ ./
registry-integration.jar
- /conf
+ ./conf
logback-spring.xml
- /
+ ./
version_${project.version}
diff --git a/server/distribution/integration/pom.xml b/server/distribution/integration/pom.xml
index d1bb77c6b..d316c6418 100644
--- a/server/distribution/integration/pom.xml
+++ b/server/distribution/integration/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-distribution
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/distribution/meta/distribution-meta.xml b/server/distribution/meta/distribution-meta.xml
index 29cf277c4..16dda1008 100644
--- a/server/distribution/meta/distribution-meta.xml
+++ b/server/distribution/meta/distribution-meta.xml
@@ -22,17 +22,17 @@
- /
+ ./
registry-meta.jar
- /conf
+ ./conf
logback-spring.xml
- /
+ ./
version_${project.version}
diff --git a/server/distribution/meta/pom.xml b/server/distribution/meta/pom.xml
index 3d7303499..de54ed413 100644
--- a/server/distribution/meta/pom.xml
+++ b/server/distribution/meta/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-distribution
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/distribution/pom.xml b/server/distribution/pom.xml
index 2e13d59b6..03eb6676e 100644
--- a/server/distribution/pom.xml
+++ b/server/distribution/pom.xml
@@ -6,7 +6,7 @@
com.alipay.sofa
registry-server-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/distribution/session/conf/application.properties.example b/server/distribution/session/conf/application.properties.example
index 76a5e17f2..80a9f918a 100644
--- a/server/distribution/session/conf/application.properties.example
+++ b/server/distribution/session/conf/application.properties.example
@@ -19,9 +19,9 @@ session.server.printTask.fixedDelay=30000
session.server.schedulerCheckVersionTimeout=3
session.server.schedulerCheckVersionFirstDelay=3
session.server.schedulerCheckVersionExpBackOffBound=10
-session.server.schedulerHeartbeatTimeout=30
-session.server.schedulerHeartbeatFirstDelay=30
-session.server.schedulerHeartbeatExpBackOffBound=10
+session.server.schedulerHeartbeatTimeout=3
+session.server.schedulerHeartbeatFirstDelay=3
+session.server.schedulerHeartbeatExpBackOffBound=1
session.server.schedulerFetchDataTimeout=3
session.server.schedulerFetchDataFirstDelay=3
session.server.schedulerFetchDataExpBackOffBound=10
diff --git a/server/distribution/session/distribution-session.xml b/server/distribution/session/distribution-session.xml
index 81849467b..06175cb8d 100644
--- a/server/distribution/session/distribution-session.xml
+++ b/server/distribution/session/distribution-session.xml
@@ -22,17 +22,17 @@
- /
+ ./
registry-session.jar
- /conf
+ ./conf
logback-spring.xml
- /
+ ./
version_${project.version}
diff --git a/server/distribution/session/pom.xml b/server/distribution/session/pom.xml
index e7061c240..750e37529 100644
--- a/server/distribution/session/pom.xml
+++ b/server/distribution/session/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-distribution
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/pom.xml b/server/pom.xml
index 23abe7efe..cdc71eb9f 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -7,7 +7,7 @@
com.alipay.sofa
registry-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
diff --git a/server/remoting/api/pom.xml b/server/remoting/api/pom.xml
index 4be3abfe7..fcb259197 100644
--- a/server/remoting/api/pom.xml
+++ b/server/remoting/api/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-remoting
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/CallbackHandler.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/CallbackHandler.java
index 2b32e72a0..aa73eeb46 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/CallbackHandler.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/CallbackHandler.java
@@ -16,6 +16,8 @@
*/
package com.alipay.sofa.registry.remoting;
+import java.util.concurrent.Executor;
+
/**
*
* @author shangyu.wh
@@ -38,4 +40,10 @@ public interface CallbackHandler {
* @param exception
*/
void onException(Channel channel, Throwable exception);
+
+ /**
+ * override executor
+ * @return
+ */
+ Executor getExecutor();
}
\ No newline at end of file
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Channel.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Channel.java
index 4f51ffed2..162c59ca2 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Channel.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Channel.java
@@ -16,9 +16,10 @@
*/
package com.alipay.sofa.registry.remoting;
-import javax.ws.rs.client.WebTarget;
import java.net.InetSocketAddress;
+import javax.ws.rs.client.WebTarget;
+
/**
*
* @author shangyu.wh
@@ -68,4 +69,6 @@ public interface Channel {
* @return
*/
WebTarget getWebTarget();
+
+ void close();
}
\ No newline at end of file
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Client.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Client.java
index f19aba5a6..aa08d9c3e 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Client.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Client.java
@@ -18,9 +18,6 @@
import com.alipay.sofa.registry.common.model.store.URL;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-
/**
*
* @author shangyu.wh
@@ -28,21 +25,6 @@
*/
public interface Client extends Endpoint {
- /**
- * get channels.
- *
- * @return channels
- */
- Collection getChannels();
-
- /**
- * get channel.
- *
- * @param remoteAddress
- * @return channel
- */
- Channel getChannel(InetSocketAddress remoteAddress);
-
/**
* get channel by url.
*
@@ -57,4 +39,35 @@ public interface Client extends Endpoint {
* @return
*/
Channel connect(URL url);
+
+ /**
+ * Sync send
+ *
+ * @param url the url
+ * @param message the message
+ * @param timeoutMillis the timeout millis
+ * @return object
+ */
+ Object sendSync(final URL url, final Object message, final int timeoutMillis);
+
+ /**
+ * Sync send
+ *
+ * @param channel the channel
+ * @param message the message
+ * @param timeoutMillis the timeout millis
+ * @return object
+ */
+ Object sendSync(final Channel channel, final Object message, final int timeoutMillis);
+
+ /**
+ * send with callback handler
+ *
+ * @param url the url
+ * @param message the message
+ * @param callbackHandler the callback handler
+ * @param timeoutMillis the timeout millis
+ */
+ void sendCallback(final URL url, final Object message, CallbackHandler callbackHandler,
+ final int timeoutMillis);
}
\ No newline at end of file
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Endpoint.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Endpoint.java
index 10cff4f22..d1b23ab5f 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Endpoint.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Endpoint.java
@@ -17,22 +17,16 @@
package com.alipay.sofa.registry.remoting;
import java.net.InetSocketAddress;
-import java.util.List;
/**
* The interface Endpoint.
+ *
* @author shangyu.wh
+ * @author kezhu.wukz
* @version $Id : Endpoint.java, v 0.1 2017-11-20 20:03 shangyu.wh Exp $
*/
public interface Endpoint {
- /**
- * get channel handlers.
- *
- * @return channel handlers
- */
- List getChannelHandlers();
-
/**
* get local address.
*
@@ -45,13 +39,6 @@ public interface Endpoint {
*/
void close();
- /**
- * Close.
- *
- * @param channel the channel
- */
- void close(final Channel channel);
-
/**
* is closed.
*
@@ -59,31 +46,4 @@ public interface Endpoint {
*/
boolean isClosed();
- /**
- * oneway send
- * @param channel the channel
- * @param message the message
- */
- void sendOneway(final Channel channel, final Object message);
-
- /**
- * Sync send
- *
- * @param channel the channel
- * @param message the message
- * @param timeoutMillis the timeout millis
- * @return object
- */
- Object sendSync(final Channel channel, final Object message, final int timeoutMillis);
-
- /**
- * send with callback handler
- *
- * @param channel the channel
- * @param message the message
- * @param callbackHandler the callback handler
- * @param timeoutMillis the timeout millis
- */
- void sendCallback(final Channel channel, final Object message, CallbackHandler callbackHandler,
- final int timeoutMillis);
}
\ No newline at end of file
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Server.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Server.java
index 7452bb4f4..5b3de39d7 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Server.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/Server.java
@@ -16,11 +16,11 @@
*/
package com.alipay.sofa.registry.remoting;
-import com.alipay.sofa.registry.common.model.store.URL;
-
import java.net.InetSocketAddress;
import java.util.Collection;
+import com.alipay.sofa.registry.common.model.store.URL;
+
/**
*
* @author shangyu.wh
@@ -57,4 +57,34 @@ public interface Server extends Endpoint {
* @return channel
*/
Channel getChannel(URL url);
+
+ /**
+ * close the channel.
+ *
+ * @param channel
+ */
+ void close(Channel channel);
+
+ int getChannelCount();
+
+ /**
+ * Sync send
+ *
+ * @param channel the channel
+ * @param message the message
+ * @param timeoutMillis the timeout millis
+ * @return object
+ */
+ Object sendSync(final Channel channel, final Object message, final int timeoutMillis);
+
+ /**
+ * send with callback handler
+ *
+ * @param channel the channel
+ * @param message the message
+ * @param callbackHandler the callback handler
+ * @param timeoutMillis the timeout millis
+ */
+ void sendCallback(final Channel channel, final Object message, CallbackHandler callbackHandler,
+ final int timeoutMillis);
}
\ No newline at end of file
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/Exchange.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/Exchange.java
index 961167107..f0f286413 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/Exchange.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/Exchange.java
@@ -41,6 +41,18 @@ public interface Exchange {
*/
Client connect(String serverType, URL serverUrl, T... channelHandlers);
+ /**
+ * connect same type server,one server ip one connection
+ * such as different server on data server,serverOne and serverTwo,different type server must match different channelHandlers,
+ * so we must connect by serverType,and get Client instance by serverType
+ * @param serverType
+ * @param connNum connection number per serverUrl
+ * @param serverUrl
+ * @param channelHandlers
+ * @return
+ */
+ Client connect(String serverType, int connNum, URL serverUrl, T... channelHandlers);
+
/**
* bind server by server port in url parameter,one port must by same server type
* @param url
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/RequestException.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/RequestException.java
index 3340bbf4b..1d5fa3e06 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/RequestException.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/RequestException.java
@@ -25,7 +25,8 @@
*/
public class RequestException extends Exception {
- private Request request;
+ private static final int MAX_BODY_SIZE = 512;
+ private Request request;
/**
* constructor
@@ -77,14 +78,19 @@ public RequestException(Throwable cause) {
* get requestInfo from Request
* @return
*/
- public String getRequestMessage() {
+ @Override
+ public String getMessage() {
StringBuilder sb = new StringBuilder();
if (request != null) {
- sb.append("Request url:").append(request.getRequestUrl()).append(" body:")
- .append(request.getRequestBody());
- } else {
- sb.append("Request data can not be null!");
+ String requestBody = request.getRequestBody() != null ? request.getRequestBody()
+ .toString() : "null";
+ if (requestBody.length() > MAX_BODY_SIZE) {
+ requestBody = requestBody.substring(0, MAX_BODY_SIZE);
+ }
+ sb.append("request url: ").append(request.getRequestUrl()).append(", body: ")
+ .append(requestBody).append(", ");
}
+ sb.append(super.getMessage());
return sb.toString();
}
}
\ No newline at end of file
diff --git a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/message/Request.java b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/message/Request.java
index 7bf15fff0..473ed2fc4 100644
--- a/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/message/Request.java
+++ b/server/remoting/api/src/main/java/com/alipay/sofa/registry/remoting/exchange/message/Request.java
@@ -16,11 +16,11 @@
*/
package com.alipay.sofa.registry.remoting.exchange.message;
+import java.util.concurrent.atomic.AtomicInteger;
+
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.remoting.CallbackHandler;
-import java.util.concurrent.atomic.AtomicInteger;
-
/**
* The interface Request.
*
@@ -60,4 +60,8 @@ default CallbackHandler getCallBackHandler() {
default AtomicInteger getRetryTimes() {
return new AtomicInteger();
}
+
+ default Integer getTimeout() {
+ return null;
+ }
}
\ No newline at end of file
diff --git a/server/remoting/api/src/test/java/com/alipay/sofa/registry/remoting/RequestExceptionTest.java b/server/remoting/api/src/test/java/com/alipay/sofa/registry/remoting/RequestExceptionTest.java
index 7f98cc690..03c7f8526 100644
--- a/server/remoting/api/src/test/java/com/alipay/sofa/registry/remoting/RequestExceptionTest.java
+++ b/server/remoting/api/src/test/java/com/alipay/sofa/registry/remoting/RequestExceptionTest.java
@@ -16,11 +16,12 @@
*/
package com.alipay.sofa.registry.remoting;
+import org.junit.Assert;
+import org.junit.Test;
+
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.remoting.exchange.RequestException;
import com.alipay.sofa.registry.remoting.exchange.message.Request;
-import org.junit.Assert;
-import org.junit.Test;
/**
* @author xuanbei
@@ -31,18 +32,16 @@ public class RequestExceptionTest {
public void doTest() {
RequestException exception = new RequestException("error message");
Assert.assertEquals("error message", exception.getMessage());
- Assert.assertEquals("Request data can not be null!", exception.getRequestMessage());
RuntimeException runtimeException = new RuntimeException("error message");
exception = new RequestException(runtimeException);
Assert.assertEquals("java.lang.RuntimeException: error message", exception.getMessage());
Assert.assertEquals(runtimeException, exception.getCause());
- Assert.assertEquals("Request data can not be null!", exception.getRequestMessage());
+ Assert.assertEquals("java.lang.RuntimeException: error message", exception.getMessage());
exception = new RequestException("error message", runtimeException);
Assert.assertEquals("error message", exception.getMessage());
Assert.assertEquals(runtimeException, exception.getCause());
- Assert.assertEquals("Request data can not be null!", exception.getRequestMessage());
Request request = new Request() {
@Override
@@ -56,11 +55,11 @@ public URL getRequestUrl() {
}
};
exception = new RequestException("error message", request);
- Assert.assertEquals("error message", exception.getMessage());
- Assert.assertEquals("Request url:null body:request body", exception.getRequestMessage());
+ Assert.assertEquals("request url: null, body: request body, error message",
+ exception.getMessage());
exception = new RequestException("error message", request, runtimeException);
- Assert.assertEquals("error message", exception.getMessage());
- Assert.assertEquals("Request url:null body:request body", exception.getRequestMessage());
+ Assert.assertEquals("request url: null, body: request body, error message",
+ exception.getMessage());
}
}
diff --git a/server/remoting/bolt/pom.xml b/server/remoting/bolt/pom.xml
index 21262538c..3c256443a 100644
--- a/server/remoting/bolt/pom.xml
+++ b/server/remoting/bolt/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-remoting
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltChannel.java b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltChannel.java
index 0e857268d..9a4ddd334 100644
--- a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltChannel.java
+++ b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltChannel.java
@@ -16,19 +16,21 @@
*/
package com.alipay.sofa.registry.remoting.bolt;
+import java.net.InetSocketAddress;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.ws.rs.client.WebTarget;
+
import com.alipay.remoting.AsyncContext;
import com.alipay.remoting.BizContext;
import com.alipay.remoting.Connection;
import com.alipay.sofa.registry.remoting.Channel;
-import javax.ws.rs.client.WebTarget;
-import java.net.InetSocketAddress;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
*
* @author shangyu.wh
+ * @author kezhu.wukz
* @version $Id: BoltChannel.java, v 0.1 2017-11-24 16:46 shangyu.wh Exp $
*/
public class BoltChannel implements Channel {
@@ -84,6 +86,11 @@ public WebTarget getWebTarget() {
return null;
}
+ @Override
+ public void close() {
+ this.connection.close();
+ }
+
/**
* Getter method for property connection.
*
diff --git a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltClient.java b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltClient.java
index ad09d9b31..b7dc0b04d 100644
--- a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltClient.java
+++ b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltClient.java
@@ -16,11 +16,19 @@
*/
package com.alipay.sofa.registry.remoting.bolt;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import com.alipay.remoting.Connection;
+import com.alipay.remoting.ConnectionEventProcessor;
import com.alipay.remoting.ConnectionEventType;
import com.alipay.remoting.InvokeCallback;
+import com.alipay.remoting.Url;
import com.alipay.remoting.exception.RemotingException;
import com.alipay.remoting.rpc.RpcClient;
+import com.alipay.remoting.rpc.protocol.RpcProtocol;
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.log.Logger;
import com.alipay.sofa.registry.log.LoggerFactory;
@@ -32,151 +40,136 @@
import com.alipay.sofa.registry.remoting.ChannelHandler.InvokeType;
import com.alipay.sofa.registry.remoting.Client;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-
/**
* The type Bolt client.
+ *
+ * @author kezhu.wukz
* @author shangyu.wh
* @version $Id : BoltClient.java, v 0.1 2017-11-27 14:46 shangyu.wh Exp $
*/
public class BoltClient implements Client {
- private static final Logger LOGGER = LoggerFactory.getLogger(BoltClient.class);
- private RpcClient boltClient;
- private List channelHandlers = new ArrayList<>();
- private Map channels = new HashMap<>();
- private AtomicBoolean initHandler = new AtomicBoolean(false);
+ private static final Logger LOGGER = LoggerFactory.getLogger(BoltClient.class);
+
+ private RpcClient rpcClient;
+
+ private AtomicBoolean closed = new AtomicBoolean(false);
+
+ private int connectTimeout = 2000;
+
+ private final int connNum;
/**
* Instantiates a new Bolt client.
*/
- public BoltClient() {
- boltClient = new RpcClient();
- boltClient.init();
- }
+ public BoltClient(int connNum) {
+ rpcClient = new RpcClient();
+ rpcClient.init();
- @Override
- public Channel connect(URL targetUrl) {
+ this.connNum = connNum;
+ }
- if (targetUrl == null) {
- throw new IllegalArgumentException("Create connection targetUrl can not be null!");
- }
- InetSocketAddress address = URL.toInetSocketAddress(targetUrl);
- Channel c = getChannel(address);
- if (c != null && c.isConnected()) {
- LOGGER.info("Target url:" + targetUrl + " has been connected!", targetUrl);
- return c;
+ /**
+ * Setter method for property channelHandlers.
+ *
+ * @param channelHandlers value to be assigned to property channelHandlers
+ */
+ public void initHandlers(List channelHandlers) {
+ ChannelHandler connectionEventHandler = null;
+ for (ChannelHandler channelHandler : channelHandlers) {
+ if (HandlerType.LISENTER.equals(channelHandler.getType())) {
+ connectionEventHandler = channelHandler;
+ break;
+ }
}
- initHandler();
-
- try {
- Connection connection = boltClient
- .getConnection(NetUtil.toAddressString(address), 1000);
- if (connection != null) {
- BoltChannel channel = new BoltChannel();
- channel.setConnection(connection);
- channels.put(connection.getUrl().getOriginUrl(), channel);
- return channel;
- } else {
- throw new RuntimeException("Bolt client connect server get none connection!");
+ rpcClient.addConnectionEventProcessor(ConnectionEventType.CONNECT,
+ newConnectionEventAdapter(connectionEventHandler, ConnectionEventType.CONNECT));
+ rpcClient.addConnectionEventProcessor(ConnectionEventType.CLOSE,
+ newConnectionEventAdapter(connectionEventHandler, ConnectionEventType.CLOSE));
+ rpcClient.addConnectionEventProcessor(ConnectionEventType.EXCEPTION,
+ newConnectionEventAdapter(connectionEventHandler, ConnectionEventType.EXCEPTION));
+
+ for (ChannelHandler channelHandler : channelHandlers) {
+ if (HandlerType.PROCESSER.equals(channelHandler.getType())) {
+ if (InvokeType.SYNC.equals(channelHandler.getInvokeType())) {
+ rpcClient.registerUserProcessor(newSyncProcessor(channelHandler));
+ } else {
+ rpcClient.registerUserProcessor(newAsyncProcessor(channelHandler));
+ }
}
-
- } catch (RemotingException e) {
- LOGGER.error("Bolt client connect server got a RemotingException! target url:"
- + targetUrl, e);
- throw new RuntimeException("Bolt client connect server got a RemotingException!", e);
- } catch (InterruptedException e) {
- LOGGER.error("Bolt client connect server has been Interrupted!", e);
- throw new RuntimeException("Bolt client connect server has been Interrupted!", e);
}
}
- private void initHandler() {
-
- if (initHandler.compareAndSet(false, true)) {
- boltClient.addConnectionEventProcessor(ConnectionEventType.CONNECT,
- new ConnectionEventAdapter(ConnectionEventType.CONNECT,
- getConnectionEventHandler(), null));
- boltClient.addConnectionEventProcessor(ConnectionEventType.CLOSE,
- new ConnectionEventAdapter(ConnectionEventType.CLOSE, getConnectionEventHandler(),
- null));
- boltClient.addConnectionEventProcessor(ConnectionEventType.EXCEPTION,
- new ConnectionEventAdapter(ConnectionEventType.EXCEPTION,
- getConnectionEventHandler(), null));
+ protected ConnectionEventProcessor newConnectionEventAdapter(ChannelHandler connectionEventHandler,
+ ConnectionEventType connectEventType) {
+ return new ConnectionEventAdapter(connectEventType, connectionEventHandler, null);
+ }
- registerUserProcessorHandler();
- }
+ protected AsyncUserProcessorAdapter newAsyncProcessor(ChannelHandler channelHandler) {
+ return new AsyncUserProcessorAdapter(channelHandler);
}
- private void registerUserProcessorHandler() {
- if (channelHandlers != null) {
- for (ChannelHandler channelHandler : channelHandlers) {
- if (HandlerType.PROCESSER.equals(channelHandler.getType())) {
- if (InvokeType.SYNC.equals(channelHandler.getInvokeType())) {
- boltClient.registerUserProcessor(new SyncUserProcessorAdapter(
- channelHandler));
- } else {
- boltClient.registerUserProcessor(new AsyncUserProcessorAdapter(
- channelHandler));
- }
- }
- }
- }
+ protected SyncUserProcessorAdapter newSyncProcessor(ChannelHandler channelHandler) {
+ return new SyncUserProcessorAdapter(channelHandler);
}
@Override
- public Collection getChannels() {
-
- Collection chs = new HashSet<>();
- for (Channel channel : this.channels.values()) {
- if (channel.isConnected()) {
- chs.add(channel);
- } else {
- channels.remove(NetUtil.toAddressString(channel.getRemoteAddress()));
- }
+ public Channel connect(URL url) {
+ if (url == null) {
+ throw new IllegalArgumentException("Create connection url can not be null!");
}
- return chs;
- }
+ try {
+ Connection connection = getBoltConnection(rpcClient, url);
+ BoltChannel channel = new BoltChannel();
+ channel.setConnection(connection);
+ return channel;
- @Override
- public Channel getChannel(InetSocketAddress remoteAddress) {
- Channel c = channels.get(NetUtil.toAddressString(remoteAddress));
- if (c == null || !c.isConnected()) {
- return null;
+ } catch (RemotingException e) {
+ LOGGER
+ .error("Bolt client connect server got a RemotingException! target url:" + url, e);
+ throw new RuntimeException("Bolt client connect server got a RemotingException!", e);
}
- return c;
}
- @Override
- public Channel getChannel(URL url) {
- Channel c = channels.get(url.getAddressString());
- if (c == null || !c.isConnected()) {
- return null;
+ protected Connection getBoltConnection(RpcClient rpcClient, URL url) throws RemotingException {
+ Url boltUrl = createBoltUrl(url);
+ try {
+ Connection connection = rpcClient.getConnection(boltUrl, connectTimeout);
+ if (connection == null || !connection.isFine()) {
+ if (connection != null) {
+ connection.close();
+ }
+ throw new RemotingException("Get bolt connection failed for boltUrl: " + boltUrl);
+ }
+ return connection;
+ } catch (InterruptedException e) {
+ throw new RuntimeException(
+ "BoltClient rpcClient.getConnection InterruptedException! target boltUrl:"
+ + boltUrl, e);
}
- return c;
}
- @Override
- public List getChannelHandlers() {
- return channelHandlers;
+ protected Url createBoltUrl(URL url) {
+ Url boltUrl = new Url(url.getIpAddress(), url.getPort());
+ boltUrl.setProtocol(RpcProtocol.PROTOCOL_CODE);
+ boltUrl.setConnNum(connNum);
+ boltUrl.setConnWarmup(true);
+ return boltUrl;
}
- /**
- * Setter method for property channelHandlers.
- *
- * @param channelHandlers value to be assigned to property channelHandlers
- */
- public void setChannelHandlers(List channelHandlers) {
- this.channelHandlers = channelHandlers;
+ @Override
+ public Channel getChannel(URL url) {
+ try {
+ Connection connection = getBoltConnection(rpcClient, url);
+ BoltChannel channel = new BoltChannel();
+ channel.setConnection(connection);
+ return channel;
+ } catch (RemotingException e) {
+ LOGGER
+ .error("Bolt client connect server got a RemotingException! target url:" + url, e);
+ throw new RuntimeException("Bolt client connect server got a RemotingException!", e);
+ }
}
@Override
@@ -184,100 +177,46 @@ public InetSocketAddress getLocalAddress() {
return NetUtil.getLocalSocketAddress();
}
- /**
- * Gets connection event handler.
- *
- * @return the connection event handler
- */
- public ChannelHandler getConnectionEventHandler() {
- if (channelHandlers != null) {
- for (ChannelHandler channelHandler : channelHandlers) {
- if (HandlerType.LISENTER.equals(channelHandler.getType())) {
- return channelHandler;
- }
- }
- }
- return null;
- }
-
@Override
public void close() {
- Collection chs = getChannels();
- if (chs != null && chs.size() > 0) {
- for (Channel ch : chs) {
- if (ch != null) {
- boltClient.closeStandaloneConnection(((BoltChannel) ch).getConnection());
- }
- }
- }
- }
-
- @Override
- public void close(Channel channel) {
- if (channel != null) {
- Connection connection = ((BoltChannel) channel).getConnection();
- if (null != connection.getUrl() && null != connection.getUrl().getOriginUrl()) {
- channels.remove(connection.getUrl().getOriginUrl());
- }
- boltClient.closeStandaloneConnection(connection);
+ if (closed.compareAndSet(false, true)) {
+ rpcClient.shutdown();
}
}
@Override
public boolean isClosed() {
- boolean ret = false;
- Collection chs = getChannels();
- if (chs != null && chs.size() > 0) {
- for (Channel ch : chs) {
- if (ch != null && !ch.isConnected()) {
- ret = true;
- break;
- }
- }
- } else {
- //has no channels
- return true;
- }
- return ret;
+ return closed.get();
}
@Override
- public void sendOneway(Channel channel, Object message) {
- if (channel != null && channel.isConnected()) {
- if (channel instanceof BoltChannel) {
- BoltChannel boltChannel = (BoltChannel) channel;
- try {
- boltClient.oneway(boltChannel.getConnection(), message);
- } catch (RemotingException e) {
- LOGGER.error("Bolt Client oneway request RemotingException! target url: {}",
- boltChannel.getRemoteAddress(), e);
- }
- }
+ public Object sendSync(URL url, Object message, int timeoutMillis) {
+ try {
+ return rpcClient.invokeSync(createBoltUrl(url), message, timeoutMillis);
+ } catch (RemotingException e) {
+ String msg = "Bolt Client sendSync message RemotingException! target url:" + url;
+ LOGGER.error(msg, e);
+ throw new RuntimeException(msg, e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(
+ "Bolt Client sendSync message InterruptedException! target url:" + url, e);
}
}
@Override
public Object sendSync(Channel channel, Object message, int timeoutMillis) {
-
if (channel != null && channel.isConnected()) {
- if (channel instanceof BoltChannel) {
- BoltChannel boltChannel = (BoltChannel) channel;
- try {
- return boltClient.invokeSync(boltChannel.getConnection(), message,
- timeoutMillis);
- } catch (RemotingException e) {
- LOGGER.error("Bolt Client sendSync message RemotingException! target url:"
- + boltChannel.getRemoteAddress(), e);
- throw new RuntimeException("Bolt Client sendSync message RemotingException!", e);
- } catch (InterruptedException e) {
- LOGGER.error("Bolt Client sendSync message InterruptedException! target url:"
- + boltChannel.getRemoteAddress(), e);
- throw new RuntimeException(
- "Bolt Client sendSync message InterruptedException!", e);
- }
- } else {
- throw new IllegalArgumentException("Input channel instance error! instance class:"
- + channel.getClass().getName());
+ BoltChannel boltChannel = (BoltChannel) channel;
+ try {
+ return rpcClient.invokeSync(boltChannel.getConnection(), message, timeoutMillis);
+ } catch (RemotingException e) {
+ LOGGER.error("Bolt Client sendSync message RemotingException! target boltUrl:"
+ + boltChannel.getRemoteAddress(), e);
+ throw new RuntimeException("Bolt Client sendSync message RemotingException!", e);
+ } catch (InterruptedException e) {
+ LOGGER.error("Bolt Client sendSync message InterruptedException! target boltUrl:"
+ + boltChannel.getRemoteAddress(), e);
+ throw new RuntimeException("Bolt Client sendSync message InterruptedException!", e);
}
}
throw new IllegalArgumentException(
@@ -286,44 +225,35 @@ public Object sendSync(Channel channel, Object message, int timeoutMillis) {
}
@Override
- public void sendCallback(Channel channel, Object message, CallbackHandler callbackHandler,
+ public void sendCallback(URL url, Object message, CallbackHandler callbackHandler,
int timeoutMillis) {
- if (channel != null && channel.isConnected()) {
- if (channel instanceof BoltChannel) {
- BoltChannel boltChannel = (BoltChannel) channel;
- try {
- boltClient.invokeWithCallback(boltChannel.getConnection(), message,
- new InvokeCallback() {
-
- @Override
- public void onResponse(Object result) {
- callbackHandler.onCallback(channel, result);
- }
+ try {
+ Connection connection = getBoltConnection(rpcClient, url);
+ BoltChannel channel = new BoltChannel();
+ channel.setConnection(connection);
+ rpcClient.invokeWithCallback(connection, message, new InvokeCallback() {
+
+ @Override
+ public void onResponse(Object result) {
+ callbackHandler.onCallback(channel, result);
+ }
- @Override
- public void onException(Throwable e) {
- callbackHandler.onException(channel, e);
- }
+ @Override
+ public void onException(Throwable e) {
+ callbackHandler.onException(channel, e);
+ }
- @Override
- public Executor getExecutor() {
- return null;
- }
- }, timeoutMillis);
- return;
- } catch (RemotingException e) {
- LOGGER.error("Bolt Client sendSync message RemotingException! target url:"
- + boltChannel.getRemoteAddress(), e);
- throw new RuntimeException("Bolt Client sendSync message RemotingException!", e);
+ @Override
+ public Executor getExecutor() {
+ return callbackHandler.getExecutor();
}
- } else {
- throw new IllegalArgumentException("Input channel instance error! instance class:"
- + channel.getClass().getName());
- }
+ }, timeoutMillis);
+ return;
+ } catch (RemotingException e) {
+ String msg = "Bolt Client sendSync message RemotingException! target url:" + url;
+ LOGGER.error(msg, e);
+ throw new RuntimeException(msg, e);
}
- throw new IllegalArgumentException(
- "Input channel: " + channel
- + " error! channel cannot be null,or channel must be connected!");
}
}
\ No newline at end of file
diff --git a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltServer.java b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltServer.java
index e9fc9ed38..547c073e8 100644
--- a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltServer.java
+++ b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/BoltServer.java
@@ -16,6 +16,16 @@
*/
package com.alipay.sofa.registry.remoting.bolt;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import com.alipay.remoting.Connection;
import com.alipay.remoting.ConnectionEventType;
import com.alipay.remoting.InvokeCallback;
@@ -33,16 +43,6 @@
import com.alipay.sofa.registry.remoting.ChannelHandler.InvokeType;
import com.alipay.sofa.registry.remoting.Server;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-
/**
*
* @author shangyu.wh
@@ -206,11 +206,6 @@ public Channel getChannel(URL url) {
return null;
}
- @Override
- public List getChannelHandlers() {
- return channelHandlers;
- }
-
@Override
public InetSocketAddress getLocalAddress() {
return new InetSocketAddress(url.getPort());
@@ -240,49 +235,27 @@ public boolean isClosed() {
return !isStarted.get();
}
- @Override
- public void sendOneway(Channel channel, Object message) {
- if (channel != null && channel.isConnected()) {
- try {
- Url url = new Url(channel.getRemoteAddress().getAddress().getHostAddress(), channel
- .getRemoteAddress().getPort());
-
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Bolt Server one way message:{} , target url:{}", message, url);
- }
- boltServer.oneway(url, message);
- } catch (RemotingException e) {
- LOGGER.error("Bolt Server one way message RemotingException! target url:" + url, e);
- throw new RuntimeException("Bolt Server one way message RemotingException!", e);
- } catch (InterruptedException e) {
- LOGGER.error("Bolt Server one way message InterruptedException! target url:" + url,
- e);
- throw new RuntimeException("Bolt Server one way message InterruptedException!", e);
- }
- }
- throw new IllegalArgumentException(
- "Send message connection can not be null or connection not be connected!");
- }
-
@Override
public Object sendSync(Channel channel, Object message, int timeoutMillis) {
if (channel != null && channel.isConnected()) {
+ Url boltUrl = null;
try {
- Url url = new Url(channel.getRemoteAddress().getAddress().getHostAddress(), channel
+ boltUrl = new Url(channel.getRemoteAddress().getAddress().getHostAddress(), channel
.getRemoteAddress().getPort());
if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Bolt Server sendSync message:{} , target url:{}", message, url);
+ LOGGER.debug("Bolt Server sendSync message:{} , target url:{}", message,
+ boltUrl);
}
- return boltServer.invokeSync(url, message, timeoutMillis);
+ return boltServer.invokeSync(boltUrl, message, timeoutMillis);
} catch (RemotingException e) {
- LOGGER
- .error("Bolt Server sendSync message RemotingException! target url:" + url, e);
+ LOGGER.error("Bolt Server sendSync message RemotingException! target url:"
+ + boltUrl, e);
throw new RuntimeException("Bolt Server sendSync message RemotingException!", e);
} catch (InterruptedException e) {
- LOGGER.error(
- "Bolt Server sendSync message InterruptedException! target url:" + url, e);
+ LOGGER.error("Bolt Server sendSync message InterruptedException! target url:"
+ + boltUrl, e);
throw new RuntimeException("Bolt Server sendSync message InterruptedException!", e);
}
}
@@ -294,14 +267,16 @@ public Object sendSync(Channel channel, Object message, int timeoutMillis) {
public void sendCallback(Channel channel, Object message, CallbackHandler callbackHandler,
int timeoutMillis) {
if (channel != null && channel.isConnected()) {
+ Url boltUrl = null;
try {
- Url url = new Url(channel.getRemoteAddress().getAddress().getHostAddress(), channel
+ boltUrl = new Url(channel.getRemoteAddress().getAddress().getHostAddress(), channel
.getRemoteAddress().getPort());
if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Bolt Server sendSync message:{} , target url:{}", message, url);
+ LOGGER.debug("Bolt Server sendSync message:{} , target url:{}", message,
+ boltUrl);
}
- boltServer.invokeWithCallback(url, message, new InvokeCallback() {
+ boltServer.invokeWithCallback(boltUrl, message, new InvokeCallback() {
@Override
public void onResponse(Object result) {
callbackHandler.onCallback(channel, result);
@@ -314,7 +289,7 @@ public void onException(Throwable e) {
@Override
public Executor getExecutor() {
- return null;
+ return callbackHandler.getExecutor();
}
}, timeoutMillis);
return;
@@ -322,7 +297,8 @@ public Executor getExecutor() {
throw new RuntimeException("Bolt Server invoke with callback RemotingException!", e);
} catch (InterruptedException e) {
PUSH_LOGGER.error(
- "Bolt Server invoke with callback InterruptedException! target url:" + url, e);
+ "Bolt Server invoke with callback InterruptedException! target url:" + boltUrl,
+ e);
throw new RuntimeException(
"Bolt Server invoke with callback InterruptedException!", e);
}
@@ -342,4 +318,9 @@ public void removeChannel(Channel channel) {
public RpcServer getRpcServer() {
return boltServer;
}
+
+ @Override
+ public int getChannelCount() {
+ return channels.size();
+ }
}
\ No newline at end of file
diff --git a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/exchange/BoltExchange.java b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/exchange/BoltExchange.java
index 701729786..52627f664 100644
--- a/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/exchange/BoltExchange.java
+++ b/server/remoting/bolt/src/main/java/com/alipay/sofa/registry/remoting/bolt/exchange/BoltExchange.java
@@ -16,8 +16,11 @@
*/
package com.alipay.sofa.registry.remoting.bolt.exchange;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import com.alipay.sofa.registry.common.model.store.URL;
-import com.alipay.sofa.registry.remoting.Channel;
import com.alipay.sofa.registry.remoting.ChannelHandler;
import com.alipay.sofa.registry.remoting.Client;
import com.alipay.sofa.registry.remoting.Server;
@@ -25,10 +28,6 @@
import com.alipay.sofa.registry.remoting.bolt.BoltServer;
import com.alipay.sofa.registry.remoting.exchange.Exchange;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
*
* @author shangyu.wh
@@ -42,38 +41,26 @@ public class BoltExchange implements Exchange {
@Override
public Client connect(String serverType, URL serverUrl, ChannelHandler... channelHandlers) {
+ return this.connect(serverType, 1, serverUrl, channelHandlers);
+ }
+ @Override
+ public Client connect(String serverType, int connNum, URL serverUrl, ChannelHandler... channelHandlers) {
if (channelHandlers == null) {
throw new IllegalArgumentException("channelHandlers cannot be null!");
}
- Client client = clients.get(serverType);
- if (client == null) {
- BoltClient boltClient = new BoltClient();
- boltClient.setChannelHandlers(Arrays.asList(channelHandlers));
- boltClient.connect(serverUrl);
- client = clients.putIfAbsent(serverType, boltClient);
- if (client == null) {
- client = boltClient;
- }
- } else {
- Channel channel = client.getChannel(serverUrl);
- if (channel == null) {
- BoltClient boltClient = (BoltClient) client;
- boltClient.setChannelHandlers(Arrays.asList(channelHandlers));
- boltClient.connect(serverUrl);
- }
- }
+ Client client = clients.computeIfAbsent(serverType, key -> newBoltClient(connNum, channelHandlers));
+ client.connect(serverUrl);
return client;
}
@Override
public Server open(URL url, ChannelHandler... channelHandlers) {
-
if (channelHandlers == null) {
throw new IllegalArgumentException("channelHandlers cannot be null!");
}
- BoltServer server = new BoltServer(url, Arrays.asList(channelHandlers));
+ BoltServer server = createBoltServer(url, channelHandlers);
setServer(server, url);
server.startServer();
return server;
@@ -97,4 +84,18 @@ public Server getServer(Integer port) {
public void setServer(Server server, URL url) {
serverMap.putIfAbsent(url.getPort(), server);
}
+
+ private BoltClient newBoltClient(int connNum, ChannelHandler[] channelHandlers) {
+ BoltClient boltClient = createBoltClient(connNum);
+ boltClient.initHandlers(Arrays.asList(channelHandlers));
+ return boltClient;
+ }
+
+ protected BoltClient createBoltClient(int connNum) {
+ return new BoltClient(connNum);
+ }
+
+ protected BoltServer createBoltServer(URL url, ChannelHandler[] channelHandlers) {
+ return new BoltServer(url, Arrays.asList(channelHandlers));
+ }
}
\ No newline at end of file
diff --git a/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/BoltServerTest.java b/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/BoltServerTest.java
index 36e8e3830..cfb25f7c8 100644
--- a/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/BoltServerTest.java
+++ b/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/BoltServerTest.java
@@ -16,13 +16,14 @@
*/
package com.alipay.sofa.registry.remoting.bolt;
-import com.alipay.sofa.registry.remoting.Channel;
-import com.alipay.sofa.registry.remoting.bolt.BoltServer;
+import java.net.InetSocketAddress;
+
+import javax.ws.rs.client.WebTarget;
+
import org.junit.Assert;
import org.junit.Test;
-import javax.ws.rs.client.WebTarget;
-import java.net.InetSocketAddress;
+import com.alipay.sofa.registry.remoting.Channel;
/**
*
@@ -67,6 +68,11 @@ public void setAttribute(String key, Object value) {
public WebTarget getWebTarget() {
return null;
}
+
+ @Override
+ public void close() {
+
+ }
});
}
sessionServer.getChannels();
diff --git a/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/MockChannel.java b/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/MockChannel.java
index b36f74838..d00c5d5b9 100644
--- a/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/MockChannel.java
+++ b/server/remoting/bolt/src/test/java/com/alipay/sofa/registry/remoting/bolt/MockChannel.java
@@ -16,10 +16,11 @@
*/
package com.alipay.sofa.registry.remoting.bolt;
-import com.alipay.sofa.registry.remoting.Channel;
+import java.net.InetSocketAddress;
import javax.ws.rs.client.WebTarget;
-import java.net.InetSocketAddress;
+
+import com.alipay.sofa.registry.remoting.Channel;
/**
* @author xuanbei
@@ -55,4 +56,9 @@ public void setAttribute(String key, Object value) {
public WebTarget getWebTarget() {
return null;
}
+
+ @Override
+ public void close() {
+
+ }
}
diff --git a/server/remoting/http/pom.xml b/server/remoting/http/pom.xml
index df9645432..c6f568351 100644
--- a/server/remoting/http/pom.xml
+++ b/server/remoting/http/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-remoting
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyChannel.java b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyChannel.java
index 54154d40f..5a061273a 100644
--- a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyChannel.java
+++ b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyChannel.java
@@ -16,13 +16,14 @@
*/
package com.alipay.sofa.registry.remoting.jersey;
-import com.alipay.sofa.registry.net.NetUtil;
-import com.alipay.sofa.registry.remoting.Channel;
+import java.net.InetSocketAddress;
+import java.net.URI;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
-import java.net.InetSocketAddress;
-import java.net.URI;
+
+import com.alipay.sofa.registry.net.NetUtil;
+import com.alipay.sofa.registry.remoting.Channel;
/**
*
@@ -77,6 +78,11 @@ public WebTarget getWebTarget() {
return webTarget;
}
+ @Override
+ public void close() {
+ client.close();
+ }
+
/**
* Setter method for property webTarget.
*
diff --git a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyClient.java b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyClient.java
index 825a7dd51..c682a8cf0 100644
--- a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyClient.java
+++ b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyClient.java
@@ -16,28 +16,27 @@
*/
package com.alipay.sofa.registry.remoting.jersey;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.HttpUrlConnectorProvider;
+import org.glassfish.jersey.jackson.JacksonFeature;
+
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.log.Logger;
import com.alipay.sofa.registry.log.LoggerFactory;
import com.alipay.sofa.registry.net.NetUtil;
import com.alipay.sofa.registry.remoting.CallbackHandler;
import com.alipay.sofa.registry.remoting.Channel;
-import com.alipay.sofa.registry.remoting.ChannelHandler;
import com.alipay.sofa.registry.remoting.Client;
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.HttpUrlConnectorProvider;
-import org.glassfish.jersey.jackson.JacksonFeature;
-
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.UriBuilder;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
/**
*
@@ -49,7 +48,9 @@ public class JerseyClient implements Client {
private static final Logger LOGGER = LoggerFactory
.getLogger(JerseyClient.class);
private volatile static JerseyClient instance;
+
private final AtomicReference client = new AtomicReference<>(null);
+
private Map channels = new HashMap<>();
/**
@@ -89,6 +90,22 @@ public Channel connect(URL url) {
}
}
+ @Override
+ public Object sendSync(URL url, Object message, int timeoutMillis) {
+ return null;
+ }
+
+ @Override
+ public Object sendSync(Channel channel, Object message, int timeoutMillis) {
+ return null;
+ }
+
+ @Override
+ public void sendCallback(URL url, Object message, CallbackHandler callbackHandler,
+ int timeoutMillis) {
+
+ }
+
private WebTarget getTarget(URL targetUrl) {
return getClient().target(getBaseUri(targetUrl));
}
@@ -125,24 +142,6 @@ public URI getBaseUri(URL targetUrl) {
return uri;
}
- @Override
- public Collection getChannels() {
- return null;
- }
-
- @Override
- public Channel getChannel(InetSocketAddress remoteAddress) {
- Channel c = channels.get(NetUtil.toAddressString(remoteAddress));
- if (c == null) {
- return null;
- } else {
- if (!c.isConnected()) {
- connect(new URL(remoteAddress));
- }
- }
- return c;
- }
-
@Override
public Channel getChannel(URL url) {
Channel c = channels.get(url.getAddressString());
@@ -156,11 +155,6 @@ public Channel getChannel(URL url) {
return c;
}
- @Override
- public List getChannelHandlers() {
- return null;
- }
-
@Override
public InetSocketAddress getLocalAddress() {
return NetUtil.getLocalSocketAddress();
@@ -171,29 +165,9 @@ public void close() {
}
- @Override
- public void close(Channel channel) {
-
- }
-
@Override
public boolean isClosed() {
return false;
}
- @Override
- public void sendOneway(Channel channel, Object message) {
-
- }
-
- @Override
- public Object sendSync(Channel channel, Object message, int timeoutMillis) {
- return null;
- }
-
- @Override
- public void sendCallback(Channel channel, Object message, CallbackHandler callbackHandler,
- int timeoutMillis) {
-
- }
}
\ No newline at end of file
diff --git a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyJettyServer.java b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyJettyServer.java
index 680384881..0e08653fa 100644
--- a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyJettyServer.java
+++ b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/JerseyJettyServer.java
@@ -16,14 +16,14 @@
*/
package com.alipay.sofa.registry.remoting.jersey;
-import com.alipay.sofa.registry.common.model.store.URL;
-import com.alipay.sofa.registry.log.Logger;
-import com.alipay.sofa.registry.log.LoggerFactory;
-import com.alipay.sofa.registry.remoting.CallbackHandler;
-import com.alipay.sofa.registry.remoting.Channel;
-import com.alipay.sofa.registry.remoting.ChannelHandler;
-import com.alipay.sofa.registry.remoting.Server;
-import com.alipay.sofa.registry.remoting.jersey.jetty.server.HttpConnectionCustomFactory;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.Collection;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.ws.rs.ProcessingException;
+
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -35,13 +35,13 @@
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spi.Container;
-import javax.ws.rs.ProcessingException;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicBoolean;
+import com.alipay.sofa.registry.common.model.store.URL;
+import com.alipay.sofa.registry.log.Logger;
+import com.alipay.sofa.registry.log.LoggerFactory;
+import com.alipay.sofa.registry.remoting.CallbackHandler;
+import com.alipay.sofa.registry.remoting.Channel;
+import com.alipay.sofa.registry.remoting.Server;
+import com.alipay.sofa.registry.remoting.jersey.jetty.server.HttpConnectionCustomFactory;
/**
*
@@ -163,8 +163,8 @@ public Channel getChannel(URL url) {
}
@Override
- public List getChannelHandlers() {
- return null;
+ public void close(Channel channel) {
+ throw new UnsupportedOperationException("Jersey Server don't support close Channel.");
}
@Override
@@ -186,11 +186,6 @@ public void close() {
throw new RuntimeException("Jersey Server has not started!Server Channel has not created!");
}
- @Override
- public void close(Channel channel) {
- throw new UnsupportedOperationException("Jersey Server don't support close Channel.");
- }
-
@Override
public boolean isClosed() {
if (server != null) {
@@ -199,11 +194,6 @@ public boolean isClosed() {
return true;
}
- @Override
- public void sendOneway(Channel channel, Object message) {
-
- }
-
@Override
public Object sendSync(Channel channel, Object message, int timeoutMillis) {
return null;
@@ -224,4 +214,9 @@ public URI getBaseUri() {
return baseUri;
}
+ @Override
+ public int getChannelCount() {
+ return 0;
+ }
+
}
\ No newline at end of file
diff --git a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/exchange/JerseyExchange.java b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/exchange/JerseyExchange.java
index be001a92b..f73c8b05f 100644
--- a/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/exchange/JerseyExchange.java
+++ b/server/remoting/http/src/main/java/com/alipay/sofa/registry/remoting/jersey/exchange/JerseyExchange.java
@@ -16,6 +16,13 @@
*/
package com.alipay.sofa.registry.remoting.jersey.exchange;
+import java.net.URI;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.log.Logger;
import com.alipay.sofa.registry.log.LoggerFactory;
@@ -24,11 +31,6 @@
import com.alipay.sofa.registry.remoting.exchange.Exchange;
import com.alipay.sofa.registry.remoting.jersey.JerseyClient;
import com.alipay.sofa.registry.remoting.jersey.JerseyJettyServer;
-import org.glassfish.jersey.server.ResourceConfig;
-
-import javax.ws.rs.core.UriBuilder;
-import java.net.URI;
-import java.util.concurrent.ConcurrentHashMap;
/**
*
@@ -51,6 +53,12 @@ public Client connect(String serverType, URL serverUrl, ResourceConfig... channe
return jerseyClient;
}
+ @Override
+ public Client connect(String serverType, int connNum, URL serverUrl,
+ ResourceConfig... channelHandlers) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public Server open(URL url, ResourceConfig... resources) {
diff --git a/server/remoting/http/src/test/java/com/alipay/sofa/registry/remoting/jersey/JerseyExchangeTest.java b/server/remoting/http/src/test/java/com/alipay/sofa/registry/remoting/jersey/JerseyExchangeTest.java
index 22713c6d2..ee005fc98 100644
--- a/server/remoting/http/src/test/java/com/alipay/sofa/registry/remoting/jersey/JerseyExchangeTest.java
+++ b/server/remoting/http/src/test/java/com/alipay/sofa/registry/remoting/jersey/JerseyExchangeTest.java
@@ -16,19 +16,21 @@
*/
package com.alipay.sofa.registry.remoting.jersey;
-import com.alipay.sofa.registry.common.model.store.URL;
-import com.alipay.sofa.registry.net.NetUtil;
-import com.alipay.sofa.registry.remoting.CallbackHandler;
-import com.alipay.sofa.registry.remoting.Channel;
-import com.alipay.sofa.registry.remoting.jersey.exchange.JerseyExchange;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executor;
+
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.Assert;
import org.junit.Test;
-import java.net.InetSocketAddress;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import com.alipay.sofa.registry.common.model.store.URL;
+import com.alipay.sofa.registry.net.NetUtil;
+import com.alipay.sofa.registry.remoting.CallbackHandler;
+import com.alipay.sofa.registry.remoting.Channel;
+import com.alipay.sofa.registry.remoting.jersey.exchange.JerseyExchange;
/**
* @author xuanbei
@@ -51,6 +53,11 @@ public void onCallback(Channel channel, Object message) {
@Override
public void onException(Channel channel, Throwable exception) {
}
+
+ @Override
+ public Executor getExecutor() {
+ return null;
+ }
};
JerseyExchange jerseyExchange = new JerseyExchange();
@@ -80,20 +87,11 @@ private void testJerseyJettyServer(URL url, JerseyJettyServer jerseyJettyServer,
Assert.assertNull(jerseyJettyServer.getChannels());
Assert.assertNull(jerseyJettyServer.getChannel(new InetSocketAddress(9663)));
Assert.assertNull(jerseyJettyServer.getChannel(url));
- Assert.assertNull(jerseyJettyServer.getChannelHandlers());
Assert.assertEquals(new InetSocketAddress(JERSEY_TEST_PORT),
jerseyJettyServer.getLocalAddress());
Assert.assertFalse(jerseyJettyServer.isClosed());
- boolean isException = false;
- try {
- jerseyJettyServer.close(new JerseyChannel());
- } catch (Throwable t) {
- isException = true;
- }
- Assert.assertTrue(isException);
jerseyJettyServer.sendCallback(new JerseyChannel(), new Object(), callbackHandler, 1000);
- jerseyJettyServer.sendOneway(new JerseyChannel(), new Object());
Assert.assertNull(jerseyJettyServer.sendSync(new JerseyChannel(), new Object(), 1000));
}
@@ -101,15 +99,10 @@ private void testJerseyClient(URL url, JerseyClient jerseyClient,
CallbackHandler callbackHandler) {
Assert.assertEquals(NetUtil.getLocalSocketAddress(), jerseyClient.getLocalAddress());
Assert.assertFalse(jerseyClient.isClosed());
- Assert.assertNull(jerseyClient.getChannels());
- Assert.assertNull(jerseyClient.getChannel(new InetSocketAddress(9663)));
Assert.assertNull(jerseyClient.getChannel(url));
- Assert.assertNull(jerseyClient.getChannelHandlers());
- Assert.assertNull(jerseyClient.sendSync(new JerseyChannel(), new Object(), 1000));
+ Assert.assertNull(jerseyClient.sendSync(new URL(), new Object(), 1000));
jerseyClient.close();
- jerseyClient.close(new JerseyChannel());
- jerseyClient.sendOneway(new JerseyChannel(), new Object());
- jerseyClient.sendCallback(new JerseyChannel(), new Object(), callbackHandler, 1000);
+ jerseyClient.sendCallback(new URL(), new Object(), callbackHandler, 1000);
}
private void testJerseyChannel(JerseyChannel jerseyChannel) {
diff --git a/server/remoting/pom.xml b/server/remoting/pom.xml
index a42a1f779..d34affeb3 100644
--- a/server/remoting/pom.xml
+++ b/server/remoting/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-server-parent
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
diff --git a/server/server/data/pom.xml b/server/server/data/pom.xml
index 4e2428f0c..e2f44c074 100644
--- a/server/server/data/pom.xml
+++ b/server/server/data/pom.xml
@@ -5,7 +5,7 @@
com.alipay.sofa
registry-server
- 5.2.0-SNAPSHOT
+ 5.4.5
../pom.xml
4.0.0
@@ -73,6 +73,10 @@
commons-lang
commons-lang
+
+ commons-collections
+ commons-collections
+
junit
junit
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/DataApplication.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/DataApplication.java
index 54079bb12..9578b0929 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/DataApplication.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/DataApplication.java
@@ -21,6 +21,7 @@
import com.alipay.sofa.registry.server.data.bootstrap.EnableDataServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
/**
*
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBeanConfiguration.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBeanConfiguration.java
index 5087a451b..50284a0e8 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBeanConfiguration.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBeanConfiguration.java
@@ -16,24 +16,45 @@
*/
package com.alipay.sofa.registry.server.data.bootstrap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import com.alipay.sofa.registry.server.data.remoting.dataserver.task.LogMetricsTask;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
import com.alipay.sofa.registry.remoting.bolt.exchange.BoltExchange;
import com.alipay.sofa.registry.remoting.exchange.Exchange;
import com.alipay.sofa.registry.remoting.jersey.exchange.JerseyExchange;
+import com.alipay.sofa.registry.server.data.cache.CacheDigestTask;
import com.alipay.sofa.registry.server.data.cache.DataServerCache;
+import com.alipay.sofa.registry.server.data.cache.DatumCache;
+import com.alipay.sofa.registry.server.data.cache.LocalDatumStorage;
import com.alipay.sofa.registry.server.data.change.DataChangeHandler;
import com.alipay.sofa.registry.server.data.change.event.DataChangeEventCenter;
import com.alipay.sofa.registry.server.data.change.notify.BackUpNotifier;
import com.alipay.sofa.registry.server.data.change.notify.IDataChangeNotifier;
import com.alipay.sofa.registry.server.data.change.notify.SessionServerNotifier;
+import com.alipay.sofa.registry.server.data.change.notify.SnapshotBackUpNotifier;
import com.alipay.sofa.registry.server.data.change.notify.TempPublisherNotifier;
-import com.alipay.sofa.registry.server.data.correction.LocalDataServerCleanHandler;
import com.alipay.sofa.registry.server.data.datasync.AcceptorStore;
import com.alipay.sofa.registry.server.data.datasync.SyncDataService;
import com.alipay.sofa.registry.server.data.datasync.sync.LocalAcceptorStore;
import com.alipay.sofa.registry.server.data.datasync.sync.Scheduler;
import com.alipay.sofa.registry.server.data.datasync.sync.StoreServiceFactory;
import com.alipay.sofa.registry.server.data.datasync.sync.SyncDataServiceImpl;
+import com.alipay.sofa.registry.server.data.event.AfterWorkingProcess;
import com.alipay.sofa.registry.server.data.event.EventCenter;
+import com.alipay.sofa.registry.server.data.event.handler.AfterWorkingProcessHandler;
import com.alipay.sofa.registry.server.data.event.handler.DataServerChangeEventHandler;
import com.alipay.sofa.registry.server.data.event.handler.LocalDataServerChangeEventHandler;
import com.alipay.sofa.registry.server.data.event.handler.MetaServerChangeEventHandler;
@@ -51,14 +72,18 @@
import com.alipay.sofa.registry.server.data.remoting.dataserver.handler.SyncDataHandler;
import com.alipay.sofa.registry.server.data.remoting.dataserver.task.AbstractTask;
import com.alipay.sofa.registry.server.data.remoting.dataserver.task.ConnectionRefreshTask;
-import com.alipay.sofa.registry.server.data.remoting.dataserver.task.ReNewNodeTask;
+import com.alipay.sofa.registry.server.data.remoting.dataserver.task.RenewNodeTask;
import com.alipay.sofa.registry.server.data.remoting.handler.AbstractClientHandler;
import com.alipay.sofa.registry.server.data.remoting.handler.AbstractServerHandler;
import com.alipay.sofa.registry.server.data.remoting.metaserver.DefaultMetaServiceImpl;
import com.alipay.sofa.registry.server.data.remoting.metaserver.IMetaServerService;
import com.alipay.sofa.registry.server.data.remoting.metaserver.MetaServerConnectionFactory;
+import com.alipay.sofa.registry.server.data.remoting.metaserver.handler.NotifyProvideDataChangeHandler;
import com.alipay.sofa.registry.server.data.remoting.metaserver.handler.ServerChangeHandler;
import com.alipay.sofa.registry.server.data.remoting.metaserver.handler.StatusConfirmHandler;
+import com.alipay.sofa.registry.server.data.remoting.metaserver.provideData.ProvideDataProcessor;
+import com.alipay.sofa.registry.server.data.remoting.metaserver.provideData.ProvideDataProcessorManager;
+import com.alipay.sofa.registry.server.data.remoting.metaserver.provideData.processor.DatumExpireProvideDataProcessor;
import com.alipay.sofa.registry.server.data.remoting.metaserver.task.ConnectionRefreshMetaTask;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.SessionServerConnectionFactory;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.disconnect.DisconnectEventHandler;
@@ -66,25 +91,20 @@
import com.alipay.sofa.registry.server.data.remoting.sessionserver.forward.ForwardServiceImpl;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.ClientOffHandler;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.DataServerConnectionHandler;
+import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.DatumSnapshotHandler;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.GetDataHandler;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.GetDataVersionsHandler;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.PublishDataHandler;
+import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.RenewDatumHandler;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.SessionServerRegisterHandler;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.handler.UnPublishDataHandler;
+import com.alipay.sofa.registry.server.data.renew.DatumLeaseManager;
+import com.alipay.sofa.registry.server.data.renew.LocalDataServerCleanHandler;
import com.alipay.sofa.registry.server.data.resource.DataDigestResource;
import com.alipay.sofa.registry.server.data.resource.HealthResource;
+import com.alipay.sofa.registry.server.data.util.DataMetricsThreadPoolExecutor;
+import com.alipay.sofa.registry.util.NamedThreadFactory;
import com.alipay.sofa.registry.util.PropertySplitter;
-import org.glassfish.jersey.jackson.JacksonFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
/**
*
@@ -111,7 +131,8 @@ public CommonConfig commonConfig() {
}
@Bean
- public DataServerConfig dataServerBootstrapConfig(CommonConfig commonConfig) {
+ @ConditionalOnMissingBean
+ public DataServerConfig dataServerConfig(CommonConfig commonConfig) {
return new DataServerConfig(commonConfig);
}
@@ -124,10 +145,39 @@ public DataNodeStatus dataNodeStatus() {
public PropertySplitter propertySplitter() {
return new PropertySplitter();
}
+
+ }
+
+ @Configuration
+ public static class DataServerStorageConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public DatumCache datumCache() {
+ return new DatumCache();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public LocalDatumStorage localDatumStorage() {
+ return new LocalDatumStorage();
+ }
+
+ }
+
+ @Configuration
+ public static class LogTaskConfigConfiguration {
+
+ @Bean
+ public CacheDigestTask cacheDigestTask() {
+ return new CacheDigestTask();
+ }
+
}
@Configuration
public static class SessionRemotingConfiguration {
+
@Bean
public Exchange jerseyExchange() {
return new JerseyExchange();
@@ -174,23 +224,25 @@ public MetaServerConnectionFactory metaServerConnectionFactory() {
}
@Bean(name = "serverHandlers")
- public Collection serverHandlers(DataServerConfig dataServerBootstrapConfig) {
+ public Collection serverHandlers() {
Collection list = new ArrayList<>();
list.add(getDataHandler());
list.add(clientOffHandler());
list.add(getDataVersionsHandler());
- list.add(publishDataProcessor(dataServerBootstrapConfig));
+ list.add(publishDataProcessor());
list.add(sessionServerRegisterHandler());
list.add(unPublishDataHandler());
list.add(dataServerConnectionHandler());
+ list.add(renewDatumHandler());
+ list.add(datumSnapshotHandler());
return list;
}
@Bean(name = "serverSyncHandlers")
- public Collection serverSyncHandlers(DataServerConfig dataServerBootstrapConfig) {
+ public Collection serverSyncHandlers() {
Collection list = new ArrayList<>();
list.add(getDataHandler());
- list.add(publishDataProcessor(dataServerBootstrapConfig));
+ list.add(publishDataProcessor());
list.add(unPublishDataHandler());
list.add(notifyFetchDatumHandler());
list.add(notifyOnlineHandler());
@@ -212,6 +264,7 @@ public Collection metaClientHandlers() {
Collection list = new ArrayList<>();
list.add(serverChangeHandler());
list.add(statusConfirmHandler());
+ list.add(notifyProvideDataChangeHandler());
return list;
}
@@ -241,8 +294,18 @@ public AbstractServerHandler clientOffHandler() {
}
@Bean
- public AbstractServerHandler publishDataProcessor(DataServerConfig dataServerBootstrapConfig) {
- return new PublishDataHandler(dataServerBootstrapConfig);
+ public AbstractServerHandler datumSnapshotHandler() {
+ return new DatumSnapshotHandler();
+ }
+
+ @Bean
+ public RenewDatumHandler renewDatumHandler() {
+ return new RenewDatumHandler();
+ }
+
+ @Bean
+ public AbstractServerHandler publishDataProcessor() {
+ return new PublishDataHandler();
}
@Bean
@@ -271,7 +334,8 @@ public AbstractServerHandler syncDataHandler() {
}
@Bean
- public AbstractClientHandler notifyDataSyncHandler() {
+ @ConditionalOnMissingBean
+ public NotifyDataSyncHandler notifyDataSyncHandler() {
return new NotifyDataSyncHandler();
}
@@ -289,6 +353,37 @@ public AbstractClientHandler serverChangeHandler() {
public AbstractClientHandler statusConfirmHandler() {
return new StatusConfirmHandler();
}
+
+ @Bean
+ public NotifyProvideDataChangeHandler notifyProvideDataChangeHandler() {
+ return new NotifyProvideDataChangeHandler();
+ }
+
+ @Bean(name = "afterWorkProcessors")
+ public List afterWorkingProcessors() {
+ List list = new ArrayList<>();
+ list.add(renewDatumHandler());
+ list.add(datumLeaseManager());
+ list.add(disconnectEventHandler());
+ list.add(notifyDataSyncHandler());
+ return list;
+ }
+
+ @Bean
+ public AfterWorkingProcessHandler afterWorkingProcessHandler() {
+ return new AfterWorkingProcessHandler();
+ }
+
+ @Bean
+ public DatumLeaseManager datumLeaseManager() {
+ return new DatumLeaseManager();
+ }
+
+ @Bean
+ public DisconnectEventHandler disconnectEventHandler() {
+ return new DisconnectEventHandler();
+ }
+
}
@Configuration
@@ -313,14 +408,21 @@ public BackUpNotifier backUpNotifier() {
return new BackUpNotifier();
}
+ @Bean
+ public SnapshotBackUpNotifier snapshotBackUpNotifier() {
+ return new SnapshotBackUpNotifier();
+ }
+
@Bean(name = "dataChangeNotifiers")
- public List dataChangeNotifiers(DataServerConfig dataServerBootstrapConfig) {
+ public List dataChangeNotifiers() {
List list = new ArrayList<>();
list.add(sessionServerNotifier());
list.add(tempPublisherNotifier());
list.add(backUpNotifier());
+ list.add(snapshotBackUpNotifier());
return list;
}
+
}
@Configuration
@@ -345,6 +447,7 @@ public Scheduler syncDataScheduler() {
public StoreServiceFactory storeServiceFactory() {
return new StoreServiceFactory();
}
+
}
@Configuration
@@ -380,11 +483,6 @@ public GetSyncDataHandler getSyncDataHandler() {
return new GetSyncDataHandler();
}
- @Bean
- public DisconnectEventHandler disconnectEventHandler() {
- return new DisconnectEventHandler();
- }
-
@Bean
public EventCenter eventCenter() {
return new EventCenter();
@@ -394,6 +492,7 @@ public EventCenter eventCenter() {
public DataChangeEventCenter dataChangeEventCenter() {
return new DataChangeEventCenter();
}
+
}
@Configuration
@@ -410,8 +509,13 @@ public ConnectionRefreshMetaTask connectionRefreshMetaTask() {
}
@Bean
- public ReNewNodeTask reNewNodeTask() {
- return new ReNewNodeTask();
+ public RenewNodeTask renewNodeTask() {
+ return new RenewNodeTask();
+ }
+
+ @Bean
+ public LogMetricsTask logMetricsTask() {
+ return new LogMetricsTask();
}
@Bean(name = "tasks")
@@ -419,7 +523,8 @@ public List tasks() {
List list = new ArrayList<>();
list.add(connectionRefreshTask());
list.add(connectionRefreshMetaTask());
- list.add(reNewNodeTask());
+ list.add(renewNodeTask());
+ list.add(logMetricsTask());
return list;
}
@@ -427,6 +532,7 @@ public List tasks() {
public IMetaServerService metaServerService() {
return new DefaultMetaServiceImpl();
}
+
}
@Configuration
@@ -445,8 +551,72 @@ public HealthResource healthResource() {
}
@Bean
+ @ConditionalOnMissingBean
public DataDigestResource dataDigestResource() {
return new DataDigestResource();
}
+
+ }
+
+ @Configuration
+ public static class ExecutorConfiguration {
+
+ @Bean(name = "publishProcessorExecutor")
+ public ThreadPoolExecutor publishProcessorExecutor(DataServerConfig dataServerConfig) {
+ return new DataMetricsThreadPoolExecutor("PublishProcessorExecutor",
+ dataServerConfig.getPublishExecutorMinPoolSize(),
+ dataServerConfig.getPublishExecutorMaxPoolSize(), 300, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(dataServerConfig.getPublishExecutorQueueSize()),
+ new NamedThreadFactory("DataServer-PublishProcessor-executor", true));
+ }
+
+ @Bean(name = "renewDatumProcessorExecutor")
+ public ThreadPoolExecutor renewDatumProcessorExecutor(DataServerConfig dataServerConfig) {
+ return new DataMetricsThreadPoolExecutor("RenewDatumProcessorExecutor",
+ dataServerConfig.getRenewDatumExecutorMinPoolSize(),
+ dataServerConfig.getRenewDatumExecutorMaxPoolSize(), 300, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(dataServerConfig.getRenewDatumExecutorQueueSize()),
+ new NamedThreadFactory("DataServer-RenewDatumProcessor-executor", true));
+ }
+
+ @Bean(name = "getDataProcessorExecutor")
+ public ThreadPoolExecutor getDataProcessorExecutor(DataServerConfig dataServerConfig) {
+ return new DataMetricsThreadPoolExecutor("GetDataProcessorExecutor",
+ dataServerConfig.getGetDataExecutorMinPoolSize(),
+ dataServerConfig.getGetDataExecutorMaxPoolSize(),
+ dataServerConfig.getGetDataExecutorKeepAliveTime(), TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(dataServerConfig.getGetDataExecutorQueueSize()),
+ new NamedThreadFactory("DataServer-GetDataProcessor-executor", true));
+ }
+
+ @Bean(name = "defaultRequestExecutor")
+ public ThreadPoolExecutor defaultRequestExecutor(DataServerConfig dataServerConfig) {
+ return new DataMetricsThreadPoolExecutor("DefaultRequestExecutor",
+ dataServerConfig.getDefaultRequestExecutorMinSize(),
+ dataServerConfig.getDefaultRequestExecutorMaxSize(),
+ dataServerConfig.getDefaultRequestExecutorKeepAliveTime(), TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(dataServerConfig.getDefaultRequestExecutorQueueSize()),
+ new NamedThreadFactory("DefaultRequestThread", true)
+
+ );
+ }
+ }
+
+ @Configuration
+ public static class DataProvideDataConfiguration {
+
+ @Bean
+ public ProvideDataProcessor provideDataProcessorManager() {
+ return new ProvideDataProcessorManager();
+ }
+
+ @Bean
+ public ProvideDataProcessor datumExpireProvideDataProcessor(ProvideDataProcessor provideDataProcessorManager) {
+ ProvideDataProcessor datumExpireProvideDataProcessor = new DatumExpireProvideDataProcessor();
+ ((ProvideDataProcessorManager) provideDataProcessorManager)
+ .addProvideDataProcessor(datumExpireProvideDataProcessor);
+ return datumExpireProvideDataProcessor;
+ }
+
}
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBootstrap.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBootstrap.java
index 02bec192f..8cc934baf 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBootstrap.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerBootstrap.java
@@ -16,6 +16,25 @@
*/
package com.alipay.sofa.registry.server.data.bootstrap;
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+import javax.annotation.Resource;
+import javax.ws.rs.Path;
+import javax.ws.rs.ext.Provider;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+
+import com.alipay.sofa.registry.common.model.constants.ValueConstants;
+import com.alipay.sofa.registry.common.model.metaserver.ProvideData;
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.log.Logger;
import com.alipay.sofa.registry.log.LoggerFactory;
@@ -23,25 +42,15 @@
import com.alipay.sofa.registry.remoting.ChannelHandler;
import com.alipay.sofa.registry.remoting.Server;
import com.alipay.sofa.registry.remoting.exchange.Exchange;
+import com.alipay.sofa.registry.server.data.cache.CacheDigestTask;
import com.alipay.sofa.registry.server.data.datasync.sync.Scheduler;
import com.alipay.sofa.registry.server.data.event.EventCenter;
import com.alipay.sofa.registry.server.data.event.MetaServerChangeEvent;
import com.alipay.sofa.registry.server.data.event.StartTaskEvent;
+import com.alipay.sofa.registry.server.data.event.StartTaskTypeEnum;
import com.alipay.sofa.registry.server.data.remoting.handler.AbstractServerHandler;
import com.alipay.sofa.registry.server.data.remoting.metaserver.IMetaServerService;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.ApplicationContext;
-
-import javax.annotation.Resource;
-import javax.ws.rs.Path;
-import javax.ws.rs.ext.Provider;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
+import com.alipay.sofa.registry.server.data.renew.DatumLeaseManager;
/**
*
@@ -55,7 +64,7 @@ public class DataServerBootstrap {
.getLogger(DataServerBootstrap.class);
@Autowired
- private DataServerConfig dataServerBootstrapConfig;
+ private DataServerConfig dataServerConfig;
@Autowired
private IMetaServerService metaServerService;
@@ -78,12 +87,18 @@ public class DataServerBootstrap {
@Autowired
private EventCenter eventCenter;
+ @Autowired
+ private CacheDigestTask cacheDigestTask;
+
@Resource(name = "serverHandlers")
private Collection serverHandlers;
@Resource(name = "serverSyncHandlers")
private Collection serverSyncHandlers;
+ @Autowired
+ private DatumLeaseManager datumLeaseManager;
+
private Server server;
private Server dataSyncServer;
@@ -103,7 +118,9 @@ public class DataServerBootstrap {
*/
public void start() {
try {
- LOGGER.info("[DataServerBootstrap] begin start server");
+ LOGGER.info("begin start server");
+
+ LOGGER.info("the configuration items are as follows: " + dataServerConfig.toString());
openDataServer();
@@ -113,13 +130,15 @@ public void start() {
startRaftClient();
+ fetchProviderData();
+
startScheduler();
Runtime.getRuntime().addShutdownHook(new Thread(this::doStop));
- LOGGER.info("[DataServerBootstrap] start server success");
+ LOGGER.info("start server success");
} catch (Exception e) {
- throw new RuntimeException("[DataServerBootstrap] start server error", e);
+ throw new RuntimeException("start server error", e);
}
}
@@ -127,15 +146,13 @@ private void openDataServer() {
try {
if (serverForSessionStarted.compareAndSet(false, true)) {
server = boltExchange.open(new URL(NetUtil.getLocalAddress().getHostAddress(),
- dataServerBootstrapConfig.getPort()), serverHandlers
+ dataServerConfig.getPort()), serverHandlers
.toArray(new ChannelHandler[serverHandlers.size()]));
- LOGGER.info("Data server for session started! port:{}",
- dataServerBootstrapConfig.getPort());
+ LOGGER.info("Data server for session started! port:{}", dataServerConfig.getPort());
}
} catch (Exception e) {
serverForSessionStarted.set(false);
- LOGGER
- .error("Data server start error! port:{}", dataServerBootstrapConfig.getPort(), e);
+ LOGGER.error("Data server start error! port:{}", dataServerConfig.getPort(), e);
throw new RuntimeException("Data server start error!", e);
}
}
@@ -144,15 +161,15 @@ private void openDataSyncServer() {
try {
if (serverForDataSyncStarted.compareAndSet(false, true)) {
dataSyncServer = boltExchange.open(new URL(NetUtil.getLocalAddress()
- .getHostAddress(), dataServerBootstrapConfig.getSyncDataPort()),
- serverSyncHandlers.toArray(new ChannelHandler[serverSyncHandlers.size()]));
+ .getHostAddress(), dataServerConfig.getSyncDataPort()), serverSyncHandlers
+ .toArray(new ChannelHandler[serverSyncHandlers.size()]));
LOGGER.info("Data server for sync started! port:{}",
- dataServerBootstrapConfig.getSyncDataPort());
+ dataServerConfig.getSyncDataPort());
}
} catch (Exception e) {
serverForDataSyncStarted.set(false);
LOGGER.error("Data sync server start error! port:{}",
- dataServerBootstrapConfig.getSyncDataPort(), e);
+ dataServerConfig.getSyncDataPort(), e);
throw new RuntimeException("Data sync server start error!", e);
}
}
@@ -162,15 +179,15 @@ private void openHttpServer() {
if (httpServerStarted.compareAndSet(false, true)) {
bindResourceConfig();
httpServer = jerseyExchange.open(
- new URL(NetUtil.getLocalAddress().getHostAddress(), dataServerBootstrapConfig
+ new URL(NetUtil.getLocalAddress().getHostAddress(), dataServerConfig
.getHttpServerPort()), new ResourceConfig[] { jerseyResourceConfig });
LOGGER.info("Open http server port {} success!",
- dataServerBootstrapConfig.getHttpServerPort());
+ dataServerConfig.getHttpServerPort());
}
} catch (Exception e) {
httpServerStarted.set(false);
- LOGGER.error("Open http server port {} error!",
- dataServerBootstrapConfig.getHttpServerPort(), e);
+ LOGGER
+ .error("Open http server port {} error!", dataServerConfig.getHttpServerPort(), e);
throw new RuntimeException("Open http server error!", e);
}
}
@@ -178,15 +195,35 @@ private void openHttpServer() {
private void startRaftClient() {
metaServerService.startRaftClient();
eventCenter.post(new MetaServerChangeEvent(metaServerService.getMetaServerMap()));
- LOGGER.info("[DataServerBootstrap] raft client started!Leader is {}",
- metaServerService.getLeader());
+ LOGGER.info("raft client started!Leader is {}", metaServerService.getLeader());
+ }
+
+ private void fetchProviderData() {
+ ProvideData provideData = metaServerService
+ .fetchData(ValueConstants.ENABLE_DATA_DATUM_EXPIRE);
+ if (provideData == null || provideData.getProvideData() == null
+ || provideData.getProvideData().getObject() == null) {
+ LOGGER
+ .info("Fetch enableDataDatumExpire but no data existed, current config not change!");
+ return;
+ }
+ boolean enableDataDatumExpire = Boolean.parseBoolean((String) provideData.getProvideData()
+ .getObject());
+ LOGGER.info("Fetch enableDataDatumExpire {} success!", enableDataDatumExpire);
+ datumLeaseManager.setRenewEnable(enableDataDatumExpire);
}
private void startScheduler() {
try {
if (schedulerStarted.compareAndSet(false, true)) {
syncDataScheduler.startScheduler();
- eventCenter.post(StartTaskEvent.getInstance());
+ // start all startTask except correction task
+ eventCenter.post(new StartTaskEvent(
+ Arrays.stream(StartTaskTypeEnum.values()).filter(type -> type != StartTaskTypeEnum.RENEW)
+ .collect(Collectors.toSet())));
+
+ //start dump log
+ cacheDigestTask.start();
}
} catch (Exception e) {
schedulerStarted.set(false);
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerConfig.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerConfig.java
index 4d801b711..66dadaed3 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerConfig.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/bootstrap/DataServerConfig.java
@@ -16,15 +16,18 @@
*/
package com.alipay.sofa.registry.server.data.bootstrap;
-import com.alipay.sofa.registry.net.NetUtil;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import com.alipay.sofa.registry.net.NetUtil;
+
/**
*
*
@@ -34,10 +37,11 @@
@ConfigurationProperties(prefix = DataServerConfig.PRE_FIX)
public class DataServerConfig {
- public static final String PRE_FIX = "data.server";
+ public static final String PRE_FIX = "data.server";
- public static final String IP = NetUtil.getLocalAddress()
- .getHostAddress();
+ public static final String IP = NetUtil
+ .getLocalAddress()
+ .getHostAddress();
private int port;
@@ -55,45 +59,80 @@ public class DataServerConfig {
private int clientOffDelayMs;
+ private int notifyTempDataIntervalMs;
+
private int rpcTimeout;
private CommonConfig commonConfig;
- private Set metaIps = null;
+ private Set metaIps = null;
+
+ private int storeNodes = 3;
+
+ private int numberOfReplicas = 1000;
+
+ private long localDataServerCleanDelay = 1000 * 60 * 30;
+
+ private int getDataExecutorMinPoolSize = 80;
+
+ private int getDataExecutorMaxPoolSize = 400;
+
+ private int getDataExecutorQueueSize = 10000;
+
+ private long getDataExecutorKeepAliveTime = 60;
+
+ private int notifyDataSyncExecutorMinPoolSize = 80;
+
+ private int notifyDataSyncExecutorMaxPoolSize = 400;
+
+ private int notifyDataSyncExecutorQueueSize = 700;
+
+ private long notifyDataSyncExecutorKeepAliveTime = 60;
+
+ private long notifySessionRetryFirstDelay = 3000;
+
+ private long notifySessionRetryIncrementDelay = 3000;
+
+ private int notifySessionRetryTimes = 5;
+
+ private int publishExecutorMinPoolSize = 200;
- private int storeNodes = 3;
+ private int publishExecutorMaxPoolSize = 400;
- private int numberOfReplicas = 1000;
+ private int publishExecutorQueueSize = 10000;
- private long localDataServerCleanDelay = 1000 * 60 * 30;
+ private int renewDatumExecutorMinPoolSize = 100;
- private int getDataExecutorMinPoolSize = 80;
+ private int renewDatumExecutorMaxPoolSize = 400;
- private int getDataExecutorMaxPoolSize = 400;
+ private int renewDatumExecutorQueueSize = 100000;
- private int getDataExecutorQueueSize = 10000;
+ private int datumTimeToLiveSec = 900;
- private long getDataExecutorKeepAliveTime = 60;
+ private int datumLeaseManagerExecutorThreadSize = 1;
- private int notifyDataSyncExecutorMinPoolSize = 80;
+ private int datumLeaseManagerExecutorQueueSize = 1000000;
- private int notifyDataSyncExecutorMaxPoolSize = 400;
+ private int sessionServerNotifierRetryExecutorThreadSize = 10;
- private int notifyDataSyncExecutorQueueSize = 700;
+ private int sessionServerNotifierRetryExecutorQueueSize = 10000;
- private long notifyDataSyncExecutorKeepAliveTime = 60;
+ private int defaultRequestExecutorMinSize = 20;
- private long notifySessionRetryFirstDelay = 1000;
+ private int defaultRequestExecutorMaxSize = 400;
- private long notifySessionRetryIncrementDelay = 1000;
+ private int defaultRequestExecutorQueueSize = 600;
+ private long defaultRequestExecutorKeepAliveTime = 60;
- private int notifySessionRetryTimes = 10;
+ private int logMetricsFixedDelay = 30;
- private int publishExecutorMinPoolSize = 80;
+ private int renewEnableDelaySec = 30;
- private int publishExecutorMaxPoolSize = 400;
+ private int dataSyncDelayTimeout = 1000;
- private int publishExecutorQueueSize = 10000;
+ private int dataSyncNotifyRetry = 3;
+
+ private int sessionDisconnectDelayMs = 30000;
/**
* constructor
@@ -103,10 +142,86 @@ public DataServerConfig(CommonConfig commonConfig) {
this.commonConfig = commonConfig;
}
+ public boolean isLocalDataCenter(String dataCenter) {
+ return commonConfig.getLocalDataCenter().equals(dataCenter);
+ }
+
+ /**
+ * Getter method for property renewEnableDelaySec.
+ *
+ * @return property value of renewEnableDelaySec
+ */
+ public int getRenewEnableDelaySec() {
+ return renewEnableDelaySec;
+ }
+
+ /**
+ * Setter method for property renewEnableDelaySec .
+ *
+ * @param renewEnableDelaySec value to be assigned to property renewEnableDelaySec
+ */
+ public void setRenewEnableDelaySec(int renewEnableDelaySec) {
+ this.renewEnableDelaySec = renewEnableDelaySec;
+ }
+
public String getLocalDataCenter() {
return commonConfig.getLocalDataCenter();
}
+ /**
+ * Getter method for property renewDatumExecutorMinPoolSize.
+ *
+ * @return property value of renewDatumExecutorMinPoolSize
+ */
+ public int getRenewDatumExecutorMinPoolSize() {
+ return renewDatumExecutorMinPoolSize;
+ }
+
+ /**
+ * Setter method for property renewDatumExecutorMinPoolSize .
+ *
+ * @param renewDatumExecutorMinPoolSize value to be assigned to property renewDatumExecutorMinPoolSize
+ */
+ public void setRenewDatumExecutorMinPoolSize(int renewDatumExecutorMinPoolSize) {
+ this.renewDatumExecutorMinPoolSize = renewDatumExecutorMinPoolSize;
+ }
+
+ /**
+ * Getter method for property renewDatumExecutorMaxPoolSize.
+ *
+ * @return property value of renewDatumExecutorMaxPoolSize
+ */
+ public int getRenewDatumExecutorMaxPoolSize() {
+ return renewDatumExecutorMaxPoolSize;
+ }
+
+ /**
+ * Setter method for property renewDatumExecutorMaxPoolSize .
+ *
+ * @param renewDatumExecutorMaxPoolSize value to be assigned to property renewDatumExecutorMaxPoolSize
+ */
+ public void setRenewDatumExecutorMaxPoolSize(int renewDatumExecutorMaxPoolSize) {
+ this.renewDatumExecutorMaxPoolSize = renewDatumExecutorMaxPoolSize;
+ }
+
+ /**
+ * Getter method for property renewDatumExecutorQueueSize.
+ *
+ * @return property value of renewDatumExecutorQueueSize
+ */
+ public int getRenewDatumExecutorQueueSize() {
+ return renewDatumExecutorQueueSize;
+ }
+
+ /**
+ * Setter method for property renewDatumExecutorQueueSize .
+ *
+ * @param renewDatumExecutorQueueSize value to be assigned to property renewDatumExecutorQueueSize
+ */
+ public void setRenewDatumExecutorQueueSize(int renewDatumExecutorQueueSize) {
+ this.renewDatumExecutorQueueSize = renewDatumExecutorQueueSize;
+ }
+
/**
* Getter method for property port.
*
@@ -233,6 +348,24 @@ public void setNotifyIntervalMs(int notifyIntervalMs) {
this.notifyIntervalMs = notifyIntervalMs;
}
+ /**
+ * Getter method for property notifyTempDataIntervalMs.
+ *
+ * @return property value of notifyTempDataIntervalMs
+ */
+ public int getNotifyTempDataIntervalMs() {
+ return notifyTempDataIntervalMs;
+ }
+
+ /**
+ * Setter method for property notifyTempDataIntervalMs.
+ *
+ * @param notifyTempDataIntervalMs value to be assigned to property notifyTempDataIntervalMs
+ */
+ public void setNotifyTempDataIntervalMs(int notifyTempDataIntervalMs) {
+ this.notifyTempDataIntervalMs = notifyTempDataIntervalMs;
+ }
+
/**
* Getter method for property rpcTimeout.
*
@@ -574,7 +707,8 @@ public Set getMetaServerIpAddresses() {
if (localDataCenter != null && !localDataCenter.isEmpty()) {
Collection metas = metaMap.get(localDataCenter);
if (metas != null && !metas.isEmpty()) {
- metaIps = metas.stream().map(NetUtil::getIPAddressFromDomain).collect(Collectors.toSet());
+ metaIps = metas.stream().map(NetUtil::getIPAddressFromDomain)
+ .collect(Collectors.toSet());
}
}
}
@@ -599,4 +733,194 @@ public int getNotifySessionRetryTimes() {
public void setNotifySessionRetryTimes(int notifySessionRetryTimes) {
this.notifySessionRetryTimes = notifySessionRetryTimes;
}
+
+ /**
+ * Getter method for property datumTimeToLiveSec.
+ *
+ * @return property value of datumTimeToLiveSec
+ */
+ public int getDatumTimeToLiveSec() {
+ return datumTimeToLiveSec;
+ }
+
+ /**
+ * Setter method for property datumTimeToLiveSec .
+ *
+ * @param datumTimeToLiveSec value to be assigned to property datumTimeToLiveSec
+ */
+ public void setDatumTimeToLiveSec(int datumTimeToLiveSec) {
+ this.datumTimeToLiveSec = datumTimeToLiveSec;
+ }
+
+ /**
+ * Getter method for property datumLeaseManagerExecutorQueueSize.
+ *
+ * @return property value of datumLeaseManagerExecutorQueueSize
+ */
+ public int getDatumLeaseManagerExecutorQueueSize() {
+ return datumLeaseManagerExecutorQueueSize;
+ }
+
+ /**
+ * Setter method for property datumLeaseManagerExecutorQueueSize .
+ *
+ * @param datumLeaseManagerExecutorQueueSize value to be assigned to property datumLeaseManagerExecutorQueueSize
+ */
+ public void setDatumLeaseManagerExecutorQueueSize(int datumLeaseManagerExecutorQueueSize) {
+ this.datumLeaseManagerExecutorQueueSize = datumLeaseManagerExecutorQueueSize;
+ }
+
+ /**
+ * Getter method for property datumLeaseManagerExecutorThreadSize.
+ *
+ * @return property value of datumLeaseManagerExecutorThreadSize
+ */
+ public int getDatumLeaseManagerExecutorThreadSize() {
+ return datumLeaseManagerExecutorThreadSize;
+ }
+
+ /**
+ * Setter method for property datumLeaseManagerExecutorThreadSize .
+ *
+ * @param datumLeaseManagerExecutorThreadSize value to be assigned to property datumLeaseManagerExecutorThreadSize
+ */
+ public void setDatumLeaseManagerExecutorThreadSize(int datumLeaseManagerExecutorThreadSize) {
+ this.datumLeaseManagerExecutorThreadSize = datumLeaseManagerExecutorThreadSize;
+ }
+
+ /**
+ * Getter method for property sessionServerNotifierRetryExecutorThreadSize.
+ *
+ * @return property value of sessionServerNotifierRetryExecutorThreadSize
+ */
+ public int getSessionServerNotifierRetryExecutorThreadSize() {
+ return sessionServerNotifierRetryExecutorThreadSize;
+ }
+
+ /**
+ * Setter method for property sessionServerNotifierRetryExecutorThreadSize .
+ *
+ * @param sessionServerNotifierRetryExecutorThreadSize value to be assigned to property sessionServerNotifierRetryExecutorThreadSize
+ */
+ public void setSessionServerNotifierRetryExecutorThreadSize(int sessionServerNotifierRetryExecutorThreadSize) {
+ this.sessionServerNotifierRetryExecutorThreadSize = sessionServerNotifierRetryExecutorThreadSize;
+ }
+
+ /**
+ * Getter method for property sessionServerNotifierRetryExecutorQueueSize.
+ *
+ * @return property value of sessionServerNotifierRetryExecutorQueueSize
+ */
+ public int getSessionServerNotifierRetryExecutorQueueSize() {
+ return sessionServerNotifierRetryExecutorQueueSize;
+ }
+
+ /**
+ * Setter method for property sessionServerNotifierRetryExecutorQueueSize .
+ *
+ * @param sessionServerNotifierRetryExecutorQueueSize value to be assigned to property sessionServerNotifierRetryExecutorQueueSize
+ */
+ public void setSessionServerNotifierRetryExecutorQueueSize(int sessionServerNotifierRetryExecutorQueueSize) {
+ this.sessionServerNotifierRetryExecutorQueueSize = sessionServerNotifierRetryExecutorQueueSize;
+ }
+
+ /**
+ * Getter method for property dataSyncDelayTimeout.
+ *
+ * @return property value of dataSyncDelayTimeout
+ */
+ public int getDataSyncDelayTimeout() {
+ return dataSyncDelayTimeout;
+ }
+
+ /**
+ * Setter method for property dataSyncDelayTimeout .
+ *
+ * @param dataSyncDelayTimeout value to be assigned to property dataSyncDelayTimeout
+ */
+ public void setDataSyncDelayTimeout(int dataSyncDelayTimeout) {
+ this.dataSyncDelayTimeout = dataSyncDelayTimeout;
+ }
+
+ /**
+ * Getter method for property dataSyncNotifyRetry.
+ *
+ * @return property value of dataSyncNotifyRetry
+ */
+ public int getDataSyncNotifyRetry() {
+ return dataSyncNotifyRetry;
+ }
+
+ /**
+ * Setter method for property dataSyncNotifyRetry .
+ *
+ * @param dataSyncNotifyRetry value to be assigned to property dataSyncNotifyRetry
+ */
+ public void setDataSyncNotifyRetry(int dataSyncNotifyRetry) {
+ this.dataSyncNotifyRetry = dataSyncNotifyRetry;
+ }
+
+ /**
+ * Getter method for property sessionDisconnectDelayMs.
+ *
+ * @return property value of sessionDisconnectDelayMs
+ */
+ public int getSessionDisconnectDelayMs() {
+ return sessionDisconnectDelayMs;
+ }
+
+ /**
+ * Setter method for property sessionDisconnectDelayMs.
+ *
+ * @param sessionDisconnectDelayMs value to be assigned to property sessionDisconnectDelayMs
+ */
+ public void setSessionDisconnectDelayMs(int sessionDisconnectDelayMs) {
+ this.sessionDisconnectDelayMs = sessionDisconnectDelayMs;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
+ }
+
+ public int getDefaultRequestExecutorMinSize() {
+ return defaultRequestExecutorMinSize;
+ }
+
+ public void setDefaultRequestExecutorMinSize(int defaultRequestExecutorMinSize) {
+ this.defaultRequestExecutorMinSize = defaultRequestExecutorMinSize;
+ }
+
+ public int getDefaultRequestExecutorMaxSize() {
+ return defaultRequestExecutorMaxSize;
+ }
+
+ public void setDefaultRequestExecutorMaxSize(int defaultRequestExecutorMaxSize) {
+ this.defaultRequestExecutorMaxSize = defaultRequestExecutorMaxSize;
+ }
+
+ public int getDefaultRequestExecutorQueueSize() {
+ return defaultRequestExecutorQueueSize;
+ }
+
+ public void setDefaultRequestExecutorQueueSize(int defaultRequestExecutorQueueSize) {
+ this.defaultRequestExecutorQueueSize = defaultRequestExecutorQueueSize;
+ }
+
+ public long getDefaultRequestExecutorKeepAliveTime() {
+ return defaultRequestExecutorKeepAliveTime;
+ }
+
+ public void setDefaultRequestExecutorKeepAliveTime(long defaultRequestExecutorKeepAliveTime) {
+ this.defaultRequestExecutorKeepAliveTime = defaultRequestExecutorKeepAliveTime;
+ }
+
+ public int getLogMetricsFixedDelay() {
+ return logMetricsFixedDelay;
+ }
+
+ public void setLogMetricsFixedDelay(int logMetricsFixedDelay) {
+ this.logMetricsFixedDelay = logMetricsFixedDelay;
+ }
+
}
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/CacheDigestTask.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/CacheDigestTask.java
index 5b09ddb31..77b7328b1 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/CacheDigestTask.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/CacheDigestTask.java
@@ -16,19 +16,21 @@
*/
package com.alipay.sofa.registry.server.data.cache;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+
import com.alipay.sofa.registry.common.model.dataserver.Datum;
import com.alipay.sofa.registry.common.model.store.Publisher;
import com.alipay.sofa.registry.common.model.store.URL;
import com.alipay.sofa.registry.log.Logger;
import com.alipay.sofa.registry.log.LoggerFactory;
import com.alipay.sofa.registry.util.NamedThreadFactory;
-import org.springframework.util.CollectionUtils;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
/**
*
@@ -39,20 +41,23 @@ public class CacheDigestTask {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheDigestTask.class);
+ @Autowired
+ private DatumCache datumCache;
+
/**
*
*/
public void start() {
- ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("CacheDigestTask"));
+ ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("CacheDigestTask"));
executor.scheduleAtFixedRate(() -> {
try {
- Map> allMap = DatumCache.getAll();
+ Map> allMap = datumCache.getAll();
if (!allMap.isEmpty()) {
for (Entry> dataCenterEntry : allMap.entrySet()) {
String dataCenter = dataCenterEntry.getKey();
Map datumMap = dataCenterEntry.getValue();
- LOGGER.info("[CacheDigestTask] size of datum in {} is {}",
- dataCenter, datumMap.size());
+ LOGGER.info("[CacheDigestTask] size of datum in {} is {}", dataCenter, datumMap.size());
for (Entry dataInfoEntry : datumMap.entrySet()) {
String dataInfoId = dataInfoEntry.getKey();
Datum data = dataInfoEntry.getValue();
@@ -63,14 +68,12 @@ public void start() {
pubStr.append(logPublisher(publisher)).append(";");
}
}
- LOGGER.info(
- "[Datum] dataInfoId={}, version={}, dataCenter={}, publishers=[{}]",
- dataInfoId, data.getVersion(), dataCenter, pubStr.toString());
+ LOGGER.info("[Datum]{},{},{},[{}]", dataInfoId,
+ data.getVersion(), dataCenter, pubStr.toString());
}
int pubCount = datumMap.values().stream().map(Datum::getPubMap)
.filter(map -> map != null && !map.isEmpty()).mapToInt(Map::size).sum();
- LOGGER.info("[CacheDigestTask] size of publisher in {} is {}",
- dataCenter, pubCount);
+ LOGGER.info("[CacheDigestTask] size of publisher in {} is {}", dataCenter, pubCount);
}
} else {
LOGGER.info("[CacheDigestTask] datum cache is empty");
@@ -79,16 +82,15 @@ public void start() {
} catch (Throwable t) {
LOGGER.error("[CacheDigestTask] cache digest error", t);
}
- }, 30, 300, TimeUnit.SECONDS);
+ }, 30, 600, TimeUnit.SECONDS);
}
private String logPublisher(Publisher publisher) {
if (publisher != null) {
URL url = publisher.getSourceAddress();
String urlStr = url != null ? url.getAddressString() : "null";
- return String.format("dataInfoId=%s, version=%s, host=%s, registerId=%s",
- publisher.getDataInfoId(), publisher.getVersion(), urlStr,
- publisher.getRegisterId());
+ return String.format("%s,%s,%s,%s", publisher.getRegisterId(),
+ publisher.getRegisterTimestamp(), urlStr, publisher.getVersion());
}
return "";
}
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DataServerCache.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DataServerCache.java
index 163d633ff..64d3d9ee0 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DataServerCache.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DataServerCache.java
@@ -16,19 +16,9 @@
*/
package com.alipay.sofa.registry.server.data.cache;
-import com.alipay.sofa.registry.common.model.metaserver.DataNode;
-import com.alipay.sofa.registry.consistency.hash.ConsistentHash;
-import com.alipay.sofa.registry.log.Logger;
-import com.alipay.sofa.registry.log.LoggerFactory;
-import com.alipay.sofa.registry.server.data.bootstrap.DataServerConfig;
-import com.alipay.sofa.registry.server.data.node.DataNodeStatus;
-import com.alipay.sofa.registry.server.data.util.LocalServerStatusEnum;
-import org.springframework.beans.factory.annotation.Autowired;
-
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -36,6 +26,21 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alipay.sofa.registry.common.model.metaserver.DataNode;
+import com.alipay.sofa.registry.common.model.store.URL;
+import com.alipay.sofa.registry.consistency.hash.ConsistentHash;
+import com.alipay.sofa.registry.log.Logger;
+import com.alipay.sofa.registry.log.LoggerFactory;
+import com.alipay.sofa.registry.server.data.bootstrap.DataServerConfig;
+import com.alipay.sofa.registry.server.data.event.DataServerChangeEvent.FromType;
+import com.alipay.sofa.registry.server.data.event.handler.AfterWorkingProcessHandler;
+import com.alipay.sofa.registry.server.data.node.DataNodeStatus;
+import com.alipay.sofa.registry.server.data.util.LocalServerStatusEnum;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
/**
* cache of dataservers
*
@@ -53,8 +58,13 @@ public class DataServerCache {
@Autowired
private DataServerConfig dataServerConfig;
+ @Autowired
+ private AfterWorkingProcessHandler afterWorkingProcessHandler;
+
+ /** current dataServer list and version */
private volatile DataServerChangeItem dataServerChangeItem = new DataServerChangeItem();
+ /** new input dataServer list and version */
private volatile DataServerChangeItem newDataServerChangeItem = new DataServerChangeItem();
private final AtomicBoolean HAS_NOTIFY_ALL = new AtomicBoolean(
@@ -72,7 +82,7 @@ public class DataServerCache {
* @param newItem
* @return changedMap(datacenter, serverIp)
*/
- public Map> compareAndSet(DataServerChangeItem newItem) {
+ public Map> compareAndSet(DataServerChangeItem newItem, FromType fromType) {
synchronized (DataServerCache.class) {
// versionMap: datacenter -> version
Map newVersionMap = newItem.getVersionMap();
@@ -103,8 +113,8 @@ public Map> compareAndSet(DataServerChangeItem newItem) {
if (isTheSame.get()) {
LOGGER
.info(
- "current process map has a same version as change map,this change will be ignored!process version={},get version={}",
- currentNewVersionMap, newVersionMap);
+ "current process map has a same version as change map,this change will be ignored!process version={},get version={},from={}",
+ currentNewVersionMap, newVersionMap, fromType);
return new HashMap<>();
}
}
@@ -132,7 +142,8 @@ public Map> compareAndSet(DataServerChangeItem newItem) {
init(newVersionMap.get(dataServerConfig.getLocalDataCenter()));
}
if (!changedMap.isEmpty()) {
- LOGGER.info("old server map = {}", dataServerChangeItem.getServerMap());
+ LOGGER.info("old server map = {},from={}", dataServerChangeItem.getServerMap(),
+ fromType);
LOGGER.info("new server map = {}", newServerMap);
LOGGER.info("new server version map = {}", newVersionMap);
LOGGER.info("status map = {}", nodeStatusMap);
@@ -242,13 +253,15 @@ private void updateDataServerStatus() {
Map map = nodeStatusMap.get(curVersion.get());
if (map != null) {
Set ips = map.keySet();
- if (!ips.containsAll(newDataServerChangeItem.getServerMap()
- .get(dataServerConfig.getLocalDataCenter()).keySet())) {
- LOGGER.info(
- "nodeStatusMap not contains all push list,nodeStatusMap {} push {}",
- nodeStatusMap,
- newDataServerChangeItem.getServerMap()
- .get(dataServerConfig.getLocalDataCenter()).keySet());
+ Set itemIps = newDataServerChangeItem.getServerMap()
+ .get(dataServerConfig.getLocalDataCenter()).keySet();
+ if (!ips.containsAll(itemIps)) {
+
+ LOGGER
+ .info(
+ "nodeStatusMap not contains all push list,nodeStatusMap {},push {},diff1{},diff2{}",
+ nodeStatusMap, itemIps, Sets.difference(ips, itemIps),
+ Sets.difference(itemIps, ips));
return;
}
} else {
@@ -263,8 +276,16 @@ private void updateDataServerStatus() {
dataNodeStatus.setStatus(LocalServerStatusEnum.WORKING);
+ //after working update current dataCenter list to old DataServerChangeItem
+ updateItem(
+ newDataServerChangeItem.getServerMap().get(dataServerConfig.getLocalDataCenter()),
+ newVersion, dataServerConfig.getLocalDataCenter());
+
//after working status,must clean this map,because calculate backupTriad need add not working node,see LocalDataServerChangeEventHandler getToBeSyncMap
resetStatusMapToWorking();
+
+ //after working process
+ afterWorkingProcessHandler.afterWorkingProcess();
}
}
@@ -351,25 +372,37 @@ public Long getDataCenterNewVersion(String dataCenter) {
}
}
- public BackupTriad calculateOldBackupTriad(String dataInfoId, String dataCenter,
- DataServerConfig dataServerBootstrapConfig) {
+ /**
+ * calculate ConsistentHash base current data server list
+ * do not return null, otherwise will lead to unexpected consequences
+ *
+ * 20200211 update: bugfix: empty dataServerList cause NPE because calculateOldConsistentHash return null
+ */
+ public ConsistentHash calculateOldConsistentHash(String dataCenter) {
Map> dataServerMap = dataServerChangeItem.getServerMap();
Map dataNodeMap = dataServerMap.get(dataCenter);
+ Collection dataServerNodes;
if (dataNodeMap != null && !dataNodeMap.isEmpty()) {
-
- Collection dataServerNodes = dataNodeMap.values();
-
- ConsistentHash consistentHash = new ConsistentHash<>(
- dataServerBootstrapConfig.getNumberOfReplicas(), dataServerNodes);
-
- List list = consistentHash.getNUniqueNodesFor(dataInfoId,
- dataServerBootstrapConfig.getStoreNodes());
-
- return new BackupTriad(dataInfoId, list);
+ dataServerNodes = dataNodeMap.values();
} else {
- LOGGER.warn("Calculate Old BackupTriad,old dataServer list is empty!");
- return null;
+ dataServerNodes = Lists.newArrayList(new DataNode(new URL(DataServerConfig.IP),
+ dataCenter));
+ LOGGER
+ .error("[calculateOldConsistentHash] Old dataServer list is empty, add on the local IP");
}
+ ConsistentHash consistentHash = new ConsistentHash<>(
+ dataServerConfig.getNumberOfReplicas(), dataServerNodes);
+
+ return consistentHash;
+ }
+
+ /**
+ * get all datacenters
+ *
+ * @return
+ */
+ public Set getAllDataCenters() {
+ return newDataServerChangeItem.getVersionMap().keySet();
}
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumCache.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumCache.java
index 6b17f7702..53b577ada 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumCache.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumCache.java
@@ -16,41 +16,28 @@
*/
package com.alipay.sofa.registry.server.data.cache;
-import com.alipay.sofa.registry.common.model.dataserver.Datum;
-import com.alipay.sofa.registry.common.model.store.Publisher;
-import com.alipay.sofa.registry.server.data.change.DataChangeTypeEnum;
-import org.springframework.util.StringUtils;
-
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alipay.sofa.registry.common.model.dataserver.Datum;
+import com.alipay.sofa.registry.common.model.store.Publisher;
+import com.alipay.sofa.registry.server.data.change.DataChangeTypeEnum;
/**
* cache of datum, providing query function to the upper module
*
+ * @author kezhu.wukz
* @author qian.lqlq
* @version $Id: DatumCache.java, v 0.1 2017-12-06 20:50 qian.lqlq Exp $
*/
public class DatumCache {
- public static final long ERROR_DATUM_VERSION = -2L;
-
- /**
- * row: dataCenter
- * column: dataInfoId
- * value: datum
- */
- private static final Map> DATUM_MAP = new ConcurrentHashMap<>();
-
- /**
- * row: ip:port
- * column: registerId
- * value: publisher
- */
- private static final Map> CLIENT_PUB_MAP = new ConcurrentHashMap<>();
+ @Autowired
+ private DatumStorage localDatumStorage;
/**
* get datum by specific dataCenter and dataInfoId
@@ -59,29 +46,38 @@ public class DatumCache {
* @param dataInfoId
* @return
*/
- public static Datum get(String dataCenter, String dataInfoId) {
- if (DATUM_MAP.containsKey(dataCenter)) {
- Map map = DATUM_MAP.get(dataCenter);
- if (map.containsKey(dataInfoId)) {
- return map.get(dataInfoId);
- }
- }
- return null;
+ public Datum get(String dataCenter, String dataInfoId) {
+ return localDatumStorage.get(dataCenter, dataInfoId);
}
/**
- * get datum of all datercenters by dataInfoId
+ * get datum of all data centers by dataInfoId
*
* @param dataInfoId
* @return
*/
- public static Map get(String dataInfoId) {
+ public Map get(String dataInfoId) {
Map datumMap = new HashMap<>();
- DATUM_MAP.forEach((dataCenter, datums) -> {
- if (datums.containsKey(dataInfoId)) {
- datumMap.put(dataCenter, datums.get(dataInfoId));
- }
- });
+
+ //local
+ Map localDataCenterToMap = localDatumStorage.get(dataInfoId);
+ datumMap.putAll(localDataCenterToMap);
+
+ return datumMap;
+ }
+
+ /**
+ * get datum of all data centers by dataInfoId
+ *
+ * @param dataInfoId
+ * @return
+ */
+ public Map getVersions(String dataInfoId) {
+ Map datumMap = new HashMap<>();
+
+ //local
+ Map localVersions = localDatumStorage.getVersions(dataInfoId);
+ datumMap.putAll(localVersions);
return datumMap;
}
@@ -93,12 +89,12 @@ public static Map get(String dataInfoId) {
* @param dataInfoId
* @return
*/
- public static Map getDatumGroupByDataCenter(String dataCenter, String dataInfoId) {
+ public Map getDatumGroupByDataCenter(String dataCenter, String dataInfoId) {
Map map = new HashMap<>();
if (StringUtils.isEmpty(dataCenter)) {
- map = DatumCache.get(dataInfoId);
+ map = this.get(dataInfoId);
} else {
- Datum datum = DatumCache.get(dataCenter, dataInfoId);
+ Datum datum = this.get(dataCenter, dataInfoId);
if (datum != null) {
map.put(dataCenter, datum);
}
@@ -111,18 +107,25 @@ public static Map getDatumGroupByDataCenter(String dataCenter, St
*
* @return
*/
- public static Map> getAll() {
- return DATUM_MAP;
+ public Map> getAll() {
+ return localDatumStorage.getAll();
}
/**
*
*
- * @param host
+ * @param connectId
* @return
*/
- public static Map getByHost(String host) {
- return CLIENT_PUB_MAP.getOrDefault(host, null);
+ public Map getByConnectId(String connectId) {
+ return localDatumStorage.getByConnectId(connectId);
+ }
+
+ /**
+ * get own publishers by connectId
+ */
+ public Map getOwnByConnectId(String connectId) {
+ return localDatumStorage.getOwnByConnectId(connectId);
}
/**
@@ -132,56 +135,8 @@ public static Map getByHost(String host) {
* @param datum
* @return the last version before datum changed, if datum is not exist, return null
*/
- public static MergeResult putDatum(DataChangeTypeEnum changeType, Datum datum) {
- MergeResult mergeResult;
- String dataCenter = datum.getDataCenter();
- String dataInfoId = datum.getDataInfoId();
- Map map = DATUM_MAP.get(dataCenter);
- if (map == null) {
- map = new ConcurrentHashMap<>();
- Map ret = DATUM_MAP.putIfAbsent(dataCenter, map);
- if (ret != null) {
- map = ret;
- }
- }
-
- //first put UnPublisher datum(dataId group instanceId is null),can not add to cache
- if (datum.getDataId() == null && map.get(dataInfoId) == null) {
- mergeResult = new MergeResult(ERROR_DATUM_VERSION, false);
- return mergeResult;
- }
-
- Datum ret = map.putIfAbsent(dataInfoId, datum);
- if (ret == null) {
- Set> entries = datum.getPubMap().entrySet();
- Iterator> iterator = entries.iterator();
- while (iterator.hasNext()) {
- Entry entry = iterator.next();
- Publisher publisher = entry.getValue();
- if (!(publisher instanceof UnPublisher)) {
- String registerId = publisher.getRegisterId();
- Map clientRegisterMap = new ConcurrentHashMap<>();
- clientRegisterMap.put(registerId, publisher);
- Map retMap = CLIENT_PUB_MAP.putIfAbsent(publisher
- .getSourceAddress().getAddressString(), clientRegisterMap);
- if (retMap != null) {
- retMap.putAll(clientRegisterMap);
- }
- } else {
- //first put to cache,UnPublisher data must remove,not so got error pub data exist
- iterator.remove();
- }
- }
- mergeResult = new MergeResult(null, true);
- } else {
- if (changeType == DataChangeTypeEnum.MERGE) {
- mergeResult = mergeDatum(datum);
- } else {
- Long lastVersion = coverDatum(datum);
- mergeResult = new MergeResult(lastVersion, true);
- }
- }
- return mergeResult;
+ public MergeResult putDatum(DataChangeTypeEnum changeType, Datum datum) {
+ return localDatumStorage.putDatum(changeType, datum);
}
/**
@@ -190,120 +145,25 @@ public static MergeResult putDatum(DataChangeTypeEnum changeType, Datum datum) {
* @param dataInfoId
* @return
*/
- public static boolean cleanDatum(String dataCenter, String dataInfoId) {
-
- Map datumMap = DATUM_MAP.get(dataCenter);
- if (datumMap != null) {
- Datum cacheDatum = datumMap.remove(dataInfoId);
- if (cacheDatum != null) {
- Map cachePubMap = cacheDatum.getPubMap();
-
- for (Entry cachePubEntry : cachePubMap.entrySet()) {
- String registerId = cachePubEntry.getKey();
- Publisher cachePub = cachePubEntry.getValue();
- //remove from cache
- if (cachePub != null) {
- cachePubMap.remove(registerId);
- CLIENT_PUB_MAP.get(cachePub.getSourceAddress().getAddressString()).remove(
- registerId);
- }
- }
- return true;
- }
- }
- return false;
+ public boolean cleanDatum(String dataCenter, String dataInfoId) {
+ return localDatumStorage.cleanDatum(dataCenter, dataInfoId);
}
/**
- * merge datum in cache
- *
- * @param datum
- * @return
+ * cover datum by snapshot
*/
- private static MergeResult mergeDatum(Datum datum) {
- boolean isChanged = false;
- Datum cacheDatum = DATUM_MAP.get(datum.getDataCenter()).get(datum.getDataInfoId());
- Map cachePubMap = cacheDatum.getPubMap();
- Map pubMap = datum.getPubMap();
- for (Entry pubEntry : pubMap.entrySet()) {
- String registerId = pubEntry.getKey();
- Publisher pub = pubEntry.getValue();
- Publisher cachePub = cachePubMap.get(registerId);
- if (pub instanceof UnPublisher) {
- //remove from cache
- if (cachePub != null
- && pub.getRegisterTimestamp() > cachePub.getRegisterTimestamp()) {
- cachePubMap.remove(registerId);
- CLIENT_PUB_MAP.get(cachePub.getSourceAddress().getAddressString()).remove(
- registerId);
- isChanged = true;
- }
- } else {
- String pubAddr = pub.getSourceAddress().getAddressString();
- long version = pub.getVersion();
- long cacheVersion = cachePub == null ? 0L : cachePub.getVersion();
- String cachePubAddr = cachePub == null ? "" : cachePub.getSourceAddress()
- .getAddressString();
- if (cacheVersion <= version) {
- cachePubMap.put(registerId, pub);
- if (cacheVersion < version || !pubAddr.equals(cachePubAddr)) {
- // if version of both pub and cachePub are not equal, or sourceAddress of both are not equal, update
- // eg: sessionserver crash, client reconnect to other sessionserver, sourceAddress changed, version not changed
- // eg: client restart, sourceAddress and version are both changed
- if (CLIENT_PUB_MAP.containsKey(cachePubAddr)) {
- CLIENT_PUB_MAP.get(cachePubAddr).remove(registerId);
- }
- if (!CLIENT_PUB_MAP.containsKey(pubAddr)) {
- CLIENT_PUB_MAP.putIfAbsent(pubAddr, new ConcurrentHashMap<>());
- }
- CLIENT_PUB_MAP.get(pubAddr).put(registerId, pub);
- isChanged = true;
- }
- }
- }
- }
- Long lastVersion = cacheDatum.getVersion();
- if (isChanged) {
- cacheDatum.setVersion(datum.getVersion());
- }
- return new MergeResult(lastVersion, isChanged);
+ public Datum putSnapshot(String dataInfoId, Map toBeDeletedPubMap,
+ Map snapshotPubMap) {
+ return localDatumStorage.putSnapshot(dataInfoId, toBeDeletedPubMap, snapshotPubMap);
}
/**
+ * Getter method for property OWN_CONNECT_ID_INDEX.
*
- * @param datum
- * @return
+ * @return property value of OWN_CONNECT_ID_INDEX
*/
- private static Long coverDatum(Datum datum) {
- String dataCenter = datum.getDataCenter();
- String dataInfoId = datum.getDataInfoId();
- Datum cacheDatum = DATUM_MAP.get(dataCenter).get(dataInfoId);
- if (datum.getVersion() != cacheDatum.getVersion()) {
- DATUM_MAP.get(dataCenter).put(dataInfoId, datum);
- Map pubMap = datum.getPubMap();
- Map cachePubMap = new HashMap<>(cacheDatum.getPubMap());
- for (Entry pubEntry : pubMap.entrySet()) {
- String registerId = pubEntry.getKey();
- Publisher pub = pubEntry.getValue();
- String pubAddr = pub.getSourceAddress().getAddressString();
- if (!CLIENT_PUB_MAP.containsKey(pubAddr)) {
- CLIENT_PUB_MAP.putIfAbsent(pubAddr, new ConcurrentHashMap<>());
- }
- CLIENT_PUB_MAP.get(pubAddr).put(registerId, pub);
- Publisher cachePub = cachePubMap.get(registerId);
- if (cachePub != null
- && pubAddr.equals(cachePub.getSourceAddress().getAddressString())) {
- cachePubMap.remove(registerId);
- }
- }
- if (!cachePubMap.isEmpty()) {
- for (Publisher cachePub : cachePubMap.values()) {
- CLIENT_PUB_MAP.get(cachePub.getSourceAddress().getAddressString()).remove(
- cachePub.getRegisterId());
- }
- }
- }
- return cacheDatum.getVersion();
+ public Set getAllConnectIds() {
+ return localDatumStorage.getAllConnectIds();
}
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumStorage.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumStorage.java
new file mode 100644
index 000000000..fc71511c8
--- /dev/null
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/DatumStorage.java
@@ -0,0 +1,102 @@
+/*
+ * 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 com.alipay.sofa.registry.server.data.cache;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.alipay.sofa.registry.common.model.dataserver.Datum;
+import com.alipay.sofa.registry.common.model.store.Publisher;
+import com.alipay.sofa.registry.server.data.change.DataChangeTypeEnum;
+
+/**
+ *
+ * @author kezhu.wukz
+ * @version $Id: DatumAccessService.java, v 0.1 2019-12-05 11:51 kezhu.wukz Exp $
+ */
+public interface DatumStorage {
+
+ /**
+ * get datum by specific dataCenter and dataInfoId
+ *
+ * @param dataCenter
+ * @param dataInfoId
+ * @return
+ */
+ Datum get(String dataCenter, String dataInfoId);
+
+ /**
+ * get datum of all datercenters by dataInfoId
+ *
+ * @param dataInfoId
+ * @return
+ */
+ Map get(String dataInfoId);
+
+ /**
+ * get all datum
+ *
+ * @return
+ */
+ Map> getAll();
+
+ /**
+ *
+ *
+ * @param connectId
+ * @return
+ */
+ Map getByConnectId(String connectId);
+
+ /**
+ * get own publishers by connectId
+ */
+ Map getOwnByConnectId(String connectId);
+
+ /**
+ * Getter method for property OWN_CONNECT_ID_INDEX.
+ *
+ * @return property value of OWN_CONNECT_ID_INDEX
+ */
+ Set getAllConnectIds();
+
+ /**
+ * put datum into cache
+ *
+ * @param changeType
+ * @param datum
+ * @return the last version before datum changed, if datum is not exist, return null
+ */
+ MergeResult putDatum(DataChangeTypeEnum changeType, Datum datum);
+
+ /**
+ * remove datum ant contains all pub data,and clean all the client map reference
+ * @param dataCenter
+ * @param dataInfoId
+ * @return
+ */
+ boolean cleanDatum(String dataCenter, String dataInfoId);
+
+ /**
+ * cover datum by snapshot
+ */
+ Datum putSnapshot(String dataInfoId, Map toBeDeletedPubMap,
+ Map snapshotPubMap);
+
+ Map getVersions(String dataInfoId);
+
+}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/LocalDatumStorage.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/LocalDatumStorage.java
new file mode 100644
index 000000000..fd1af059f
--- /dev/null
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/LocalDatumStorage.java
@@ -0,0 +1,427 @@
+/*
+ * 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 com.alipay.sofa.registry.server.data.cache;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.alipay.sofa.registry.common.model.constants.ValueConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alipay.sofa.registry.common.model.dataserver.Datum;
+import com.alipay.sofa.registry.common.model.store.Publisher;
+import com.alipay.sofa.registry.common.model.store.WordCache;
+import com.alipay.sofa.registry.server.data.bootstrap.DataServerConfig;
+import com.alipay.sofa.registry.server.data.change.DataChangeTypeEnum;
+import com.alipay.sofa.registry.server.data.node.DataServerNode;
+import com.alipay.sofa.registry.server.data.remoting.dataserver.DataServerNodeFactory;
+
+/**
+ * datum storage of local dataCenter
+ *
+ * @author kezhu.wukz
+ * @version $Id: LocalDatumAccessService.java, v 0.1 2019-12-06 15:22 kezhu.wukz Exp $
+ */
+public class LocalDatumStorage implements DatumStorage {
+
+ public static final long ERROR_DATUM_VERSION = -2L;
+
+ /**
+ * row: dataCenter
+ * column: dataInfoId
+ * value: datum
+ */
+ protected final Map> DATUM_MAP = new ConcurrentHashMap<>();
+
+ /**
+ * all datum index
+ *
+ * row: ip:port
+ * column: registerId
+ * value: publisher
+ */
+ protected final Map> ALL_CONNECT_ID_INDEX = new ConcurrentHashMap<>();
+
+ @Autowired
+ private DataServerConfig dataServerConfig;
+
+ /**
+ * get datum by specific dataCenter and dataInfoId
+ *
+ * @param dataCenter
+ * @param dataInfoId
+ * @return
+ */
+ public Datum get(String dataCenter, String dataInfoId) {
+ Map map = DATUM_MAP.get(dataCenter);
+ if (map != null) {
+ return map.get(dataInfoId);
+ }
+ return null;
+ }
+
+ /**
+ * get datum of all datercenters by dataInfoId
+ *
+ * @param dataInfoId
+ * @return
+ */
+ public Map get(String dataInfoId) {
+ Map datumMap = new HashMap<>();
+ DATUM_MAP.forEach((dataCenter, datums) -> {
+ Datum datum = datums.get(dataInfoId);
+ if (datum != null) {
+ datumMap.put(dataCenter, datum);
+ }
+ });
+
+ return datumMap;
+ }
+
+ /**
+ * get all datum
+ *
+ * @return
+ */
+ public Map> getAll() {
+ return DATUM_MAP;
+ }
+
+ /**
+ *
+ *
+ * @param connectId
+ * @return
+ */
+ public Map getByConnectId(String connectId) {
+ return ALL_CONNECT_ID_INDEX.getOrDefault(connectId, null);
+ }
+
+ /**
+ * get own publishers by connectId
+ */
+ public Map getOwnByConnectId(String connectId) {
+ Map ownPubMap = new HashMap<>();
+ Map allPubMap = ALL_CONNECT_ID_INDEX.getOrDefault(connectId, null);
+ if (allPubMap != null) {
+ for (Entry entry : allPubMap.entrySet()) {
+ String registerId = entry.getKey();
+ Publisher publisher = entry.getValue();
+ if (isOwnByMyself(publisher.getDataInfoId())) {
+ ownPubMap.put(registerId, publisher);
+ }
+ }
+ }
+ return ownPubMap;
+ }
+
+ /**
+ * whether dataInfoId own by self
+ */
+ protected boolean isOwnByMyself(String dataInfoId) {
+ DataServerNode dataServerNode = DataServerNodeFactory.computeDataServerNode(
+ dataServerConfig.getLocalDataCenter(), dataInfoId);
+ return DataServerConfig.IP.equals(dataServerNode.getIp());
+ }
+
+ /**
+ * put datum into cache
+ *
+ * @param changeType
+ * @param datum
+ * @return the last version before datum changed, if datum is not exist, return null
+ */
+ public MergeResult putDatum(DataChangeTypeEnum changeType, Datum datum) {
+ MergeResult mergeResult;
+ String dataCenter = datum.getDataCenter();
+ String dataInfoId = datum.getDataInfoId();
+ Map map = getDatumMapByDataCenter(dataCenter);
+
+ //first put UnPublisher datum(dataId group instanceId is null),can not add to cache
+ if (datum.getDataId() == null && map.get(dataInfoId) == null) {
+ mergeResult = new MergeResult(ERROR_DATUM_VERSION, false);
+ return mergeResult;
+ }
+
+ // filter out the unPubs of datum when first put.
+ // Otherwise, "syncData" or "fetchData" when get Datum with unPubs, which will result something error
+ boolean[] exists = { true };
+ Datum cacheDatum = map.computeIfAbsent(dataInfoId, k -> filterUnPubs(exists, datum));
+ if (!exists[0]) {
+ Iterator> iterator = datum.getPubMap().entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry entry = iterator.next();
+ Publisher publisher = entry.getValue();
+ addToIndex(publisher);
+ }
+ mergeResult = new MergeResult(null, true);
+ } else {
+ if (changeType == DataChangeTypeEnum.MERGE) {
+ mergeResult = mergeDatum(cacheDatum, datum);
+ } else {
+ Long lastVersion = coverDatum(datum);
+ mergeResult = new MergeResult(lastVersion, true);
+ }
+ }
+ return mergeResult;
+ }
+
+ /**
+ * remove unPubs from datum
+ */
+ private Datum filterUnPubs(boolean[] exists, Datum datum) {
+ Iterator> iterator = datum.getPubMap().entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry entry = iterator.next();
+ Publisher publisher = entry.getValue();
+ if (publisher instanceof UnPublisher) {
+ //first put to cache,UnPublisher data must remove,not so got error pub data exist
+ iterator.remove();
+ }
+ }
+ exists[0] = false;
+ return datum;
+ }
+
+ private Map getDatumMapByDataCenter(String dataCenter) {
+ Map map = DATUM_MAP.get(dataCenter);
+ if (map == null) {
+ map = new ConcurrentHashMap<>();
+ Map ret = DATUM_MAP.putIfAbsent(dataCenter, map);
+ if (ret != null) {
+ map = ret;
+ }
+ }
+ return map;
+ }
+
+ /**
+ * remove datum ant contains all pub data,and clean all the client map reference
+ * @param dataCenter
+ * @param dataInfoId
+ * @return
+ */
+ public boolean cleanDatum(String dataCenter, String dataInfoId) {
+
+ Map datumMap = DATUM_MAP.get(dataCenter);
+ if (datumMap != null) {
+ Datum cacheDatum = datumMap.remove(dataInfoId);
+ if (cacheDatum != null) {
+ Map cachePubMap = cacheDatum.getPubMap();
+
+ for (Entry cachePubEntry : cachePubMap.entrySet()) {
+ String registerId = cachePubEntry.getKey();
+ Publisher cachePub = cachePubEntry.getValue();
+ //remove from cache
+ if (cachePub != null) {
+ cachePubMap.remove(registerId);
+ removeFromIndex(cachePub);
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * merge datum in cache
+ *
+ * @param datum
+ * @return
+ */
+ private MergeResult mergeDatum(Datum cacheDatum, Datum datum) {
+ boolean isChanged = false;
+ Map cachePubMap = cacheDatum.getPubMap();
+ Map pubMap = datum.getPubMap();
+ for (Entry pubEntry : pubMap.entrySet()) {
+ String registerId = pubEntry.getKey();
+ Publisher pub = pubEntry.getValue();
+ Publisher cachePub = cachePubMap.get(registerId);
+ if (mergePublisher(pub, cachePubMap, cachePub)) {
+ isChanged = true;
+ }
+ }
+ Long lastVersion = cacheDatum.getVersion();
+ if (isChanged) {
+ cacheDatum.setVersion(datum.getVersion());
+ }
+ return new MergeResult(lastVersion, isChanged);
+ }
+
+ /**
+ * cover datum by snapshot
+ */
+ public Datum putSnapshot(String dataInfoId, Map toBeDeletedPubMap,
+ Map snapshotPubMap) {
+ // get cache datum
+ Map datumMap = getDatumMapByDataCenter(dataServerConfig.getLocalDataCenter());
+ Datum cacheDatum = datumMap.get(dataInfoId);
+ if (cacheDatum == null) {
+ cacheDatum = new Datum(dataInfoId, dataServerConfig.getLocalDataCenter());
+ Publisher publisher = snapshotPubMap.values().iterator().next();
+ cacheDatum.setInstanceId(publisher.getInstanceId());
+ cacheDatum.setDataId(publisher.getDataId());
+ cacheDatum.setGroup(publisher.getGroup());
+ Datum datum = datumMap.putIfAbsent(dataInfoId, cacheDatum);
+ if (datum != null) {
+ cacheDatum = datum;
+ }
+ }
+ //remove toBeDeletedPubMap from cacheDatum
+ for (Entry toBeDeletedPubEntry : toBeDeletedPubMap.entrySet()) {
+ String registerId = toBeDeletedPubEntry.getKey();
+ Publisher toBeDeletedPub = toBeDeletedPubEntry.getValue();
+ if (cacheDatum != null) {
+ cacheDatum.getPubMap().remove(registerId);
+ removeFromIndex(toBeDeletedPub);
+ }
+ }
+ // add snapshotPubMap to cacheDatum
+ for (Entry pubEntry : snapshotPubMap.entrySet()) {
+ String registerId = pubEntry.getKey();
+ Publisher snapshotPub = pubEntry.getValue();
+ Publisher cachePub = cacheDatum.getPubMap().put(registerId, snapshotPub);
+ if (cachePub != null) {
+ removeFromIndex(cachePub);
+ }
+ addToIndex(snapshotPub);
+ }
+
+ cacheDatum.updateVersion();
+
+ return cacheDatum;
+ }
+
+ @Override
+ public Map getVersions(String dataInfoId) {
+ Map versions = new HashMap<>(1);
+ Map datumMap = this.get(dataInfoId);
+ if (datumMap != null) {
+ for (Map.Entry entry : datumMap.entrySet()) {
+ String dataCenter = entry.getKey();
+ Datum datum = entry.getValue();
+ versions.put(dataCenter, datum.getVersion());
+ }
+ }
+ return versions;
+ }
+
+ private boolean mergePublisher(Publisher pub, Map cachePubMap,
+ Publisher cachePub) {
+ boolean isChanged = false;
+ String registerId = pub.getRegisterId();
+ if (pub instanceof UnPublisher) {
+ //remove from cache
+ if (cachePub != null && pub.getRegisterTimestamp() > cachePub.getRegisterTimestamp()) {
+ cachePubMap.remove(registerId);
+ removeFromIndex(cachePub);
+ isChanged = true;
+ }
+ } else {
+ long version = pub.getVersion();
+ long cacheVersion = cachePub == null ? 0L : cachePub.getVersion();
+ if (cacheVersion <= version) {
+ cachePubMap.put(registerId, pub);
+ // connectId and cacheConnectId may not be equal, so indexes need to be deleted and added, rather than overwritten directly.
+ // why connectId and cacheConnectId may not be equal?
+ // eg: sessionserver crash, client(RegistryClient but not ConfregClient) reconnect to other sessionserver, sourceAddress changed, version not changed
+ removeFromIndex(cachePub);
+ addToIndex(pub);
+ isChanged = true;
+ }
+ }
+ return isChanged;
+ }
+
+ /**
+ *
+ * @param datum
+ * @return
+ */
+ private Long coverDatum(Datum datum) {
+ String dataCenter = datum.getDataCenter();
+ String dataInfoId = datum.getDataInfoId();
+ Datum cacheDatum = DATUM_MAP.get(dataCenter).get(dataInfoId);
+ if (datum.getVersion() != cacheDatum.getVersion()) {
+ DATUM_MAP.get(dataCenter).put(dataInfoId, datum);
+ Map pubMap = datum.getPubMap();
+ Map cachePubMap = new HashMap<>(cacheDatum.getPubMap());
+ for (Entry pubEntry : pubMap.entrySet()) {
+ String registerId = pubEntry.getKey();
+ Publisher pub = pubEntry.getValue();
+ addToIndex(pub);
+ Publisher cachePub = cachePubMap.get(registerId);
+ if (cachePub != null && getConnectId(pub).equals(getConnectId(cachePub))) {
+ cachePubMap.remove(registerId);
+ }
+ }
+ if (!cachePubMap.isEmpty()) {
+ for (Publisher cachePub : cachePubMap.values()) {
+ removeFromIndex(cachePub);
+ }
+ }
+ }
+ return cacheDatum.getVersion();
+ }
+
+ private void removeFromIndex(Publisher publisher) {
+ if (publisher == null) {
+ return;
+ }
+ String connectId = getConnectId(publisher);
+
+ // remove from ALL_CONNECT_ID_INDEX
+ Map publisherMap = ALL_CONNECT_ID_INDEX.get(connectId);
+ if (publisherMap != null) {
+ publisherMap.remove(publisher.getRegisterId());
+ }
+ }
+
+ private void addToIndex(Publisher publisher) {
+ if (publisher == null) {
+ return;
+ }
+ String connectId = getConnectId(publisher);
+
+ // add to ALL_CONNECT_ID_INDEX
+ Map publisherMap = ALL_CONNECT_ID_INDEX
+ .computeIfAbsent(connectId, s -> new ConcurrentHashMap<>());
+ publisherMap.put(publisher.getRegisterId(), publisher);
+
+ }
+
+ private String getConnectId(Publisher cachePub) {
+ return WordCache.getInstance().getWordCache(
+ cachePub.getSourceAddress().getAddressString() + ValueConstants.CONNECT_ID_SPLIT
+ + cachePub.getTargetAddress().getAddressString());
+ }
+
+ /**
+ * Getter method for property OWN_CONNECT_ID_INDEX.
+ *
+ * @return property value of OWN_CONNECT_ID_INDEX
+ */
+ public Set getAllConnectIds() {
+ return ALL_CONNECT_ID_INDEX.keySet();
+ }
+
+}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/UnPublisher.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/UnPublisher.java
index 5db5d80b9..1f3488dc8 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/UnPublisher.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/cache/UnPublisher.java
@@ -45,6 +45,6 @@ public UnPublisher(String dataInfoId, String registerId, long registerTimeStamp)
@Override
public DataType getDataType() {
- return DataType.UNPUBLISHER;
+ return DataType.UN_PUBLISHER;
}
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/ChangeData.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/ChangeData.java
index 166f8fa48..f3e541877 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/ChangeData.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/ChangeData.java
@@ -16,11 +16,11 @@
*/
package com.alipay.sofa.registry.server.data.change;
-import com.alipay.sofa.registry.common.model.dataserver.Datum;
-
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
+import com.alipay.sofa.registry.common.model.dataserver.Datum;
+
/**
* changed data
*
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataChangeHandler.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataChangeHandler.java
index 6bf66a946..f79dc8682 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataChangeHandler.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataChangeHandler.java
@@ -16,21 +16,33 @@
*/
package com.alipay.sofa.registry.server.data.change;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
import com.alipay.sofa.registry.common.model.dataserver.Datum;
+import com.alipay.sofa.registry.common.model.store.Publisher;
import com.alipay.sofa.registry.log.Logger;
import com.alipay.sofa.registry.log.LoggerFactory;
import com.alipay.sofa.registry.server.data.bootstrap.DataServerConfig;
import com.alipay.sofa.registry.server.data.cache.DatumCache;
+import com.alipay.sofa.registry.server.data.cache.LocalDatumStorage;
import com.alipay.sofa.registry.server.data.cache.MergeResult;
import com.alipay.sofa.registry.server.data.change.event.DataChangeEventCenter;
import com.alipay.sofa.registry.server.data.change.event.DataChangeEventQueue;
import com.alipay.sofa.registry.server.data.change.notify.IDataChangeNotifier;
import com.alipay.sofa.registry.server.data.executor.ExecutorFactory;
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
+import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
/**
@@ -39,40 +51,35 @@
* @author qian.lqlq
* @version $Id: DataChangeHandler.java, v 0.1 2017-12-07 18:44 qian.lqlq Exp $
*/
-public class DataChangeHandler implements InitializingBean {
+public class DataChangeHandler {
+
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(DataChangeHandler.class);
- private static final Logger LOGGER = LoggerFactory.getLogger(DataChangeHandler.class);
+ private static final Logger LOGGER_START = LoggerFactory.getLogger("DATA-START-LOGS");
@Autowired
- private DataServerConfig dataServerBootstrapConfig;
+ private DataServerConfig dataServerConfig;
@Autowired
private DataChangeEventCenter dataChangeEventCenter;
+ @Autowired
+ private DatumCache datumCache;
+
@Resource
private List dataChangeNotifiers;
- @Override
- public void afterPropertiesSet() {
- //init DataChangeEventCenter
- dataChangeEventCenter.init(dataServerBootstrapConfig);
- start();
- }
-
- /**
- *
- */
+ @PostConstruct
public void start() {
DataChangeEventQueue[] queues = dataChangeEventCenter.getQueues();
int queueCount = queues.length;
- Executor executor = ExecutorFactory.newFixedThreadPool(queueCount,
- DataChangeHandler.class.getSimpleName());
- Executor notifyExecutor = ExecutorFactory.newFixedThreadPool(
- dataServerBootstrapConfig.getQueueCount() * 5, this.getClass().getSimpleName());
+ Executor executor = ExecutorFactory.newFixedThreadPool(queueCount, DataChangeHandler.class.getSimpleName());
+ Executor notifyExecutor = ExecutorFactory
+ .newFixedThreadPool(dataServerConfig.getQueueCount() * 5, this.getClass().getSimpleName());
for (int idx = 0; idx < queueCount; idx++) {
final DataChangeEventQueue dataChangeEventQueue = queues[idx];
final String name = dataChangeEventQueue.getName();
- LOGGER.info("[DataChangeHandler] begin to notify datum in queue:{}", name);
executor.execute(() -> {
while (true) {
try {
@@ -83,7 +90,7 @@ public void start() {
}
}
});
- LOGGER.info("[DataChangeHandler] notify datum in queue:{} success", name);
+ LOGGER_START.info("[DataChangeHandler] notify datum in queue:{} success", name);
}
}
@@ -108,66 +115,85 @@ public ChangeNotifier(ChangeData changeData, String name) {
@Override
public void run() {
- Datum datum = changeData.getDatum();
- String dataCenter = datum.getDataCenter();
- String dataInfoId = datum.getDataInfoId();
- long version = datum.getVersion();
- DataSourceTypeEnum sourceType = changeData.getSourceType();
- DataChangeTypeEnum changeType = changeData.getChangeType();
- try {
- if (sourceType == DataSourceTypeEnum.CLEAN) {
- if (DatumCache.cleanDatum(dataCenter, dataInfoId)) {
- LOGGER
- .info(
- "[DataChangeHandler][{}] clean datum, dataCenter={}, dataInfoId={}, version={},sourceType={}, changeType={}",
- name, dataCenter, dataInfoId, version, sourceType, changeType);
- }
+ if (changeData instanceof SnapshotData) {
+ SnapshotData snapshotData = (SnapshotData) changeData;
+ String dataInfoId = snapshotData.getDataInfoId();
+ Map toBeDeletedPubMap = snapshotData.getToBeDeletedPubMap();
+ Map snapshotPubMap = snapshotData.getSnapshotPubMap();
+ Datum oldDatum = datumCache.get(dataServerConfig.getLocalDataCenter(), dataInfoId);
+ long lastVersion = oldDatum != null ? oldDatum.getVersion() : 0l;
+ Datum datum = datumCache.putSnapshot(dataInfoId, toBeDeletedPubMap, snapshotPubMap);
+ long version = datum != null ? datum.getVersion() : 0l;
+ LOGGER
+ .info(
+ "[DataChangeHandler][{}] snapshot handle,dataInfoId={}, version={}, lastVersion={}",
+ name, dataInfoId, version, lastVersion);
+ notify(datum, changeData.getSourceType(), null);
+
+ } else {
+ Datum datum = changeData.getDatum();
+
+ String dataCenter = datum.getDataCenter();
+ String dataInfoId = datum.getDataInfoId();
+ DataSourceTypeEnum sourceType = changeData.getSourceType();
+ DataChangeTypeEnum changeType = changeData.getChangeType();
+
+ if (changeType == DataChangeTypeEnum.MERGE
+ && sourceType != DataSourceTypeEnum.BACKUP
+ && sourceType != DataSourceTypeEnum.SYNC) {
+ //update version for pub or unPub merge to cache
+ //if the version product before merge to cache,it may be cause small version override big one
+ datum.updateVersion();
+ }
- } else {
- Long lastVersion = null;
+ long version = datum.getVersion();
- if (sourceType == DataSourceTypeEnum.PUB_TEMP) {
+ try {
+ if (sourceType == DataSourceTypeEnum.CLEAN) {
+ if (datumCache.cleanDatum(dataCenter, dataInfoId)) {
+ LOGGER
+ .info(
+ "[DataChangeHandler][{}] clean datum, dataCenter={}, dataInfoId={}, version={},sourceType={}, changeType={}",
+ name, dataCenter, dataInfoId, version, sourceType, changeType);
+ }
+
+ } else if (sourceType == DataSourceTypeEnum.PUB_TEMP) {
notifyTempPub(datum, sourceType, changeType);
- return;
- }
- MergeResult mergeResult = DatumCache.putDatum(changeType, datum);
- lastVersion = mergeResult.getLastVersion();
+ } else {
+ MergeResult mergeResult = datumCache.putDatum(changeType, datum);
+ Long lastVersion = mergeResult.getLastVersion();
+
+ if (lastVersion != null
+ && lastVersion.longValue() == LocalDatumStorage.ERROR_DATUM_VERSION) {
+ LOGGER
+ .error(
+ "[DataChangeHandler][{}] first put unPub datum into cache error, dataCenter={}, dataInfoId={}, version={}, sourceType={},isContainsUnPub={}",
+ name, dataCenter, dataInfoId, version, sourceType,
+ datum.isContainsUnPub());
+ return;
+ }
- if (lastVersion != null
- && lastVersion.longValue() == DatumCache.ERROR_DATUM_VERSION) {
LOGGER
- .error(
- "[DataChangeHandler][{}] first put unPub datum into cache error, dataCenter={}, dataInfoId={}, version={}, sourceType={},isContainsUnPub={}",
- name, dataCenter, dataInfoId, version, sourceType,
+ .info(
+ "[DataChangeHandler][{}] datum handle,datum={},dataCenter={}, dataInfoId={}, version={}, lastVersion={}, sourceType={}, changeType={},changeFlag={},isContainsUnPub={}",
+ name, datum.hashCode(), dataCenter, dataInfoId, version,
+ lastVersion, sourceType, changeType, mergeResult.isChangeFlag(),
datum.isContainsUnPub());
- return;
- }
-
- boolean changeFlag = mergeResult.isChangeFlag();
-
- LOGGER
- .info(
- "[DataChangeHandler][{}] datum handle,datum={},dataCenter={}, dataInfoId={}, version={}, lastVersion={}, sourceType={}, changeType={},changeFlag={},isContainsUnPub={}",
- name, datum.hashCode(), dataCenter, dataInfoId, version, lastVersion,
- sourceType, changeType, changeFlag, datum.isContainsUnPub());
- //lastVersion null means first add datum
- if (lastVersion == null || version != lastVersion) {
- if (changeFlag) {
- for (IDataChangeNotifier notifier : dataChangeNotifiers) {
- if (notifier.getSuitableSource().contains(sourceType)) {
- notifier.notify(datum, lastVersion);
- }
+ //lastVersion null means first add datum
+ if (lastVersion == null || version != lastVersion) {
+ if (mergeResult.isChangeFlag()) {
+ notify(datum, sourceType, lastVersion);
}
}
}
+ } catch (Exception e) {
+ LOGGER
+ .error(
+ "[DataChangeHandler][{}] put datum into cache error, dataCenter={}, dataInfoId={}, version={}, sourceType={},isContainsUnPub={}",
+ name, dataCenter, dataInfoId, version, sourceType,
+ datum.isContainsUnPub(), e);
}
- } catch (Exception e) {
- LOGGER
- .error(
- "[DataChangeHandler][{}] put datum into cache error, dataCenter={}, dataInfoId={}, version={}, sourceType={},isContainsUnPub={}",
- name, dataCenter, dataInfoId, version, sourceType, datum.isContainsUnPub(),
- e);
}
}
@@ -178,17 +204,30 @@ private void notifyTempPub(Datum datum, DataSourceTypeEnum sourceType,
String dataCenter = datum.getDataCenter();
String dataInfoId = datum.getDataInfoId();
long version = datum.getVersion();
+
+ Datum existDatum = datumCache.get(dataCenter, dataInfoId);
+ if (existDatum != null) {
+ Map cachePubMap = existDatum.getPubMap();
+ if (cachePubMap != null && !cachePubMap.isEmpty()) {
+ datum.getPubMap().putAll(cachePubMap);
+ }
+ }
+
LOGGER
.info(
- "[DataChangeHandler][{}] datum handle temp pub,datum={},dataCenter={}, dataInfoId={}, version={}, sourceType={}, changeType={},isContainsUnPub={}",
- name, datum.hashCode(), dataCenter, dataInfoId, version, sourceType,
- changeType, datum.isContainsUnPub());
+ "[DataChangeHandler][{}] datum handle temp pub,datum={},dataCenter={}, dataInfoId={}, version={}, sourceType={}, changeType={}",
+ name, datum.hashCode(), dataCenter, dataInfoId, version, sourceType, changeType);
+ notify(datum, sourceType, null);
+ }
+
+ private void notify(Datum datum, DataSourceTypeEnum sourceType, Long lastVersion) {
for (IDataChangeNotifier notifier : dataChangeNotifiers) {
if (notifier.getSuitableSource().contains(sourceType)) {
- notifier.notify(datum, null);
+ notifier.notify(datum, lastVersion);
}
}
}
}
+
}
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataSourceTypeEnum.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataSourceTypeEnum.java
index c41a14f51..b2787fbb9 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataSourceTypeEnum.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/DataSourceTypeEnum.java
@@ -46,5 +46,10 @@ public enum DataSourceTypeEnum {
/**
* local dataInfo check,not belong this node schedule remove
*/
- CLEAN
+ CLEAN,
+
+ /**
+ * Snapshot data, after renew finds data inconsistent
+ */
+ SNAPSHOT,
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/SnapshotData.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/SnapshotData.java
new file mode 100644
index 000000000..495019d65
--- /dev/null
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/SnapshotData.java
@@ -0,0 +1,83 @@
+/*
+ * 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 com.alipay.sofa.registry.server.data.change;
+
+import java.util.Map;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
+
+import com.alipay.sofa.registry.common.model.store.Publisher;
+
+/**
+ * changed data
+ *
+ * @author kezhu.wukz
+ * @version $Id: ChangeData.java, v 0.1 2019-07-12 16:23 kezhu.wukz Exp $
+ */
+public class SnapshotData extends ChangeData {
+
+ private String dataInfoId;
+
+ private Map toBeDeletedPubMap;
+
+ private Map snapshotPubMap;
+
+ public SnapshotData(String dataInfoId, Map toBeDeletedPubMap,
+ Map snapshotPubMap) {
+ super(null, 0, DataSourceTypeEnum.SNAPSHOT, null);
+ this.dataInfoId = dataInfoId;
+ this.toBeDeletedPubMap = toBeDeletedPubMap;
+ this.snapshotPubMap = snapshotPubMap;
+ }
+
+ /**
+ * Getter method for property dataInfoId.
+ *
+ * @return property value of dataInfoId
+ */
+ public String getDataInfoId() {
+ return dataInfoId;
+ }
+
+ /**
+ * Getter method for property toBeDeletedPubMap.
+ *
+ * @return property value of toBeDeletedPubMap
+ */
+ public Map getToBeDeletedPubMap() {
+ return toBeDeletedPubMap;
+ }
+
+ /**
+ * Getter method for property snapshotPubMap.
+ *
+ * @return property value of snapshotPubMap
+ */
+ public Map getSnapshotPubMap() {
+ return snapshotPubMap;
+ }
+
+ @Override
+ public long getDelay(TimeUnit unit) {
+ return 0;
+ }
+
+ @Override
+ public int compareTo(Delayed o) {
+ return -1;
+ }
+}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/ClientChangeEvent.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/ClientChangeEvent.java
index c063f50d4..b2eb9f036 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/ClientChangeEvent.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/ClientChangeEvent.java
@@ -16,6 +16,8 @@
*/
package com.alipay.sofa.registry.server.data.change.event;
+import com.alipay.sofa.registry.util.DatumVersionUtil;
+
/**
*
* @author qian.lqlq
@@ -41,7 +43,7 @@ public ClientChangeEvent(String host, String dataCenter, long occurredTimestamp)
this.host = host;
this.dataCenter = dataCenter;
this.occurredTimestamp = occurredTimestamp;
- this.version = System.currentTimeMillis();
+ this.version = DatumVersionUtil.nextId();
}
@Override
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventCenter.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventCenter.java
index 58c5496e2..01b5e220d 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventCenter.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventCenter.java
@@ -16,16 +16,21 @@
*/
package com.alipay.sofa.registry.server.data.change.event;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
import com.alipay.sofa.registry.common.model.PublishType;
import com.alipay.sofa.registry.common.model.dataserver.Datum;
import com.alipay.sofa.registry.common.model.store.Publisher;
import com.alipay.sofa.registry.server.data.bootstrap.DataServerConfig;
+import com.alipay.sofa.registry.server.data.cache.DatumCache;
import com.alipay.sofa.registry.server.data.cache.UnPublisher;
import com.alipay.sofa.registry.server.data.change.DataChangeTypeEnum;
import com.alipay.sofa.registry.server.data.change.DataSourceTypeEnum;
-import java.util.concurrent.atomic.AtomicBoolean;
-
/**
*
* @author qian.lqlq
@@ -44,16 +49,20 @@ public class DataChangeEventCenter {
*/
private DataChangeEventQueue[] dataChangeEventQueues;
- /**
- *
- * @param config
- */
- public void init(DataServerConfig config) {
+ @Autowired
+ private DataServerConfig dataServerConfig;
+
+ @Autowired
+ private DatumCache datumCache;
+
+ @PostConstruct
+ public void init() {
if (isInited.compareAndSet(false, true)) {
- queueCount = config.getQueueCount();
+ queueCount = dataServerConfig.getQueueCount();
dataChangeEventQueues = new DataChangeEventQueue[queueCount];
for (int idx = 0; idx < queueCount; idx++) {
- dataChangeEventQueues[idx] = new DataChangeEventQueue(idx, config);
+ dataChangeEventQueues[idx] = new DataChangeEventQueue(idx, dataServerConfig, this,
+ datumCache);
dataChangeEventQueues[idx].start();
}
}
@@ -101,6 +110,16 @@ public void onChange(ClientChangeEvent event) {
}
}
+ /**
+ *
+ * @param event
+ */
+ public void onChange(DatumSnapshotEvent event) {
+ for (DataChangeEventQueue dataChangeEventQueue : dataChangeEventQueues) {
+ dataChangeEventQueue.onChange(event);
+ }
+ }
+
/**
*
* @param changeType
@@ -118,7 +137,7 @@ public void sync(DataChangeTypeEnum changeType, DataSourceTypeEnum sourceType, D
* @param key
* @return
*/
- private int hash(String key) {
+ public int hash(String key) {
if (queueCount > 1) {
return Math.abs(key.hashCode() % queueCount);
} else {
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventQueue.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventQueue.java
index 45e5cffab..985c57702 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventQueue.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeEventQueue.java
@@ -16,6 +16,16 @@
*/
package com.alipay.sofa.registry.server.data.change.event;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.alipay.sofa.registry.common.model.constants.ValueConstants;
import com.alipay.sofa.registry.common.model.dataserver.Datum;
import com.alipay.sofa.registry.common.model.store.Publisher;
import com.alipay.sofa.registry.log.Logger;
@@ -26,19 +36,12 @@
import com.alipay.sofa.registry.server.data.change.ChangeData;
import com.alipay.sofa.registry.server.data.change.DataChangeTypeEnum;
import com.alipay.sofa.registry.server.data.change.DataSourceTypeEnum;
+import com.alipay.sofa.registry.server.data.change.SnapshotData;
import com.alipay.sofa.registry.server.data.executor.ExecutorFactory;
import com.alipay.sofa.registry.server.data.node.DataServerNode;
import com.alipay.sofa.registry.server.data.remoting.dataserver.DataServerNodeFactory;
import com.google.common.collect.Interners;
-import java.util.Map;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.DelayQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.locks.ReentrantLock;
-
/**
* a queue of DataChangeEvent
*
@@ -47,8 +50,16 @@
*/
public class DataChangeEventQueue {
- private static final Logger LOGGER = LoggerFactory
- .getLogger(DataChangeEventQueue.class);
+ private static final Logger LOGGER = LoggerFactory
+ .getLogger(DataChangeEventQueue.class);
+
+ private static final Logger LOGGER_START = LoggerFactory
+ .getLogger("DATA-START-LOGS");
+
+ private static final Logger RENEW_LOGGER = LoggerFactory
+ .getLogger(
+ ValueConstants.LOGGER_NAME_RENEW,
+ "[DataChangeEventQueue]");
/**
*
@@ -63,27 +74,36 @@ public class DataChangeEventQueue {
/**
*
*/
- private final Map> CHANGE_DATA_MAP = new ConcurrentHashMap<>();
+ private final Map> CHANGE_DATA_MAP_FOR_MERGE = new ConcurrentHashMap<>();
/**
*
*/
- private final DelayQueue CHANGE_QUEUE = new DelayQueue();
+ private final DelayQueue CHANGE_QUEUE = new DelayQueue();
private final int notifyIntervalMs;
- private final ReentrantLock lock = new ReentrantLock();
+ private final int notifyTempDataIntervalMs;
+
+ private final ReentrantLock lock = new ReentrantLock();
+
+ private final int queueIdx;
private DataServerConfig dataServerConfig;
+ private DataChangeEventCenter dataChangeEventCenter;
+
+ private DatumCache datumCache;
+
/**
* constructor
- * @param idx
+ * @param queueIdx
* @param dataServerConfig
*/
- public DataChangeEventQueue(int idx, DataServerConfig dataServerConfig) {
-
- this.name = String.format("%s_%s", DataChangeEventQueue.class.getSimpleName(), idx);
+ public DataChangeEventQueue(int queueIdx, DataServerConfig dataServerConfig,
+ DataChangeEventCenter dataChangeEventCenter, DatumCache datumCache) {
+ this.queueIdx = queueIdx;
+ this.name = String.format("%s_%s", DataChangeEventQueue.class.getSimpleName(), queueIdx);
this.dataServerConfig = dataServerConfig;
int queueSize = dataServerConfig.getQueueSize();
if (queueSize <= 0) {
@@ -92,6 +112,9 @@ public DataChangeEventQueue(int idx, DataServerConfig dataServerConfig) {
eventQueue = new LinkedBlockingDeque<>(queueSize);
}
this.notifyIntervalMs = dataServerConfig.getNotifyIntervalMs();
+ this.notifyTempDataIntervalMs = dataServerConfig.getNotifyTempDataIntervalMs();
+ this.dataChangeEventCenter = dataChangeEventCenter;
+ this.datumCache = datumCache;
}
/**
@@ -100,7 +123,12 @@ public DataChangeEventQueue(int idx, DataServerConfig dataServerConfig) {
* @param event
*/
public void onChange(IDataChangeEvent event) {
- eventQueue.add(event);
+ try {
+ eventQueue.add(event);
+ } catch (Throwable e) {
+ LOGGER.error("Error onChange: " + e.getMessage(), e);
+ throw e;
+ }
}
/**
@@ -120,14 +148,20 @@ public ChangeData take() throws InterruptedException {
ChangeData changeData = CHANGE_QUEUE.take();
lock.lock();
try {
- Datum datum = changeData.getDatum();
- CHANGE_DATA_MAP.get(datum.getDataCenter()).remove(datum.getDataInfoId());
+ removeMapForMerge(changeData);
return changeData;
} finally {
lock.unlock();
}
}
+ private void removeMapForMerge(ChangeData changeData) {
+ Datum datum = changeData.getDatum();
+ if (changeData.getSourceType() != DataSourceTypeEnum.PUB_TEMP && datum != null) {
+ CHANGE_DATA_MAP_FOR_MERGE.get(datum.getDataCenter()).remove(datum.getDataInfoId());
+ }
+ }
+
/**
*
* @param dataCenter
@@ -138,10 +172,10 @@ public ChangeData take() throws InterruptedException {
*/
private ChangeData getChangeData(String dataCenter, String dataInfoId,
DataSourceTypeEnum sourceType, DataChangeTypeEnum changeType) {
- Map map = CHANGE_DATA_MAP.get(dataCenter);
+ Map map = CHANGE_DATA_MAP_FOR_MERGE.get(dataCenter);
if (map == null) {
Map newMap = new ConcurrentHashMap<>();
- map = CHANGE_DATA_MAP.putIfAbsent(dataCenter, newMap);
+ map = CHANGE_DATA_MAP_FOR_MERGE.putIfAbsent(dataCenter, newMap);
if (map == null) {
map = newMap;
}
@@ -164,9 +198,8 @@ private ChangeData getChangeData(String dataCenter, String dataInfoId,
*
*/
public void start() {
- LOGGER.info("[{}] begin start DataChangeEventQueue", getName());
- Executor executor = ExecutorFactory.newSingleThreadExecutor(
- String.format("%s_%s", DataChangeEventQueue.class.getSimpleName(), getName()));
+ Executor executor = ExecutorFactory
+ .newSingleThreadExecutor(String.format("%s_%s", DataChangeEventQueue.class.getSimpleName(), getName()));
executor.execute(() -> {
while (true) {
try {
@@ -174,26 +207,42 @@ public void start() {
DataChangeScopeEnum scope = event.getScope();
if (scope == DataChangeScopeEnum.DATUM) {
DataChangeEvent dataChangeEvent = (DataChangeEvent) event;
- handleDatum(dataChangeEvent.getChangeType(),
- dataChangeEvent.getSourceType(), dataChangeEvent.getDatum());
+ //Temporary push data will be notify as soon as,and not merge to normal pub data;
+ if (dataChangeEvent.getSourceType() == DataSourceTypeEnum.PUB_TEMP) {
+ addTempChangeData(dataChangeEvent.getDatum(), dataChangeEvent.getChangeType(),
+ dataChangeEvent.getSourceType());
+ } else {
+ handleDatum(dataChangeEvent.getChangeType(), dataChangeEvent.getSourceType(),
+ dataChangeEvent.getDatum());
+ }
} else if (scope == DataChangeScopeEnum.CLIENT) {
- handleHost((ClientChangeEvent) event);
+ handleClientOff((ClientChangeEvent) event);
+ } else if (scope == DataChangeScopeEnum.SNAPSHOT) {
+ handleSnapshot((DatumSnapshotEvent) event);
}
} catch (Throwable e) {
LOGGER.error("[{}] handle change event failed", getName(), e);
}
}
});
- LOGGER.info("[{}] start DataChangeEventQueue success", getName());
+ LOGGER_START.info("[{}] start DataChangeEventQueue success", getName());
}
- private void handleHost(ClientChangeEvent event) {
- String clientHost = event.getHost();
- synchronized (Interners.newWeakInterner().intern(clientHost)) {
- Map pubMap = DatumCache.getByHost(clientHost);
+ private void handleClientOff(ClientChangeEvent event) {
+ String connectId = event.getHost();
+ synchronized (Interners.newWeakInterner().intern(connectId)) {
+ Map pubMap = datumCache.getByConnectId(connectId);
if (pubMap != null && !pubMap.isEmpty()) {
+ LOGGER.info(
+ "[{}] client off begin, connectId={}, occurTimestamp={}, all pubSize={}",
+ getName(), connectId, event.getOccurredTimestamp(), pubMap.size());
int count = 0;
for (Publisher publisher : pubMap.values()) {
+ // Only care dataInfoIds which belong to this queue
+ if (!belongTo(publisher.getDataInfoId())) {
+ continue;
+ }
+
DataServerNode dataServerNode = DataServerNodeFactory.computeDataServerNode(
dataServerConfig.getLocalDataCenter(), publisher.getDataInfoId());
//current dataCenter backup data need not unPub,it will be unPub by backup sync event
@@ -208,11 +257,9 @@ private void handleHost(ClientChangeEvent event) {
}
LOGGER
.info(
- "[{}] client off handle, host={}, occurTimestamp={},version={},handle pub size={}",
- getName(), clientHost, event.getOccurredTimestamp(), event.getVersion(),
+ "[{}] client off handle, connectId={}, occurTimestamp={}, version={}, handle pubSize={}",
+ getName(), connectId, event.getOccurredTimestamp(), event.getVersion(),
count);
- } else {
- LOGGER.info("[{}] no datum to handle, host={}", getName(), clientHost);
}
}
}
@@ -243,7 +290,7 @@ private void handleDatum(DataChangeTypeEnum changeType, DataSourceTypeEnum sourc
// and version of cachePub is greater than version of pub, should be ignored
if (!(pub instanceof UnPublisher) && !(cachePub instanceof UnPublisher)
&& pub.getSourceAddress().equals(cachePub.getSourceAddress())
- && cachePub.getVersion() >= pub.getVersion()) {
+ && cachePub.getVersion() > pub.getVersion()) {
continue;
}
}
@@ -255,4 +302,77 @@ private void handleDatum(DataChangeTypeEnum changeType, DataSourceTypeEnum sourc
lock.unlock();
}
}
+
+ private void handleSnapshot(DatumSnapshotEvent event) {
+ String connectId = event.getConnectId();
+ Map cachePubMap = event.getCachePubMap();
+ Map snapshotPubMap = event.getPubMap();
+
+ // build SnapshotData
+ Map dataInfoId2SnapshotData = new HashMap<>();
+ synchronized (Interners.newWeakInterner().intern(connectId)) {
+ for (Map.Entry entry : snapshotPubMap.entrySet()) {
+ String registerId = entry.getKey();
+ Publisher publisher = entry.getValue();
+ String dataInfoId = publisher.getDataInfoId();
+
+ // Only care dataInfoIds which belong to this queue
+ if (!belongTo(dataInfoId)) {
+ continue;
+ }
+
+ SnapshotData snapshotData = getOrCreateSnapshotData(dataInfoId2SnapshotData,
+ dataInfoId);
+ snapshotData.getSnapshotPubMap().put(registerId, publisher);
+ }
+ for (Map.Entry entry : cachePubMap.entrySet()) {
+ String registerId = entry.getKey();
+ Publisher publisher = entry.getValue();
+ String dataInfoId = publisher.getDataInfoId();
+
+ // Only care dataInfoIds which belong to this queue
+ if (!belongTo(dataInfoId)) {
+ continue;
+ }
+
+ SnapshotData snapshotData = getOrCreateSnapshotData(dataInfoId2SnapshotData,
+ dataInfoId);
+ snapshotData.getToBeDeletedPubMap().put(registerId, publisher);
+ }
+ }
+
+ // put all SnapshotDatas to queue
+ for (SnapshotData snapshotData : dataInfoId2SnapshotData.values()) {
+ RENEW_LOGGER
+ .info(
+ "SnapshotData: connectId={}, dataInfoId={}, cachePubSize={}, snapshotPubSize={}",
+ connectId, snapshotData.getDataInfoId(), snapshotData.getToBeDeletedPubMap()
+ .size(), snapshotData.getSnapshotPubMap().size());
+ CHANGE_QUEUE.put(snapshotData);
+ }
+ }
+
+ private SnapshotData getOrCreateSnapshotData(Map dataInfoId2SnapshotData,
+ String dataInfoId) {
+ SnapshotData snapshotData = dataInfoId2SnapshotData.get(dataInfoId);
+ if (snapshotData == null) {
+ snapshotData = new SnapshotData(dataInfoId, new HashMap<>(), new HashMap<>());
+ dataInfoId2SnapshotData.put(dataInfoId, snapshotData);
+ }
+ return snapshotData;
+ }
+
+ private void addTempChangeData(Datum targetDatum, DataChangeTypeEnum changeType,
+ DataSourceTypeEnum sourceType) {
+ ChangeData tempChangeData = new ChangeData(targetDatum, this.notifyTempDataIntervalMs,
+ sourceType, changeType);
+ CHANGE_QUEUE.put(tempChangeData);
+ }
+
+ /**
+ * Determine whether dataInfoId belongs to the current queue
+ */
+ private boolean belongTo(String dataInfoId) {
+ return this.queueIdx == this.dataChangeEventCenter.hash(dataInfoId);
+ }
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeScopeEnum.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeScopeEnum.java
index bfba719e5..94bbdb0d3 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeScopeEnum.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DataChangeScopeEnum.java
@@ -22,5 +22,5 @@
* @version $Id: DataChangeScopeEnum.java, v 0.1 2018-05-10 16:51 qian.lqlq Exp $
*/
public enum DataChangeScopeEnum {
- CLIENT, DATUM
+ CLIENT, DATUM, SNAPSHOT
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DatumSnapshotEvent.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DatumSnapshotEvent.java
new file mode 100644
index 000000000..af08c25c6
--- /dev/null
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/event/DatumSnapshotEvent.java
@@ -0,0 +1,76 @@
+/*
+ * 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 com.alipay.sofa.registry.server.data.change.event;
+
+import java.util.Map;
+
+import com.alipay.sofa.registry.common.model.store.Publisher;
+
+/**
+ *
+ * @author kezhu.wukz
+ * @version $Id: DatumSnapshotEvent.java, v 0.1 2019-05-30 18:22 kezhu.wukz Exp $
+ */
+public class DatumSnapshotEvent implements IDataChangeEvent {
+
+ /** connId, format is ip:port */
+ private String connectId;
+
+ private Map pubMap;
+
+ private Map cachePubMap;
+
+ public DatumSnapshotEvent(String connectId, Map cachePubMap,
+ Map pubMap) {
+ this.connectId = connectId;
+ this.cachePubMap = cachePubMap;
+ this.pubMap = pubMap;
+ }
+
+ /**
+ * Getter method for property connectId.
+ *
+ * @return property value of connectId
+ */
+ public String getConnectId() {
+ return connectId;
+ }
+
+ /**
+ * Getter method for property pubMap.
+ *
+ * @return property value of pubMap
+ */
+ public Map getPubMap() {
+ return pubMap;
+ }
+
+ /**
+ * Getter method for property cachePubMap.
+ *
+ * @return property value of cachePubMap
+ */
+ public Map getCachePubMap() {
+ return cachePubMap;
+ }
+
+ @Override
+ public DataChangeScopeEnum getScope() {
+ return DataChangeScopeEnum.SNAPSHOT;
+ }
+
+}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/BackUpNotifier.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/BackUpNotifier.java
index 293376031..45ac0e0b5 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/BackUpNotifier.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/BackUpNotifier.java
@@ -16,14 +16,15 @@
*/
package com.alipay.sofa.registry.server.data.change.notify;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
import com.alipay.sofa.registry.common.model.dataserver.Datum;
import com.alipay.sofa.registry.server.data.change.DataSourceTypeEnum;
import com.alipay.sofa.registry.server.data.datasync.Operator;
import com.alipay.sofa.registry.server.data.datasync.SyncDataService;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.HashSet;
-import java.util.Set;
/**
*
@@ -39,7 +40,6 @@ public class BackUpNotifier implements IDataChangeNotifier {
public Set getSuitableSource() {
Set set = new HashSet<>();
set.add(DataSourceTypeEnum.PUB);
- set.add(DataSourceTypeEnum.SYNC);
return set;
}
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SessionServerNotifier.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SessionServerNotifier.java
index 727156d35..f66fb747e 100644
--- a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SessionServerNotifier.java
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SessionServerNotifier.java
@@ -16,6 +16,16 @@
*/
package com.alipay.sofa.registry.server.data.change.notify;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
import com.alipay.remoting.Connection;
import com.alipay.sofa.registry.common.model.CommonResponse;
import com.alipay.sofa.registry.common.model.dataserver.Datum;
@@ -29,16 +39,11 @@
import com.alipay.sofa.registry.server.data.bootstrap.DataServerConfig;
import com.alipay.sofa.registry.server.data.cache.DatumCache;
import com.alipay.sofa.registry.server.data.change.DataSourceTypeEnum;
+import com.alipay.sofa.registry.server.data.executor.ExecutorFactory;
import com.alipay.sofa.registry.server.data.remoting.sessionserver.SessionServerConnectionFactory;
import com.alipay.sofa.registry.timer.AsyncHashedWheelTimer;
import com.alipay.sofa.registry.timer.AsyncHashedWheelTimer.TaskFailedCallback;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
/**
* Notify session DataChangeRequest,if fail get result callback retry
@@ -54,7 +59,7 @@ public class SessionServerNotifier implements IDataChangeNotifier {
private AsyncHashedWheelTimer asyncHashedWheelTimer;
@Autowired
- private DataServerConfig dataServerBootstrapConfig;
+ private DataServerConfig dataServerConfig;
@Autowired
private Exchange boltExchange;
@@ -62,13 +67,19 @@ public class SessionServerNotifier implements IDataChangeNotifier {
@Autowired
private SessionServerConnectionFactory sessionServerConnectionFactory;
- public SessionServerNotifier() {
+ @Autowired
+ private DatumCache datumCache;
+
+ @PostConstruct
+ public void init() {
ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder();
threadFactoryBuilder.setDaemon(true);
asyncHashedWheelTimer = new AsyncHashedWheelTimer(threadFactoryBuilder.setNameFormat(
- "Registry-SessionServerNotifier-WheelTimer").build(), 100, TimeUnit.MILLISECONDS, 1024,
- threadFactoryBuilder.setNameFormat("Registry-SessionServerNotifier-WheelExecutor-%d")
- .build(), new TaskFailedCallback() {
+ "Registry-SessionServerNotifier-WheelTimer").build(), 500, TimeUnit.MILLISECONDS, 1024,
+ dataServerConfig.getSessionServerNotifierRetryExecutorThreadSize(),
+ dataServerConfig.getSessionServerNotifierRetryExecutorQueueSize(), threadFactoryBuilder
+ .setNameFormat("Registry-SessionServerNotifier-WheelExecutor-%d").build(),
+ new TaskFailedCallback() {
@Override
public void executionRejected(Throwable e) {
LOGGER.error("executionRejected: " + e.getMessage(), e);
@@ -86,6 +97,7 @@ public Set getSuitableSource() {
Set set = new HashSet<>();
set.add(DataSourceTypeEnum.PUB);
set.add(DataSourceTypeEnum.SYNC);
+ set.add(DataSourceTypeEnum.SNAPSHOT);
return set;
}
@@ -93,7 +105,7 @@ public Set getSuitableSource() {
public void notify(Datum datum, Long lastVersion) {
DataChangeRequest request = new DataChangeRequest(datum.getDataInfoId(),
datum.getDataCenter(), datum.getVersion());
- List connections = sessionServerConnectionFactory.getConnections();
+ List connections = sessionServerConnectionFactory.getSessionConnections();
for (Connection connection : connections) {
doNotify(new NotifyCallback(connection, request));
}
@@ -105,21 +117,19 @@ private void doNotify(NotifyCallback notifyCallback) {
try {
//check connection active
if (!connection.isFine()) {
- if (LOGGER.isInfoEnabled()) {
- LOGGER
- .info(String
- .format(
- "connection from sessionserver(%s) is not fine, so ignore notify, retryTimes=%s,request=%s",
- connection.getRemoteAddress(), notifyCallback.retryTimes, request));
- }
+ LOGGER
+ .info(String
+ .format(
+ "connection from sessionServer(%s) is not fine, so ignore notify, retryTimes=%s,request=%s",
+ connection.getRemoteAddress(), notifyCallback.retryTimes, request));
return;
}
- Server sessionServer = boltExchange.getServer(dataServerBootstrapConfig.getPort());
+ Server sessionServer = boltExchange.getServer(dataServerConfig.getPort());
sessionServer.sendCallback(sessionServer.getChannel(connection.getRemoteAddress()),
- request, notifyCallback, dataServerBootstrapConfig.getRpcTimeout());
+ request, notifyCallback, dataServerConfig.getRpcTimeout());
} catch (Exception e) {
LOGGER.error(String.format(
- "invokeWithCallback failed: sessionserver(%s),retryTimes=%s, request=%s",
+ "invokeWithCallback failed: sessionServer(%s),retryTimes=%s, request=%s",
connection.getRemoteAddress(), notifyCallback.retryTimes, request), e);
onFailed(notifyCallback);
}
@@ -129,26 +139,32 @@ private void doNotify(NotifyCallback notifyCallback) {
* on failed, retry if necessary
*/
private void onFailed(NotifyCallback notifyCallback) {
+
DataChangeRequest request = notifyCallback.request;
Connection connection = notifyCallback.connection;
notifyCallback.retryTimes++;
- if (notifyCallback.retryTimes <= dataServerBootstrapConfig.getNotifySessionRetryTimes()) {
+ //check version, if it's fall behind, stop retry
+ long _currentVersion = datumCache.get(request.getDataCenter(), request.getDataInfoId()).getVersion();
+ if (request.getVersion() != _currentVersion) {
+ LOGGER.info(String.format(
+ "current version change %s, retry version is %s, stop before retry! retryTimes=%s, request=%s",
+ _currentVersion, request.getVersion(), notifyCallback.retryTimes, request));
+ return;
+ }
+
+ if (notifyCallback.retryTimes <= dataServerConfig.getNotifySessionRetryTimes()) {
this.asyncHashedWheelTimer.newTimeout(timeout -> {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info(String.format("retrying notify sessionserver(%s), retryTimes=%s, request=%s",
- connection.getRemoteAddress(), notifyCallback.retryTimes, request));
- }
+ LOGGER.info(String.format("retrying notify sessionServer(%s), retryTimes=%s, request=%s",
+ connection.getRemoteAddress(), notifyCallback.retryTimes, request));
//check version, if it's fall behind, stop retry
- long currentVersion = DatumCache.get(request.getDataCenter(), request.getDataInfoId()).getVersion();
+ long currentVersion = datumCache.get(request.getDataCenter(), request.getDataInfoId()).getVersion();
if (request.getVersion() == currentVersion) {
doNotify(notifyCallback);
} else {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info(String.format(
- "current version change %s, retry version is %s, stop retry! retryTimes=%s, request=%s",
- currentVersion, request.getVersion(), notifyCallback.retryTimes, request));
- }
+ LOGGER.info(String.format(
+ "current version change %s, retry version is %s, stop retry! retryTimes=%s, request=%s",
+ currentVersion, request.getVersion(), notifyCallback.retryTimes, request));
}
}, getDelayTimeForRetry(notifyCallback.retryTimes), TimeUnit.MILLISECONDS);
} else {
@@ -159,9 +175,9 @@ private void onFailed(NotifyCallback notifyCallback) {
}
private long getDelayTimeForRetry(int retryTimes) {
- long initialSleepTime = TimeUnit.MILLISECONDS.toMillis(dataServerBootstrapConfig
+ long initialSleepTime = TimeUnit.MILLISECONDS.toMillis(dataServerConfig
.getNotifySessionRetryFirstDelay());
- long increment = TimeUnit.MILLISECONDS.toMillis(dataServerBootstrapConfig
+ long increment = TimeUnit.MILLISECONDS.toMillis(dataServerConfig
.getNotifySessionRetryIncrementDelay());
long result = initialSleepTime + (increment * (retryTimes - 1));
return result >= 0L ? result : 0L;
@@ -185,7 +201,7 @@ public void onCallback(Channel channel, Object message) {
LOGGER
.error(String
.format(
- "response not success when notify sessionserver(%s), retryTimes=%s, request=%s, response=%s",
+ "response not success when notify sessionServer(%s), retryTimes=%s, request=%s, response=%s",
connection.getRemoteAddress(), retryTimes, request, result));
onFailed(this);
}
@@ -194,11 +210,16 @@ public void onCallback(Channel channel, Object message) {
@Override
public void onException(Channel channel, Throwable e) {
LOGGER.error(String.format(
- "exception when notify sessionserver(%s), retryTimes=%s, request=%s",
+ "exception when notify sessionServer(%s), retryTimes=%s, request=%s",
connection.getRemoteAddress(), retryTimes, request), e);
onFailed(this);
}
+ @Override
+ public Executor getExecutor() {
+ return ExecutorFactory.NOTIFY_SESSION_CALLBACK_EXECUTOR;
+ }
+
}
}
\ No newline at end of file
diff --git a/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SnapshotBackUpNotifier.java b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SnapshotBackUpNotifier.java
new file mode 100644
index 000000000..aab640fb2
--- /dev/null
+++ b/server/server/data/src/main/java/com/alipay/sofa/registry/server/data/change/notify/SnapshotBackUpNotifier.java
@@ -0,0 +1,51 @@
+/*
+ * 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 com.alipay.sofa.registry.server.data.change.notify;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alipay.sofa.registry.common.model.dataserver.Datum;
+import com.alipay.sofa.registry.server.data.change.DataSourceTypeEnum;
+import com.alipay.sofa.registry.server.data.datasync.SnapshotOperator;
+import com.alipay.sofa.registry.server.data.datasync.SyncDataService;
+
+/**
+ *
+ * @author kezhu.wukz
+ * @version $Id: SnapshotBackUpNotifier.java, v 0.1 2019-07-12 18:40 kezhu.wukz Exp $
+ */
+public class SnapshotBackUpNotifier implements IDataChangeNotifier {
+
+ @Autowired
+ private SyncDataService syncDataService;
+
+ @Override
+ public Set getSuitableSource() {
+ Set