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

如何接推广的单子北京网站优化方法

如何接推广的单子,北京网站优化方法,wordpress 前端登陆,中英文网站前端怎么做引言 在现代分布式系统中,Redis 作为高性能的键值存储系统,广泛应用于缓存、消息队列、实时计数器等多种场景。然而,在高并发和分布式环境下,如何有效地管理和控制资源访问成为一个关键问题。Redis 分布式锁正是为了解决这一问题…
引言

在现代分布式系统中,Redis 作为高性能的键值存储系统,广泛应用于缓存、消息队列、实时计数器等多种场景。然而,在高并发和分布式环境下,如何有效地管理和控制资源访问成为一个关键问题。Redis 分布式锁正是为了解决这一问题而诞生的技术。

本文将从 Redis 的数据结构应用入手,结合 Redisson 分布式锁的实现,深入探讨如何解决常见的缓存问题(如穿透、击穿、雪崩),并提供详尽的代码示例和注释。

一、Redis 数据结构应用

Redis 提供了多种数据结构,每种数据结构都有其特定的应用场景。以下是几种常见数据结构及其典型应用场景:

1. String(字符串)
  • 应用场景:适用于简单的键值存储,如用户会话、计数器等。
  • 示例代码
import org.springframework.data.redis.core.StringRedisTemplate; 
import org.springframework.stereotype.Service; @Service 
public class CounterService {@Autowired private StringRedisTemplate stringRedisTemplate;public void incrementCounter(String key) {stringRedisTemplate.opsForValue().increment(key,  1);}public Long getCounter(String key) {return stringRedisTemplate.opsForValue().get(key); }
}

 

  • increment(key, 1):原子递增计数器。
  • get(key):获取计数器的值。
2. List(列表)
  • 应用场景:适用于队列或栈结构,如消息队列、任务队列等。
  • 示例代码
import org.springframework.data.redis.core.ListOperations; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.stereotype.Service; @Service 
public class QueueService {@Autowired private RedisTemplate<String, String> redisTemplate;public void addToQueue(String queueName, String message) {ListOperations<String, String> listOps = redisTemplate.opsForList(); listOps.rightPush(queueName,  message);}public String removeFromQueue(String queueName) {ListOperations<String, String> listOps = redisTemplate.opsForList(); return listOps.leftPop(queueName); }
}

 

  • rightPush(queueName, message):将消息添加到队列尾部。
  • leftPop(queueName):从队列头部取出消息。
3. Hash(哈希)
  • 应用场景:适用于存储对象或映射表,如用户信息、商品详情等。
  • 示例代码
import org.springframework.data.redis.core.HashOperations; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.stereotype.Service; @Service 
public class UserService {@Autowired private RedisTemplate<String, Object> redisTemplate;public void saveUser(String userId, Map<String, Object> userMap) {HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash(); hashOps.putAll(userId,  userMap);}public Map<String, Object> getUser(String userId) {HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash(); return hashOps.entries(userId); }
}

 

  • putAll(userId, userMap):将用户信息存储到哈希中。
  • entries(userId):获取用户的完整信息。
4. Set(集合)
  • 应用场景:适用于存储唯一元素的集合,如用户关注列表、标签分类等。
  • 示例代码
import org.springframework.data.redis.core.SetOperations; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.stereotype.Service; @Service 
public class TagService {@Autowired private RedisTemplate<String, String> redisTemplate;public void addTagToUser(String userId, String tag) {SetOperations<String, String> setOps = redisTemplate.opsForSet(); setOps.add(userId,  tag);}public Set<String> getAllTags(String userId) {SetOperations<String, String> setOps = redisTemplate.opsForSet(); return setOps.members(userId); }
}
  • add(userId, tag):向用户的标签集合中添加一个标签。
  • members(userId):获取用户的全部标签。
5. ZSet(有序集合)
  • 应用场景:适用于需要排序的场景,如排行榜、优先级队列等。
  • 示例代码
import org.springframework.data.redis.core.ZSetOperations; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.stereotype.Service; @Service 
public class RankingService {@Autowired private RedisTemplate<String, String> redisTemplate;public void addScore(String rankingKey, String user, double score) {ZSetOperations<String, String> zSetOps = redisTemplate.opsForZSet(); zSetOps.add(rankingKey,  user, score);}public Set<String> getTopUsers(String rankingKey, int limit) {ZSetOperations<String, String> zSetOps = redisTemplate.opsForZSet(); return zSetOps.reverseRange(rankingKey,  0, limit);}
}

 

 

  • add(rankingKey, user, score):向排行榜中添加用户及其分数。
  • reverseRange(rankingKey, 0, limit):获取排行榜前几名的用户。

二、Redisson 分布式锁

1. 什么是 Redisson?

Redisson 是一个 Redis 的 Java 客户端,提供了许多高级功能,包括分布式锁、分布式集合、分布式消息队列等。它简化了 Redis 的使用,并提供了丰富的功能。

2. 分布式锁的应用场景

在分布式系统中,多个服务实例可能同时访问共享资源(如数据库、文件等),这可能导致数据不一致或竞争条件。分布式锁可以确保在同一时间只有一个服务实例能够访问共享资源。

3. 使用 Redisson 实现分布式锁
步骤 1:添加依赖

pom.xml 中添加 Redisson 依赖:

<dependencies><dependency><groupId>org.redisson</groupId> <artifactId>redisson</artifactId><version>3.17.6</version></dependency>
</dependencies>

 

步骤 2:配置 Redisson

在配置类中配置 Redisson 客户端:

import org.redisson.Redisson; 
import org.redisson.config.Config; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; @Configuration 
public class RedissonConfig {@Bean public Redisson redisson() {Config config = new Config();config.useSingleServer() .setAddress("redis://localhost:6379");return Redisson.create(config); }
}

步骤 3:实现分布式锁

import org.redisson.api.RLock; 
import org.redisson.api.Redisson; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; @Service 
public class DistributedLockService {@Autowired private Redisson redisson;public void executeWithLock(String lockName) {RLock lock = redisson.getLock(lockName); try {boolean isLocked = lock.tryLock(10,  1000, TimeUnit.MILLISECONDS);if (isLocked) {// 执行临界区代码 System.out.println("Lock  acquired. Executing critical section...");Thread.sleep(2000);  // 模拟耗时操作 } else {System.out.println("Failed  to acquire lock.");}} catch (InterruptedException e) {Thread.currentThread().interrupt(); } finally {if (lock.isHeldByCurrentThread())  {lock.unlock(); }}}
}

 

 

  • tryLock(10, 1000, TimeUnit.MILLISECONDS):尝试获取锁,最长等待 10 秒,每次轮询间隔 1 秒。
  • unlock():释放锁。
步骤 4:测试分布式锁
@RunWith(SpringRunner.class) 
@SpringBootTest 
public class DistributedLockServiceTest {@Autowired private DistributedLockService distributedLockService;@Test public void testDistributedLock() throws InterruptedException {// 同时启动多个线程尝试获取锁 Runnable task = () -> distributedLockService.executeWithLock("my_lock"); Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start(); thread2.start(); thread1.join(); thread2.join(); }
}

 

运行后,控制台将显示只有其中一个线程成功获取锁并执行临界区代码。


三、缓存问题解决方案

在实际应用中,缓存可能会遇到以下问题:

1. 缓存穿透
  • 问题描述:查询一个不存在的数据,导致每次都去数据库查询。
  • 解决方案
    • 缓存空值:将不存在的数据也缓存起来。
    • 布隆过滤器:预先过滤不存在的数据。

示例代码(缓存空值)

import org.springframework.cache.annotation.Cacheable; 
import org.springframework.stereotype.Service; @Service 
public class UserService {@Cacheable(value = "users", key = "#id")public User getUserById(Long id) {User user = userRepository.findById(id).orElse(null); if (user == null) {// 缓存空值 return new User();}return user;}
}

 

2. 缓存击穿
  • 问题描述:高并发下同一个热点数据过期,导致大量请求同时访问数据库。
  • 解决方案
    • 互斥锁加延迟过期:在更新缓存时加锁,避免多个请求同时更新。
    • 永不过期:通过版本号或其他方式实现逻辑过期。
示例代码(互斥锁加延迟过期)
import org.redisson.api.RLock; 
import org.redisson.api.Redisson; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; @Service 
public class UserService {@Autowired private Redisson redisson;@Autowired private UserRepository userRepository;public User getUserById(Long id) {String key = "user:" + id;String value = redisTemplate.opsForValue().get(key); if (value != null) {return JSON.parseObject(value,  User.class); }RLock lock = redisson.getLock("lock:"  + id);try {boolean isLocked = lock.tryLock(10,  1000, TimeUnit.MILLISECONDS);if (isLocked) {value = redisTemplate.opsForValue().get(key); if (value != null) {return JSON.parseObject(value,  User.class); }User user = userRepository.findById(id).orElse(null); if (user != null) {redisTemplate.opsForValue().set(key,  JSON.toJSONString(user),  3600L, TimeUnit.SECONDS);} else {// 缓存空值 redisTemplate.opsForValue().set(key,  "", 3600L, TimeUnit.SECONDS);}}} catch (InterruptedException e) {Thread.currentThread().interrupt(); } finally {if (lock.isHeldByCurrentThread())  {lock.unlock(); }}return user != null ? user : new User();}
}

 

3. 缓存雪崩
  • 问题描述:大量缓存同时过期,导致数据库压力骤增。
  • 解决方案
    • 随机过期时间:为每个缓存设置不同的过期时间。
    • 永不过期:通过版本号或其他方式实现逻辑过期。
示例代码(随机过期时间)
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.stereotype.Service; @Service 
public class CacheService {@Autowired private RedisTemplate<String, Object> redisTemplate;public void setValueWithRandomExpire(String key, Object value) {long randomExpireTime = 3600L + (long) (Math.random()  * 3600); // 随机过期时间(1-2小时)redisTemplate.opsForValue().set(key,  value, randomExpireTime, TimeUnit.SECONDS);}
}

 

 

http://www.hkea.cn/news/26594/

相关文章:

  • 嵩县网站开发友情链接获取的途径有哪些
  • 国家企业信息公示网(广东)海南快速seo排名优化
  • 高端网站设计 上海徐州seo排名公司
  • 泰安网站建设公司排名石家庄最新消息
  • 域名只做邮箱没网站要备案吗常见的网络推广方式包括
  • 昆山建设局网站360搜索首页
  • 正常做网站多少钱无锡网站制作无锡做网站
  • php做网站csdn网站seo公司哪家好
  • 今日头条建站工具何鹏seo
  • wordpress 培训模板优化落实疫情防控新十条
  • 关于做外汇现货的网站太原整站优化排名外包
  • 星悦做任务网站是新网站百度收录
  • 十大营销网站seo关键词查询工具
  • 怎么查询网站所有关键词靠谱的广告联盟
  • 超酷的网站设计磁力搜索引擎
  • 网站建设写程序用什么软件成都疫情最新消息
  • 做网站需要什么资金2022今天刚刚发生地震了
  • 建设网站费用主要包括哪些google商店
  • 专注邯郸建设手机网站贴吧友情链接在哪
  • 网站备案拍照背景志鸿优化网官网
  • 网站百度知道怎么做推广网站搜索引擎优化的方法
  • 网站建设注意哪些问题sem和seo是什么职业岗位
  • 一_建设网站前的市场分析奶茶软文案例300字
  • 做网站智能工具江阴企业网站制作
  • 怎么看网站有没有做推广大数据营销系统多少钱
  • 广东工厂搜索seoseo平台优化服务
  • 网站开发平台 eclipseseo网站推广案例
  • 什么网站做调查能赚钱关键词优化报价推荐
  • 网站开发职业认知小结开发一个app平台大概需要多少钱?
  • 装修公司全包项目seo搜索引擎实训心得体会