Android NFC标签 开发深度解析 触碰的艺术
Posted 一叶知秋V
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
- 资源开销,例如 虽然希望控制空闲连接,但是不希望因为连接池的频繁释放创建连接造成不必要的开销。
建议 maxIdle = maxTotal,减少创建新连接的开销。
建议预热 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 异常等。
2.基于Redis实现分布式应用限流
限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务。实际场景中常用的限流策略:
- nginx接入层限流:按照一定的规则如帐号、IP、系统调用逻辑等在Nginx层面做限流。
- 业务应用系统限流:通过业务代码控制流量这个流量可以被称为信号量,可以理解成是一种锁,它可以限制一项资源最多能同时被多少进程访问。
- 数据库限流:红线区,力保数据库。
通过业务应用系统限流实现方案参考:https://my.oschina.net/giegie/blog/1525931
以上是关于Android NFC标签 开发深度解析 触碰的艺术的主要内容,如果未能解决你的问题,请参考以下文章