buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

不忘初心,方得始终。内存数据刷新改造小记

 

获取地区数据的RestAPI接口(程序代码见文末),原先的实现是:首次http请求时,一次性把全量地区数据从DB加载过来,存放到静态内存变量里,以后的调用则直接从内存读取。这样虽然快,但弊端显而易见,当数据有更新,只能通过重启站点服务的方式搞定。

所以,要改造。
直觉想到的是用redis缓存。

在coding的时候,突然觉得还是从内存上做文章多好啊,毕竟读本地内存是最快的方式了。于是,想到了一个办法,每到整点清空数据变量。代码如下。使用地区数据的地方不再直接访问areaStr变量,而是调用getAreaStr()方法。

复制代码
import org.joda.time.DateTime;

private static String areaStr = "";
private  String getAreaStr(){
    //整点清除数据,重新调用rpc并加载到内存
    int minuteOfHour = DateTime.now().getMinuteOfHour();
    if (0 == minuteOfHour) {
        areaStr = "";
    }

    if (StringUtil.isBlank(areaStr)) {
        log.info("初始化地区数据到内存");
        //rpc请求
        areaStr = threeLevelClient.selectAreaList();
    }
    
    return areaStr;
}
复制代码

还没等自测,我就意识到不对头了。这是web接口啊,那整点没有http请求的话,岂不是就达不到刷新数据的预期了!
还是不忘初心的好!就用redis来搞。——考虑到数据量大,我还是做了点改动:依然把数据放到内存里,只是通过redis来控制内存数据的刷新。

复制代码
private static String areaStr = "";
private static JedisCluster jedis = JedisClusterUtil.getJedisCluster();

// 地区数据量大(2712条),不宜直接放到redis里。这里通过redis控制内存数据的刷新。
private void resetAreaStr() {
    final String areaStr_Key = "payment_api_areaStr";
    String value = jedis.get(areaStr_Key);
    if (StringUtils.isBlank(value)) {
        areaStr = threeLevelClient.selectAreaList();
        jedis.setex(areaStr_Key, "1", 300);
        log.info("重置redis缓存:" + areaStr_Key);

    }
    if (StringUtils.isBlank(areaStr)) {
        log.info("初始化地区数据到内存");
        //rpc请求
        areaStr = threeLevelClient.selectAreaList();
    }
}
复制代码

这样无疑是不错的方案了。使用areaStr之前调用resetAreaStr()方法即可。

复制代码
    @RequestMapping("cityQuery")
    public void cityQuery(HttpServletResponse response) throws Exception {

//        log.debug("payment_api----获取地区列表:{}", 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("集合size:{}", areaList.size());

        WebUtil.outputJson(showAreaList, response);

    }
复制代码

 

posted on   buguge  阅读(458)  评论(0编辑  收藏  举报

编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
· 全程使用 AI 从 0 到 1 写了个小工具
点击右上角即可分享
微信分享提示