âæ¥åä¸ä¸ªå¥½æ¶æ¯ï¼æµè¯è³ä»ï¼ä¾ç¶æ²¡æBUGãâ
è¿ä¸¤å¤©åéå°äºä¸¤ä¸ªåï¼ä¸ä¸ªãhostãç¼åï¼ä¸ä¸ªå¤èç¹ç¨æ·éï¼è§£å³æ¹æ¡æ¯è¾ç°æï¼ä½æ¯å®æ½èµ·æ¥è¿æ¯è´¹äºå¤§å²ã
hostç¼å
è¿è¡ç¨ä¾è·åãhostãï¼ä¹åçæ¹æ¡æ¯ç¨åå¯å¨æææçãhostãå ¨é¨æ¾å¨
JVM
éé¢ï¼è¿æ ·ç´æ¥ä»ä¸ä¸ª
map
ä¸è·åãhostãä¿¡æ¯ï¼ä¼é常æ¹ä¾¿ã忥å¨è°è¯è¿ç¨ä¸åç°ï¼è¿æ ·æä¸ä¸ªå¼ç«¯ï¼æ æ³æç¥å°æ°æ®åºæ°æ®çååï¼æ¬æ¥æ³çå¯ä»¥åä¸ä¸ªè®¢é æè éç¥åè½ï¼ç±äºå®æ½æ¹æ¡æ¯è¾éº»ç¦ï¼æ¹æäºå ¨é¨æ¥åºï¼æ¯æ¬¡æ¥è¯¢çèæ¶å¨ã20-50ãmsï¼å 为å¤çº¿ç¨è¿è¡ï¼æ»ä½èæ¶å¢å æ¯å¯ä»¥æ¥åçãä¸è¿è¿æ¯è§å¾ãhostãä¿¡æ¯æ´æ¹çæºä¼å¤ªå°äºï¼ç¼å䏿¥æ¯è¾æ¹ä¾¿ãç°å¨çæ¹æ¡å°±æ¯ææ¥è¯¢è¿çï¼éè¿éªè¯çãhostãç¼åå¨
JVM
éé¢ï¼è®¾ç½®ä¸ä¸ªæææãè¿é没æç¨å°çº¿ç¨éï¼å 为éå¤è®¾ç½®ãhostãä¸ä¼å¯¼è´ç¨åºåº
BUG
ã
代ç å¦ä¸ï¼
- serviceå±å®ç°
    /**
     * è·åhost,ç¼å
     *
     * @param envId
     * @param service_id
     * @return
     */
    @Override
    public String getHost(int envId, int service_id) {
        String host = ServerHost.getHost(envId, service_id);
        if (StringUtils.isBlank(host)) {
            host = commonMapper.getHost(envId, service_id);
            if (StringUtils.isBlank(host) || !host.startsWith("http")) CommonException.fail("æå¡ID:{},ç¯å¢ID:{}ååé
ç½®é误");
            ServerHost.putHost(envId, service_id, host);
        }
        return host;
    }
å¤å¶
- éæç±»
package com.okay.family.common.basedata
import com.okay.family.fun.frame.SourceCode
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.util.concurrent.ConcurrentHashMap
class ServerHost extends SourceCode {
    private static Logger logger = LoggerFactory.getLogger(ServerHost.class)
    static Map<Integer, String> hosts = new ConcurrentHashMap<>()
    static Map<Integer, Integer> timeout = new ConcurrentHashMap<>()
    public static String getHost(int id) {
        if ((getMark() - timeout.getOrDefault(id,) > OkayConstant.HOST_TIMEOUT) || !hosts.containsKey(id)) null
        else hosts.get(id)
    }
    static String getHost(int envId, int serviceId) {
        getHost(serviceId *  + envId)
    }
    static void putHost(int envId, int serviceId, String host) {
        int key = serviceId *  + envId
        timeout.put(key, getMark())
        hosts.put(key, host)
    }
}
å¤å¶
åå¸å¼é
ç»è¿åäºå»ºè®®ï¼å³å®éç¨
MySQL
æ°æ®åºå®ç°ï¼æ°å»ºä¸å¼ 表ï¼ç¨è¡¨ç主é®IDä½ä¸ºéç
key
ï¼æ ¹æ®æå ¥
id=key
è¿æ¡æ°æ®çåå¨ä¸å¦ä½ä¸ºè·åéçæåç¶æï¼å é¤è¡¨ç¤ºéæ¾è¯¥éãåºæ¬æ¹æ¡æ¯è¾ç°æï¼ä»£ç å¦ä¸ï¼
- serviceå®ç°
- ä¸é¢æ¯è·åç¨æ·åæ®çæ¹æ³ï¼éç¼åï¼
    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
    public TestUserCheckBean getCertificate(int id) {
        Object o = UserLock.get(id);
        synchronized (o) {
            TestUserCheckBean user = testUserMapper.findUser(id);
            if (user == null) UserStatusException.fail("ç¨æ·ä¸åå¨,ID:" + id);
            String create_time = user.getCreate_time();
            long create = Time.getTimestamp(create_time);
            long now = Time.getTimeStamp();
            if (now - create < OkayConstant.CERTIFICATE_TIMEOUT && user.getStatus() == UserState.OK.getCode())
                return user;
            boolean b = UserUtil.checkUserLoginStatus(user);
            if (!b) {
                updateUserStatus(user);
            } else {
                testUserMapper.updateUserStatus(user);
            }
            return user;
        }
    }
å¤å¶
- ä¸é¢æ¯éè¿ç»å½è·åç¨æ·åæ®çæ¹æ³
    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
    public int updateUserStatus(TestUserCheckBean bean) {
        Object o = UserLock.get(bean.getId());
        int userLock = NodeLock.getUserLock(bean.getId());
        synchronized (o) {
            int lock = commonService.lock(userLock);
            if (lock == ) {
                int i = ;
                while (true) {
                    SourceCode.sleep(OkayConstant.WAIT_INTERVAL);
                    TestUserCheckBean user = testUserMapper.findUser(bean.getId());
                    String create_time = user.getCreate_time();
                    long create = Time.getTimestamp(create_time);
                    long now = Time.getTimeStamp();
                    if (now - create < OkayConstant.CERTIFICATE_TIMEOUT && user.getStatus() == UserState.OK.getCode())
                        return ;
                    i++;
                    if (i > OkayConstant.WAIT_MAX_TIME) {
                        UserStatusException.fail("è·ååå¸å¼éè¶
æ¶,å¯¼è´æ æ³æ´æ°ç¨æ·åæ®:id:" + bean.getId());
                    }
                }
            } else {
                try {
                    UserUtil.updateUserStatus(bean);
                    int i = testUserMapper.updateUserStatus(bean);
                    return i;
                } finally {
                    commonService.unlock(userLock);
                }
            }
        }
    }
å¤å¶
- ä¸é¢æ¯æ°æ®åº
CREATE TABLE `qa_lock` (
`id` bigint(20) unsigned NOT NULL COMMENT 'ékey',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'å建æ¶é´',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='åå¸å¼é表-QA-FunTester-20200715';
å¤å¶
- å ¬ä¼å·ãFunTesterãé¦åï¼æ´å¤ååæç« ï¼FunTester420+ååæç« ï¼æ¬¢è¿å ³æ³¨ã交æµï¼ç¦æ¢ç¬¬ä¸æ¹æ èªè½¬è½½ã