网站优化提升速度/找个免费网站这么难吗

网站优化提升速度,找个免费网站这么难吗,客户提出网站建设申请,做特色创意菜品的网站前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三)Redis&#x…

 前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。

基础篇:

  1. Redis(一)
  2. Redis(二)
  3. Redis(三)
  4. Redis(四)
  5. Redis(五)
  6. Redis(六)
  7. Redis(七)

接上期内容:上期完成了Redis集群的学习。下面开始学习Java集成Redis,话不多说,直接发车。


一、Java连接Redis的四种方式

(一)、底层客户端库

1、Jedis

1.1、定义

Jedis是Redis官方推荐的Java客户端,它提供了一套简洁易用的 API,用于与Redis 进行交互。Jedis支持同步、异步和管道操作,能够满足不同场景下的需求。


1.2、优劣势

优势:

  • 使用简单,学习成本低,对初学者友好。
  • 同步阻塞 I/O,在单线程环境下使用方便。
  • 与 Redis的命令对应性强,容易上手

劣势:

  • 在高并发场景下,由于同步阻塞 I/O 的特性,性能会受到一定影响
  • 多线程环境下,需要手动管理连接池,增加了开发复杂度

2、Lettuce

2.1、定义

Lettuce是一个基于Netty的可伸缩线程安全的Redis客户端,它支持同步、异步和响应式编程模型。Lettuce的设计目标是提供高性能和可扩展性,适用于各种复杂的应用场景。


2.2、优劣势

优势:

  • 基于Netty实现,支持异步 I/O,在高并发场景下性能表现出色
  • 线程安全,无需手动管理连接池。
  • 支持多种编程模型,灵活性高

劣势:

  • 相比Jedis,学习成本较高
  • API相对复杂,对于简单场景可能显得过于繁琐。


(二)、上层框架封装

1、RedisTemplate

1.1、定义

RedisTemplate是Spring Data Redis 提供的一个高级封装,它简化了Java与Redis的交互操作。RedisTemplate提供了丰富的方法,支持各种数据结构的操作,并且可以方便地进行事务管理和序列化配置。


1.2、优劣势

优势:

  • 与Spring 框架无缝集成,使用方便
  • 对各种数据结构的操作进行了封装,代码简洁
  • 支持事务管理和序列化配置,提高了应用的灵活性和可维护性

劣势:

  • 依赖Spring框架,如果项目中没有使用 Spring,引入RedisTemplate会增加项目的复杂度
  • 相比底层客户端库,性能上可能会有一定损耗

2、Redisson

2.1、定义

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,如分布式锁、分布式集合、分布式对象等,极大地简化了分布式系统的开发。


2.2、优劣势

优势:

  • 提供了丰富的分布式服务,开箱即用,像分布式锁、分布式集合等,非常适合构建分布式系统
  • 对Redis功能进行了高度抽象和扩展,使用起来更加便捷。
  • 支持多种序列化方式,兼容性好

劣势:

  • 相比直接使用 Redis 客户端,增加了一定的学习成本
  • 由于其功能丰富,依赖的包可能较多,在一些对依赖大小敏感的场景下不太适用。

二、实操

(一)、集成Jedis

1、新建项目

新建步骤略。最终效果图:

2、导入依赖

        <!--jedis--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.2.0</version></dependency>

3、编写方法

3.1、连接redis单机
public class JedisDemoTest {public static void main(String[] args) {Jedis jedis = new Jedis("192.168.112.129", 6379);jedis.auth("root");jedis.set("k1", "你好jedis");System.out.println(jedis.get("k1"));//keySet<String> keys = jedis.keys("*");for (String key : keys) {System.out.println(key);}System.out.println("jedis.exists====>" + jedis.exists("k2"));System.out.println(jedis.ttl("k1"));//StringSystem.out.println(jedis.get("k1"));jedis.set("k4", "k4_redis");System.out.println("----------------------------------------");jedis.mset("str1", "v1", "str2", "v2", "str3", "v3");System.out.println(jedis.mget("str1", "str2", "str3"));//listSystem.out.println("----------------------------------------");jedis.lpush("myList", "v1", "v2", "v3", "v4", "v5");List<String> list = jedis.lrange("myList", 0, -1);for (String element : list) {System.out.println(element);}//setjedis.sadd("orders", "jd001");jedis.sadd("orders", "jd002");jedis.sadd("orders", "jd003");Set<String> set1 = jedis.smembers("orders");for (String string : set1) {System.out.println(string);}jedis.srem("orders", "jd002");System.out.println(jedis.smembers("orders").size());//hashjedis.hset("hash1", "userName", "lisi");System.out.println(jedis.hget("hash1", "userName"));Map<String, String> map = new HashMap<>();map.put("telephone", "138xxxxxxxx");map.put("address", "fatigue");map.put("email", "sxxxx@qq.com");//jedis.hmset("hash2", map);List<String> result = jedis.hmget("hash2", "telphone", "email");for (String element : result) {System.out.println(element);}//zSetjedis.zadd("zSet01", 60d, "v1");jedis.zadd("zSet01", 70d, "v2");jedis.zadd("zSet01", 80d, "v3");jedis.zadd("zSet01", 90d, "v4");List<String> zSet01 = jedis.zrange("zSet01", 0, -1);zSet01.forEach(System.out::println);// 关闭连接jedis.close();}
}

3.2、连接redis集群
public class JedisColonyDemoTest {public static void main(String[] args) {// 添加主节点HashSet<HostAndPort> jedisClusterNodes = new HashSet<>();jedisClusterNodes.add(new HostAndPort("192.168.112.129", 6379));jedisClusterNodes.add(new HostAndPort("192.168.112.130", 6381));jedisClusterNodes.add(new HostAndPort("192.168.112.129", 6380));// 连接redis集群JedisCluster cluster = new JedisCluster(jedisClusterNodes,"default","root");// 清除单机Redis设置的key// 如果用Jedis连接Redis集群模式下,// flushAll这类全局操作不能直接使用,在集群模式下对于一些全局操作命令(如 KEYS)的处理不够完善,// 没有内置的逻辑来处理 KEYS 命令在集群环境下的复杂性。for (HostAndPort node : jedisClusterNodes) {try (Jedis jedis = new Jedis(node.getHost(), node.getPort())) {jedis.auth("root");// 对每个节点执行 flushDB 命令jedis.flushDB();System.out.println("Flushed database on node: " + node);}}cluster.set("k1", "你好redis集群");System.out.println(cluster.get("k1"));System.out.println("cluster.exists====>" + cluster.exists("k2"));System.out.println(cluster.ttl("k1"));//StringSystem.out.println(cluster.get("k1"));cluster.set("k4", "k4_redis");System.out.println("----------------------------------------");cluster.mset("str1{x}", "v1", "str2{x}", "v2", "str3{x}", "v3");System.out.println(cluster.mget("str1{x}", "str2{x}", "str3{x}"));//listSystem.out.println("----------------------------------------");cluster.lpush("myList", "v1", "v2", "v3", "v4", "v5");List<String> list = cluster.lrange("myList", 0, -1);for (String element : list) {System.out.println(element);}//setcluster.sadd("orders", "jd001");cluster.sadd("orders", "jd002");cluster.sadd("orders", "jd003");Set<String> set1 = cluster.smembers("orders");for (String string : set1) {System.out.println(string);}cluster.srem("orders", "jd002");System.out.println(cluster.smembers("orders").size());//hashcluster.hset("hash1", "userName", "lisi");System.out.println(cluster.hget("hash1", "userName"));Map<String, String> map = new HashMap<>();map.put("telephone", "138xxxxxxxx");map.put("address", "fatigue");map.put("email", "sxxxx@qq.com");//cluster.hmset("hash2", map);List<String> result = cluster.hmget("hash2", "telphone", "email");for (String element : result) {System.out.println(element);}//zSetcluster.zadd("zSet01", 60d, "v1");cluster.zadd("zSet01", 70d, "v2");cluster.zadd("zSet01", 80d, "v3");cluster.zadd("zSet01", 90d, "v4");List<String> zSet01 = cluster.zrange("zSet01", 0, -1);zSet01.forEach(System.out::println);cluster.close();}
}

4、测试用例 

4.1、单机测试结果

 直接main方法启动,

redis客户端:


4.2、redis集群测试结果

控制台输入:

redis客户端:


(二)、集成Lettuce

1、导入依赖

        <!--lettuce--><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.5.4.RELEASE</version></dependency>

 *注意:如果你的Springboot版本为3.4.3,那么导入这个依赖后,可能需要清除IDEA缓存,不然一直无法new RedisURI类。刷新过maven也没用,只有清除缓存重启后才成功,就很奇怪( ╯□╰ )。


2、编写方法

2.1、连接Redis单机
public class LettuceDemoTest {public static void main(String[] args) {// 构建 RedisURI 对象RedisURI uri = RedisURI.builder(RedisURI.create("redis://192.168.112.129")).withPort(6379).withAuthentication("default", "root").withDatabase(0).build();// 创建连接客户端RedisClient client = RedisClient.create(uri);StatefulRedisConnection<String, String> conn = client.connect();// 操作命令apiRedisCommands<String, String> commands = conn.sync();// 清空Jedis设置的keycommands.flushdb();//keysList<String> list = commands.keys("*");for (String s : list) {System.out.println(s);}//Stringcommands.set("k1", "hello Lettuce");String s1 = commands.get("k1");System.out.println("String s ===" + s1);//listcommands.lpush("myList2", "v1", "v2", "v3");List<String> list2 = commands.lrange("myList2", 0, -1);for (String s : list2) {System.out.println("list ssss===" + s);}//setcommands.sadd("mySet2", "v1", "v2", "v3");Set<String> set = commands.smembers("mySet2");for (String s : set) {System.out.println("set ssss===" + s);}//hashMap<String, String> map = new HashMap<>();map.put("k1", "138xxxxxxxx");map.put("k2", "fatigue");map.put("k3", "zzyybs@126.com");//课后有问题请给我发邮件commands.hmset("myHash2", map);Map<String, String> retMap = commands.hgetall("myHash2");for (String k : retMap.keySet()) {System.out.println("hash  k=" + k + " , v==" + retMap.get(k));}//zSetcommands.zadd("myzSet2", 100.0, "s1", 110.0, "s2", 90.0, "s3");List<String> list3 = commands.zrange("myzSet2", 0, 10);for (String s : list3) {System.out.println("zSet ssss===" + s);}//sortSortArgs sortArgs = new SortArgs();sortArgs.alpha();sortArgs.desc();List<String> list4 = commands.sort("myList2", sortArgs);for (String s : list4) {System.out.println("sort ssss===" + s);}//关闭conn.close();client.shutdown();}
}

2.2、连接Redis集群
public class LettuceColonyDemoTest {public static void main(String[] args) {HashSet<RedisURI> uris = new HashSet<>();uris.add(RedisURI.builder().withHost("192.168.112.129").withPort(6379).withAuthentication("default", "root").build());uris.add(RedisURI.builder().withHost("192.168.112.130").withPort(6381).withAuthentication("default", "root").build());uris.add(RedisURI.builder().withHost("192.168.112.129").withPort(6380).withAuthentication("default", "root").build());RedisClusterClient client = RedisClusterClient.create(uris);StatefulRedisClusterConnection<String, String> con = client.connect();RedisAdvancedClusterCommands<String, String> clusterCommands = con.sync();// 清除单机Redis设置的key// Lettuce连接Redis集群模式下,能使用flushAll命令// 因为Lettuce内部实现了智能的路由机制,能够自动将 KEYS 命令分发到集群中的各个节点,并将结果聚合返回clusterCommands.flushallAsync();//keysList<String> list = clusterCommands.keys("*");for (String s : list) {System.out.println(s);}//StringclusterCommands.set("k1", "hello Lettuce");String s1 = clusterCommands.get("k1");System.out.println("redis集群===" + s1);//listclusterCommands.lpush("myList2", "v1", "v2", "v3");List<String> list2 = clusterCommands.lrange("myList2", 0, -1);for (String s : list2) {System.out.println("list ssss===" + s);}//setclusterCommands.sadd("mySet2", "v1", "v2", "v3");Set<String> set = clusterCommands.smembers("mySet2");for (String s : set) {System.out.println("set ssss===" + s);}//hashMap<String, String> map = new HashMap<>();map.put("k1", "138xxxxxxxx");map.put("k2", "fatigue");map.put("k3", "zzyybs@126.com");//课后有问题请给我发邮件clusterCommands.hmset("myHash2", map);Map<String, String> retMap = clusterCommands.hgetall("myHash2");for (String k : retMap.keySet()) {System.out.println("hash  k=" + k + " , v==" + retMap.get(k));}//zSetclusterCommands.zadd("myzSet2", 100.0, "s1", 110.0, "s2", 90.0, "s3");List<String> list3 = clusterCommands.zrange("myzSet2", 0, 10);for (String s : list3) {System.out.println("zSet ssss===" + s);}//sortSortArgs sortArgs = new SortArgs();sortArgs.alpha();sortArgs.desc();List<String> list4 = clusterCommands.sort("myList2", sortArgs);for (String s : list4) {System.out.println("sort ssss===" + s);}//关闭con.close();client.shutdown();client.close();}
}

3、测试用例

3.1、单机测试结果

 控制台输出:

redis客户端:


3.2、redis集群测试结果

控制台输出:

redis客户端:


(三)、集成RedisTemplate

1、新建配置文件

新建application.properties文件:

server.port=8080
spring.application.name=RedisDemo
# ========================logging=====================
logging.level.root=info
logging.level.xxx.xx.xxx=info
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%nlogging.file.name=D:/myLogs/RedisDemo.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n# ========================redis单机=====================
spring.data.redis.database=0
#修改为自己的真实IP
spring.data.redis.host=xxx.xxx.xxx.xxx
spring.data.redis.port=6379
spring.data.redis.password=xxxx
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1ms
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0

2、导入依赖

        <!--SpringBoot通用依赖模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--SpringBoot与Redis整合依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!--日志--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.24.3</version></dependency><!-- swagger3生成接口文档依赖--><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency>

3、编写业务类

3.1、新建controller
@RestController
@Tag(name = "订单管理", description = "订单的创建和查询操作")
public class OrderController {@Resourceprivate OrderService orderService;/*** redis单机*/@RequestMapping(value = "/order/add", method = RequestMethod.POST)public void addOrder() {orderService.addOrder();}@RequestMapping(value = "/order/{id}", method = RequestMethod.GET)public String findUserById(@PathVariable Integer id) {return orderService.getOrderById(id);}/*** redis集群*/@RequestMapping(value = "/cluster/order/add", method = RequestMethod.POST)public void clusterAddOrder() {orderService.clusterAddOrder();}@RequestMapping(value = "cluster/order/{id}", method = RequestMethod.GET)public String clusterFindUserById(@PathVariable Integer id) {return orderService.clusterFindUserById(id);}
}

3.2、新建service

*注意:只编写String类型的数据操作,其他类型的API操作,私底下练习

@Service
@Slf4j
public class OrderService {public static final String ORDER_KEY = "order:";@Resourceprivate RedisTemplate<String, String> redisTemplate;public void addOrder() {int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;String orderNo = UUID.randomUUID().toString();redisTemplate.opsForValue().set(ORDER_KEY + keyId, "订单编号" + orderNo);log.info("redis单机=====>编号{}的订单流水生成:{}", keyId, orderNo);}public String getOrderById(Integer id) {System.out.println(redisTemplate.opsForList().range("myList", 0, -1));HashMap<String, String> map = new HashMap<>();map.put("k1", "k2");map.put("k3", "k4");map.put("k5", "k6");redisTemplate.opsForValue().multiSet(map);return redisTemplate.opsForValue().get(ORDER_KEY + id);}public void clusterAddOrder() {int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;String orderNo = UUID.randomUUID().toString();redisTemplate.opsForValue().set(ORDER_KEY + keyId, "订单编号" + orderNo);log.info("redis集群=====>编号{}的订单流水生成:{}", keyId, orderNo);}public String clusterFindUserById(Integer id) {return redisTemplate.opsForValue().get(ORDER_KEY + id);}
}

3.3、新建config

这个配置主要是生成接口文档。

@Configuration
public class OpenAPIConfig {@Beanpublic OpenAPI customOpenAPI() {String currentDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now());return new OpenAPI().info(new Info().title("springBoot利用swagger3构建api接口文档 " + "\t" + currentDate).description("springboot+redis整合").version("1.0").termsOfService("https://www.baidu.com/"));}
}

3.4、连接redis单机


3.5、连接redis集群


4、测试接口

启动项目,访问http://localhost:8080/swagger-ui/index.html

4.1、单机测试结果

控制台输出:

redis客户端:

Q:数据是存进去了,但是为啥是乱码的?在连接redis客户端的时候加上了--raw的参数还是乱码?为啥通过接口获取的数据是正常的,但是通过redis客户端去查看的又是乱码?

A:是因为序列化方式不一致造成。键(key)和值(value)都是通过spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer。解决办法就是统一序列化方式。

新建RedisConfig类:

@Configuration
public class RedisConfig {/***设置存储key的序列化方式* @param redisConnectionFactory 创建与Redis连接的工厂类*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);//设置StringredisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new StringRedisSerializer());// 设置hash、set、zSet、list.....redisTemplate.afterPropertiesSet();return redisTemplate;}
}

重启项目,重新测试:

问题解决。


4.2、redis集群测试结果

修改application.properties文件,注释redis单机配置:

重启项目,进行测试:

redis客户端:

初步看来,连接redis集群没毛病。


Q:假设集群中,有主机服务宕机了,从机上位后,程序是否还能正常从redis集群获取与写入数据呢?

A:读能正常但是写不正常

手动关闭6379,模拟测试一下。

是需要手动开启刷新节点拓扑网落的,

#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
spring.data.redis.lettuce.cluster.refresh.adaptive=true
#定时刷新 毫秒
spring.data.redis.lettuce.cluster.refresh.period=2000

不然,当某个Master主机宕机后,虽然从机上位了,但还是不可用的(针对于这个key刚好落在宕机的Master上)。


(四)、集成Redisson

1、导入依赖

        <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.45.0</version></dependency>

2、编写业务类

2.1、新建controller
@RestController
@Tag(name = "Redisson订单管理", description = "订单的创建和查询操作")
public class RedissonOrderController {@Resourceprivate RedissonOrderService redissonOrderService;/*** redisson连接redis单机*/@RequestMapping(value = "/redisson/order/add", method = RequestMethod.POST)public void redissonAddOrder() {redissonOrderService.redissonAddOrder();}@RequestMapping(value = "/redisson/order/{id}", method = RequestMethod.GET)public String redissonFindUserById(@PathVariable Integer id) {return redissonOrderService.redissonFindUserById(id);}/*** redisson连接redis集群*/@RequestMapping(value = "/redisson/cluster/order/add", method = RequestMethod.POST)public void redissonClusterAddOrder() {redissonOrderService.redissonClusterAddOrder();}@RequestMapping(value = "/redisson/cluster/order/{id}", method = RequestMethod.GET)public String redissonClusterFindUserById(@PathVariable Integer id) {return redissonOrderService.redissonClusterFindUserById(id);}}

2.2、新建service

*注意:只编写String类型的数据操作,其他类型的API操作,私底下练习。

@Service
@Slf4j
public class RedissonOrderService {public static final String ORDER_KEY = "order:";private final RedissonClient redissonSingleClient;private final RedissonClient redissonColonyClient;@Autowiredpublic RedissonOrderService(@Qualifier("redissonColonyClient") RedissonClient redissonColonyClient,@Qualifier("redissonSingleClient") RedissonClient redissonSingleClient) {this.redissonColonyClient = redissonColonyClient;this.redissonSingleClient = redissonSingleClient;}public void redissonAddOrder() {int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;String orderNo = UUID.randomUUID().toString();redissonSingleClient.getBucket(ORDER_KEY + keyId).set("订单编号" + orderNo);log.info("redisson连接redis单机=====>编号{}的订单流水生成:{}", keyId, orderNo);}public String redissonFindUserById(Integer id) {RBucket<Object> bucket = redissonSingleClient.getBucket(ORDER_KEY + id);return (String) bucket.get();}public void redissonClusterAddOrder() {int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;String orderNo = UUID.randomUUID().toString();redissonColonyClient.getBucket(ORDER_KEY + keyId).set("订单编号" + orderNo);log.info("redisson连接redis集群=====>编号{}的订单流水生成:{}", keyId, orderNo);}public String redissonClusterFindUserById(Integer id) {RBucket<Object> bucket = redissonColonyClient.getBucket(ORDER_KEY + id);return (String) bucket.get();}
}

2.3、新建config
@Configuration
public class RedissonConfig {/*** redisson连接redis单机*/@Bean(name = "redissonSingleClient")@Primarypublic RedissonClient redissonSingleClient() {Config config = new Config();// 单机模式config.useSingleServer().setAddress("redis://192.168.112.131:6381").setPassword("root");// 设置 JSON 序列化编解码器config.setCodec(new JsonJacksonCodec(new ObjectMapper()));return Redisson.create(config);}/*** redisson连接redis集群*/@Bean(name = "redissonColonyClient")public RedissonClient redissonColonyClient() {Config config = new Config();// 设置JSON序列化编解码器config.setCodec(new JsonJacksonCodec(new ObjectMapper()));// 集群模式config.useClusterServers().addNodeAddress("redis://192.168.112.129:6379","redis://192.168.112.129:6380","redis://192.168.112.130:6381","redis://192.168.112.130:6382","redis://192.168.112.131:6383","redis://192.168.112.131:6384").setScanInterval(2000)// 集群状态扫描间隔时间,单位是毫秒.setPassword("root");return Redisson.create(config);}
}

2.4、连接redis单机


2.5、连接redis集群


3、测试接口

3.1、单机测试结果

控制台输出:

redis客户端:


3.2、redis集群测试结果

控制台输出:

redis客户端:


三、总结

在Java开发中,与 Redis 进行高效整合是提升系统性能和可扩展性的关键环节。本文为你详细介绍四种主流的Java整合Redis的方式,涵盖底层客户端库Jedis和Lettuce,以及上层框架封装RedisTemplate和Redisson。

Jedis以其简单易懂的使用方式脱颖而出,对于刚刚接触 Redis 集成的初学者而言,它就像一位耐心的导师,引导着开发者逐步熟悉 Redis的操作。同时,由于其在单线程环境下表现稳定,成为单线程应用场景的理想选择。

Lettuce则凭借卓越的性能在高并发领域独树一帜。它基于 Netty 实现,具备出色的异步处理能力和线程安全性,能够在高并发的浪潮中稳健前行,为高并发场景提供强大的支持。

RedisTemplate与Spring框架深度融合,仿佛是为Spring项目量身定制的利器。在 Spring 项目中,使用RedisTemplate可以轻松地与其他Spring组件协同工作,极大地提高了开发效率,让开发者能够更加专注于业务逻辑的实现。

Redisson作为一个独立的框架,不依赖于任何特定的框架,它专注于分布式系统的开发,提供了丰富的分布式数据结构和服务,如分布式锁、分布式集合等,为分布式系统的搭建提供了全方位的解决方案。

在实际的项目开发中,我们应根据项目的具体需求和应用场景,审慎地选择合适的整合方式。希望本文能够帮助你更好地掌握 Java与Redis的集成技术,为项目注入强大的性能和可扩展性动力。


ps:努力到底,让持续学习成为贯穿一生的坚守。学习笔记持续更新中。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yolov12 部署瑞芯微 rk3588、RKNN 部署工程难度小、模型推理速度快

yolov12 部署又来了。 特别说明&#xff1a;如有侵权告知删除&#xff0c;谢谢。 完整代码&#xff1a;包括onnx转rknn和测试代码、rknn板端部署C代码&#xff1a; 【onnx转rknn和测试代码】 【rknn板端部署C代码】 1 模型训练 yolov12训练官方开源的已经非常详细了&#…

windows本地化部署Dify+Deepseek

Windows本地化部署DifyDeepseek 一、下载Docker 前往 Docker 官网 下载 Docker Desktop&#xff0c;按序安装。 1.1启用WSL 打开本机的控制面板>程序>启用或关闭 Windows 功能,勾选: Linux 的 Windows 子系统虚拟机平台&#xff08;若无该选择则勾选 Hyper-V &#…

第二十四:5.2【搭建 pinia 环境】axios 异步调用数据

第一步安装&#xff1a;npm install pinia 第二步&#xff1a;操作src/main.ts 改变里面的值的信息&#xff1a; <div class"count"><h2>当前求和为&#xff1a;{{ sum }}</h2><select v-model.number"n">  // .number 这里是…

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流

在现代工作与学习中&#xff0c;可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本&#xff0c;结合 Typora 快速生成流程图和甘特图&#xff0c;并通过 Markdown 格式生成思维导图&#xff0c;最终…

【数据集】ACM数据集

ACM&#xff08;Association for Computing Machinery&#xff09;数据集是计算机科学领域常用于研究学术论文、作者关系、引文网络、推荐系统、图神经网络&#xff08;GNN&#xff09;等任务的数据集之一。该数据集通常包含学术论文、作者、研究领域以及它们之间的关系&#x…

SQL server配置ODBC数据源(本地和服务器)

本地配置 1. 控制面板中找到系统ODBC数据源&#xff08;打开控制面板直接搜&#xff09; 2. 选择“系统DSN”&#xff0c;点击“添加” 3. 选择“SQL server” 4. 名称和描述自己填&#xff0c;服务器选择本机设备名称 5. 选择ID和密码验证&#xff0c;并填写本地SQL server登…

使用 Postman 访问 Keycloak 端点

1. 引言 在本教程中&#xff0c;我们将首先快速回顾 OAuth 2.0、OpenID 和 Keycloak。然后&#xff0c;我们将了解 Keycloak REST API 以及如何在 Postman 中调用它们。 2. OAuth 2.0 OAuth 2.0 是一个授权框架&#xff0c;它允许经过身份验证的用户通过令牌向第三方授予访问…

微服务学习(2):实现SpringAMQP对RabbitMQ的消息收发

目录 SpringAMQP是什么 为什么采用SpringAMQP SpringAMQP应用 准备springBoot工程 实现消息发送 SpringAMQP是什么 Spring AMQP是Spring框架下用于简化AMQP&#xff08;高级消息队列协议&#xff09;应用开发的一套工具集&#xff0c;主要针对RabbitMQ等消息中间件的集成…

WPF高级 | WPF 与数据库交互:连接、查询与数据更新

WPF高级 | WPF 与数据库交互&#xff1a;连接、查询与数据更新 前言一、数据库交互基础概念1.1 数据库简介1.2 数据访问技术 二、WPF 与数据库连接2.1 连接字符串2.2 建立连接 三、WPF 中的数据查询3.1 使用ADO.NET进行数据查询3.2 使用 Entity Framework 进行数据查询3.3 使用…

【ESP32S3接入讯飞在线语音识别】

【ESP32S3接入讯飞在线语音识别】 1. 前言1.1 步骤概括1.2 硬件介绍1.3 接线2. 操作流程2.1 创建语音识别应用2.2 记录API秘钥3. JSON语音接入api3.1 JSON格式3.2 交互流程3.2 ESP32S3 Sense接入代码1. 核心功能2. 主要模块3. 工作流程4. 典型应用场景5. 关键技术点6. 待完善功…

学生管理前端

文章目录 首页student.html查询功能 首页 SpringBoot前端html页面放在static文件夹下&#xff1a;/src/main/resources/static 默认首页为index.html&#xff0c;我们可以用两个超链接或者两个button跳转到对应的页面。这里只是单纯的跳转页面&#xff0c;不需要提交表单等其…

(动态规划 最长递增的子序列)leetcode 300

这道题我第一眼反应就是暴力&#xff0c;但是暴力的话就是n*n-1*n-2*...n-(n-1) 也就是O(n^n)dfs做绝对超时 贪心也不行&#xff0c;这里是子序列&#xff0c;要考虑在ni的范围内考虑多种路线取最优&#xff0c;所以用动态规划 如何用动态规划呢&#xff1f; 答&#xff1a;…

Ubuntu 安装 Nginx并配置反向代理

Ubuntu版本&#xff1a;Ubuntu 24.04.2 LTS 一、安装Nginx ​更新系统软件包​ 安装前需确保系统处于最新状态&#xff0c;避免依赖冲突 sudo apt update && sudo apt upgrade -y ​安装Nginx主程序​ Ubuntu官方仓库已包含稳定版Nginx&#xff0c;直接安装即可 sudo…

Solr中得Core和Collection的作用和关系

Solr中得Core和Collection的作用和关系 一&#xff0c; 总结 在Apache Solr中&#xff0c;Core和Collection 是两个核心概念&#xff0c;他们分别用于单机模式和分布式模式&#xff08;SolrCloud&#xff09;中&#xff0c;用于管理和组织数据。 二&#xff0c;Core 定义&am…

yolov8,yolo11,yolo12 服务器训练到部署全流程 笔记

正在进行中&#xff0c;随时更新 一. Anaconda配置 1.安装anaconda (1)下载.sh文件 Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror (2)scp到服务器后&#xff0c;运行安装包 bash Anaconda3-2020.07-Linux-x86_64.sh (3)安装anacond…

从零开始开发纯血鸿蒙应用之语音朗读

从零开始开发纯血鸿蒙应用 〇、前言一、API 选型1、基本情况2、认识TextToSpeechEngine 二、功能集成实践1、改造右上角菜单2、实现语音播报功能2.1、语音引擎的获取和关闭2.2、设置待播报文本2.3、speak 目标文本2.4、设置语音回调 三、总结 〇、前言 中华汉字洋洋洒洒何其多…

25年前端如何走的更稳

2025年&#xff0c;随着deepseek引起的AI大模型技术的深度革命&#xff0c;带来了很多机会和挑战&#xff0c;前端程序员作为互联网里一个普通但必不可少的岗位&#xff0c;在当前形势下&#xff0c;需要主动变革才能走的更稳。本文简单介绍三个方向&#xff0c;Web3前端、全栈…

市场加速下跌,但监管「坚冰」正在消融

作者&#xff1a;Techub 热点速递 撰文&#xff1a;Yangz&#xff0c;Techub News 与近日气温逐步回暖不同&#xff0c;自 2 月 25 日比特币跌破 9 万美元以来&#xff0c;加密货币市场行情一路下滑。今日 10 时 50 分左右&#xff0c;比特币更是跌破 8 万美元大关&#xff0c…

【Android】安卓付款密码输入框、支付密码输入框

如图 代码部分&#xff1a; public class PayPasswordDialog extends AppCompatDialogFragment {private String mPayPass "";private String mTitle, mMoney;private final TextView[] mPayPassTextViewArray new TextView[6];private List<Integer> mPayP…

Java数据结构_一篇文章了解常用排序_8.1

本文所有排序举例均默认为升序排列。 目录 1. 常见的排序算法 2. 常见排序算法的实现 2.1 插入排序 2.1.1 基本思想&#xff1a; 2.1.2 直接插入排序 2.1.3 希尔排序&#xff08;缩小增量排序&#xff09; 2.2 选择排序 2.2.1 基本思想&#xff1a; 2.2.2 直接选择排…