Never forget why you started, and your mission can be accomplished. Memory data refresh and transformation

The original implementation of the api interface (see the end of the article for the program code) to obtain the region data is to load it into the memory variable at the first http request, and then directly read it from the memory variable for later calls. This is fast, but the disadvantages are obvious. When the data is updated, it can only be done by restarting the site service.
So, we need to transform.
Intuitive thinking is to use redis cache.

In coding, I suddenly think it's better to do articles from memory. After all, reading memory is the fastest way. So, I came up with a way to clear the data variables at every point. The code is as follows. Instead of directly accessing the areaStr variable, places that use the region data call the getAreaStr() method.

import org.joda.time.DateTime;

private static String areaStr = "";
private  String getAreaStr(){
    //Clear data at whole point and call again rpc And load into memory
    int minuteOfHour = DateTime.now().getMinuteOfHour();
    if (0 == minuteOfHour) {
        areaStr = "";
    }

    if (StringUtil.isBlank(areaStr)) {
        log.info("Initialize region data to memory");
        //rpc request
        areaStr = threeLevelClient.selectAreaList();
    }
    
    return areaStr;
}

Before I could wait for the self-test, I realized that I was wrong. This is a web interface. If there is no http request at all, it will not meet the expectation of refreshing data!
It's better not to forget the original intention! Just use redis. ——Considering the large amount of data, I still made some changes: put the data in memory, and control the refresh of memory data through redis.

private static String areaStr = "";
private static JedisCluster jc = JedisClusterUtil.getJedisCluster();

// The amount of regional data is large (2712 pieces), so it is not suitable to put it directly redis Li. Passed here redis Control the refresh of memory data.
private void resetAreaStr() {
    final String areaStr_Key = "payment_api_areaStr";
    String value = jc.get(areaStr_Key);
    if (StringUtils.isBlank(value)) {
        areaStr = threeLevelClient.selectAreaList();
        jc.setex(areaStr_Key, 300, "1");
        log.info("Reset redis cache:" + areaStr_Key);

    }
    if (StringUtils.isBlank(areaStr)) {
        log.info("Initialize region data to memory");
        //rpc request
        areaStr = threeLevelClient.selectAreaList();
    }
}

This is undoubtedly a good plan. The resetAreaStr() method can be called before using areaStr.

    @RequestMapping("cityQuery")
    public void cityQuery(HttpServletResponse response) throws Exception {

//        log.debug("payment_api----Get region list:{}", areaStr);
        resetAreaStr();
        List<JSONObject> areaList = JSON.parseArray(areaStr, JSONObject.class);

        List<Map<String, String>> showAreaList = new ArrayList<>();
        areaList.forEach(one -> {
            Map<String, String> bankInfo = new HashMap<>();
            bankInfo.put("provinceName", one.getString("provinceName"));
            bankInfo.put("areaName", one.getString("areaName"));
            showAreaList.add(bankInfo);
        });

        log.info("aggregate size: {}", areaList.size());

        WebUtil.outputJson(showAreaList, response);

    }

Tags: Java Redis JSON

Posted on Fri, 29 Nov 2019 23:12:59 -0800 by skateme