Redisson是一个Redis Java客户端,具有In-Memory Data Grid的功能。它提供了更方便和最简单的方法来使用 Redis。Redisson 对象提供了关注点分离,使您可以专注于数据建模和应用程序逻辑。

基于高性能异步和无锁的Java Redis客户端和Netty框架。

支持的 JDK:1.8 ...19 和安卓

支持的 Redis: 3.0 ...7.0

官网:1. Overview · redisson/redisson Wiki (github.com)

一、特征:

  • 线程安全实现

  • 支持 Redis 复制、Redis 集群、Redis Sentinel、Redis 主从、Redis 单一设置

  • 支持 AWS ElastiCache、Amazon MemoryDB、Azure Redis Cache、Google Cloud Memorystore for Redis、Redis Enterprise、Aiven for Redis

  • 支持自动重连

  • 支持发送失败命令自动重试

  • 支持OSGi

  • 支持静态服务器

  • 异步连接池

  • Lua 脚本编写

  • JSON 数据类型

  • 反应流应用程序接口

  • RxJava3应用程序接口

  • 异步应用程序接口

  • 本地缓存支持,包括基于Caffeine-based的实现

  • 分布式 Java 对象 对象
    持有者、二进制流持有者、地理空间持有者、BitSet、AtomicLong、AtomicDouble、PublishSubscribe、 布隆过滤器、超日志日志

  • 分布式 Java 集合 映射, 多重映射, 集合
    , 列表, 排序集, 得分排序集, LexSortedSet, 队列, 双端克, 阻塞队列, 有界阻塞队列, 阻塞双节, 延迟队列, 优先级队列, 优先级双端

  • 分布式 Java 锁和同步器
    Lock、FairLock、MultiLock、RedLock、ReadWriteLock、Semaphore、PermitExpirableSemaphore、CountDownLatch

  • 分布式服务 远程服务、活对象服务、执行器服务、调度程序服务、MapReduce 服务

二、分布式锁和同步器

1、锁定

基于 Redis 的分布式重入 Lock 对象 Java 并实现 Lock 接口。如果获取锁的 Redisson 实例崩溃,则此类锁可以永远处于获取状态。为了避免这种情况 Redisson 维护锁看门狗,它会在锁持有人 Redisson 实例处于活动状态时延长锁过期时间。默认情况下,锁定看门狗超时为 30 秒,可以通过 Config.lockWatchdogTimeout 设置进行更改。leaseTime可以定义锁采集期间的参数。在指定的时间间隔后,锁定的锁将自动释放。RLock对象的行为符合 Java Lock 规范。这意味着只有锁所有者线程才能解锁它,否则会被抛出。否则,请考虑使用 RSemaphore 对象。

代码示例:

RLock lock = redisson.getLock("myLock");// traditional lock method
lock.lock();// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {lock.unlock();}
}

异步接口用法的代码示例:

RLock lock = redisson.getLock("myLock");RFuture<Void> lockFuture = lock.lockAsync();// or acquire lock and automatically unlock it after 10 seconds
RFuture<Void> lockFuture = lock.lockAsync(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> lockFuture = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);lockFuture.whenComplete((res, exception) -> {// ...lock.unlockAsync();
});

反应式接口用法的代码示例:

edissonReactiveClient redisson = redissonClient.reactive();
RLockReactive lock = redisson.getLock("myLock");Mono<Void> lockMono = lock.lock();// or acquire lock and automatically unlock it after 10 seconds
Mono<Void> lockMono = lock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> lockMono = lock.tryLock(100, 10, TimeUnit.SECONDS);lockMono.doOnNext(res -> {// ...
})
.doFinally(lock.unlock())
.subscribe();

RxJava3 接口使用的代码示例:

RedissonRxClient redisson = redissonClient.rxJava();
RLockRx lock = redisson.getLock("myLock");Completable lockRes = lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
Completable lockRes = lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Single<Boolean> lockRes = lock.tryLock(100, 10, TimeUnit.SECONDS);
lockRes.doOnSuccess(res -> {// ...
})
.doFinally(lock.unlock())
.subscribe();

2、公平锁定

基于 Redis 的分布式重入公平 Java 的 Lock 对象实现了 Lock 接口。

公平锁保证线程将按照与请求相同的顺序获取它。所有等待的线程都已排队,如果某个线程已死亡,则 Redisson 将等待其返回 5 秒。例如,如果 5 个线程由于某种原因死亡,则延迟将为 25 秒。

如果获取锁的 Redisson 实例崩溃,则此类锁可以永远处于获取状态。为了避免这种情况 Redisson 维护锁看门狗,它会在锁持有人 Redisson 实例处于活动状态时延长锁过期时间。默认情况下,锁定看门狗超时为 30 秒,可以通过 Config.lockWatchdogTimeout 设置进行更改。

leaseTime可以定义锁采集期间的参数。在指定的时间间隔后,锁定的锁将自动释放。

RLock对象的行为符合 Java Lock 规范。这意味着只有锁所有者线程才能解锁它,否则会被抛出。否则,请考虑使用 RSemaphore 对象。

代码示例:

RLock lock = redisson.getFairLock("myLock");// traditional lock method
lock.lock();// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {lock.unlock();}
}

3、 多重锁

基于 Redis 的分布式对象允许对 Lock 对象进行分组并将它们作为单个锁处理。每个对象可能属于不同的 Redisson 实例。MultiLockRLock

如果获取的 Redisson 实例崩溃,那么该实例可能会永远处于获取状态。为了避免这种情况 Redisson 维护锁看门狗,它会在锁持有人 Redisson 实例处于活动状态时延长锁过期时间。默认情况下,锁定看门狗超时为 30 秒,可以通过 Config.lockWatchdogTimeout 设置进行更改。MultiLockMultiLock

leaseTime可以定义锁采集期间的参数。在指定的时间间隔后,锁定的锁将自动释放。

MultiLock对象的行为符合 Java Lock 规范。这意味着只有锁所有者线程才能解锁它,否则会被抛出。否则,请考虑使用 RSemaphore 对象

RLock lock1 = redisson1.getLock("lock1");
RLock lock2 = redisson2.getLock("lock2");
RLock lock3 = redisson3.getLock("lock3");RLock multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);// traditional lock method
multiLock.lock();// or acquire lock and automatically unlock it after 10 seconds
multiLock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = multiLock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {multiLock.unlock();}
}

异步接口用法的代码示例:

RLock lock1 = redisson1.getLock("lock1");
RLock lock2 = redisson2.getLock("lock2");
RLock lock3 = redisson3.getLock("lock3");RLock multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);RFuture<Void> lockFuture = multiLock.lockAsync();// or acquire lock and automatically unlock it after 10 seconds
RFuture<Void> lockFuture = multiLock.lockAsync(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> lockFuture = multiLock.tryLockAsync(100, 10, TimeUnit.SECONDS);lockFuture.whenComplete((res, exception) -> {// ...multiLock.unlockAsync();
});

反应式接口用法的代码示例:

RedissonReactiveClient anyRedisson = redissonClient.reactive();RLockReactive lock1 = redisson1.getLock("lock1");
RLockReactive lock2 = redisson2.getLock("lock2");
RLockReactive lock3 = redisson3.getLock("lock3");RLockReactive multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);Mono<Void> lockMono = multiLock.lock();// or acquire lock and automatically unlock it after 10 seconds
Mono<Void> lockMono = multiLock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> lockMono = multiLock.tryLock(100, 10, TimeUnit.SECONDS);lockMono.doOnNext(res -> {// ...
})
.doFinally(multiLock.unlock())
.subscribe();

4、 读写锁定

基于 Redis 的分布式重入器 ReadWriteLock 对象 for Java 实现了 ReadWriteLock 接口。读锁和写锁都实现 RLock 接口。

允许多个 ReadLock 所有者和仅允许一个 WriteLock 所有者。

如果获取锁的 Redisson 实例崩溃,则此类锁可以永远处于获取状态。为了避免这种情况 Redisson 维护锁看门狗,它会在锁持有人 Redisson 实例处于活动状态时延长锁过期时间。默认情况下,锁定看门狗超时为 30 秒,可以通过 Config.lockWatchdogTimeout 设置进行更改。

Redisson还允许在锁采集期间指定参数。在指定的时间间隔后,锁定的锁将自动释放。leaseTime

RLock对象的行为符合 Java Lock 规范。这意味着只有锁所有者线程才能解锁它,否则会被抛出。否则,请考虑使用 RSemaphore 对象。

RReadWriteLock rwlock = redisson.getReadWriteLock("myLock");RLock lock = rwlock.readLock();
// or
RLock lock = rwlock.writeLock();// traditional lock method
lock.lock();// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {lock.unlock();}
}

异步接口用法的代码示例:

RReadWriteLock rwlock = redisson.getReadWriteLock("myLock");RLock lock = rwlock.readLock();
// or
RLock lock = rwlock.writeLock();RFuture<Void> lockFuture = lock.lockAsync();// or acquire lock and automatically unlock it after 10 seconds
RFuture<Void> lockFuture = lock.lockAsync(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Boolean> lockFuture = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);lockFuture.whenComplete((res, exception) -> {// ...lock.unlockAsync();
});

反应式接口用法的代码示例:

RedissonReactiveClient redisson = redissonClient.reactive();RReadWriteLockReactive rwlock = redisson.getReadWriteLock("myLock");RLockReactive lock = rwlock.readLock();
// or
RLockReactive lock = rwlock.writeLock();Mono<Void> lockMono = lock.lock();// or acquire lock and automatically unlock it after 10 seconds
Mono<Void> lockMono = lock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Mono<Boolean> lockMono = lock.tryLock(100, 10, TimeUnit.SECONDS);lockMono.doOnNext(res -> {// ...
})
.doFinally(lock.unlock())
.subscribe();

5、信号量

基于 Redis 的分布式 Java 信号量对象类似于 Semaphore 对象。

可以在使用前初始化,但这不是必需的,通过方法提供可用的许可证数量

RSemaphore semaphore = redisson.getSemaphore("mySemaphore");// acquire single permit
semaphore.acquire();// or acquire 10 permits
semaphore.acquire(10);// or try to acquire permit
boolean res = semaphore.tryAcquire();// or try to acquire permit or wait up to 15 seconds
boolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS);// or try to acquire 10 permit
boolean res = semaphore.tryAcquire(10);// or try to acquire 10 permits or wait up to 15 seconds
boolean res = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
if (res) {try {...} finally {semaphore.release();}
}

6、 允许可过期信号量

基于 Redis 的分布式 Java 信号量对象,每个获取的许可证都支持租用时间参数。每个许可证都由自己的身份证标识,只能使用其身份证签发。

应在使用前初始化,通过方法使用可用的许可金额。允许通过方法增加/减少可用许可证的数量。

代码示例:

RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore");semaphore.trySetPermits(23);// acquire permit
String id = semaphore.acquire();// or acquire permit with lease time in 10 seconds
String id = semaphore.acquire(10, TimeUnit.SECONDS);// or try to acquire permit
String id = semaphore.tryAcquire();// or try to acquire permit or wait up to 15 seconds
String id = semaphore.tryAcquire(15, TimeUnit.SECONDS);// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
String id = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
if (id != null) {try {...} finally {semaphore.release(id);}
}

7、倒计时锁存器

基于 Redis 的分布式 CountDownLatch 对象 Java 具有类似于 CountDownLatch 对象的结构。

使用前应使用 count by 方法初始化

RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");latch.trySetCount(1);
// await for count down
latch.await();// in other thread or JVM
RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
latch.countDown();

8、旋转锁定

基于Redis的分布式重入器SpinLock对象用于Java并实现Lock接口。

由于 Lock 对象中的 pubsub 使用率,每个短时间间隔获取/释放的数千个或更多锁可能会导致达到网络吞吐量限制和 Redis CPU 过载。这是由于 Redis pubsub 的性质 - 消息被分发到 Redis 集群中的所有节点。默认情况下,旋转锁定使用指数退避策略进行锁定获取,而不是发布子通道。

如果获取锁的 Redisson 实例崩溃,则此类锁可以永远处于获取状态。为了避免这种情况 Redisson 维护锁看门狗,它会在锁持有人 Redisson 实例处于活动状态时延长锁过期时间。默认情况下,锁定看门狗超时为 30 秒,可以通过 Config.lockWatchdogTimeout 设置进行更改。

leaseTime可以定义锁采集期间的参数。在指定的时间间隔后,锁定的锁将自动释放。

RLock对象的行为符合 Java Lock 规范。这意味着只有锁所有者线程才能解锁它,否则会被抛出。否则,请考虑使用 RSemaphore 对象

RLock lock = redisson.getSpinLock("myLock");// traditional lock method
lock.lock();// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {lock.unlock();}
}

9、 围栏锁

基于Redis的分布式重入器FencedLock对象用于Java并实现Lock接口。

这种类型的锁维护屏蔽令牌,以避免客户端获取锁由于长时间的 GC 暂停或其他原因而延迟,并且无法检测到它不再拥有锁的情况。要解决此问题,令牌通过锁定方法或方法返回。应通过此锁保护的服务检查令牌是否大于或等于前一个令牌,如果条件为 false,则应拒绝操作。getToken()

如果获取锁的 Redisson 实例崩溃,则此类锁可以永远处于获取状态。为了避免这种情况 Redisson 维护锁看门狗,它会在锁持有人 Redisson 实例处于活动状态时延长锁过期时间。默认情况下,锁定看门狗超时为 30 秒,可以通过 Config.lockWatchdogTimeout 设置进行更改。

leaseTime可以定义锁采集期间的参数。在指定的时间间隔后,锁定的锁将自动释放。

RLock对象的行为符合 Java Lock 规范。这意味着只有锁所有者线程才能解锁它,否则会被抛出。否则,请考虑使用 RSemaphore 对象。

RFencedLock lock = redisson.getFencedLock("myLock");// traditional lock method
Long token = lock.lockAndGetToken();// or acquire lock and automatically unlock it after 10 seconds
token = lock.lockAndGetToken(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Long token = lock.tryLockAndGetToken(100, 10, TimeUnit.SECONDS);
if (token != null) {try {// check if token >= old token...} finally {lock.unlock();}
}

异步接口用法的代码示例:

RFencedLock lock = redisson.getFencedLock("myLock");RFuture<Long> lockFuture = lock.lockAndGetTokenAsync();// or acquire lock and automatically unlock it after 10 seconds
RFuture<Long> lockFuture = lock.lockAndGetTokenAsync(10, TimeUnit.SECONDS);// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
RFuture<Long> lockFuture = lock.tryLockAndGetTokenAsync(100, 10, TimeUnit.SECONDS);long threadId = Thread.currentThread().getId();
lockFuture.whenComplete((token, exception) -> {if (token != null) {try {// check if token >= old token...} finally {lock.unlockAsync(threadId);}}
});

三、开发实例

1、 依赖引入:

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

2、参数配置

spring:redis:cluster:nodeAddresses: ["redis://127.0.0.1:7005","redis://127.0.0.1:7004","redis://127.0.0.1:7003","redis://127.0.0.1:7002","redis://127.0.0.1:7001","redis://127.0.0.1:7000"]password: 99999single:address: "redis://127.0.0.1:6379"database: 7

3、配置参数读取类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.io.Serializable;
import java.util.List;@Data
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfigProperties implements Serializable {private static final long serialVersionUID = 8815222005846355408L;private String password;private cluster cluster;private Single single;public static class cluster {private List<String> nodeAddresses;public List<String> getNodeAddresses() {return nodeAddresses;}public void setNodeAddresses(List<String> nodeAddresses) {this.nodeAddresses = nodeAddresses;}@Overridepublic String toString() {return "{" +"nodeAddresses=" + nodeAddresses +'}';}}public static class Single {private String address;public Integer database;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getDatabase() {return database;}public void setDatabase(Integer database) {this.database = database;}@Overridepublic String toString() {return "Single{" +"address='" + address + '\'' +", database=" + database +'}';}}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public RedisConfigProperties.cluster getCluster() {return cluster;}public void setCluster(RedisConfigProperties.cluster cluster) {this.cluster = cluster;}
}

4、Redisson 客户端配置

import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.redisson.config.TransportMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.IOException;
import java.util.List;
@Slf4j
@Configuration
public class MyRedissonConfig {@Autowired(required = false)private RedisConfigProperties redisConfigProperties;/*** 配置redisson单机* @return*/@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.setTransportMode(TransportMode.EPOLL); // 默认是NIO的方式config.useClusterServers()//可以用"rediss://"来启用SSL连接,前缀必须是redis:// or rediss://.addNodeAddress("redis://127.0.0.1:7181");return Redisson.create(config);}/*** 配置redisson集群* @return*/@Bean(destroyMethod = "shutdown")public RedissonClient getRedissonClient() {List<String> clusterNodes = redisConfigProperties.getCluster().getNodeAddresses();Config config = new Config();//对象编码选择纯字符串编码config.setCodec(StringCodec.INSTANCE);ClusterServersConfig clusterServersConfig = config.useClusterServers().addNodeAddress(clusterNodes.toArray(new String[clusterNodes.size()]));//设置密码clusterServersConfig.setPassword(redisConfigProperties.getPassword());//redis连接心跳检测,防止一段时间过后,与redis的连接断开clusterServersConfig.setPingConnectionInterval(32000);return Redisson.create(config);}}

5、测试代码:

@Autowiredprivate RedissonClient redissonClient;private static void test() {RBucket<Object> bucket = redissonClient.getBucket("string-demo");bucket.set("hello");System.out.println(bucket.get());}

Redisson分布式锁及springboot 整合实例相关推荐

  1. redisson分布式锁,实战

    目录 什么时候用分布式锁? 分布式锁入门 超时设置 释放了不是自己加的锁 正确设置锁超时 加解锁代码位置有讲究 实现可重入锁 Redis Hash 可重入锁 主从架构带来的问题 什么是 Redlock ...

  2. Jmeter Springboot Redisson分布式锁并发订单操作(下单、取消单、完成单、加库存)

    Jmeter+Springboot+Redisson分布式锁并发订单操作(下单.取消单.完成单.加库存) 涉及知识点: java+springboot+mybatis开发 redis分布式锁+Redi ...

  3. springboot基础(72):Redisson分布式锁

    文章目录 前言 第一节 入门使用Redisson 第二节 注解形式的分布式锁 1. 分布式锁的注解实现 2. 分析MyRedissonLock注解和使用 传送门 前言 并发执行是比较场景的场景,单机情 ...

  4. Redisson分布式锁实战-1:构建分布式锁

    我们现在来到Task类当中,这个方法就是V4了/*** Redisson分布式锁实现* @throws InterruptedException*/ // @Scheduled(cron=" ...

  5. 年轻人,看看 Redisson 分布式锁—可重入锁吧!太重要了

    作者 | 李祥    责编 | 张文 来源 | 企鹅杏仁技术站(ID:xingren-tech) 引言 作为后端开发,对于所谓的线程安全.高并发等一系列名词肯定都不会陌生,相关的一些概念及技术框架是面 ...

  6. Redisson分布式锁的配置和使用

    基于springBoot的redisson分布式锁 之前使用Redis分布式锁都是自己写的工具类,利用Redis的setNX特性:后来发现Redisson提供的分布式锁是真的好用. Redisson可 ...

  7. redis ,redisson 分布式锁深入剖析

    目录 为什么要用分布式锁? 分布式锁所遵循的原则? redis 分布式锁 redis 原始分布式锁实现 加锁 释放锁 redis 分布式锁存在的问题 redisson  实现分布式锁 redisson ...

  8. 年轻人,看看Redisson分布式锁—可重入锁吧!太重要了

    1.引言 作为后端开发,对于所谓的线程安全.高并发等一系列名词肯定都不会陌生,相关的一些概念及技术框架是面试中的宠儿,也是工作中解决一些特定场景下的技术问题的银弹.今天我们就来聊聊这些银弹中的其中一枚 ...

  9. Redis进阶- Redisson分布式锁实现原理及源码解析

    文章目录 Pre 用法 Redisson分布式锁实现原理 Redisson分布式锁源码分析 redisson.getLock(lockKey) 的逻辑 redissonLock.lock()的逻辑 r ...

最新文章

  1. Spark学习之Spark RDD算子
  2. mysql数据库二级233_MySQL数据库开发必备常识
  3. R语言数据挖掘实践——系谱聚类
  4. 深入理解Javascript之执行上下文(Execution Context)
  5. picturectrl控件中加载图片并显示_在 CRA 中使用 webp 图片提升加载性能
  6. 解决:RabbitMQ 连接报错:amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
  7. QNX下挂载USB设备
  8. 来了!iPhone 12今晚天猫首销:12期分期免息,还送5G流量包
  9. 固态硬盘新趋势?美光3D QLC闪存出货量猛增75%
  10. Extjs grid禁用头部点击三角下拉菜单
  11. SC-RoadDeepNet学习笔记
  12. 步进式解读Apache许可证
  13. MD5,SHA1,SHA256,NTLM,LM等Hash在线破解网站收集
  14. python字符串str拼接
  15. 阿里云云边一体容器架构创新论文被云计算顶会 ACM SoCC 录用
  16. matlab解五元方程,哪位大侠帮忙解这个五元四次方程组
  17. 安装版—安装MySQL
  18. 防止你的WP7手机偷跑流量——系统设置篇
  19. 下载的软件包保存在缓存中,直到下次成功执行事务。 您可以通过执行 'dnf clean packages' 删除软件包缓存。 错误:事务检查错误
  20. c语言表示三个数除却最大最小,湖南师范大l历年年语言学及应用语言学现代汉语考研试题.doc...

热门文章

  1. mini-spinner格式化
  2. unity c#非法字符(脏词)检测
  3. 公司服务器被攻破后的处理
  4. 麻将胡牌算番-台州麻将
  5. 为奥运喝彩!百度智能云联合央视体育客户端打造奥运播报新体验!
  6. 使用 Python 进行 GUI 掷骰子模拟
  7. 阿里巴巴2016校园招聘 研发工程师(四)详解
  8. python.列表全方位解读
  9. 2006年美国福布斯“全球富豪榜”
  10. [Warning] implicit declaration of function ‘clrscr‘ [-Wimplicit-function-declaration]