springboot+shiro-redis 使用Redis sentinel(哨兵)主从实现

最近公司项目遇到一台服务器崩溃导致项目无法运行,因项目采用单点的 Redis做session共享,权限处理,所以想到采用Redis主从方式这样降低耦合性,为方便以后查阅特记录此处。

服务器系统为centos 7 redis 4.0.6

两台主从Redis服务器: 192.168.0.35 6379 主
192.168.0.34 6379 从
一、Redis安装

cd /opt

wget http://download.redis.io/releases/redis-4.0.6.tar.gz 若提示为找到该命令,那么需要安装:yum install wget

tar xzf redis-4.0.6.tar.gz

cd redis-4.0.6
make

src/redis-server

客户端访问:

src/redis-cli


Redis设置开机自启动:

1.修改配置文件参数daemonize为yes
.vi /opt/redis-4.0.6/redis.conf

  1. 复制redis配置文件(启动脚本需要用到配置文件内容,所以要复制)
    #1.在/etc下新建redis文件夹
    $ mkdir /etc/redis
    #2.把安装redis目录里面的redis.conf文件复制/etc/redis/6379.conf面,6379.conf是取的文件名称,启动脚本里面的变量会读取这个名称,所以要是redis的端口号改了,这里也要修改
    $ cp /opt/redis-4.0.6/redis.conf /etc/redis/6379.conf

    1. 复制redis启动脚本
      find / -name redis_init_script

      • redis启动脚本一般在redis根目录的utils,如果不知道路径,可以先查看路径

    find / -name redis_init_script

    • 复制启动脚本到/etc/init.d/redis文件中
      cp /opt/redis-3.2.4//utils/redis_init_script /etc/init.d/redis
    • 修改启动脚本参数
      vi /etc/init.d/redis

#在/etc/init.d/redis文件的头部添加下面两行注释代码,也就是在文件中#!/bin/sh的下方添加

#chkconfig: 2345 10 90
#description: Start and Stop redis

如图


同时还要修改参数,指定redis的安装路径

由于项目需求,redis需要外界访问所以采用密码方式:
masterauth test(注意若设置密码主从密码最好一直,方便后面sentinel模式访问)

打开redis命令:service redis start
关闭redis命令:service redis stop
设为开机启动:chkconfig redis on

至此35上的Redis安装成功,34服务器上也按类似方法安装,由于34是从所以在6379.conf中多一些配置
slaveof 192.168.0.35 6379
如图

登陆34查看信息

至此Redis主从全部安装完成,下面配置哨兵

二、sentinel 配置
#将sentinel配置文件拷贝到/etc/redis目录后编辑

1.自动启动


2.启动
redis-sentinel sentinel.conf


当退出是 sentinel也退出 了,这时我们就采用redis-sentinel /etc/redis/sentinel.conf

查看进程sentinel进程一直都在。在35上也同样配置到此Redis所以操作结束。

三、shior-Redis连接Redis

maven配置

此处切记shiro-redis架包使用比较新的,当时使用2.4.2.1-RELEASE时无法使用哨兵主从。
application配置

ShiroConfig 代码



@Configuration
public class ShiroConfig {

@Value("${spring.redis.host}")
private String host;

@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;

@Value("${spring.redis.sentinel.nodes}")
private String redisNodes;
@Value("${spring.redis.sentinel.master}")
private String master;

@Value("${shiro.redisCacheExpire:1800}")
private int redisCacheExpire;

@Value("${shiro.filterChainDefinitions}")
private String filterChainDefinitions;

@Value("${shiro.sessionValidationInterval:300000}")
private long sessionValidationInterval;

@Autowired
private AuthorityService authorityService;

/**
 * 配置shiro redisManager  ----单点时使用
 * 使用的是shiro-redis开源插件
 *
 * @return
 */

// public RedisManager redisManager() {
// RedisManager redisManager = new RedisManager();
// redisManager.setHost(host);
// redisManager.setPort(port);
// redisManager.setPassword(password);
// redisManager.setExpire(redisCacheExpire);
//// redisManager.setTimeout(2000);
// return redisManager;
// }

/**
 * 配置shiro redisSentinelManager   哨兵模式
 * 使用的是shiro-redis开源插件
 * @return
 */
public RedisSentinelManager redisSentinelManager(){
    RedisSentinelManager redisSentinelManager = new RedisSentinelManager();
    redisSentinelManager.setMasterName(master);
    redisSentinelManager.setHost(redisNodes);
    redisSentinelManager.setPassword(password);
    return redisSentinelManager;
}

/**
 * cacheManager 缓存 redis实现
 * 使用的是shiro-redis开源插件
 *
 * @return
 */
public RedisCacheManager cacheManager() {
    RedisCacheManager redisCacheManager = new RedisCacheManager();

// redisCacheManager.setRedisManager(redisManager());
redisCacheManager.setRedisManager(redisSentinelManager());
return redisCacheManager;
}

/**
 * RedisSessionDAO shiro sessionDao层的实现 通过redis
 * 使用的是shiro-redis开源插件
 */
public RedisSessionDAO redisSessionDAO() {
    RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
    redisSessionDAO.setRedisManager(redisSentinelManager());
    return redisSessionDAO;
}

/**
 * shiro session的管理
 */
public DefaultWebSessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    sessionManager.setSessionDAO(redisSessionDAO());
    Cookie cookie =  sessionManager.getSessionIdCookie();
    cookie.setName("emp_sid");
    sessionManager.setSessionIdCookie(cookie);
    //shiro session过期监听器
    sessionManager.setSessionListeners(Arrays.asList(new ShiroSessionListener()));
    sessionManager.setSessionValidationInterval(sessionValidationInterval);
    return sessionManager;
}

/**
 * 凭证匹配器
 *
 * @return
 */
public CredentialsMatcher credentialsMatcher() {
    RetryLimitHashedCredentialsMatcher credentialsMatcher = new RetryLimitHashedCredentialsMatcher(cacheManager());
    credentialsMatcher.setHashAlgorithmName("md5");//加密算法名称
    credentialsMatcher.setHashIterations(2);
    credentialsMatcher.setStoredCredentialsHexEncoded(true);
    return credentialsMatcher;
}

/**
 * Realm实现
 *
 * @return
 */
@Bean
public AuthorizingRealm userRealm() {
    EmployeeRealm employeeRealm = new EmployeeRealm();
    employeeRealm.setCredentialsMatcher(credentialsMatcher());
    //关闭登陆用户信息缓存
    employeeRealm.setAuthenticationCachingEnabled(false);
    employeeRealm.setAuthorizationCachingEnabled(true);
    return employeeRealm;
}

/**
 * 安全管理器
 *
 * @return
 */
@Bean
public SecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(userRealm());
    securityManager.setSessionManager(sessionManager());
    securityManager.setCacheManager(cacheManager());

    ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
    authorizer.setRealms(securityManager.getRealms());
    authorizer.setPermissionResolver(new EmployeePermissionResolver());
    authorizer.setRolePermissionResolver(rolePermissionResolver());

    securityManager.setAuthorizer(authorizer);

    securityManager.setRememberMeManager(rememberMeManager());

    return securityManager;
}

@Bean
public RolePermissionResolver rolePermissionResolver() {
    return new MyRolePermissionResolver();
}

@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);

    Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
    StaticUrlFilter staticUrlFilter = new StaticUrlFilter();
    filters.put("staticUrl", staticUrlFilter);
    TokenFilter tokenFilter=new TokenFilter();
    filters.put("token",tokenFilter);
    AuthorityFilter authorityFilter = new AuthorityFilter();
    authorityFilter.setActionService(authorityService);
    filters.put("auth", authorityFilter);
    VersionFilter versionFilter = new VersionFilter();
    filters.put("version", versionFilter);

    shiroFilterFactoryBean.setFilters(filters);
    //拦截器.
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
    // 配置不会被拦截的链接 顺序判断
    //拦截器url配置格式为:/**=user,等号前面为路径,后面为名称,多个拦截器用‘,‘分割,多个配置之间用‘;‘分割
    if (!StringUtils.isEmpty(filterChainDefinitions)) {
        String[] array = StringUtils.delimitedListToStringArray(filterChainDefinitions, ";");
        for (String str : array) {
            if(StringUtils.isEmpty(str)){
                continue;
            }
            String[] urlArray = str.split("=");

            filterChainDefinitionMap.put(urlArray[0].trim(), urlArray[1].trim());

// String[] filterArray = urlArray[1].split(",");
// for (String s : filterArray) {
// filterChainDefinitionMap.put(urlArray[0].trim(), s.trim());
// }
}
}
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// shiroFilterFactoryBean.setFilterChainDefinitions(filterChainDefinitions);
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/");
shiroFilterFactoryBean.setUnauthorizedUrl("/401");

    return shiroFilterFactoryBean;
}

public CookieRememberMeManager rememberMeManager() {
    CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
    rememberMeManager.getCookie().setMaxAge(2592000);//有效期30天
    rememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
    return rememberMeManager;
}

}

原文地址:http://blog.51cto.com/1745012/2115011

时间: 2024-10-14 16:05:43

springboot+shiro-redis 使用Redis sentinel(哨兵)主从实现的相关文章

redis哨兵主从配置

REDIS哨兵主从配置 环境描述操作系统:CentOS 5.10 x64硬件配置:阿里云8核8G100G硬盘.IP地址:10.253.2.32 [默认主]IP地址:10.253.5.158[默认从]版本号:redis-2.8 Redis安装部署 Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串,链表,集 合和有序集合.支持在服务器端计算集合的并,交和补集.(difference)等,还支持多种排序功能.所以Redis

Redis高可用方案哨兵机制------ 配置文件sentinel.conf详解

redis的哨兵机制是官方推荐的一种高可用(HA)方案,我们在使用Redis的主从结构时,如果主节点挂掉,这时是不能自动进行主备切换和通知客户端主节点下线的. Redis-Sentinel机制主要用三个功能: (1)监控:不停监控Redis主从节点是否安装预期运行 (2)提醒:如果Redis运行出现问题可以 按照配置文件中的配置项 通知客户端或者集群管理员 (3)自动故障转移:当主节点下线之后,哨兵可以从主节点的多个从节点中选出一个为主节点,并更新配置文件和其他从节点的主节点信息. 这里先把哨兵

Redis的主从复制与Redis Sentinel哨兵机制

1    Redis的主从复制 1.1   什么是主从复制 持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,不过通过redis的主从复制机制就可以避免这种单点故障,如下图: 说明: n  主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务. n  主redis中的数据和从re

redis高可用之redis sentinel(哨兵)的搭建以及应用

redis的sentinel可以监控redis一个和多个redis的主从复制架构. 主要实现的功能有: 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常. 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知. 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会

redis可用性提升(哨兵sentinel)配置示例

redis提供了sentinel(哨兵)机制,通过sentinel模式启动redis后,自动监控master/slave的运行状态,基本原理是:心跳机制+投票裁决 每个sentinel会向其它sentinal.master.slave定时发送消息,以确认对方是否"活"着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的"主观认为宕机" Subjective Down,简称SDOWN). 若"哨兵群"中的多数sentinel,都

redis sentinel哨兵模式集群搭建教程

1.环境说明 我们将使用192.168.220.128.192.168.220.129.192.168.220.130三台机器搭建sentinel集群 当前我们已在192.168.220.128上按redis安装教程安装了redis,192.168.220.129和192.168.220.130两台上没有安装 2.配置并启动192.168.220.128上的sentinel 2.1修改conf/redis.conf,配置masterauth字段值 2.2修改conf/sentinel.conf,

springboot+shiro+redis(单机redis版)整合教程-续(添加动态角色权限控制)

相关教程: 1. springboot+shiro整合教程 2. springboot+shiro+redis(单机redis版)整合教程 3. springboot+shiro+redis(集群redis版)整合教程 参考此教程前请先阅读 2.springboot+shiro+redis(单机redis版)整合教程,此教程是在其基础上进行修改添加动态角色权限的. 本教程整合环境: java8 maven redis(单机) 开发工具: idea 版本: springboot 1.5.15.RE

Redis sentinel 哨兵监测

  Sentinel 进程是用于监控 redis 集群中 Master 主服务器工作的状态,在 Master 主服务器发生故障的时候,可以实现 Master 和 Slave 服务器的切换,保证系统的高可用,其已经被集成在 redis2.6+的版本中, Redis 的哨兵模式到了 2.8 版本之后就稳定了下来.一般在生产环境也建议使用 Redis 的 2.8 版本的以后版本.哨兵(Sentinel) 是一个分布式系统, 可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(

Redis Sentinel(哨兵详解)

摘要:Redis Sentinel(哨兵):集群解决方案 官方文档(英文) http://redis.io/topics/sentinel .Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常. 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应

(六) Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)

参考并感谢 官方文档 https://hub.docker.com/_/redis GitHub https://github.com/antirez/redis happyJared https://blog.csdn.net/qq_28804275/article/details/80938659 下载redis镜像(不带tag标签则表示下载latest版本) docker pull redis 从github 下载最新的redis.conf,注意重要参数 # 端口 port 6379 #