聊聊nacos ServiceManager的removeInstance

本文主要研究一下nacos ServiceManager的removeInstance

ServiceManager

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java

@Component
@DependsOn("nacosApplicationContext")
public class ServiceManager implements RecordListener<Service> {

    /**
     * Map<namespace, Map<group::serviceName, Service>>
     */
    private Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();

    private LinkedBlockingDeque<ServiceKey> toBeUpdatedServicesQueue = new LinkedBlockingDeque<>(1024 * 1024);

    private Synchronizer synchronizer = new ServiceStatusSynchronizer();

    private final Lock lock = new ReentrantLock();

    @Resource(name = "consistencyDelegate")
    private ConsistencyService consistencyService;

    @Autowired
    private SwitchDomain switchDomain;

    @Autowired
    private DistroMapper distroMapper;

    @Autowired
    private ServerListManager serverListManager;

    @Autowired
    private PushService pushService;

    private final Object putServiceLock = new Object();

    //......

    public void removeInstance(String namespaceId, String serviceName, boolean ephemeral, Instance... ips) throws NacosException {
        Service service = getService(namespaceId, serviceName);
        removeInstance(namespaceId, serviceName, ephemeral, service, ips);
    }

    public void removeInstance(String namespaceId, String serviceName, boolean ephemeral, Service service, Instance... ips) throws NacosException {

        String key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral);

        List<Instance> instanceList = substractIpAddresses(service, ephemeral, ips);

        Instances instances = new Instances();
        instances.setInstanceList(instanceList);

        consistencyService.put(key, instances);
    }

    public List<Instance> substractIpAddresses(Service service, boolean ephemeral, Instance... ips) throws NacosException {
        return updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE, ephemeral, ips);
    }

    public List<Instance> updateIpAddresses(Service service, String action, boolean ephemeral, Instance... ips) throws NacosException {

        Datum datum = consistencyService.get(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), ephemeral));

        Map<String, Instance> oldInstanceMap = new HashMap<>(16);
        List<Instance> currentIPs = service.allIPs(ephemeral);
        Map<String, Instance> map = new ConcurrentHashMap<>(currentIPs.size());

        for (Instance instance : currentIPs) {
            map.put(instance.toIPAddr(), instance);
        }
        if (datum != null) {
            oldInstanceMap = setValid(((Instances) datum.value).getInstanceList(), map);
        }

        // use HashMap for deep copy:
        HashMap<String, Instance> instanceMap = new HashMap<>(oldInstanceMap.size());
        instanceMap.putAll(oldInstanceMap);

        for (Instance instance : ips) {
            if (!service.getClusterMap().containsKey(instance.getClusterName())) {
                Cluster cluster = new Cluster(instance.getClusterName(), service);
                cluster.init();
                service.getClusterMap().put(instance.getClusterName(), cluster);
                Loggers.SRV_LOG.warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.",
                    instance.getClusterName(), instance.toJSON());
            }

            if (UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE.equals(action)) {
                instanceMap.remove(instance.getDatumKey());
            } else {
                instanceMap.put(instance.getDatumKey(), instance);
            }

        }

        if (instanceMap.size() <= 0 && UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD.equals(action)) {
            throw new IllegalArgumentException("ip list can not be empty, service: " + service.getName() + ", ip list: "
                + JSON.toJSONString(instanceMap.values()));
        }

        return new ArrayList<>(instanceMap.values());
    }

    //......
}
  • removeInstance方法通過substractIpAddresses獲取移除執(zhí)行instances之后的instanceList圃伶,然后通過consistencyService.put方法進(jìn)行更新;substractIpAddresses方法執(zhí)行updateIpAddresses方法,其action參數(shù)值為UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE留攒,它先使用service.allIPs(ephemeral)獲取instance列表煤惩,針對remove動(dòng)作會(huì)根據(jù)instance.getDatumKey()將其從instanceMap中移除

Service.allIPs

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/core/Service.java

public class Service extends com.alibaba.nacos.api.naming.pojo.Service implements Record, RecordListener<Instances> {

    private static final String SERVICE_NAME_SYNTAX = "[0-9a-zA-Z@\\.:_-]+";

    @JSONField(serialize = false)
    private ClientBeatCheckTask clientBeatCheckTask = new ClientBeatCheckTask(this);

    private String token;
    private List<String> owners = new ArrayList<>();
    private Boolean resetWeight = false;
    private Boolean enabled = true;
    private Selector selector = new NoneSelector();
    private String namespaceId;

    /**
     * IP will be deleted if it has not send beat for some time, default timeout is 30 seconds.
     */
    private long ipDeleteTimeout = 30 * 1000;

    private volatile long lastModifiedMillis = 0L;

    private volatile String checksum;

    /**
     * TODO set customized push expire time:
     */
    private long pushCacheMillis = 0L;

    private Map<String, Cluster> clusterMap = new HashMap<>();

    //......

    public List<Instance> allIPs(boolean ephemeral) {
        List<Instance> allIPs = new ArrayList<>();
        for (Map.Entry<String, Cluster> entry : clusterMap.entrySet()) {
            allIPs.addAll(entry.getValue().allIPs(ephemeral));
        }

        return allIPs;
    }

    //......
}
  • Service的allIPs方法會(huì)遍歷clusterMap,然后通過Cluster.allIPs(ephemeral)收集Instance

Cluster.allIPs

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/core/Cluster.java

public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implements Cloneable {

    private static final String CLUSTER_NAME_SYNTAX = "[0-9a-zA-Z-]+";
    /**
     * a addition for same site routing, can group multiple sites into a region, like Hangzhou, Shanghai, etc.
     */
    private String sitegroup = StringUtils.EMPTY;

    private int defCkport = 80;

    private int defIPPort = -1;

    @JSONField(serialize = false)
    private HealthCheckTask checkTask;

    @JSONField(serialize = false)
    private Set<Instance> persistentInstances = new HashSet<>();

    @JSONField(serialize = false)
    private Set<Instance> ephemeralInstances = new HashSet<>();

    @JSONField(serialize = false)
    private Service service;

    @JSONField(serialize = false)
    private volatile boolean inited = false;

    private Map<String, String> metadata = new ConcurrentHashMap<>();

    //......

    public List<Instance> allIPs(boolean ephemeral) {
        return ephemeral ? new ArrayList<>(ephemeralInstances) : new ArrayList<>(persistentInstances);
    }

    //......
}
  • Cluster的allIPs方法根據(jù)ephemeral來返回ephemeralInstances或者persistentInstances

小結(jié)

ServiceManager的removeInstance方法通過substractIpAddresses獲取移除執(zhí)行instances之后的instanceList炼邀,然后通過consistencyService.put方法進(jìn)行更新魄揉;substractIpAddresses方法執(zhí)行updateIpAddresses方法,其action參數(shù)值為UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE拭宁,它先使用service.allIPs(ephemeral)獲取instance列表洛退,針對remove動(dòng)作會(huì)根據(jù)instance.getDatumKey()將其從instanceMap中移除

doc

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市杰标,隨后出現(xiàn)的幾起案子兵怯,更是在濱河造成了極大的恐慌,老刑警劉巖腔剂,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媒区,死亡現(xiàn)場離奇詭異,居然都是意外死亡掸犬,警方通過查閱死者的電腦和手機(jī)袜漩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來湾碎,“玉大人宙攻,你說我怎么就攤上這事〗槿欤” “怎么了座掘?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柔滔。 經(jīng)常有香客問我溢陪,道長,這世上最難降的妖魔是什么廊遍? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任嬉愧,我火速辦了婚禮,結(jié)果婚禮上喉前,老公的妹妹穿的比我還像新娘没酣。我一直安慰自己,他們只是感情好卵迂,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布裕便。 她就那樣靜靜地躺著,像睡著了一般见咒。 火紅的嫁衣襯著肌膚如雪偿衰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天,我揣著相機(jī)與錄音下翎,去河邊找鬼缤言。 笑死,一個(gè)胖子當(dāng)著我的面吹牛视事,可吹牛的內(nèi)容都是我干的胆萧。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼俐东,長吁一口氣:“原來是場噩夢啊……” “哼跌穗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虏辫,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蚌吸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后砌庄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體羹唠,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年娄昆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肉迫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稿黄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跌造,到底是詐尸還是另有隱情杆怕,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布壳贪,位于F島的核電站陵珍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏违施。R本人自食惡果不足惜互纯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磕蒲。 院中可真熱鬧留潦,春花似錦、人聲如沸辣往。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽站削。三九已至坊萝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背十偶。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工菩鲜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惦积。 一個(gè)月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓接校,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荣刑。 傳聞我的和親對象是個(gè)殘疾皇子馅笙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 序 本文主要研究一下nacos ServiceManager的updateInstance ServiceMana...
    go4it閱讀 491評論 0 0
  • 序 本文主要研究一下nacos ServiceManager的registerInstance ServiceMa...
    go4it閱讀 1,593評論 0 0
  • 序 本文主要研究一下nacos ServiceManager的UpdatedServiceProcessor Se...
    go4it閱讀 657評論 0 0
  • 最近,總是想些關(guān)于愛情的事情厉亏,也許現(xiàn)在單身想有個(gè)對象吧董习。 心里又告訴自己,何必要急著去戀愛呢爱只?每天到處看看女孩兒...
    憶上阡陌閱讀 187評論 0 1
  • 夜皿淋,寂靜無聲。 搖曳的路燈照亮了她眼前的積雪恬试,卻無法將它們的刺骨減去分毫窝趣。 大腿內(nèi)側(cè)的陣痛刺激著她敏感的神經(jīng),她噙...
    匕邇閱讀 198評論 0 0