亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述Android NFC标签 开发深度解析 触碰的艺术相关的知识,希望能为你提供帮助。
Jedis 是一个基于 java 语言的 Redis 客户端,
本文主要介绍使用 Jedis 访问 Redis 的一些基本方法。这里安装的 Redis 版本是 redis-5.0.4 稳定版。Redis 最广泛的应用场景就是使用它作为缓存,
除此还有网站访问统计、数据过期处理(
可以精确到毫秒)
、应用排行榜、分布式集群架构中的 session 分离等。
使用 Jedis 需要添加 Maven 依赖:
<
!-- redis -->
<
dependency>
<
groupId>
redis.clients<
/groupId>
<
artifactId>
jedis<
/artifactId>
<
version>
2.10.2<
/version>
<
/dependency>
1.Jedis的使用 1.xml配置方式 这里我们创建一个 Redis 操作的接口, 分别创建两个实现类对应 Redis 的单机版和集群版。当使用单机版 Redis 时, 配置单机版的实现类, 当使用集群版的时候, 配置集群版的实现类。
创建 JedisClient 接口:
public interface JedisClient {
String set(String key, String value);
String get(String key);
}
分别创建实现类:
public class JedisClientSingle implements JedisClient {
@
Autowired
private JedisPool jedisPool;
@
Override
public String set(String key, String value) {
Jedis jedis =
jedisPool.getResource();
String result =
jedis.set(key, value);
jedis.close();
return result;
}
//省略get实现
}
public class JedisClientCluster implements JedisClient {
@
Autowired
private JedisCluster jedisCluster;
@
Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
}
//省略get实现
}
然后增加配置 resources/spring-config-cache-redis.xml( 单机版和集群版只能开一个) :
<
?xml version=
"
1.0"
encoding=
"
UTF-8"
?>
<
beans xmlns=
"
http://www.springframework.org/schema/beans"
xmlns:xsi=
"
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<
!-- Redis连接池 -->
<
bean id=
"
jedisPoolConfig"
class=
"
redis.clients.jedis.JedisPoolConfig"
>
<
!-- 连接池最大连接数,使用负值表示没有限制,默认8 -->
<
property name=
"
maxTotal"
value=
"
8"
/>
<
!-- 连接池中的最大空闲连接,默认8 -->
<
property name=
"
maxIdle"
value=
"
8"
/>
<
!-- 连接池中的最小空闲连接,默认0 -->
<
property name=
"
minIdle"
value=
"
0"
/>
<
!-- 是否开启jmx监控,可用于监控,默认true,建议开启 -->
<
property name=
"
jmxEnabled"
value=
"
true"
/>
<
!-- 当连接池用尽后,调用者是否要等待,只有当为true时,下面的maxWaitMillis才会生效,默认true,建议使用默认值 -->
<
property name=
"
blockWhenExhausted"
value=
"
true"
/>
<
!-- 当连接池用尽后,调用者最大阻塞等待时间,默认-1L表示永不超时 -->
<
property name=
"
maxWaitMillis"
value=
"
15000"
/>
<
!-- 向连接池借用连接时是否做连接有效性检测(ping),无效连接会被移除,并尝试取出另一个,默认false,建议false -->
<
property name=
"
testOnBorrow"
value=
"
false"
/>
<
!-- 向连接池归还连接时是否做连接有效性检测(ping),无效连接会被移除,默认false,建议false -->
<
property name=
"
testOnReturn"
value=
"
false"
/>
<
!-- 在空闲时检查有效性,默认false -->
<
property name=
"
testWhileIdle"
value=
"
true"
/>
<
/bean>
<
!-- 配置Redis客户端单机版 -->
<
bean id=
"
jedisPool"
class=
"
redis.clients.jedis.JedisPool"
>
<
constructor-arg name=
"
poolConfig"
ref=
"
jedisPoolConfig"
/>
<
constructor-arg name=
"
host"
value=
"
127.0.0.1"
/>
<
constructor-arg name=
"
port"
value=
"
6379"
/>
<
constructor-arg name=
"
timeout"
value=
"
3000"
/>
<
constructor-arg name=
"
password"
value=
"
123456"
/>
<
/bean>
<
!-- 配置Redis客户端集群版 -->
<
!--<
bean id=
"
jedisCluster"
class=
"
redis.clients.jedis.JedisCluster"
>
<
constructor-arg>
<
set>
<
bean class=
"
redis.clients.jedis.HostAndPort"
>
<
constructor-arg index=
"
0"
name=
"
host"
value=
"
127.0.0.1"
/>
<
constructor-arg index=
"
1"
name=
"
port"
value=
"
6379"
/>
<
/bean>
<
bean class=
"
redis.clients.jedis.HostAndPort"
>
<
constructor-arg index=
"
0"
name=
"
host"
value=
"
127.0.0.1"
/>
<
constructor-arg index=
"
1"
name=
"
port"
value=
"
6380"
/>
<
/bean>
<
bean class=
"
redis.clients.jedis.HostAndPort"
>
<
constructor-arg index=
"
0"
name=
"
host"
value=
"
127.0.0.1"
/>
<
constructor-arg index=
"
1"
name=
"
port"
value=
"
6381"
/>
<
/bean>
<
/set>
<
/constructor-arg>
<
constructor-arg name=
"
connectionTimeout"
value=
"
3000"
/>
<
constructor-arg name=
"
soTimeout"
value=
"
3000"
/>
<
constructor-arg name=
"
maxAttempts"
value=
"
3"
/>
<
constructor-arg name=
"
password"
value=
"
123456"
/>
<
constructor-arg name=
"
poolConfig"
ref=
"
jedisPoolConfig"
/>
<
/bean>
-->
<
!-- 配置Redis客户端实现类 -->
<
bean id=
"
redisClient"
class=
"
com.example.server.soa.dao.redis.impl.RedisClientSingle"
/>
<
!--<
bean id=
"
redisClient"
class=
"
com.example.server.soa.dao.redis.impl.RedisClientCluster"
/>
-->
<
/beans>
然后在项目启动类中导入配置即可:
@
SpringBootApplication
@
ImportResource(
"
classpath:spring-config-cache-redis.xml"
)
使用的时候当作普通的类注入就可以了:
@
Resource
private JedisClient jedisClient;
2.连接池配置优化 1、选择适合的 maxTotal, 举个例子, 命令平均执行时间为 0.1ms = 0.001s, 如果业务需要 50000 QPS, 则 maxTotal 理论值 = 0.001 * 50000 = 50 个。实际设置时要偏大一些。
实际上对于 maxTotal 需要考虑的事情比较多, 大概有下面四点:
- 业务希望 Redis 并发量;
- 客户端执行命令时间;
- Redis 资源, 例如 应用个数 * maxTotal 是不能超过 Redis 的最大连接数的( config get maxclients) ;
- 资源开销, 例如 虽然希望控制空闲连接, 但是不希望因为连接池的频繁释放创建连接造成不必要的开销。
建议预热 minIdle, 减少第一次启动后的新连接开销。
2、常见问题与解决思路:
报错: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool …
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
原因: 获取空闲连接的时候发生超时了。
报错: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool …
Caused by: java.util.NoSuchElementException: Pool exhausted
原因: 连接池里资源已经耗尽。
解决思路:
- 检查是否存在慢查询阻塞, 连接池连接都被 hang 住了;
- 检查是否存在资源池参数不合理, 例如 QPS 高、连接池小;
- 检查是否存在连接泄露( 没有 close()) , 此类问题比较难定位, 例如 client list、netstat 等, 最重要的是代码;
- 检查是否存在 DNS 异常等。
- nginx接入层限流: 按照一定的规则如帐号、IP、系统调用逻辑等在Nginx层面做限流。
- 业务应用系统限流: 通过业务代码控制流量这个流量可以被称为信号量, 可以理解成是一种锁, 它可以限制一项资源最多能同时被多少进程访问。
- 数据库限流: 红线区, 力保数据库。
推荐阅读
- Android疑难杂症之android:configChanges="orientation" 无效
- 12个最佳门票转售网站推荐合集(适合买家和卖家)
- 如何在Windows 10笔记本电脑或PC上录制Zoom会议(分步指南)
- 如何在Windows 10家庭版或企业版中禁用Cortana(方法介绍)
- 如何自动关闭Windows 10笔记本电脑或计算机(4种方式介绍)
- 如何寻找离我最近的公共厕所的9款最佳应用推荐合集
- 如何修复Windows 10无法调整屏幕亮度(解决方法指南)
- PHP如何使用ImagickDraw annotation()函数(代码示例)
- .NET Framework开发简要介绍