0 x00 the
SOFARegistry is ant Financial’s open source, production-grade, time-sensitive, and highly available service registry.
This series of articles focuses on analyzing design and architecture, that is, using multiple articles to summarize the implementation mechanism and architecture ideas of DataServer or SOFARegistry from multiple perspectives, so that you can learn how Ali designs.
This article, part 11, describes how SOFARegistry handles Data node changes, that is, processing DataServerChangeEvent messages.
0 x02 probe,
As mentioned above, MetaServerChangeEvent will also be converted to DataServerChangeEvent and put into EventCenter.
This is because Meta Server’s push is probably telling the Data Server, “Hi, data Server is also changing.” So in this installment, we’ll show you how to handle a DataServerChangeEvent.
0x03 Business Category
We’ll start with a few areas of business.
3.1 DataServer Data Consistency
To support large volumes of data, SOFARegistry uses consistent hashes to store Publisher data in fragments, avoiding the capacity bottlenecks that can occur when a single server stores the full amount of data. In this model, each data shard has multiple copies. When the DataServer that stores registered data expands or shrinks, MetaServer will notify the change to the DataServer and SessionServer, and the data shard will carry out data migration and synchronization within the cluster. Here comes the problem of consistency within DataServer.
3.2 Data synchronization when a node changes
MetaServer senses when a new node comes online or goes offline through the network connection. All dataservers run a ConnectionRefreshTask that periodically polls MetaServer to obtain information about data nodes. It should be noted that in addition to DataServer actively fetching node information from MetaServer, MetaServer also actively sends NodeChangeResult requests to each node to inform the node of information changes. The final effect of pushing and pulling to obtain information is consistent.
0x04 General Logic
The general logic is as follows:
When the data node returned by polling information changes, a DataServerChangeEvent will be sent to EventCenter. If the processor of this event determines that the node information in the equipment room has changed, LocalDataServerChangeEvent will deliver new events.
The event processor LocalDataServerChangeEventHandler will decide whether the current node is a new node, if it is a new node will be sent to the other node NotifyOnlineRequest request, as shown in figure:
The logic of a new node when a graph DataServer node goes online
This article mainly explain the logic of this part from DataServerChangeEvent to LocalDataServerChangeEvent.
0x05 DataServerChangeEvent
5.1 Sources
Dataserverchangeevents come from three sources: start active fetching, regular fetching, and push. The three types are as follows:
- Initiate active fetch: This process of active query and pull, which is basically similar to a synchronization process, reflected in the client’s synchronous return of a query result.
- Version change push: In order to determine changes to the service release data, all client subscribers interested in the service need to push, push. Because of performance requirements, the push must be executed concurrently and asynchronously to determine success.
- Regular rotation: This prevents a change notification from reaching all subscribers.
With the above knowledge, we should know that the two ways of initiating active acquisition and push are completed through MetaServerChangeEvent. Combined with the above logic diagram, it is summarized as follows:
+-------------------------------+
|[DataServerBootstrap] | MetaServerChangeEvent
| |
| +-------------------------+
| startRaftClient | a |
| | | +---------------+
| | | | |
+-------------------------------+ | | |
+-------------------------------+ | | |
| [Timer] | | v |
| | b | 1 +-------+-----+ |
| ConnectionRefreshMetaTask +------------------------------> | EventCenter +----+ |
| | MetaServerChangeEvent | +-------+-----+ | |
+-------------------------------+ | ^ | |
+-------------------------------+ | | | |
| | | | | |
| [Push<NodeChangeResult>] | | | | |
| | c | | | |
| +-------------------------+ | | |
| | MetaServerChangeEvent | | |
| ServerChangeHandler | 2| | | | +----------------------------------------+ | | +-------------------------------+ DataServerChangeEvent | | | | | | MetaServerChangeEvent | |3 | |
+----------------------------------------------------+ |
| |
v |
+-----------------+--------------+ DataServerChangeEvent |
| | 4 |
| MetaServerChangeEventHandler +------------------------------------------+
| |
+--------------------------------+
Copy the code
5.1.1 start
5.1.1.1 Generating Messages
After the DataServer is successfully initialized, a task is started to automatically connect to the MetaServer. Starts, would read meta server configuration from the configuration metaServerService. GetMetaServerMap (); Build a MetaServerChangeEvent and drop it into the EventCenter.
private void startRaftClient() {
metaServerService.startRaftClient();
eventCenter.post(new MetaServerChangeEvent(metaServerService.getMetaServerMap()));
}
Copy the code
5.1.1.2 MetaServerChangeEventHandler
MetaServerChangeEvent MetaServerChangeEventHandler used to response the message. Because its inherited AbstractEventHandler MetaServerChangeEventHandler have been registered to EventCenter.
After the MetaServerChangeEvent is processed, the task registers a DataServerChangeEvent event with EventCenter, which is triggered, calculates the Hash value for the new node, and manages sharding.
It corresponds to the line a, 1, 3, and 4 in the figure above, which is the source of DataServerChangeEvent 1.
5.1.2 push
This source is a transformation of other messages, namely a transformation of NodeChangeResult. And there are two transitions.
5.1.2.1 push
In addition to DataServer actively fetching node information from MetaServer, MetaServer also actively sends NodeChangeResult requests to each node to notify node information changes. The final effect of pushing and pulling to obtain information is consistent.
5.1.2.2 Layer 1 conversion
ServerChangeHandler is part of metaClientHandler, which is a metanodesano1100Response function.
In ServerChangeHandler, once you’ve got NodeChangeResult, it will determine the node type to change, depending on the Note type, Decide whether to generate a DataServerChangeEvent or a MetaServerChangeEvent.
Post (New MetaServerChangeEvent(map)); post(New MetaServerChangeEvent(map)); .
This is one of the sources of MetaserVerChangeEvents and dataserVerChangeEvents. The line in figure 2 is the source of DataServerChangeEvent 2.
public class ServerChangeHandler extends AbstractClientHandler<NodeChangeResult> {
@Autowired
private EventCenter eventCenter;
@Autowired
private DataServerConfig dataServerConfig;
@Override
public Object doHandle(Channel channel, NodeChangeResult request) {
ExecutorFactory.getCommonExecutor().execute(() -> {
if (request.getNodeType() == NodeType.DATA) {
eventCenter.post(new DataServerChangeEvent(request.getNodes(),
request.getDataCenterListVersions(), FromType.META_NOTIFY));
} else if (request.getNodeType() == NodeType.META) {
Map<String, Map<String, MetaNode>> metaNodesMap = request.getNodes();
if(metaNodesMap ! =null && !metaNodesMap.isEmpty()) {
Map<String, MetaNode> metaNodeMap = metaNodesMap.get(dataServerConfig.getLocalDataCenter());
if(metaNodeMap ! =null && !metaNodeMap.isEmpty()) {
HashMap<String, Set<String>> map = new HashMap<>();
map.put(dataServerConfig.getLocalDataCenter(), metaNodeMap.keySet());
eventCenter.post(newMetaServerChangeEvent(map)); }}}});return CommonResponse.buildSuccessResponse();
}
@Override
public Class interest(a) {
return NodeChangeResult.class;
}
@Override
public HandlerType getType(a) {
return HandlerType.PROCESSER;
}
@Override
protected Node.NodeType getConnectNodeType(a) {
returnNode.NodeType.DATA; }}Copy the code
5.1.2.3 Layer 2 Conversion
MetaServerChangeEvent MetaServerChangeEventHandler used to response the message. Because its inherited AbstractEventHandler MetaServerChangeEventHandler have been registered to EventCenter.
Note that there is a process of converting DataServerChangeEvent again, will be active and MetaServer interaction, namely MetaServerChangeEventHandler here due to the fact that the the Meta Server push, Maybe it’s telling the Data Server, “Hi, there’s been a change in the Data Server.”
If the returned message is NodeChangeResult, it is converted to a DataServerChangeEvent, and a DataServerChangeEvent is placed in the Event Center.
It corresponds to line B, 1, 3, and 4 above, which is the source of DataServerChangeEvent 3.
public class MetaServerChangeEventHandler extends AbstractEventHandler<MetaServerChangeEvent> {
private void registerMetaServer(String dataCenter, String ip) {...if (obj instanceof NodeChangeResult) {
NodeChangeResult<DataNode> result = (NodeChangeResult<DataNode>) obj;
Map<String, Long> versionMap = result.getDataCenterListVersions();
//send renew after first register dataNode
Set<StartTaskTypeEnum> set = new HashSet<>();
set.add(StartTaskTypeEnum.RENEW);
eventCenter.post(new StartTaskEvent(set));
eventCenter.post(new DataServerChangeEvent(result.getNodes(), versionMap,
DataServerChangeEvent.FromType.REGISTER_META));
break; }}}Copy the code
0 x06 training in rotation
Here we are going to focus on explaining the source of DataServerChangeEvent “Lunxun La”.
MetaServer senses when a new node comes online or goes offline through the network connection. All dataservers run a ConnectionRefreshTask that periodically polls MetaServer to obtain information about data nodes.
6.1 the Bean
ConnectionRefreshTask starts in the Tasks Bean.
@Bean(name = "tasks")
public List<AbstractTask> tasks(a) {
List<AbstractTask> list = new ArrayList<>();
list.add(connectionRefreshTask());
list.add(connectionRefreshMetaTask());
list.add(renewNodeTask());
return list;
}
Copy the code
6.2 start
Tasks are started indirectly in startScheduler.
eventCenter.post(newStartTaskEvent( Arrays.stream(StartTaskTypeEnum.values()).filter(type -> type ! = StartTaskTypeEnum.RENEW).collect(Collectors.toSet())));Copy the code
StartTaskEventHandler responds to StartTaskEvent, which starts tasks one by one.
public class StartTaskEventHandler extends AbstractEventHandler<StartTaskEvent> {
@Resource(name = "tasks")
private List<AbstractTask> tasks;
private ScheduledExecutorService executor = null;
@Override
public void doHandle(StartTaskEvent event) {
if (executor == null || executor.isShutdown()) {
getExecutor();
}
for (AbstractTask task : tasks) {
if(event.getSuitableTypes().contains(task.getStartTaskTypeEnum())) { executor.scheduleWithFixedDelay(task, task.getInitialDelay(), task.getDelay(), task.getTimeUnit()); }}}private void getExecutor(a) {
executor = ExecutorFactory.newScheduledThreadPool(tasks.size(), this.getClass() .getSimpleName()); }}Copy the code
Here’s a trick.
ConnectionRefreshTask specifies that CONNECT_DATA is supported. When StartTaskEventHandler checks the supported type and finds that CONNECT_DATA is supported, ConnectionRefreshTask is enabled.
AbstractEventHandler registers eventCenter. Register so that all of its classes are registered to eventCenter by default.
public abstract class AbstractEventHandler<Event> implements InitializingBean {
@Autowired
private EventCenter eventCenter;
@Override
public void afterPropertiesSet(a) throws Exception {
eventCenter.register(this);
}
/**
* event handle func
* @param event
*/
public void handle(Event event) {
doHandle(event);
}
public abstract List<Class<? extends Event>> interest();
public abstract void doHandle(Event event);
}
Copy the code
The connectionRefreshTask is then started.
6.3 ConnectionRefreshTask
ConnectionRefreshTask is responsible for polling and interacting with meta Server, as you can see, sending a DataServerChangeEvent as well.
public class ConnectionRefreshTask extends AbstractTask {
@Autowired
private IMetaServerService metaServerService;
@Autowired
private EventCenter eventCenter;
@Override
public void handle(a) {
DataServerChangeItem dataServerChangeItem = metaServerService.getDateServers();
if(dataServerChangeItem ! =null) {
eventCenter
.post(newDataServerChangeEvent(dataServerChangeItem, FromType.CONNECT_TASK)); }}@Override
public int getDelay(a) {
return 30;
}
@Override
public int getInitialDelay(a) {
return 0;
}
@Override
public TimeUnit getTimeUnit(a) {
return TimeUnit.SECONDS;
}
@Override
public StartTaskTypeEnum getStartTaskTypeEnum(a) {
returnStartTaskTypeEnum.CONNECT_DATA; }}Copy the code
ConnectionRefreshTask call metaServerService. GetDateServers (); GetDateServers is used to:
- From metaServerConnectionFactory connectionMap;
- Get raft Leader by raft;
- Get the Leader connection from connectionMap, which is a Bolt connection;
- Bolt Connection GetNodesRequest(nodeType.data);
- Build a DataServerChangeItem from the result of the request;
- Put a message DataServerChangeEvent(dataServerChangeItem, fromType.connect_task) in EventCenter;
Details are as follows:
@Override
public DataServerChangeItem getDateServers(a) {
Map<String, Connection> connectionMap = metaServerConnectionFactory
.getConnections(dataServerConfig.getLocalDataCenter());
String leader = getLeader().getIp();
if (connectionMap.containsKey(leader)) {
Connection connection = connectionMap.get(leader);
if (connection.isFine()) {
try {
GetNodesRequest request = new GetNodesRequest(NodeType.DATA);
Object obj = metaNodeExchanger.request(new Request() {
@Override
public Object getRequestBody(a) {
return request;
}
@Override
public URL getRequestUrl(a) {
return new URL(connection.getRemoteIP(), connection.getRemotePort());
}
}).getResult();
if (obj instanceof NodeChangeResult) {
NodeChangeResult<DataNode> result = (NodeChangeResult<DataNode>) obj;
Map<String, Long> versionMap = result.getDataCenterListVersions();
versionMap.put(result.getLocalDataCenter(), result.getVersion());
return new DataServerChangeItem(result.getNodes(), versionMap);
}
}
}
}
String newip = refreshLeader().getIp();
return null;
}
Copy the code
0x07 DataServerChangeEventHandler
7.1 General Logic
DataServerChangeEvent event is triggered, the DataServerChangeEventHandler to make corresponding processing, respectively, can be divided into the following steps:
- Initializes the consistent Hash value of the current data node and adds the current node to the consistent Hash ring.
- Gets the changed DataServer nodes that were retrieved from MetaServer when the DataServer service was started and passed in as a DataServerChangeItem in the DataServerChangeEvent event.
- After obtaining the current DataServer node, if the node list is not empty, it traverses each node to establish connections between the current node and other data nodes, and deletes locally maintained node data that is not in the node list to update dataServerCache. At the same time, if the current node is the DataCenter, then trigger LocalDataServerChangeEvent events.
LocalDataServerChangeEvent SOFA here mainly processing, long distance part of the room is not open source.
7.2 LocalDataServerChangeEvent
On the third point above, details are as follows:
Extract a DataServerChangeItem from a DataServerChangeEvent. If a DataCenter is found to be the native DataCenter, use the following statement to retrieve the newly added DataServer.
Set<String> newjoined = new HashSet<>(ips);
newjoined.removeAll(localDataServers);
Copy the code
These new DataServer is then used to construct LocalDataServerChangeEvent.
See the following snippet:
//get changed dataservers
Map<String, Set<String>> changedMap = dataServerCache.compareAndSet(
dataServerChangeItem, event.getFromType());
if(! changedMap.isEmpty()) {for (Entry<String, Set<String>> changeEntry : changedMap.entrySet()) {
String dataCenter = changeEntry.getKey();
Set<String> ips = changeEntry.getValue();
String dataCenter = changeEntry.getKey();
Set<String> ips = changeEntry.getValue();
//if the dataCenter is self, post LocalDataServerChangeEvent
if (dataServerConfig.isLocalDataCenter(dataCenter)) {
Set<String> newjoined = new HashSet<>(ips);
newjoined.removeAll(localDataServers);
eventCenter.post(new LocalDataServerChangeEvent(map, newjoined,
dataServerChangeItem.getVersionMap().get(dataCenter), newVersion));
} else {
dataServerCache.updateItem(newDataNodes, newVersion, dataCenter);
eventCenter.post(newRemoteDataServerChangeEvent(dataCenter, map, dataServerChangeItem.getVersionMap().get(dataCenter), newVersion)); }}Copy the code
The specific code is as follows:
public class DataServerChangeEventHandler extends AbstractEventHandler<DataServerChangeEvent> {
private static final int TRY_COUNT = 5;
@Autowired
private DataServerConfig dataServerConfig;
@Autowired
private DataServerCache dataServerCache;
@Autowired
private DataNodeExchanger dataNodeExchanger;
@Autowired
private EventCenter eventCenter;
@Override
public List<Class<? extends DataServerChangeEvent>> interest() {
return Lists.newArrayList(DataServerChangeEvent.class);
}
@Override
public void doHandle(DataServerChangeEvent event) {
synchronized (this) {
//register self first,execute once
DataServerNodeFactory.initConsistent(dataServerConfig);
DataServerChangeItem dataServerChangeItem = event.getDataServerChangeItem();
Set<String> localDataServers = dataServerCache.getDataServers(
dataServerConfig.getLocalDataCenter()).keySet();
// Get changed dataservers
Map<String, Set<String>> changedMap = dataServerCache.compareAndSet(
dataServerChangeItem, event.getFromType());
if(! changedMap.isEmpty()) {for (Entry<String, Set<String>> changeEntry : changedMap.entrySet()) {
String dataCenter = changeEntry.getKey();
Set<String> ips = changeEntry.getValue();
Long newVersion = dataServerCache.getDataCenterNewVersion(dataCenter);
if(! CollectionUtils.isEmpty(ips)) {for (String ip : ips) {
if(! StringUtils.equals(ip, DataServerConfig.IP)) { DataServerNode dataServerNode = DataServerNodeFactory .getDataServerNode(dataCenter, ip);if (dataServerNode == null
|| dataServerNode.getConnection() == null| |! dataServerNode.getConnection().isFine()) { connectDataServer(dataCenter, ip); }}}//remove all old DataServerNode not in change map
Set<String> ipSet = DataServerNodeFactory.getIps(dataCenter);
for (String ip : ipSet) {
if(! ips.contains(ip)) { DataServerNodeFactory.remove(dataCenter, ip, dataServerConfig); } } Map<String, DataNode> newDataNodes = dataServerCache .getNewDataServerMap(dataCenter);//avoid input map reference operation DataServerNodeFactory MAP
Map<String, DataNode> map = new ConcurrentHashMap<>(newDataNodes);
//if the dataCenter is self, post LocalDataServerChangeEvent
if (dataServerConfig.isLocalDataCenter(dataCenter)) {
// Why not do updateItem when local
Set<String> newjoined = new HashSet<>(ips);
newjoined.removeAll(localDataServers);
eventCenter.post(new LocalDataServerChangeEvent(map, newjoined,
dataServerChangeItem.getVersionMap().get(dataCenter), newVersion));
} else {
dataServerCache.updateItem(newDataNodes, newVersion, dataCenter);
eventCenter.post(newRemoteDataServerChangeEvent(dataCenter, map, dataServerChangeItem.getVersionMap().get(dataCenter), newVersion)); }}else {
//if the dataCenter which has no dataServers is not self, remove it
if(! dataServerConfig.isLocalDataCenter(dataCenter)) { removeDataCenter(dataCenter); eventCenter.post(newRemoteDataServerChangeEvent(dataCenter, Collections.EMPTY_MAP, dataServerChangeItem.getVersionMap().get( dataCenter), newVersion)); } Map<String, DataNode> newDataNodes = dataServerCache .getNewDataServerMap(dataCenter); dataServerCache.updateItem(newDataNodes, newVersion, dataCenter); }}}else {
//refresh for keep connect other dataServers
// If there is no DataServer with changes, reconnect the existing DataServer
Set<String> allDataCenter = new HashSet<>(dataServerCache.getAllDataCenters());
for (String dataCenter : allDataCenter) {
Map<String, DataNode> dataNodes = dataServerCache
.getNewDataServerMap(dataCenter);
if(dataNodes ! =null) {
for (DataNode dataNode : dataNodes.values()) {
if(! StringUtils.equals(dataNode.getIp(), DataServerConfig.IP)) { DataServerNode dataServerNode = DataServerNodeFactory .getDataServerNode(dataCenter, dataNode.getIp()); Connection connection = dataServerNode ! =null ? dataServerNode
.getConnection() : null;
if (connection == null| |! connection.isFine()) { connectDataServer(dataCenter, dataNode.getIp()); } } } } } } } }/**
* connect specific dataserver
*
* @param dataCenter
* @param ip
*/
private void connectDataServer(String dataCenter, String ip) {
Connection conn = null;
for (int tryCount = 0; tryCount < TRY_COUNT; tryCount++) {
try {
conn = ((BoltChannel) dataNodeExchanger.connect(new URL(ip, dataServerConfig
.getSyncDataPort()))).getConnection();
break;
} catch (Exception e) {
TimeUtil.randomDelay(3000); }}if (conn == null| |! conn.isFine()) {throw new RuntimeException(
String
.format(
"[DataServerChangeEventHandler] connect dataServer %s in %s failed five times,dataServer will not work,please check connect!",
ip, dataCenter));
}
//maybe get dataNode from metaServer,current has not start! register dataNode info to factory,wait for connect task next execute
DataServerNodeFactory.register(new DataServerNode(ip, dataCenter, conn), dataServerConfig);
}
/**
* remove dataCenter, and close connections of dataServers in this dataCenter
*
* @param dataCenter
*/
private void removeDataCenter(String dataCenter) { DataServerNodeFactory.getDataServerNodes(dataCenter).values().stream().map(DataServerNode::getConnection) .filter(connection -> connection ! =null&& connection.isFine()).forEach(Connection::close); DataServerNodeFactory.remove(dataCenter); }}Copy the code
7.3 logic diagram
Thus, our logical diagram expands as follows:
Dataserverchangeevents come from four sources.
The first three sources are related to MetaserverChangeEvents.
- Start actively seek: MetaServerChangeEventHandler response to MetaServerChangeEvent news. After processing the MetaServerChangeEvent, the task registers a DataServerChangeEvent event with the EventCenter EventCenter. It corresponds to line A in figure 1, 1, 3 and 4, which is the source of DataServerChangeEvent 1.
- Version change push: ServerChangeHandler is the Metanodesano1100Response function. In ServerChangeHandler, once you’ve got NodeChangeResult, it will determine the node type to change, depending on the Note type, Decide whether to generate a DataServerChangeEvent or a MetaServerChangeEvent.
- If it is nodeType.data, ServerChangeHandler sends a message to eventCenter, i.e
eventCenter.post(new MetaServerChangeEvent(map));
;It is the line in figure 2, the source of DataServerChangeEvent 2. - If it is nodeType.data, ServerChangeHandler sends a message to eventCenter, i.e
eventCenter.post(new MetaServerChangeEvent(map));
; Note that there is a process of converting DataServerChangeEvent again, will be active and MetaServer interaction, namely MetaServerChangeEventHandler here if return messages are NodeChangeResult, Change it to a DataServerChangeEvent and drop a DataServerChangeEvent into the Event Center.It is the line 1, 3 and 4 in figure B, which is the source of DataServerChangeEvent 3.
- If it is nodeType.data, ServerChangeHandler sends a message to eventCenter, i.e
The fourth source is regular rotation training.
All dataservers run a ConnectionRefreshTask that periodically polls MetaServer for data node information.
ConnectionRefreshTask call metaServerService. GetDateServers (); Contact MetaServer to build a DataServerChangeItem from the result of the request; Put a message DataServerChangeEvent(dataServerChangeItem, fromType.connect_task) in EventCenter; The line in figure 5 is the source of DataServerChangeEvent 3.
Finally, DataServerChangeEvent event is triggered, the DataServerChangeEventHandler for corresponding processing. It corresponds to the line 6 and 7 in the figure below.
If the current node is the DataCenter, the trigger LocalDataServerChangeEvent events. LocalDataServerChangeEvent SOFA here mainly processing, long distance part of the room is not open source.
+---------------------------+ |[DataServerBootstrap] | MetaServerChangeEvent +------------------------+ | | | | | +-------------------------+ | +------------------+ | | startRaftClient | a | | | | | | | | | | +-------------+ | | | | | | | | | | | +---------------------------+ | | | | | | | +---------------------------+ | v | | | | | | [Timer] | | | v | | | | | b |1+----+--+-----+ | | | | ConnectionRefreshMetaTask +------------------------------> | EventCenter +----+ | | | | | MetaServerChangeEvent | +-------+---+-+ | | | | +---------------------------+ | ^ ^ | | | | +---------------------------+ | | | | | | | | | | | | | | | | | [Push<NodeChangeResult>] | | | | | | | | | | c | | | | | | | | +-------------------------+ | |5 | | | |
| | MetaServerChangeEvent | | | | | |
| ServerChangeHandler | 2| | | | | | | +----------------------------------------+ | | | | | +---------------------------+ DataServerChangeEvent | | | | | | | | | | +-------------------------+ | | | | | | | | | | | | | ConnectionRefreshTask +----------------------------------------------+ | | | | | | | | | | +-------------------------+ | | | | | | | | MetaServerChangeEvent | | | |3 | | | |
+----------------------------------------------------+ | | |
| | | |
v | | |
+-----------------+--------------+ DataServerChangeEvent | | |
| | 4 | | |
| MetaServerChangeEventHandler +----------------------------------------+ | |
| | | |
+--------------------------------+ | |
| |
DataServerChangeEvent | |
+------------------------------+ | |
| DataServerChangeEventHandler | <----------------------------------------+ |
+---------------+--------------+ 6 |
| |
| 7 |
+------------------------------------------------------------+
LocalDataServerChangeEvent / RemoteDataServerChangeEvent
Copy the code
0 x08 summary
This article explains how SOFARegistry handles Data node changes.
This part is mainly from DataServerChangeEvent to LocalDataServerChangeEvent logic. LocalDataServerChangeEvent SOFA here mainly processing, long distance part of the room is not open source. So we introduce LocalDataServerChangeEvent below.
0xEE Personal information
★★★★ Thoughts on life and technology ★★★★★
Wechat official account: Rosie’s Thoughts
If you want to get a timely news feed of personal articles, or want to see the technical information of personal recommendations, please pay attention.
0 XFF reference
How does ant Financial Service registry realize the smooth scaling of DataServer
Ant gold uniform service registry SOFARegistry parsing | service discovery path optimization
The service registry Session storage policy | SOFARegistry parsing
Introduction to the Registry – SOFARegistry architecture for Massive Data
Service registry data fragmentation and synchronization scheme, rounding | SOFARegistry parsing
Ant Financial open source communication framework SOFABolt analysis of connection management analysis
Timeout control mechanism and heartbeat mechanism resolved by SOFABolt, ant Financial’s open source communication framework
SOFABolt protocol framework analysis of Ant Financial open source communication framework
Ant gold uniform service registry data consistency analysis | SOFARegistry parsing