一般情况下,一个web系统的架构是类似这样的:
一个或多个nginx做负载均衡,后面连多个tomcat(或别的类型的web服务器)。
nginx做负载的时候,关于request的分流,至少就有两种策略,第一种就是根据请求的ip做hash,这样能保证同一个ip的请求都映射到同一个tomcat上。第二种,就是直接按照时间或者后端服务器的性能,负载等条件进行分流,那么这样,比如就会产生session问题。
所以一般的web系统,会把用户的session单独放到一个服务器上,业内大多使用Redis来存储用户session。
这种架构,后端可以使用一个redis实例,也可以使用多个redis实例。
如果是单redis的话,与tomcat整合比较简单
见下文
http://blog.csdn.net/qq584852076/article/details/46502185
但是,如果只有一个redis,总感觉有点不安全,我们可以使用多个redis。
一般的架构如图:
OK,在这篇博客里
我用了一个nginx,版本号1.10.2
2个tomcat,版本号都是7.0.68
6个Redis实例构成的RedisCluster,版本号是3.2.0。集群的模式,就是官方推出的Cluster,key在服务器端分流。关于redis集群的构建,大家可以参考 http://blog.csdn.net/xu470438000/article/details/42971091
我当时在搭建redis集群的时候,碰到的最大的问题就是关于ruby组件的使用。
太tm丢人了。
当时总是出现./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)
后来误打误撞解决了问题。
似乎当时使用了rvm选择了默认的ruby版本才OK的
参见: https://my.oschina.net/junfrost/blog/143487
OK,行文到此,我默认大家目前都已经把nginx和redis集群都搭建好了(其实这篇文章里面的技术和nginx没关系)
那么单redis和rediscluster的使用有什么区别么?
单redis的java客户端使用的是jedis,例子如下:
RedisCluster的java客户端使用的不是jedis而是JedisCluster,例子如下:
为啥没有?
因为JedisCluster内部就有池的实现。同时JedisCluser的get/set/exist都是使用的模板模式,connection是共用的。如果还不清楚,那就去看源码
参见 http://brandnewuser.iteye.com/blog/2312071
大家明白了么?
我们按照 http://blog.csdn.net/qq584852076/article/details/46502185 这篇博客里说的
tomcat-redis-session-manager
里面使用的Jedis!
那么如果我使用的RedisCluster的集群模式
改动tomcat的context.xml,如下:(同时那几个jar包也得放进去,参见之前的 单redis与tomcat整合)
会报这个错误:
这个错误是什么意思?
你用jedis去连接RedisCluster还问我为什么!!!???
那咋办?改呗。改什么?改tomcat-redis-session-manager的源码呗。
我们根据上面那个错误,可以看到问题发生在RedisSessionManager的loadSessionDataFromRedis方法。
那既然知道问题了,那就好改了
大体的说:把Jedis改成JedisCluster即可
但是具体要改的的地方还不少,代码我就不贴上来了,具体见:
https://github.com/cxyxd/tomcat-redis-session-manager/blob/master/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java
这个项目用的别的组件如下:
本来想直接上传到csdn的资源栏目的,不过传了几次都是错误。
jredis cluster客户端使用
JedisCluster中应用的Apache Commons Pool对象池技术
tomcat7 redis session 共享
一个或多个nginx做负载均衡,后面连多个tomcat(或别的类型的web服务器)。
nginx做负载的时候,关于request的分流,至少就有两种策略,第一种就是根据请求的ip做hash,这样能保证同一个ip的请求都映射到同一个tomcat上。第二种,就是直接按照时间或者后端服务器的性能,负载等条件进行分流,那么这样,比如就会产生session问题。
所以一般的web系统,会把用户的session单独放到一个服务器上,业内大多使用Redis来存储用户session。
这种架构,后端可以使用一个redis实例,也可以使用多个redis实例。
如果是单redis的话,与tomcat整合比较简单
见下文
http://blog.csdn.net/qq584852076/article/details/46502185
但是,如果只有一个redis,总感觉有点不安全,我们可以使用多个redis。
一般的架构如图:
OK,在这篇博客里
我用了一个nginx,版本号1.10.2
2个tomcat,版本号都是7.0.68
6个Redis实例构成的RedisCluster,版本号是3.2.0。集群的模式,就是官方推出的Cluster,key在服务器端分流。关于redis集群的构建,大家可以参考 http://blog.csdn.net/xu470438000/article/details/42971091
我当时在搭建redis集群的时候,碰到的最大的问题就是关于ruby组件的使用。
太tm丢人了。
当时总是出现./redis-trib.rb:24:in `require': no such file to load -- rubygems (LoadError)
后来误打误撞解决了问题。
似乎当时使用了rvm选择了默认的ruby版本才OK的
参见: https://my.oschina.net/junfrost/blog/143487
OK,行文到此,我默认大家目前都已经把nginx和redis集群都搭建好了(其实这篇文章里面的技术和nginx没关系)
那么单redis和rediscluster的使用有什么区别么?
单redis的java客户端使用的是jedis,例子如下:
Jedis jedis=new Jedis("192.168.0.100", 6379);
jedis.set("name","xinxin");
如果是使用JedisPool那后面就要close一下,差别不大
RedisCluster的java客户端使用的不是jedis而是JedisCluster,例子如下:
String key = "2";
// 这东西 可以直接看到key 的分片数,就能知道放哪个 节点
System.out.println(JedisClusterCRC16.getSlot(key));
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000));
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001));
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7002));
// 3个master 节点
JedisCluster jc = new JedisCluster(jedisClusterNodes);
System.out.println(jc.get(key));
jc.setnx(key, "bar");
String value = jc.get(key);
System.out.println(value);
那JedisCluster的连接池呢?有没有JedisClusterPool?答案是没有。
为啥没有?
因为JedisCluster内部就有池的实现。同时JedisCluser的get/set/exist都是使用的模板模式,connection是共用的。如果还不清楚,那就去看源码
参见 http://brandnewuser.iteye.com/blog/2312071
大家明白了么?
我们按照 http://blog.csdn.net/qq584852076/article/details/46502185 这篇博客里说的
tomcat-redis-session-manager
里面使用的Jedis!
那么如果我使用的RedisCluster的集群模式
改动tomcat的context.xml,如下:(同时那几个jar包也得放进去,参见之前的 单redis与tomcat整合)
<?xml version='1.0' encoding='utf-8'?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!-- tomcat-redis-session共享配置 -->
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60" />
<!----------------------------- -->
</Context>
会如何呢?
会报这个错误:
这个错误是什么意思?
你用jedis去连接RedisCluster还问我为什么!!!???
那咋办?改呗。改什么?改tomcat-redis-session-manager的源码呗。
我们根据上面那个错误,可以看到问题发生在RedisSessionManager的loadSessionDataFromRedis方法。
源码如下:
//RedisSessionManager.java
public byte[] loadSessionDataFromRedis(String id) throws IOException {
Jedis jedis = null;
Boolean error = true;
try {
log.trace("Attempting to load session " + id + " from Redis");
jedis = acquireConnection();
byte[] data = jedis.get(id.getBytes());
error = false;
if (data == null) {
log.trace("Session " + id + " not found in Redis");
}
return data;
} finally {
if (jedis != null) {
returnConnection(jedis, error);
}
}
}
看到了吧,使用的是jedis。
那既然知道问题了,那就好改了
大体的说:把Jedis改成JedisCluster即可
但是具体要改的的地方还不少,代码我就不贴上来了,具体见:
https://github.com/cxyxd/tomcat-redis-session-manager/blob/master/src/main/java/com/orangefunction/tomcat/redissessions/RedisSessionManager.java
这个项目用的别的组件如下:
compile group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '7.0.68'
compile group: 'redis.clients', name: 'jedis', version: '2.8.2'
compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.4.2'
我靠你说了半天,整合rediscluster(v-3.2.0)与tomcat7的最主要的jar包在哪么?
http://pan.baidu.com/s/1dEZZFmp本来想直接上传到csdn的资源栏目的,不过传了几次都是错误。
好的我们看看效果
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
/usr/local/tomcat7_forZW/webapps/PathTest--8080
<br>
SessionID:<%=session.getId()%>
</body>
</html>
我们在两个tomcat下都放一个sessiontest.jsp,内容如上
/usr/local/tomcat7_forZW/webapps/PathTest--8080这是tomcat的地址与端口号,两个jsp的这部分内容不一样(一个端口是,8080一个是1314)
我们访问一下:
换个地址,结果如下:
我们再去看看redis里面
jredis cluster客户端使用
JedisCluster中应用的Apache Commons Pool对象池技术
tomcat7 redis session 共享