SpirngBoot2.13+Tomcat集群+redis5.0存储session

前言:本文章为慕课网上Java企业级电商项目架构演进之路Tomcat集群与Redis分布式的学习笔记.

目录

第一章 思路与配置概要

1.1 思路概要

1.2 配置概要

第二章 springboot连接操作redis数据库

2.1 引入redis的包

2.2 对redis进行配置

2.3 获得redis连接池

2.4 操作redis数据库

第三章 应用配置与nginx服务器与redis服务器的配置

3.1 应用配置

3.2 nginx服务器的配置

3.3 redis服务器的配置

第四章 模拟登陆展示session的存储

4.1 CookieUtil类的设置

4.2 Controller登陆模拟


第一章 思路与配置概要

1.1 思路概要

用户的http请求通过nginx反向代理到tomcat集群上,tomcat根据用户发送来的cookie中的id(自己设置的)去redis数据库中进行查找,如果找到即等于用户登陆了.

1.2 配置概要

windows服务器放nginx1.14.2

两台centos7.3服务器,一台放一个tomcat应用,另一台放一个tomcat应用+一个redis.

 

第二章 springboot连接操作redis数据库

2.1 引入redis的包

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>3.0.0</version>
</dependency>

2.2 对redis进行配置

在application.properties中对填写如下.

#redis
redis.maxtotal = 20
redis.maxIdle = 10
redis.minIdle = 2
redis.testOnReturn = true
redis.testOnBorrow = true
redis.redisPort = 6379
redis.redisIp = 202.112.88.1

2.3 获得redis连接池

将刚才在application.properties中的配置注入类中.

@Component
@ConfigurationProperties(prefix = "redis")
@Slf4j
@Getter
@Setter
public class RedisPool {
    private JedisPool pool;//jedis连接池
    private Integer maxtotal; //最大连接数
    private Integer maxIdle ; //在jedispool中最大的idle(空闲的)状态的jedis实例的个数
    private Integer minIdle ; //在jedispool中最小的idle(空闲的)状态的jedis实例的个数
    private Boolean testOnBorrow ;
    private Boolean testOnReturn ;
    private Integer redisPort ;
    private String redisIp;
    public RedisPool(){
        log.info("构造方法开始执行");
    }
    @PostConstruct
    public void initPool(){
        if(maxtotal==20) log.info("属性已经注入");
        log.info("开始创建连接池");
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxtotal);
        config.setMaxIdle(maxIdle);
        config.setMinIdle(minIdle);
        config.setTestOnBorrow(testOnBorrow);
        config.setTestOnReturn(testOnReturn);
        config.setBlockWhenExhausted(true);
        pool = new JedisPool(config,redisIp,redisPort,1000*2);
    }
    public  Jedis getJedis(){
        return pool.getResource();
    }

}

2.4 操作redis数据库

通过连接池获得jedis对象,然后就可以操作redis数据库了.

@Component
@Slf4j
public class RedisPoolUtil {
//注入刚才的redis连接池
    @Autowired
    RedisPool redisPool;
//获取redis数据库中key的值
    public  String get(String key){
        Jedis jedis = null;
        String result = null;
        try {
            jedis = redisPool.getJedis();
            result = jedis.get(key);
        } catch (Exception e) {
            log.error("get key:{} error",key,e);

        }
        jedis.close();
        return result;
    }
//增加redis数据库中的值
    public  String set(String key,String value){
        Jedis jedis = null;
        String result = null;
        try {
            jedis = redisPool.getJedis();
            result = jedis.set(key,value);
        } catch (Exception e) {
            log.error("set key:{} error",key,e);
        }
        jedis.close();
        return result;
    }
//增加redis数据库中的值并设置时间 30*60就是30分钟
    public String setEx(String key,String value,int exTime){
        Jedis jedis = null;
        String result = null;
        try {
            jedis = redisPool.getJedis();
            result = jedis.setex(key,exTime,value);
        } catch (Exception e) {
            log.error("setex key:{} value:{} error",key,value,e);
        }
        jedis.close();
        return result;
    }
//设置redis数据库中hey的时间
    public Long expire(String key,int exTime){
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = redisPool.getJedis();
            result = jedis.expire(key,exTime);
        } catch (Exception e) {
            log.error("expire key:{} error",key,e);
        }
        jedis.close();
        return result;
    }
//删除redis数据库中的key
    public Long del(String key){
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = redisPool.getJedis();
            result = jedis.del(key);
        } catch (Exception e) {
            log.error("del key:{} error",key,e);
        }
        jedis.close();
        return result;
    }
//判断redis数据库中是否存在某个key
    public Boolean exists(String key){
        Jedis jedis = null;
        Boolean result = null;
        try {
            jedis = redisPool.getJedis();
            result = jedis.exists(key);
        } catch (Exception e) {
            log.error("exists key:{} error",key,e);
        }
        jedis.close();
        return result;
    }
    
}

 

第三章 应用配置与nginx服务器与redis服务器的配置

 

打开centos服务器的的8079端口与6379端口

3.1 应用配置

 

运行mvn clean package,将jar放到两台centos7.3服务器上并用java -jar运行应用.

#Server
server.servlet.context-path=/tarcluster
server.port=8079

 

3.2 nginx服务器的配置

将端口80的请求反向代理到两个tomcat服务器上.

upstream zhang {
      server 202.112.99.1:8079;
      server 202.112.99.2:8079;
    }
    server {
        listen       80;
        server_name  zhangsan;
        location / {
            proxy_pass http://zhang;
            proxy_read_timeout 150;
            add_header Access-Control-Allow-Origin *;
        }
    }

3.3 redis服务器的配置

在后台启动redis服务器,并关闭安全模式即可.

关闭安全模式:

1.我们需要修改配置文件../redis.conf 

# bind 127.0.0.1

2.在redis.conf中设置保护模式为no

protected-mode no

启动redis服务器: ./redis-server ../redis.conf

第四章 模拟登陆展示session的存储

 

4.1 CookieUtil类的设置

@Slf4j
public class CookieUtil {
    private final static String COOKIE_DOMAIN = "";
    public static final String COOKIE_NAME = "mmall_login_token";
//将cookie写入response
    public static void writeLoginToken(HttpServletResponse response,String token){
        Cookie ck = new Cookie(COOKIE_NAME,token);
        ck.setMaxAge(60*60*24);
        ck.setPath("/");
        ck.setHttpOnly(true);
        log.info("已设置cookie:{},value:{}",ck.getName(),ck.getValue());
        response.addCookie(ck);
    }
//将cookie从request中读出
    public static String readLoginToken(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        if(cookies!=null){
            for (Cookie ck :cookies) {
                if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
                    log.info("已读取到cookie:{},value:{}",ck.getName(),ck.getValue());
                    return ck.getValue();
                }
            }
        }
        return null;
    }
//删除cookie
    public static void delLoginToken(HttpServletRequest request,HttpServletResponse response){
        Cookie[] cookies = request.getCookies();
        if(cookies!=null){
            for (Cookie ck:cookies
                 ) {
                if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
                    ck.setMaxAge(0);
                    ck.setPath("/");
                    response.addCookie(ck);
                }
            }
        }
    }

}

4.2 Controller登陆模拟

@RequestMapping("/login")
    public String login(String username, Model model, HttpSession session, HttpServletResponse response, HttpServletRequest request){
        String key = CookieUtil.readLoginToken(request);
        model.addAttribute("sessionid",session.getId());

        //key为null证明request中不存在我们设置的cookieName
        //cookie中存在我们设置的cookieName,但是reids库中不找不到对应的记录
        //key既不为null,在redis中也能根据key查找到值,表示用户已不用登陆.

        if(key!=null&&redisPoolUtil.exists(key)){
            redisPoolUtil.expire(key,30*60);
            log.info("检测到key,直接登陆");
            model.addAttribute("keyValue",redisPoolUtil.get(key));
        }else{
            log.info("请求登陆");
            User user = new User();
            user.setAddress("shijiazhuang");
            user.setName("张晨");
            user.setAge(24);
            user.setSchool("bnu");
            //模拟登陆成功找到user,将user序列化成字符串,以当次请求的sessionid为
            //key,将其存储到redis数据库中,再将sessionid为value,mmall_login_token为
            //key存储到cookie中返回.以后用户每次请求从cookie中根据mmall_login_token
            //读取出sessionid,再根据sessionid拿到序列化后的字符串.
            //obj2String是将对象序列化为字符串
            log.info("登陆成功");
            redisPoolUtil.setEx(session.getId(),JsonUtil.obj2String(user),30*60);
            CookieUtil.writeLoginToken(response,session.getId());

        }
        return  "index";
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值