44import static org .tron .common .backup .BackupManager .BackupStatusEnum .MASTER ;
55import static org .tron .common .backup .BackupManager .BackupStatusEnum .SLAVER ;
66import static org .tron .common .backup .message .UdpMessageTypeEnum .BACKUP_KEEP_ALIVE ;
7+ import static org .tron .core .config .args .InetUtil .resolveInetAddress ;
78
89import io .netty .util .internal .ConcurrentSet ;
910import java .net .InetAddress ;
1011import java .net .InetSocketAddress ;
12+ import java .util .Map ;
1113import java .util .Set ;
14+ import java .util .concurrent .ConcurrentHashMap ;
1215import java .util .concurrent .ScheduledExecutorService ;
1316import java .util .concurrent .TimeUnit ;
17+ import lombok .Getter ;
18+ import lombok .Setter ;
1419import lombok .extern .slf4j .Slf4j ;
1520import org .springframework .stereotype .Component ;
1621import org .tron .common .backup .message .KeepAliveMessage ;
2025import org .tron .common .backup .socket .UdpEvent ;
2126import org .tron .common .es .ExecutorServiceManager ;
2227import org .tron .common .parameter .CommonParameter ;
28+ import org .tron .p2p .utils .NetUtil ;
2329
2430@ Slf4j (topic = "backup" )
2531@ Component
2632public class BackupManager implements EventHandler {
2733
28- private CommonParameter parameter = CommonParameter .getInstance ();
34+ private final CommonParameter parameter = CommonParameter .getInstance ();
2935
30- private int priority = parameter .getBackupPriority ();
36+ private final int priority = parameter .getBackupPriority ();
3137
32- private int port = parameter .getBackupPort ();
38+ private final int port = parameter .getBackupPort ();
3339
34- private int keepAliveInterval = parameter .getKeepAliveInterval ();
40+ private final int keepAliveInterval = parameter .getKeepAliveInterval ();
3541
36- private int keepAliveTimeout = keepAliveInterval * 6 ;
42+ private final int keepAliveTimeout = keepAliveInterval * 6 ;
3743
3844 private String localIp = "" ;
3945
40- private Set <String > members = new ConcurrentSet <>();
46+ private final Set <String > members = new ConcurrentSet <>();
4147
42- private final String esName = "backup-manager" ;
48+ private final Map < String , String > domainIpCache = new ConcurrentHashMap <>() ;
4349
44- private ScheduledExecutorService executorService =
50+ private final String esName = "backup-manager" ;
51+ private final ScheduledExecutorService executorService =
4552 ExecutorServiceManager .newSingleThreadScheduledExecutor (esName );
4653
54+ private final String dnsEsName = "backup-dns-refresh" ;
55+ private ScheduledExecutorService dnsExecutorService ;
56+
57+ @ Setter
4758 private MessageHandler messageHandler ;
4859
60+ @ Getter
4961 private BackupStatusEnum status = MASTER ;
5062
5163 private volatile long lastKeepAliveTime ;
5264
5365 private volatile boolean isInit = false ;
5466
55- public void setMessageHandler (MessageHandler messageHandler ) {
56- this .messageHandler = messageHandler ;
57- }
58-
59- public BackupStatusEnum getStatus () {
60- return status ;
61- }
62-
6367 public void setStatus (BackupStatusEnum status ) {
6468 logger .info ("Change backup status to {}" , status );
6569 this .status = status ;
@@ -78,10 +82,20 @@ public void init() {
7882 logger .warn ("Failed to get local ip" );
7983 }
8084
81- for (String member : parameter .getBackupMembers ()) {
82- if (!localIp .equals (member )) {
83- members .add (member );
85+ for (String ipOrDomain : parameter .getBackupMembers ()) {
86+ InetAddress inetAddress = resolveInetAddress (ipOrDomain );
87+ if (inetAddress == null ) {
88+ logger .warn ("Failed to resolve backup member domain: {}" , ipOrDomain );
89+ continue ;
90+ }
91+ String ip = inetAddress .getHostAddress ();
92+ if (localIp .equals (ip )) {
93+ continue ;
94+ }
95+ if (!NetUtil .validIpV4 (ipOrDomain ) && !NetUtil .validIpV6 (ipOrDomain )) {
96+ domainIpCache .put (ipOrDomain , ip );
8497 }
98+ members .add (ip );
8599 }
86100
87101 logger .info ("Backup localIp:{}, members: size= {}, {}" , localIp , members .size (), members );
@@ -111,6 +125,17 @@ public void init() {
111125 logger .error ("Exception in send keep alive" , t );
112126 }
113127 }, 1000 , keepAliveInterval , TimeUnit .MILLISECONDS );
128+
129+ if (!domainIpCache .isEmpty ()) {
130+ dnsExecutorService = ExecutorServiceManager .newSingleThreadScheduledExecutor (dnsEsName );
131+ dnsExecutorService .scheduleWithFixedDelay (() -> {
132+ try {
133+ refreshMemberIps ();
134+ } catch (Throwable t ) {
135+ logger .error ("Exception in backup DNS refresh" , t );
136+ }
137+ }, 60_000L , 60_000L , TimeUnit .MILLISECONDS );
138+ }
114139 }
115140
116141 @ Override
@@ -149,6 +174,9 @@ public void handleEvent(UdpEvent udpEvent) {
149174
150175 public void stop () {
151176 ExecutorServiceManager .shutdownAndAwaitTermination (executorService , esName );
177+ if (dnsExecutorService != null ) {
178+ ExecutorServiceManager .shutdownAndAwaitTermination (dnsExecutorService , dnsEsName );
179+ }
152180 }
153181
154182 @ Override
@@ -162,4 +190,26 @@ public enum BackupStatusEnum {
162190 MASTER
163191 }
164192
193+ /**
194+ * Re-resolves all tracked domain entries. If an IP has changed, the old IP is
195+ * removed from {@link #members} and the new IP is added.
196+ */
197+ private void refreshMemberIps () {
198+ for (Map .Entry <String , String > entry : domainIpCache .entrySet ()) {
199+ String domain = entry .getKey ();
200+ String oldIp = entry .getValue ();
201+ InetAddress inetAddress = resolveInetAddress (domain );
202+ if (inetAddress == null ) {
203+ logger .warn ("DNS refresh: failed to re-resolve backup member domain {}, keep it" , domain );
204+ continue ;
205+ }
206+ String newIp = inetAddress .getHostAddress ();
207+ if (!newIp .equals (oldIp )) {
208+ logger .info ("DNS refresh: backup member {} IP changed {} -> {}" , domain , oldIp , newIp );
209+ members .remove (oldIp );
210+ members .add (newIp );
211+ domainIpCache .put (domain , newIp );
212+ }
213+ }
214+ }
165215}
0 commit comments