1、内容管理功能添加缓存。
a) 使用redis做缓存工具
b) 实现系统高可用,redis需要做主备。使用redis做分片集群。Redis集群的搭建。
c) 向业务逻辑中添加缓存。
遇到406问题:
1.检查是否有Jackson包。
2.如果后缀是HTML是不能相应json数据的。需要修改后缀名。
Post乱码问题:
使用redis做缓存
先决条件:yum install gcc-c++1.下载redis的源码包。
2.把源码包上传到服务器。
3.解压源代码
tar -zxvf redis-3.0.0.tar.gz
4.make
5.make install PREFIX=/usr/local/redis
启动redis
1丶/usr/local/redis/redis-service 端口是6397
2、后端启动
1)从redis的源码目录中复制redis.conf到redis的安装目录。
2)修改配置文件
3)[root@bogonbin]# ./redis-server redis.conf
Redis集群的搭建
需要安装rubyyum install ruby
yum install rubygems
redis集群管理工具redis-trib.rb
[root@bogon ~]# cd redis-3.0.0
[root@bogon redis-3.0.0]# cd src
[root@bogon src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 Apr 1 07:01 redis-trib.rb
[root@bogon src]#
安装ruby的包:
gem install redis-3.0.0.gem
[root@bogon ~]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation forredis-3.0.0...
Installing RDoc documentation forredis-3.0.0...
1.创建6个redis实例,端口号从7001~7006
2.修改redis的配置文件
3.把创建集群的ruby脚本复制到redis-cluster目录下
4.启动6个redis实例
5.创建集群
./redis-trib.rb create --replicas 1 192.168.25.153:7001 192.168.25.153:7002 192.168.25.153:7003 192.168.25.153:7004 192.168.25.153:7005 192.168.25.153:7006
测试集群:
[root@bogon redis-cluster]# redis01/redis-cli -h 192.168.25.153 -p 7002 -c
关闭redis:
redis01/redis-cli -p 7001 shutdown
[root@bogon redis-cluster]# redis01/redis-cli -h 192.168.25.153 -p 7002
192.168.25.153:7002> set a 100
(error) MOVED 15495 192.168.25.153:7003
192.168.25.153:7002>
[root@bogon redis-cluster]# redis01/redis-cli -h 192.168.25.153 -p 7002 -c
192.168.25.153:7002> set a 100
-> Redirected to slot [15495] located at 192.168.25.153:7003
OK
192.168.25.153:7003>
Redis客户端
Redis-cli
自带客户端。使用最多的。
图形化界面客户端
需要注意哦:开启6397的端口
Jedis客户端
需要把jedis的jar包添加到工程中,如果是maven需要添加jar包的坐标。
单机版:
@Test
public void testJedisSingle(){
//创建一个jedis的对象
Jedis jedis = new Jedis("192.168.126.133",6379);
jedis.auth("123");
//调用jedis对象的方法,方法名称和redis的命令一致
jedis.set("key1","jedis test");
String string = jedis.get("key1");
System.out.println(string);
jedis.close();
}
@Test
public void testJedispoll(){
JedisPool pool = new JedisPool("192.168.126.133",6379);
Jedis resource = pool.getResource();
resource.auth("123");
String string = resource.get("key1");
System.out.println(string);
resource.close();
pool.close();
}
集群版:要打开虚拟机的端口,见另外转载的一篇博客。
@Test
public void testJedisCluster(){
HashSet<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.126.133", 7001));
nodes.add(new HostAndPort("192.168.126.133", 7002));
nodes.add(new HostAndPort("192.168.126.133", 7003));
nodes.add(new HostAndPort("192.168.126.133", 7004));
nodes.add(new HostAndPort("192.168.126.133", 7005));
nodes.add(new HostAndPort("192.168.126.133", 7006));
JedisCluster cluster = new JedisCluster(nodes);
//cluster.auth("123");
cluster.set("key1", "1000");
String string = cluster.get("key1");
System.out.println(string);
cluster.close();
}
jedis整合spring
单机整合:
<bean id="redisClient" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="6379"></constructor-arg>
</bean>
@Test
public void testSpring(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-jedis.xml");
JedisPool pool = (JedisPool) context.getBean("redisClient");
Jedis jedis = pool.getResource();
jedis.auth("123");
String string = jedis.get("key1");
System.out.println(string);
pool.close();
jedis.close();
}
集群版:<!-- 集群版 -->
<bean id="redisClient" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7002"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7003"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.153"></constructor-arg>
<constructor-arg name="port" value="7004"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7005"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7006"></constructor-arg>
</bean>
</set>
</constructor-arg>
<!-- <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg> -->
</bean>
@Test
public void testCluster(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-jedis.xml");
JedisCluster cluster = (JedisCluster) context.getBean("redisClient");
//cluster.auth("123");
String string = cluster.get("key1");
System.out.println(string);
cluster.close();
}
添加jedis dao
单机版
@Autowired
private JedisPool jedisPool;
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
jedis.auth("123");
String string = jedis.get(key);
jedis.close();
return string;
}
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
jedis.auth("123");
String set = jedis.set(key, value);
jedis.close();
return set;
}
@Override
public String hget(String hkey, String key) {
Jedis jedis = jedisPool.getResource();
jedis.auth("123");
String set = jedis.hget(hkey, key);
jedis.close();
return set;
}
@Override
public Long hset(String hkey, String key, String value) {
Jedis jedis = jedisPool.getResource();
jedis.auth("123");
Long hset = jedis.hset(hkey, key, value);
jedis.close();
return hset;
}
@Override
public long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long long1 = jedis.incr(key);
jedis.close();
return long1;
}
@Override
public long expire(String key, int second) {
Jedis jedis = jedisPool.getResource();
Long expire = jedis.expire(key, second);
jedis.close();
return expire;
}
@Override
public long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long ttl = jedis.ttl(key);
jedis.close();
return ttl;
}
spring配置文件<bean id="redisClient" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="6379"></constructor-arg>
</bean>
<bean id="jedisClient" class="com.taotao.rest.dao.impl.JedisClientSingle">
</bean>
集群版
@Autowired
private JedisCluster jedisCluster;
@Override
public String get(String key) {
// TODO Auto-generated method stub
return jedisCluster.get(key);
}
@Override
public String set(String key, String value) {
// TODO Auto-generated method stub
return jedisCluster.set(key, value);
}
@Override
public String hget(String hkey, String key) {
// TODO Auto-generated method stub
return jedisCluster.hget(hkey, key);
}
@Override
public Long hset(String hkey, String key, String value) {
// TODO Auto-generated method stub
return jedisCluster.hset(hkey, key, value);
}
@Override
public long incr(String key) {
// TODO Auto-generated method stub
return jedisCluster.incr(key);
}
@Override
public long expire(String key, int second) {
// TODO Auto-generated method stub
return jedisCluster.expire(null, second);
}
@Override
public long ttl(String key) {
// TODO Auto-generated method stub
return jedisCluster.ttl(key);
}
spring配置文件
<bean id="redisClient" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7002"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7003"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.153"></constructor-arg>
<constructor-arg name="port" value="7004"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7005"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.126.133"></constructor-arg>
<constructor-arg name="port" value="7006"></constructor-arg>
</bean>
</set>
</constructor-arg>
</bean>
<bean id="jedisClientCluster" class="com.taotao.rest.dao.impl.JedisClientCluster"></bean>
把缓存添加到业务逻辑
@Autowired
private TbContentMapper contentMapper;
@Autowired
private JedisClient jedisClient;
@Value("${INDEX_CONTENT_REIDS_KEY}")
private String INDEX_CONTENT_REIDS_KEY;
@Override
public List<TbContent> getContentList(long contentCid) {
//从缓存中取
try {
String string = jedisClient.hget(INDEX_CONTENT_REIDS_KEY, contentCid+"");
if(!StringUtils.isEmpty(string)){
List<TbContent> resultList = JsonUtils.jsonToList(string, TbContent.class);
return resultList;
}
} catch (Exception e) {
e.printStackTrace();
}
TbContentExample example = new TbContentExample();
Criteria criteria = example.createCriteria();
criteria.andCategoryIdEqualTo(contentCid);
List<TbContent> list = contentMapper.selectByExample(example);
//向缓存中添加内容
try {
//把list转换成字符串
String cacheString = JsonUtils.objectToJson(list);
jedisClient.hset(INDEX_CONTENT_REIDS_KEY, contentCid+"", cacheString);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
缓存同步
当后台管理系统,修改内容之后需要通知redis把修改的内容对应的分类id的key删除。
Dao层
使用JedisClient接口对应的实现类。
6.4 Service层
接收内容分类id,调用dao删除redis中对应的hash中key为分类id的项。
参数:内容分类id
返回值:TaotaoResult
@Service
class RedisServiceImpl implements RedisService{
@Autowired
private JedisClient jedisClient;
@Value("${INDEX_CONTENT_REIDS_KEY}")
private String INDEX_CONTENT_REIDS_KEY;
@Override
public TaotaoResult syncContent(long contentCid) {
try {
jedisClient.hdel(INDEX_CONTENT_REIDS_KEY, contentCid+"");
} catch (Exception e) {
return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
}
return TaotaoResult.ok();
}
}
Controller层接收内容分类id,调用Service返回taotaoResult。
@Controller
@RequestMapping("/cache/sync")
public class RedisController {
@Autowired
private RedisService redisService;
@RequestMapping("/content/{contentCid}")
@ResponseBody
public TaotaoResult contentCahceSync(@PathVariable Long contentCid){
TaotaoResult result = redisService.syncContent(contentCid);
return result;
}
}
同步缓存服务的调用需要在后台管理系统中添加一个服务调用的逻辑。当修改内容信息后,需要调用此服务同步缓存。
//添加缓存同步逻辑
try {
HttpClientUtil.doGet(REST_BASE_URL+REST_CONTENT_SYNC_URL+tbContent.getCategoryId());
} catch (Exception e) {
e.printStackTrace();
}