c++实现lru lfu页面置换算法_SpringBoot2.x系列教程|SpringBoot整合Hazelcast实现分布式缓存...

本文详细介绍了如何在SpringBoot2.x项目中整合Hazelcast实现分布式缓存,包括配置步骤、代码实现、监听器配置以及测试过程。通过创建配置文件、添加依赖、设置数据释放策略等,成功搭建并测试了分布式缓存功能。
摘要由CSDN通过智能技术生成

SpringBoot2.x系列教程|SpringBoot整合Hazelcast实现分布式缓存

作者:一一哥

一. 分布式缓存代码实现步骤

1. 创建web项目

我们按照之前的经验,创建一个web程序,并将之改造成Spring Boot项目,具体过程略。

9e995b887cc7a057cce6d43e1837f6c1.png

2. 添加依赖包

com.hazelcast    hazelcastcom.hazelcast    hazelcast-spring

3. 创建application.yml配置文件

创建application.yml配置文件,可以在这里设置服务器端口号。

server:  port: 8081

4. 添加Hazelcast配置类

package com.yyg.boot.config;import com.hazelcast.config.*;import com.hazelcast.core.Hazelcast;import com.hazelcast.core.HazelcastInstance;import com.hazelcast.core.IMap;import com.hazelcast.core.ITopic;import com.yyg.boot.interceptor.IMapInterceptor;import com.yyg.boot.interceptor.MapListener;import com.yyg.boot.interceptor.TopicListener;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @Author 一一哥Sun * @Date Created in 2020/4/23 * @Description Description */@Configurationpublic class HazelcastConfiguration {    @Bean    public Config hazelCastConfig() {        Config config = new Config();        //解决同网段下,不同库项目        GroupConfig gc=new GroupConfig("hazelGroup");        config.setInstanceName("hazelcast-instance")                .addMapConfig(new MapConfig()                                .setName("configuration")                                // Map中存储条目的最大值[0~Integer.MAX_VALUE]。默认值为0。                                .setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))                                 //数据释放策略[NONE|LRU|LFU]。这是Map作为缓存的一个参数,用于指定数据的回收算法。默认为NONE。LRU:“最近最少使用“策略。                                .setEvictionPolicy(EvictionPolicy.LRU)                                //数据留存时间[0~Integer.MAX_VALUE]。缓存相关参数,单位秒,默认为0。                                .setTimeToLiveSeconds(-1))                                .setGroupConfig(gc);        return config;    }}
关于配置说明
eviction-policy

数据释放策略[NONE|LRU|LFU]。这是Map作为缓存的一个参数,用于指定数据的回收算法,默认为NONE。

NONE:当设置为NONE时,不会发生数据回收,同时max-size会失效。但是任然可以使用time-to-live-seconds和max-idle-seconds参数来控制数据留存时间。

LRU:“最近最少使用“策略。

LFU:“最不常用的使用”策略。

time-to-live-seconds(TTL)

数据留存时间[0~Integer.MAX_VALUE]。缓存相关参数,单位秒,默认为0。这个参数决定了一条数据在map中的停留时间。当数据在Map中留存超过这个时间并且没有被更新时,它会根据指定的回收策略从Map中移除。值为0时,意味着无求大。

4. 创建Controller接口方法

package com.yyg.boot.web;import com.hazelcast.core.HazelcastInstance;import com.hazelcast.core.IList;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.Map;import java.util.Queue;/** * @Author 一一哥Sun * @Date Created in 2020/4/23 * @Description Description */@Slf4j@RestController@RequestMapping("/hazelcast")public class HazelcastController {    @Autowired    private HazelcastInstance hazelcastInstance;    @PostMapping(value = "/save")    public String saveMapData(@RequestParam String key, @RequestParam String value) {        Map hazelcastMap = hazelcastInstance.getMap("hazelcastMap");        hazelcastMap.put(key, value);        return "success";    }    @GetMapping(value = "/get")    public String getMapData(@RequestParam String key) {        Map hazelcastMap = hazelcastInstance.getMap("hazelcastMap");        return hazelcastMap.get(key);    }    @GetMapping(value = "/all")    public Map readAllDataFromHazelcast() {        return hazelcastInstance.getMap("hazelcastMap");    }    @GetMapping(value = "/list")    public String saveList(@RequestParam(required = false) String value) {        // 创建集群List        IList clusterList = hazelcastInstance.getList("myList");        clusterList.add(value);        return "success";    }    @GetMapping(value = "/showList")    public IList showList() {        return hazelcastInstance.getList("myList");    }    @GetMapping(value = "/clearList")    public String clearList() {        IList clusterList = hazelcastInstance.getList("myList");        clusterList.clear();        return "success";    }    @GetMapping(value = "/queue")    public String saveQueue(@RequestParam String value) {        // 创建集群Queue        Queue clusterQueue = hazelcastInstance.getQueue("myQueue");        clusterQueue.offer(value);        return "success";    }    @GetMapping(value = "/showQueue")    public Queue showQueue() {        Queue clusterQueue = hazelcastInstance.getQueue("myQueue");        for (String obj : clusterQueue) {            log.warn("value=" + obj);        }        return clusterQueue;    }    @GetMapping(value = "/clearQueue")    public String clearQueue() {        Queue clusterQueue = hazelcastInstance.getQueue("myQueue");        clusterQueue.clear();        return "success";    }}

5. 创建入口类

package com.yyg.boot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * @Author 一一哥Sun * @Date Created in 2020/4/23 * @Description Description */@SpringBootApplicationpublic class HazelcastApplication {    public static void main(String[] args){        SpringApplication.run(HazelcastApplication.class,args);    }}

6. 启动项目进行测试

6.1 启动集群

运行解析:

程序启动时,控制台会输出如下信息:

[hazelGroup] [3.12.6] Prefer IPv4 stack is true, prefer IPv6 addresses is false2020-04-24 11:37:45.790  INFO 5820 --- com.hazelcast.instance.AddressPicker     [hazelGroup] [3.12.6] Picked [192.168.87.102]:5702, using socket ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5702], bind any local is true

这一段输出说明了当前 Hazelcast 的网络环境。首先是检测IPv4可用且检查到当前的IPv4地址是192.168.87.102。然后使用IPv6启用socket。在某些无法使用IPv6的环境上,需要强制指定使用IPv4,增加jvm启动参数:-Djava.net.preferIPv4Stack=true 即可。

 [192.168.87.102]:5702 [hazelGroup] [3.12.6] Hazelcast 3.12.6 (20200130 - be02cc5) starting at [192.168.87.102]:5702com.hazelcast.system                     : [192.168.87.102]:5702 [hazelGroup] [3.12.6] Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.

这一段输出说明了当前实例的初始化端口号是5701。Hazelcast 默认使用5701端口。如果发现该端口被占用,会+1查看5702是否可用,如果还是不能用会继续向后探查直到5800。Hazelcast 默认使用5700到5800的端口,如果都无法使用会抛出启动异常。

我们先在8081端口上进行启动,在控制台会发现此时Members数量只有1,个,Hazelcast运行在5701端口上。

64d18e2a034c8054e1785b5b09e0b5a8.png

然后我们在8082端口上,再次启动第2个进程。此时在控制台,会发现Members数量变成了2个,意味着一个新的Hazelcast实例加入到了集群中。

68c80da8c4414702fe9b0179cf721ae2.png

Members[2]表示当前集群只有2个节点,2个节点都在ip为192.168.87.102的这台设备上,2个节点分别占据了5701端口和5702端口。端口后面的this说明这是当前节点,而未标记this的是其他接入集群的节点。

由此可见,Hazelcast实现集群非常的简单,会自动把不同进程添加到集群中。

6.2 测试map结构

我们先在8081端口的进程上存储一个数据到map中。

fe92ec83ee061a6689120dd66ac31cca.png

然后我们在8081上取数据,会发现数据已经获取到了。

6ba4acabbba811a62d55c15d27d850d8.png

然后我们在8082端口的进程上获取数据,发现同样也可以获取到之前存储的数据。说明在Hazelcast中只要在一个服务器节点上存储了数据,就可以自动实现从其他集群节点中获取到另一个节点中存储的数据。

5ae44bf2397234aff1b9ca7aa0189489.png
6.3 测试list结构

我们先在8081端口的进程上存储一个数据到list中。

3ca00af0af01c7773c90560f97591711.png

然后我们在8082上取数据,会发现数据已经获取到了。

a2e906636b57125eabce81ea8fd2e894.png

同样的实现了集群数据共享。

6.4 测试queue结构

我们先在8081端口的进程上存储一个数据到queue中。

27380d816313b1fe2a32b7e46233f8f3.png

然后我们在8082上取数据,会发现数据已经获取到了。

91cf71f9908cb7cf470e2bc6adab93b6.png

同样的实现了集群数据共享。

7. 添加Hazelcast监听器配置

我们在上面的HazelcastConfiguration配置类中添加一些监听器类。

@Beanpublic HazelcastInstance hazelcastInstance(Config config) {    HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance(config);    //分布式map监听    IMap imap = hzInstance.getMap("hazelcastMap");    imap.addLocalEntryListener(new MapListener());    //拦截器(没写内容)    imap.addInterceptor(new IMapInterceptor());    //发布/订阅模式    ITopic topic = hzInstance.getTopic("hazelcastTopic");    topic.addMessageListener(new TopicListener());    return hzInstance;}

此时完整的HazelcastConfiguration类代码为:

package com.yyg.boot.config;import com.hazelcast.config.*;import com.hazelcast.core.Hazelcast;import com.hazelcast.core.HazelcastInstance;import com.hazelcast.core.IMap;import com.hazelcast.core.ITopic;import com.yyg.boot.interceptor.IMapInterceptor;import com.yyg.boot.interceptor.MapListener;import com.yyg.boot.interceptor.TopicListener;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @Author 一一哥Sun * @Date Created in 2020/4/23 * @Description Description */@Configurationpublic class HazelcastConfiguration {    @Bean    public Config hazelCastConfig() {        Config config = new Config();        //解决同网段下,不同库项目        GroupConfig gc=new GroupConfig("hazelGroup");        config.setInstanceName("hazelcast-instance")                .addMapConfig(new MapConfig()                                .setName("configuration")                                // Map中存储条目的最大值[0~Integer.MAX_VALUE]。默认值为0。                                .setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))                                 //数据释放策略[NONE|LRU|LFU]。这是Map作为缓存的一个参数,用于指定数据的回收算法。默认为NONE。LRU:“最近最少使用“策略。                                .setEvictionPolicy(EvictionPolicy.LRU)                                //数据留存时间[0~Integer.MAX_VALUE]。缓存相关参数,单位秒,默认为0。                                .setTimeToLiveSeconds(-1))                                .setGroupConfig(gc);        return config;    }    @Bean    public HazelcastInstance hazelcastInstance(Config config) {        HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance(config);        //分布式map监听        IMap imap = hzInstance.getMap("hazelcastMap");        imap.addLocalEntryListener(new MapListener());        //拦截器(没写内容)        imap.addInterceptor(new IMapInterceptor());        //发布/订阅模式        ITopic topic = hzInstance.getTopic("hazelcastTopic");        topic.addMessageListener(new TopicListener());        return hzInstance;    }}

8. 重新启动8081和8082进程测试

此时我们可以8081进程的map结构中添加一个新的key与value,如下所示:

3ca309bf4fa44e3ab8f7e228a49dbaf3.png

然后在控制台可以看到我们之前Map结构的监听器类中,打印的log输出如下:

fc3d3ac997b161c5235b538b28e54256.png

说明我们的IMap的拦截器生效了。而且8082进程中也获取到了存储的age值。

e50242bfa954903e7e27dabd13314432.png

因为Hazelcast是集群的,数据可以在许多应用程序实例之间共享。

9. 完整项目结构

d4222fea576f6b1ade6440b6f2fab2e9.png

二. hazelcast管理终端

hazelcast其实提供了一个管理中心程序,可以帮助我们查看hazelcast中缓存的数据,当然这个管理中心可以不用安装,它只是帮我们查看缓存状态的一个工具而已。

1. 下载hazelcast管理中心

https://hazelcast.org/download/archives/#management-center

be393d68dbf689f4f81c236f2d9be3a2.png

2. 解压之后,进入根目录进行启动。

8a410ff3d07e2fb379e2d7cce8f02dad.png

3. 启动start.bat命令

8a9f7d2e7e49d9b31b381a16ee7e6556.png

4. 打开管理中心mancenter。

一开始会要求先注册一个管理员用户,密码需要8位以上,然后进行登录。

dcb5cc2aa9fe2e4f05547ea17db133aa.png
f6447aea4ec13345a8d1300c08585e5a.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值