大家好,又见面了,我是你们的朋友全栈君。
目录
一、连接前的准备
二、使用JedisPool连接池创建连接
ThreadLocal为多线程保证一个线程始终同一个连接
多线程测试
三、配置多数据源
一、连接前的准备
1 . 确保windows能够ping通linux,linux能够ping通windows。
2. 开放CentOS7的端口6379 。
firewall-cmd –add-port=6379/tcp –permanent
3. 将redis.conf文件中的bind 改为 0.0.0.0
bind 0.0.0.0
4. 需要给redis设置密码才能访问,要不然会提醒没有设置密码, 修改redis.conf配置文件,指定永久密码:
# requirepass foobared requirepass 123456
5. 将protecetd-mode 设置为no
protected-mode no
6. 启动服务器。
./redis-server ../redis.conf
windows:
cd D:Program Filesredis-server-5.0.9 d: redis-server.exe redis.windows-service.conf
二、使用JedisPool连接池创建连接
添加pom依赖:
代码语言:javascript复制 <dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
</dependency>
注:访问的地址为ping通linux的地址,可以先通过redis桌面程序RedisDesktopManager测试是否可以通,再进行如下的工作。
ThreadLocal为多线程保证一个线程始终同一个连接
定义RedisConstants常量
代码语言:javascript复制package com.bing.sh.redis;
public class RedisConstants {
public static final String DEFAULT_REDIS_HOST = "localhost";
//端口
public static final int DEFAULT_REDIS_PORT = 6379;
//密码
public static final String DEFAULT_REDIS_PWD = "123456";
public static final int DEFAULT_REDIS_MAX_ACTIVE = 1024;
//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
public static final int DEFAULT_REDIS_MAX_IDLE = 200;
//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
public static final int DEFAULT_REDIS_MAX_WAIT = 10000;
//连接超时的时间
public static final int DEFAULT_REDIS_TIMEOUT = 10000;
// 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
public static final boolean DEFAULT_REDIS_TEST_ON_BORROW = true;
// 默认数据库
public static final int DEFAULT_REDIS_DATABASE = 0;
}
定义RedisProperty类:
代码语言:javascript复制package com.bing.sh.redis;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RedisProperty {
//服务器IP地址
private String host = RedisConstants.DEFAULT_REDIS_HOST;
//端口
private int port = RedisConstants.DEFAULT_REDIS_PORT;
//密码
private String pwd = RedisConstants.DEFAULT_REDIS_PWD;
//连接实例的最大连接数
private int maxActive = RedisConstants.DEFAULT_REDIS_MAX_ACTIVE;
//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private int maxIdle = RedisConstants.DEFAULT_REDIS_MAX_IDLE;
//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
private int maxWait = RedisConstants.DEFAULT_REDIS_MAX_WAIT;
//连接超时的时间
private int timeout = RedisConstants.DEFAULT_REDIS_TIMEOUT;
// 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
private boolean testOnBorrow = RedisConstants.DEFAULT_REDIS_TEST_ON_BORROW;
//数据库模式是16个数据库 0~15
public int defaultDatabase = RedisConstants.DEFAULT_REDIS_DATABASE;
}
使用ThreadLocal存放Jedis实例,保证一个线程使用的连接始终是同一个, 获取连接的时候直接从ThreadLocal里拿
代码语言:javascript复制package com.bing.sh.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisTemplate {
private static Logger logger = LoggerFactory.getLogger(JedisTemplate.class);
private static ThreadLocal<Jedis> jedisThreadLocal = new ThreadLocal<>();
private static JedisTemplate jedisTemplate = new JedisTemplate();
private static JedisPoolConfig config;
private static JedisPool jedisPool;
public static JedisTemplate getJedisTemplate(RedisProperty prop) {
if (jedisPool == null) {
initJedisPool(prop.getHost(), prop.getPort(), prop.getPwd(), prop.getTimeout(), prop.getDefaultDatabase());
}
return jedisTemplate;
}
public static JedisTemplate getJedisTemplate() {
RedisProperty prop = new RedisProperty();
if (jedisPool == null) {
initJedisPool(prop.getHost(), prop.getPort(), prop.getPwd(), prop.getTimeout(), prop.getDefaultDatabase());
}
return jedisTemplate;
}
static {
config = new JedisPoolConfig();
config.setMaxTotal(RedisConstants.DEFAULT_REDIS_MAX_ACTIVE);
config.setMaxIdle(RedisConstants.DEFAULT_REDIS_MAX_IDLE);
config.setMaxWaitMillis(RedisConstants.DEFAULT_REDIS_MAX_WAIT);
config.setTestOnBorrow(RedisConstants.DEFAULT_REDIS_TEST_ON_BORROW);
}
public static JedisPool initJedisPool(String host, int port, String pwd, int timeout, int db) {
jedisPool = new JedisPool(config, host, port, timeout, pwd, db);
logger.info("init jedis pool success >>>" jedisPool.hashCode());
return jedisPool;
}
public Jedis getJedisConnection() {
Jedis jedis = jedisThreadLocal.get();
if (ObjectUtils.isEmpty(jedis)) {
jedis = jedisPool.getResource();
jedisThreadLocal.set(jedis);
}
return jedis;
}
public void releaseConnection() {
Jedis jedis = jedisThreadLocal.get();
if (!ObjectUtils.isEmpty(jedis)) {
jedisPool.returnResource(jedis);
System.out.println("线程 ID " Thread.currentThread().getId() " 释放连接, jedis code=" jedis.hashCode() " release success !");
}
jedisThreadLocal.remove();
}
}
多线程测试
代码语言:javascript复制 public static void main(String[] args) {
RedisProperty property = new RedisProperty();
// 将自定义属性注入
property.setPwd("mypassword");
JedisTemplate jedisTemplate = JedisTemplate.getJedisTemplate(property);
for (int i = 0; i < 10; i ) {
new Thread(() -> {
System.out.println("线程 ID " Thread.currentThread().getId() " 获取连接, jedis code=" jedisTemplate.getJedisConnection().hashCode());
jedisTemplate.releaseConnection();
}).start();
}
}
三、配置多数据源
也可以采用如下的方式配置redis的多数据源,只要从jedisPoolsMap根据host取出连接池列表即可。
代码语言:javascript复制package com.bing.sh.redis;
import com.bing.sh.exception.custom.RedisInitException;
import com.bing.sh.utils.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MultipleJedisTemplate extends RedisConn {
private static Logger logger = LoggerFactory.getLogger(MultipleJedisTemplate.class);
private static MultipleJedisTemplate multipleJedisTemplate = new MultipleJedisTemplate();
private static Map<String/**host**/, List<JedisPool>> jedisPoolsMap = new ConcurrentHashMap<>();
public static Map<String, List<JedisPool>> getJedisPoolsMap() {
return jedisPoolsMap;
}
public List<JedisPool> getJedisPoolsByHost(String host) {
List<JedisPool> jedisPools = jedisPoolsMap.get(host);
logger.info(host " get jedis pool " jedisPools);
if (CollectionUtils.isNotEmpty(jedisPools)) return jedisPools;
throw new RedisInitException(host "has no JedisPoll found ! please init first");
}
private static void initMultipleJedisPool(List<RedisProperty> props) {
props.forEach((prop) -> {
String host = prop.getHost();
List<JedisPool> jedisPools = jedisPoolsMap.get(host);
if (CollectionUtils.isEmpty(jedisPools)) {
jedisPools = new ArrayList<>();
}
jedisPools.add(new JedisPool(poolConfig, prop.getHost(), prop.getPort(), prop.getTimeout(), prop.getPwd(), prop.getDefaultDatabase()));
jedisPoolsMap.put(host, jedisPools);
});
}
public static MultipleJedisTemplate getMultipleJedisTemplate(List<RedisProperty> props) {
if (CollectionUtils.isEmpty(props)) {
throw new RedisInitException("init jedis fail >>> no properties input !");
}
initMultipleJedisPool(props);
return multipleJedisTemplate;
}
@Override
void setConfig(JedisPoolConfig config) {
poolConfig = config;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/197166.html原文链接:https://javaforall.cn