当前位置: 首页 > news >正文

一品威客网套路seo搜索引擎优化排名

一品威客网套路,seo搜索引擎优化排名,衢州市住房和城乡建设局网站,wordpress幼儿园汉化主题目录前言一、食用步骤1.1 安装步骤1.1.1 客户端安装1.2 添加依赖1.3 修改配置1.4 项目使用1.5 序列化二、应用场景2.1 缓存2.2.分布式锁2.2.1 redis实现2.2.2 使用Redisson 作为分布式锁2.3 全局ID、计数器、限流2.4 购物车2.5 消息队列 (List)2.6 点赞、签到、打卡 (Set)2.7 筛…

目录

  • 前言
  • 一、食用步骤
    • 1.1 安装步骤
      • 1.1.1 客户端安装
      • 1.2 添加依赖
      • 1.3 修改配置
      • 1.4 项目使用
      • 1.5 序列化
  • 二、应用场景
    • 2.1 缓存
    • 2.2.分布式锁
      • 2.2.1 redis实现
      • 2.2.2 使用Redisson 作为分布式锁
    • 2.3 全局ID、计数器、限流
    • 2.4 购物车
    • 2.5 消息队列 (List)
    • 2.6 点赞、签到、打卡 (Set)
    • 2.7 筛选(Set)
    • 2.8 排行榜


前言

在日常的Java开发中,Redis是使用频次非常高的一个nosql数据库,数据以key-value键值对的形式存储在内存中,可以做缓存,分布式锁等。

spring-data-redis属于spring-data,提供给spring项目对于redis的操作,里边主要封装了jedis和lettuce两个客户端。


一、食用步骤

1.1 安装步骤

1.1.1 客户端安装

https://redis.io/docs/getting-started/installation/

1.2 添加依赖

<!-- redis依赖  -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

默认使用lettuce客户端
在这里插入图片描述

1.3 修改配置

spring:redis:host: localhostport: 6379password: database: 0

redis客户端配置连接池

<!-- redis依赖commons-pool 这个依赖一定要添加 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

1.4 项目使用

通过spring-data-redis中为我们提供的 RedisTemplate 这个类操作redis服务器

@RestController
public class RedisController {@Autowiredprivate RedisTemplate redisTemplate;@GetMapping("save")public void save(String key, String value){redisTemplate.opsForValue().set(key, value);}
}

1.5 序列化

运行后,发现redis里的值不直观,不利于排查问题
在这里插入图片描述
原因是RedisTemplate默认的序列化方式导致的,需要重新配置序列化方式

经常使用的对象序列化方式是: Jackson2JsonRedisSerializer

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Bean(name = "redisTemplate")public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();redisTemplate.setConnectionFactory(factory);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key的序列化类型redisTemplate.setKeySerializer(stringRedisSerializer); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);// value的序列化类型redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer);redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}

在这里插入图片描述

二、应用场景

2.1 缓存

  1. String字符串类型: 动态变长字符串
  2. List列表类型:类似LinkedList前后插入和删除速度快
  3. Hash:类似Hashmap数组+链表的数据结构
  4. Set集合类型:类似HashSet,键值是无序唯一
  5. Zset有序集合:Set和Map的结合体,既能保证key唯一、又能根据value做排序

2.2.分布式锁

2.2.1 redis实现

在分布式环境下我们需要保证某一方法同一时刻只能被一个线程执行,或者多个服务的定时任务只能执行一次。

原理:SETNX

redis> SETNX mykey "Hello"
(integer) 1
redis> SETNX mykey "World"
(integer) 0
redis> GET mykey
"Hello"

NX :表示key不存在的时候,才能set成功,也即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁,才能获取。

分布式锁具备的特征

  1. 互斥:任意时刻只能有一个客户端持有锁
  2. 锁超时释放:锁超时要释放,防止资源浪费和死锁
  3. 可重入性:一个线程如果获取了锁之后,可以再次对其请求加锁。(锁续期)
  4. 高性能和高可用:加锁和解锁需要开销尽可能低,同时也要保证高可用,避免分布式锁失效。
  5. 安全性:锁只能被持有的客户端删除,不能被其他客户端删除

场景伪代码:

//获取锁
ifSETNX key "lock" == 1{ //设置过期时间expire(key,100);try {业务;}catch(){}finally {//释放锁del(key);}
}

以上代码,有以下问题:

  1. setnx和expire不是原子操作,会导致key永久存在
  2. 当线程a锁过期释放了,业务还没执行完,b抢到锁执行方法,此时线程a方法执行完后,把b抢到的锁给释放了…达不到锁的标准

代码如下(示例):

public String testLock() {//uuid保证只能释放当前线程的锁String uuid = UUID.randomUUID().toString();//推荐使用setIfAbsent这样redis在set的时候是单线程的,原子的,不会存在短时间重复set的问题。Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);if (Boolean.TRUE.equals(lock)) {System.out.println("获取分布式锁成功...");try {System.out.println("加锁成功...执行业务");} finally {// lua 脚本解锁String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";// 删除redis.call('get', "lock") 的值和uuid相等的锁,成功返回1 失败返回 0redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList("lock"), uuid);}return "执行完成";} return "获取分布式锁失败";}

2.2.2 使用Redisson 作为分布式锁

官方文档:https://github.com/redisson/redisson/wiki

引入依赖

 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.11.1</version>
</dependency>

配置redission

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyRedissonConfig {//所有对 Redisson 的使用都是通过 RedissonClient@Bean(destroyMethod = "shutdown")public RedissonClient redisson() {// 1、创建配置Config config = new Config();// 路径要加上 redis:// 或者 rediss:// //单节点模式config.useSingleServer().setAddress("redis://192.168.3.25:6379");// 2、根据 Config 创建出 RedissonClient 实例return Redisson.create(config);}
}

使用

@Autowired
RedissonClient redisson;public List<User> getUser() {// 1. 获取一把锁RLock lock = redisson.getLock("lock");// 2. 加锁, 阻塞式等待 默认30s 会自动续期// 指定过期时间就不会自动续期lock.lock();try {Thread.sleep(10000);System.out.println("加锁成功,执行业务...");} catch (Exception e) {System.out.println("报错啦...");} finally {// 3. 解锁 假设解锁代码没有运行,Redisson也不会出现死锁lock.unlock();}return userServiceImpl.queryAll();
}

特点

  1. redission继承了juc的锁
  2. 调用lock方法后,会调用renewExpiration() 开启后台线程『看门狗』,30 / 3 = 10s后自动续期到30s。
  3. 锁的自动续期,如果业务耗时长,运行期间自动给锁续期 ,所以不用担心业务时间过长,锁自动过期被删掉;
//读写锁 锁粒度细,运行越快
RReadWriteLock readWriteLock = redisson.getReadWriteLock("lock");
//读锁 非阻塞
RLock rLock = readWriteLock.readLock();
rLock.lock();
rLock.unlock();
//写锁 阻塞,数据被写锁占有,读锁会被阻塞
RLock wLock = readWriteLock.writeLock();
wLock.lock();
wLock.unlock();

2.3 全局ID、计数器、限流

利用incrby的原子性

  • 计数器:阅读量、点赞数
  • 限流:访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false
Long incr = redisTemplate.opsForValue().increment("incrlock");

2.4 购物车

public void testStringCart() {//添加购物车 +1Car.CartItem cartItem = new Car.CartItem(1L, "iphone13 256G 蓝色",new BigDecimal(100), 1);Car carSave = new Car(Collections.singletonList(cartItem));redisTemplate.opsForValue().set("user_001", JSONObject.toJSONString(carSave));//删除 -1 skuId = 1Car car = JSON.parseObject((String) redisTemplate.opsForValue().get("user_001"), Car.class);//记得判空car.getItems().forEach(i -> {if(Objects.equals(i.getSkuId(), 1L)){i.setCount(i.getCount() - 1);}} );//删除后保存新的购物车redisTemplate.opsForValue().set("user_001", JSONObject.toJSONString(car));
}

2.5 消息队列 (List)

//左推
redisTemplate.opsForList().leftPushAll("list", "西瓜1","西瓜2","西瓜3");
//右取 西瓜1 =》 "西瓜2" =》 "西瓜3" 
redisTemplate.opsForList().rightPop("list");

2.6 点赞、签到、打卡 (Set)

//user_001给新闻01点赞
redisTemplate.opsForSet().add("like:news01","user_001");
redisTemplate.opsForSet().add("like:news01","user_001");
redisTemplate.opsForSet().add("like:news01","user_002");
//set大小为2
redisTemplate.opsForSet().size("like:news01");
//点赞的所有用户 [user_002, user_001]
redisTemplate.opsForSet().members("like:news01");

2.7 筛选(Set)

  • (用户关注)我关注的人也关注了他
  • 可能认识的人
  • 商品筛选
//user1给新闻点赞
redisTemplate.opsForSet().add("like:news01","user_001");
redisTemplate.opsForSet().add("like:news01","user_002");
redisTemplate.opsForSet().add("like:news02","user_001");
redisTemplate.opsForSet().add("like:news02","user_003");
//获取新闻点赞的用户差集 => [user_002]
System.out.println(redisTemplate.opsForSet().difference("like:news01", "like:news02"));
//获取新闻点赞的用户交集 => [user_001]
System.out.println(redisTemplate.opsForSet().intersect("like:news01", "like:news02"));
//获取新闻点赞的用户并集 => [user_002, user_001, user_003]
System.out.println(redisTemplate.opsForSet().union("like:news01", "like:news02"));

2.8 排行榜

点击率排行榜

示例

public void testZset() {//用户点击新闻自增1Double news_01 = redisTemplate.opsForZSet().incrementScore("hot:20230222", "news_01", 1);//初始化ZSetredisTemplate.opsForZSet().add("hot:20230222","news_01", 700);redisTemplate.opsForZSet().add("hot:20230222","news_02", 1700);redisTemplate.opsForZSet().add("hot:20230222","news_03", 3700);redisTemplate.opsForZSet().add("hot:20230222","news_04", 500);//获取新闻点击最多的3条//[DefaultTypedTuple [score=3700.0, value=news_03],// DefaultTypedTuple [score=1700.0, value=news_02], // DefaultTypedTuple [score=700.0, value=news_01]]//reverseRangeWithScores 分数倒序从下标0取到2 System.out.println(redisTemplate.opsForZSet().reverseRangeWithScores("hot:20230222", 0,2));
}
http://www.hkea.cn/news/798384/

相关文章:

  • 百度爱采购推广平台天津网络推广seo
  • 福州市闽侯县建设局网站推广引流吸引人的文案
  • wordpress目录 读写权限泰安短视频seo
  • 东莞建设网站流程澎湃新闻
  • 萧县住房和城乡建设局网站seo排名推广工具
  • 企业网站php模板下载百度百科官网首页
  • 做愛視頻网站在线网页制作网站
  • 织梦pc怎么做手机网站搜索引擎优化的基础是什么
  • 课程建设网站设计源码爱站网反链查询
  • 安徽省建设业协会网站个人网页制作教程
  • 好的摄影网站推荐福州seo顾问
  • html做的好看的网站如何宣传推广产品
  • 微信手机网站制作怎么引流客源最好的方法
  • 宿州建设网站公司前端seo搜索引擎优化
  • 做王境泽表情的网站百度seo关键词优化排名
  • 怎么选择无锡网站建设虚拟主机搭建网站
  • 做原油期货关注什么网站搜索引擎优化是做什么
  • 微信小程序怎么制作游戏安卓优化清理大师
  • 胶南做网站初学者做电商怎么入手
  • 网站为什么要维护佛山网络营销推广
  • 国企网站建设报告怎么建造自己的网站
  • 免费做司考真题的网站余姚网站如何进行优化
  • 如何网站开发1688网站
  • 丽水专业网站建设价格青岛网站优化
  • 网站开发专业培训学校百度推广登录官网入口
  • 贵阳做网站公司网站热度查询
  • 做课件最好的素材网站考拉seo
  • 网站建设玖首选金手指seo网站优化收藏
  • 台州卓远做网站好不好广州seo教程
  • dz网站数据备份bt磁力猪