溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

springboot+shiro-redis 使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

發(fā)布時(shí)間:2020-07-10 12:22:04 來(lái)源:網(wǎng)絡(luò) 閱讀:30258 作者:zhanfeng00 欄目:開(kāi)發(fā)技術(shù)

最近公司項(xiàng)目遇到一臺(tái)服務(wù)器崩潰導(dǎo)致項(xiàng)目無(wú)法運(yùn)行,因項(xiàng)目采用單點(diǎn)的 Redis做session共享,權(quán)限處理,所以想到采用Redis主從方式這樣降低耦合性,為方便以后查閱特記錄此處。

服務(wù)器系統(tǒng)為centos 7 redis 4.0.6

兩臺(tái)主從Redis服務(wù)器: 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

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

客戶端訪問(wèn):

src/redis-cli

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
Redis設(shè)置開(kāi)機(jī)自啟動(dòng):

1.修改配置文件參數(shù)daemonize為yes
.vi /opt/redis-4.0.6/redis.conf

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

  1. 復(fù)制redis配置文件(啟動(dòng)腳本需要用到配置文件內(nèi)容,所以要復(fù)制)
    #1.在/etc下新建redis文件夾
    $ mkdir /etc/redis
    #2.把安裝redis目錄里面的redis.conf文件復(fù)制/etc/redis/6379.conf面,6379.conf是取的文件名稱,啟動(dòng)腳本里面的變量會(huì)讀取這個(gè)名稱,所以要是redis的端口號(hào)改了,這里也要修改
    $ cp /opt/redis-4.0.6/redis.conf /etc/redis/6379.conf

    1. 復(fù)制redis啟動(dòng)腳本
      find / -name redis_init_script
      • redis啟動(dòng)腳本一般在redis根目錄的utils,如果不知道路徑,可以先查看路徑

    find / -name redis_init_script

    • 復(fù)制啟動(dòng)腳本到/etc/init.d/redis文件中
      cp /opt/redis-3.2.4//utils/redis_init_script /etc/init.d/redis
    • 修改啟動(dòng)腳本參數(shù)
      vi /etc/init.d/redis

#在/etc/init.d/redis文件的頭部添加下面兩行注釋代碼,也就是在文件中#!/bin/sh的下方添加

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

如圖

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
同時(shí)還要修改參數(shù),指定redis的安裝路徑
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
由于項(xiàng)目需求,redis需要外界訪問(wèn)所以采用密碼方式:
masterauth test(注意若設(shè)置密碼主從密碼最好一直,方便后面sentinel模式訪問(wèn))
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

打開(kāi)redis命令:service redis start
關(guān)閉redis命令:service redis stop
設(shè)為開(kāi)機(jī)啟動(dòng):chkconfig redis on

至此35上的Redis安裝成功,34服務(wù)器上也按類似方法安裝,由于34是從所以在6379.conf中多一些配置
slaveof 192.168.0.35 6379
如圖
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
登陸34查看信息
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

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

二、sentinel 配置
#將sentinel配置文件拷貝到/etc/redis目錄后編輯

1.自動(dòng)啟動(dòng)

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

2.啟動(dòng)
redis-sentinel sentinel.conf

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
當(dāng)退出是 sentinel也退出 了,這時(shí)我們就采用redis-sentinel /etc/redis/sentinel.conf
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
查看進(jìn)程sentinel進(jìn)程一直都在。在35上也同樣配置到此Redis所有操作結(jié)束。

三、shior-Redis連接Redis

maven配置
springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)
此處切記shiro-redis架包使用比較新的,當(dāng)時(shí)使用2.4.2.1-RELEASE時(shí)無(wú)法使用哨兵主從。
application配置

springboot+shiro-redis  使用Redis sentinel(哨兵)主從實(shí)現(xiàn)

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  ----單點(diǎn)時(shí)使用
 * 使用的是shiro-redis開(kāi)源插件
 *
 * @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開(kāi)源插件
 * @return
 */
public RedisSentinelManager redisSentinelManager(){
    RedisSentinelManager redisSentinelManager = new RedisSentinelManager();
    redisSentinelManager.setMasterName(master);
    redisSentinelManager.setHost(redisNodes);
    redisSentinelManager.setPassword(password);
    return redisSentinelManager;
}

/**
 * cacheManager 緩存 redis實(shí)現(xiàn)
 * 使用的是shiro-redis開(kāi)源插件
 *
 * @return
 */
public RedisCacheManager cacheManager() {
    RedisCacheManager redisCacheManager = new RedisCacheManager();

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

/**
 * RedisSessionDAO shiro sessionDao層的實(shí)現(xiàn) 通過(guò)redis
 * 使用的是shiro-redis開(kāi)源插件
 */
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過(guò)期監(jiān)聽(tīng)器
    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實(shí)現(xiàn)
 *
 * @return
 */
@Bean
public AuthorizingRealm userRealm() {
    EmployeeRealm employeeRealm = new EmployeeRealm();
    employeeRealm.setCredentialsMatcher(credentialsMatcher());
    //關(guān)閉登陸用戶信息緩存
    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>();
    // 配置不會(huì)被攔截的鏈接 順序判斷
    //攔截器url配置格式為:/**=user,等號(hào)前面為路徑,后面為名稱,多個(gè)攔截器用','分割,多個(gè)配置之間用';'分割
    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);
// 如果不設(shè)置默認(rèn)會(huì)自動(dòng)尋找Web工程根目錄下的"/login.jsp"頁(yè)面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登錄成功后要跳轉(zhuǎn)的鏈接
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;
}

}

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI