Pray for the only ID project. Is there any problem with the local number of each node in the following JAVA code?

problem description

(1) there is a project that provides a unique ID
(2) according to the project name and table name, the project uses REDIS as the global lock (REDIS single-threaded feature, one batch at a time)
(3) the project provides an additional toolkit for the user to call to get the next ID

.

the following code is "the toolkit calls the consumer to get the next ID". Ask everyone to point out
(1) idProviderApi is a regular feign http method. Go to the ID service to get a batch of numbers
(2) getNextId will get the next ID
(3) it is divided into primary MAP and backup MAP, both of which are used to store a batch of numbers, the main one is used to provide ID directly, and the backup MAP is used to provide the main MAP when the master does not have a number. Then empty the backup MAP
(4) there is a timer to check whether the backup MAP has data. If not, go to the ID project to get

.

under your own test, if there are N threads in a node, it is the same to get ID temporarily. Please give us some advice

.

related codes

package com.jiangdaxian.project.biz;

import com.jiangdaxian.project.api.IdProviderApi;
import com.jiangdaxian.project.dto.IdProviderDto;
import com.jiangdaxian.project.request.IdProviderRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@ Component
public class GetIdProviderInfo {

private static final String SPLIT = "_________";

//
Map<String,IdProviderObj> map = new HashMap<String,IdProviderObj>();

//KEY
Map<String,IdProviderObj> backMap = new HashMap<String,IdProviderObj>();

//KEY
Map<String,ReentrantLock> lockMap = new HashMap<String,ReentrantLock>();
@Autowired
private IdProviderApi idProviderApi;

/**
 * ID
 * @param projectName
 * @param tableName
 * @return
 * @throws Exception
 */
public Long getNextId(String projectName,String tableName) throws Exception {
    String key = getKey(projectName,tableName);
    if(map.containsKey(key)==false){
        //
        synchronized (key.intern()){
            if(map.containsKey(key)==false) {
                getNextIdProvider(projectName, tableName,true);
                lockMap.put(getKey(projectName,tableName),new ReentrantLock());
                getNextIdProvider(projectName, tableName,false);
            }
        }
    }

    IdProviderObj obj = map.get(key);
    Lock lock = lockMap.get(key);
    try {
        //10
        boolean result = lock.tryLock(10, TimeUnit.SECONDS);
        if (result == false) {
            throw new Exception("");
        }
        return getId(obj,projectName, tableName);
    }catch(Exception e){
        e.printStackTrace();
        throw e;
    }finally {
        lock.unlock();
    }
}

private Long getId(IdProviderObj obj,String projectName,String tableName) throws Exception {
    long nextId = obj.getNowId().longValue();
    obj.getNowId().increment();
    if (nextId > (obj.getIdProviderDto().getIdEnd())) {
        //,MAPMAP
        IdProviderObj getObj= backMap.get(getKey(projectName,tableName));
        if(getObj!=null && getObj.getIdProviderDto()!=null){
            //MAP
            map.put(getKey(projectName,tableName),getObj);
            backMap.put(getKey(projectName,tableName),null);
            System.out.println("obj " + getKey(projectName,tableName) + ",getIdbackMap");
            return getId(getObj,projectName, tableName);
        }else{
            //ID
            IdProviderObj idProviderObj = getNextIdProvider(projectName, tableName,true);
            System.out.println("obj " + getKey(projectName,tableName) + ",getId");
            return getId(idProviderObj,projectName,tableName);
        }
    } else {
        //
        return nextId;
    }
}

/**
 *
 * @param projectName
 * @param tableName
 * @param isSetBackNullTRUEMAP;FALSEMAP
 * @return
 * @throws Exception
 */
private IdProviderObj getNextIdProvider(String projectName, String tableName,boolean isSetBackNull) throws Exception {
    IdProviderObj idProviderObj = new IdProviderObj();
    try {
        IdProviderRequest idProviderRequest = new IdProviderRequest();
        idProviderRequest.setTableName(tableName);
        idProviderRequest.setProjectName(projectName);
        IdProviderDto dto = idProviderApi.get(idProviderRequest);
        if(dto!=null && dto.getId()!=null) {
            idProviderObj.setIdProviderDto(dto);
            LongAdder la = new LongAdder();
            la.add(dto.getIdStart());
            idProviderObj.setNowId(la);

            if(isSetBackNull==true) {
                map.put(getKey(projectName,tableName), idProviderObj);
                backMap.put(getKey(projectName, tableName), null);
            }else{
                backMap.put(getKey(projectName, tableName), idProviderObj);
            }
            return idProviderObj;
        }else{
            throw new Exception();
        }
    }catch(Exception e){
        e.printStackTrace();
        throw e;
    }
}

private class IdProviderObj{
    private IdProviderDto idProviderDto = null;
    private LongAdder nowId;

    public IdProviderDto getIdProviderDto() {
        return idProviderDto;
    }

    public void setIdProviderDto(IdProviderDto idProviderDto) {
        this.idProviderDto = idProviderDto;
    }

    public LongAdder getNowId() {
        return nowId;
    }

    public void setNowId(LongAdder nowId) {
        this.nowId = nowId;
    }
}

private class NameObj{
    private String projectName;
    private String tableName;

    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
}

private String getKey(String projectName,String tableName){
    return projectName + SPLIT+tableName;
}

private NameObj getNameObj(String str){
    NameObj nameObj = new NameObj();
    String []arr = str.split(SPLIT);
    nameObj.setProjectName(arr[0]);
    nameObj.setTableName(arr[1]);
    return nameObj;
}

@Scheduled(cron = "0/10 * * * * *")
public void addIdProviderDto(){
    backMap.entrySet().parallelStream().forEach(obj->{
        if(obj.getValue()==null){
            System.out.println("obj " + obj.getKey() + ",");
            NameObj nameObj = getNameObj(obj.getKey());
            try {
                getNextIdProvider(nameObj.getProjectName(),nameObj.getTableName(),false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("obj " + obj.getKey() + ",");
        }
    });
}

}

Jul.11,2022
Menu