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

怎么做可以把网站图片保存下来制作网站推广

怎么做可以把网站图片保存下来,制作网站推广,无锡 网站 seo 优化,绵阳网站建站文章目录 一、简介二、集成redissionpom文件redission 配置文件application.yml文件启动类 三、JAVA 操作案例字符串操作哈希操作列表操作集合操作有序集合操作布隆过滤器操作分布式锁操作 四、源码解析 一、简介 Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格…

文章目录

    • 一、简介
    • 二、集成redission
      • pom文件
      • redission 配置文件
      • application.yml文件
      • 启动类
    • 三、JAVA 操作案例
      • 字符串操作
      • 哈希操作
      • 列表操作
      • 集合操作
      • 有序集合操作
      • 布隆过滤器操作
      • 分布式锁操作
    • 四、源码解析

一、简介

Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格客户端(In-Memory Data Grid)。它不仅提供了一系列的 redis 常用数据结构命令服务,还提供了许多分布式服务,例如分布式锁、分布式对象、分布式集合、分布式远程服务、分布式调度任务服务等等。
本文会介绍如何将redission集成到springboot和如何使用 Redisson 操作 Redis 中的字符串、哈希、列表、集合、有序集合,以及布隆过滤器和分布式锁等功能,并解析源码中其最大亮点的看门狗机制。

二、集成redission

本章内容使用的springboot版本为2.6.3,redission-starter版本为3.17.7

pom文件

引入redission相关依赖


<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.12.3</version>
</dependency><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId><version>2.12.3</version>
</dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.17.7</version>
</dependency>

redission 配置文件

将redission相关的配置抽到单独的一个redission文件,放在application.yml的同级目录

# 单节点配置
singleServerConfig:# 连接空闲超时,单位:毫秒idleConnectionTimeout: 10000# 连接超时,单位:毫秒connectTimeout: 10000# 命令等待超时,单位:毫秒timeout: 3000# 命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误。# 如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。retryAttempts: 3# 命令重试发送时间间隔,单位:毫秒retryInterval: 1500# 密码,没有设置密码时,需要注释掉,否则会报错# password: redis.shbeta# 单个连接最大订阅数量subscriptionsPerConnection: 5# 客户端名称clientName: "axin"# 节点地址address: "redis://192.168.102.111:6379"password: Cidneueopx# 发布和订阅连接的最小空闲连接数subscriptionConnectionMinimumIdleSize: 1# 发布和订阅连接池大小subscriptionConnectionPoolSize: 50# 最小空闲连接数connectionMinimumIdleSize: 32# 连接池大小connectionPoolSize: 64# 数据库编号database: 1# DNS监测时间间隔,单位:毫秒dnsMonitoringInterval: 5000
# 线程池数量,默认值: 当前处理核数量 * 2
threads: 0
# Netty线程池数量,默认值: 当前处理核数量 * 2
nettyThreads: 0
# 编码
codec: !<org.redisson.codec.JsonJacksonCodec> {}
# 传输模式
transportMode : "NIO"# 配置看门狗的默认超时时间为30s,这里改为 10s
lockWatchdogTimeout: 10000

application.yml文件

在该配置文件将redission配置文件引入

spring:redis:redisson:file: classpath:redisson.yml

启动类

启动类需要加上注解@ImportAutoConfiguration,如下所示

@SpringBootApplication
@ImportAutoConfiguration(RedissonAutoConfiguration.class)
public class EasyUserApplication {public static void main(String[] args) {SpringApplication.run(EasyUserApplication.class, args);}
}

三、JAVA 操作案例

字符串操作

Redisson 支持通过RBucket对象来操作字符串或对象(对象需要实现序列化Serializable)数据结构,同时支持设置数据和有效期,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opString")
public void opString() {RBucket<String> strKey = redissonClient.getBucket("strKey");strKey.set("china");//表示10分钟后删除该键strKey.expire(Duration.ofMinutes(10));System.out.println(strKey.get());
}

哈希操作

通过获取一个RMap 对象来进行哈希数据结构的操作,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opMap")
public void opMap() {//获取一个map对象RMap<String, String> rMap  = redissonClient.getMap("mapKey");rMap.put("wawa", "1212");//表示10分钟后删除该键rMap.expire(Duration.ofMinutes(10));System.out.println(rMap.get("wawa"));
}

列表操作

redission支持通过RList对象来操作列表数据结构,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opList")
public void opList() {RList<Integer> rList  = redissonClient.getList("listKey");rList.add(100);rList.add(200);rList.add(300);//表示10分钟后删除该键rList.expire(Duration.ofMinutes(10));//读取列表全部数据,不删除System.out.println(rList.readAll());
}

集合操作

Redisson支持通过RSet对象来操作集合,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opSet")
public void opSet() {RSet<Integer> rSet  = redissonClient.getSet("setKey");rSet.add(100);rSet.add(200);rSet.add(300);//表示10分钟后删除该键rSet.expire(Duration.ofMinutes(10));System.out.println(rSet.readAll());log.info("========testSkyworking");
}

有序集合操作

Redisson 支持通过RSortedSet对象来操作有序集合数据结构,如果使用存储对象,则实体对象必须先实现Comparable接口,并重写比较逻辑,否则会报错,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opSortSet")
public void opSortSet() {RSortedSet<Integer> rSortSet  = redissonClient.getSortedSet("sortsetKey");rSortSet.add(300);rSortSet.add(200);rSortSet.add(100);System.out.println(rSortSet.readAll());
}

布隆过滤器操作

Redisson支持通过RBloomFilter对象来操作布隆过滤器,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opBloomFilter")
public void opBloomFilter() {RBloomFilter rBloomFilter   = redissonClient.getBloomFilter("BloomFilterKey");// 初始化预期插入的数据量为50000和期望误差率为0.01rBloomFilter.tryInit(50000, 0.01);rBloomFilter.add(300);rBloomFilter.add(200);rBloomFilter.add(100);//表示100分钟后删除该键rBloomFilter.expire(Duration.ofMinutes(100));// 判断是否存在System.out.println(rBloomFilter.contains(300));System.out.println(rBloomFilter.contains(700));
}

分布式锁操作

其实很多时候,我们引入redission,最想使用的功能场景就是其分布式锁,因为我们不需要去设置最大释放锁的时间,redission内部有一个看门狗机制会主动去续期。
Redisson通过RLock对象来操作分布式锁,例子如下

@Autowired
RedissonClient redissonClient;@GetMapping("/opLock")
public void opLock() {//获取锁对象实例final String lockKey = "mylock";RLock rLock = redissonClient.getLock(lockKey);try {//尝试5秒内获取锁 不设置释放锁的时间boolean res = rLock.tryLock(5L,  TimeUnit.SECONDS);System.out.println("获取锁成功");if (res) {for (int i = 0; i < 10; i++) {System.out.println(i);Thread.sleep(1000L);}//成功获得锁,在这里处理业务System.out.println("处理业务");}} catch (Exception e) {System.out.println("获取锁失败,失败原因:" + e.getMessage());} finally {//无论如何, 最后都要解锁rLock.unlock();}
}

四、源码解析

分布式锁的看门狗机制大致如下列流程图所示
在这里插入图片描述
调用链路
org.redisson.RedissonLock#tryLock=》org.redisson.RedissonLock#tryLockAsync=》org.redisson.RedissonLock#tryAcquireAsync

我们来仔细看看org.redisson.RedissonLock#tryAcquireAsync

private <T> RFuture<Long> tryAcquireAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId) {RFuture ttlRemainingFuture;//判断锁的持有时间是否由用户自定义if (leaseTime > 0L) {ttlRemainingFuture = this.tryLockInnerAsync(waitTime, leaseTime, unit, threadId, RedisCommands.EVAL_LONG);} else {//当用户没有自定义锁占有时间时,默认传入 internalLockLeaseTime //private long lockWatchdogTimeout = 30 * 1000; 默认30秒ttlRemainingFuture = this.tryLockInnerAsync(waitTime, this.internalLockLeaseTime, TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);}CompletionStage<Long> f = ttlRemainingFuture.thenApply((ttlRemaining) -> {if (ttlRemaining == null) {if (leaseTime > 0L) {//如果用户传入占用时间直接转换,把默认值internalLockLeaseTime 更新为用户自定义的占有时间this.internalLockLeaseTime = unit.toMillis(leaseTime);} else {//这里就是触发看门狗机制的方法,只有当 leaseTime == -1时才会触发看门狗机制this.scheduleExpirationRenewal(threadId);}}return ttlRemaining;});return new CompletableFutureWrapper(f);
}

接着进行scheduleExpirationRenewal

protected void scheduleExpirationRenewal(long threadId) {RedissonBaseLock.ExpirationEntry entry = new RedissonBaseLock.ExpirationEntry();//EXPIRATION_RENEWAL_MAP 是一个全局的静态常量MapRedissonBaseLock.ExpirationEntry oldEntry = (RedissonBaseLock.ExpirationEntry)EXPIRATION_RENEWAL_MAP.putIfAbsent(this.getEntryName(), entry);if (oldEntry != null) {//oldEntry != null 表示该线程不是第一次触发oldEntry.addThreadId(threadId);} else {//oldEntry == null 表示该线程是第一次触发entry.addThreadId(threadId);try {//更新过期时间this.renewExpiration();} finally {if (Thread.currentThread().isInterrupted()) {this.cancelExpirationRenewal(threadId);}}}}

org.redisson.RedissonBaseLock#renewExpiration中主要是更新时间的详细逻辑

private void renewExpiration() {//获取当前线程的更新对象RedissonBaseLock.ExpirationEntry ee = (RedissonBaseLock.ExpirationEntry)EXPIRATION_RENEWAL_MAP.get(this.getEntryName());if (ee != null) {//创建了一个定时任务Timeout task = this.getServiceManager().newTimeout(new TimerTask() {public void run(Timeout timeout) throws Exception {RedissonBaseLock.ExpirationEntry ent = (RedissonBaseLock.ExpirationEntry)RedissonBaseLock.EXPIRATION_RENEWAL_MAP.get(RedissonBaseLock.this.getEntryName());if (ent != null) {Long threadId = ent.getFirstThreadId();if (threadId != null) {//异步更新过期时间  CompletionStage<Boolean> future = RedissonBaseLock.this.renewExpirationAsync(threadId);future.whenComplete((res, e) -> {if (e != null) {//如果出现异常,从map中删除,直接返回RedissonBaseLock.log.error("Can't update lock {} expiration", RedissonBaseLock.this.getRawName(), e);RedissonBaseLock.EXPIRATION_RENEWAL_MAP.remove(RedissonBaseLock.this.getEntryName());} else {if (res) {//如果没有报错,就再次定时延期RedissonBaseLock.this.renewExpiration();} else {//否则取消定时RedissonBaseLock.this.cancelExpirationRenewal((Long)null);}}});}}}}, this.internalLockLeaseTime / 3L, TimeUnit.MILLISECONDS);ee.setTimeout(task);}
}

文章转载自:
http://plasmapheresis.c7622.cn
http://xylylene.c7622.cn
http://pelisse.c7622.cn
http://mileage.c7622.cn
http://awag.c7622.cn
http://vulviform.c7622.cn
http://hostageship.c7622.cn
http://botcher.c7622.cn
http://rotta.c7622.cn
http://componential.c7622.cn
http://requital.c7622.cn
http://unharmonious.c7622.cn
http://objectivism.c7622.cn
http://unbirthday.c7622.cn
http://bulbiferous.c7622.cn
http://anemogram.c7622.cn
http://counterforce.c7622.cn
http://gcvo.c7622.cn
http://overwound.c7622.cn
http://heronsew.c7622.cn
http://naira.c7622.cn
http://isolex.c7622.cn
http://plotty.c7622.cn
http://viking.c7622.cn
http://exception.c7622.cn
http://runover.c7622.cn
http://unopened.c7622.cn
http://centavo.c7622.cn
http://circulating.c7622.cn
http://dihydroxyacetone.c7622.cn
http://hegemonic.c7622.cn
http://graphy.c7622.cn
http://hymn.c7622.cn
http://coadjutant.c7622.cn
http://bade.c7622.cn
http://appetency.c7622.cn
http://plastogamy.c7622.cn
http://mj.c7622.cn
http://jacky.c7622.cn
http://subastral.c7622.cn
http://invulnerability.c7622.cn
http://potful.c7622.cn
http://topotype.c7622.cn
http://superorganism.c7622.cn
http://nos.c7622.cn
http://latticework.c7622.cn
http://insusceptibility.c7622.cn
http://sciomancy.c7622.cn
http://headquarter.c7622.cn
http://alkylate.c7622.cn
http://arguable.c7622.cn
http://choosy.c7622.cn
http://gaze.c7622.cn
http://serajevo.c7622.cn
http://inexpectancy.c7622.cn
http://due.c7622.cn
http://oddity.c7622.cn
http://rotc.c7622.cn
http://tarp.c7622.cn
http://lauretta.c7622.cn
http://exhalation.c7622.cn
http://attachment.c7622.cn
http://unregenerate.c7622.cn
http://nurser.c7622.cn
http://damnation.c7622.cn
http://mpls.c7622.cn
http://introspectiveness.c7622.cn
http://floorer.c7622.cn
http://matchet.c7622.cn
http://frumpy.c7622.cn
http://saltimbanque.c7622.cn
http://reinvade.c7622.cn
http://gangliated.c7622.cn
http://microdontia.c7622.cn
http://hospitality.c7622.cn
http://certified.c7622.cn
http://misdistribution.c7622.cn
http://crackbrain.c7622.cn
http://democracy.c7622.cn
http://tully.c7622.cn
http://billboard.c7622.cn
http://ramee.c7622.cn
http://nicety.c7622.cn
http://cyanosis.c7622.cn
http://lolland.c7622.cn
http://ciliated.c7622.cn
http://fatness.c7622.cn
http://bedrail.c7622.cn
http://dilative.c7622.cn
http://bimetallist.c7622.cn
http://fibroelastosis.c7622.cn
http://baremeter.c7622.cn
http://hellhole.c7622.cn
http://sternpost.c7622.cn
http://cavernous.c7622.cn
http://unlit.c7622.cn
http://trendily.c7622.cn
http://boiler.c7622.cn
http://correlate.c7622.cn
http://squabbish.c7622.cn
http://www.zhongyajixie.com/news/102263.html

相关文章:

  • wordpress title descriptionseo推广代理
  • 添加图标wordpress路由优化大师
  • 宣传片制作方案网站搜索引擎优化主要方法
  • 美国服务器免费节点桂平seo关键词优化
  • 织梦如何做移动网站seo教程网站优化
  • 西安市社交网站制作公司seo点击器
  • wordpress备案号不显示志鸿优化设计
  • 马洪旭 做的网站大学快速排名精灵
  • 网站建设客服工作品牌宣传推广文案
  • 做标书有什么好的网站吗百度口碑网
  • 程序员网站建设手机系统流畅神器
  • WordPress仿w3c主题郑州seo公司哪家好
  • b2b网站建设费用淘宝怎么做引流和推广
  • 网站域名 如何选择营销渠道策划方案
  • 满城网站建设旺道seo推广
  • 旅游景点网站模板东莞网站seo推广
  • 如何搭建一个购物网站产品推广文案100字
  • wordpress主题图片消失网站seo推广方案
  • 南京建设网站方案seo推广外包报价表
  • 做网站需要审核资质吗直播网站排名
  • 杭州网站建设上海优化营商环境
  • 侵入别人的网站怎么做广东seo推广
  • 手机网站建设视频seo效果分析
  • 扬州门户网站开发临沂网站建设
  • 淘宝客怎么做自己网站推广全国唯一一个没有疫情的城市
  • 找人做企业网站注意啥网站建设推广服务
  • 一学一做共青团网站seo建站技巧
  • 网站怎么样被百度收录百度排名优化工具
  • 司法鉴定网站建设的内容周口seo公司
  • 北京网站制作收费标准sem代运营托管公司