2019-08-20 tomcat基于redis會(huì)話共享的集群配置。

實(shí)際上這個(gè)需求包含三個(gè)部分:

  • 基于tomcat的多個(gè)應(yīng)用節(jié)點(diǎn),但并不希望配置tomcat cluster
  • 基于httpd 實(shí)現(xiàn)負(fù)載均衡。
  • 為實(shí)現(xiàn)上述目的,考慮使用redis作為集中session存儲(chǔ),實(shí)現(xiàn)一個(gè)節(jié)點(diǎn)登錄后,在所有節(jié)點(diǎn)都處于已登錄狀態(tài)。

tomcat的配置

tomcat的部署和配置過程就不描述了,屬于基本操作。
這里只描述部署的結(jié)構(gòu),后面配置httpd的負(fù)載均衡時(shí)要用到。
tomcat1:
訪問路徑:http://ip1:port1/appName
tomcat2:
訪問路徑:http://ip1:port2/appName
tomcat3:
訪問路徑:http://ip2:port3/appName

httpd負(fù)載均衡

httpd2.4版本的配置文件結(jié)構(gòu),和我們有關(guān)的部分如下:

/etc/httpd/
               conf/
               conf.d/
               conf.module.d/
  1. 添加負(fù)載均衡配置
    使用如下命令編輯配置文件:
vi /etc/httpd/conf.d/proxy.conf

添加內(nèi)容:

<Proxy balancer://myCluster>
    BalancerMember http://ip1:port1/appName loadfactor=3
    BalancerMember http://ip1:port2/appName loadfactor=3
    BalancerMember http://ip2:port3/appName loadfactor=3
    ProxySet lbmethod=byrequests
</Proxy>
ProxyRequests Off
ProxyPass /appName balancer://myCluster stickysession=JSESSIONID nofailover=Off
ProxyPassReverse /appName balancer://myCluster
  1. 添加負(fù)載均衡監(jiān)控配置
    使用個(gè)如下命令新增配置文件:
vi /etc/httpd/conf.d/lbmgr.conf

添加內(nèi)容:

<Location /balancer-manager>
    SetHandler balancer-manager
    Order Allow,Deny
    Allow from all
</Location>

其中,<Location / 后面的名字,不一定是 balancer-manager,你可以取自己喜歡的名字,比如lbmgr。在最后訪問httpd的負(fù)載均衡器監(jiān)控時(shí),記得你配置的是什么就行了。
最后訪問負(fù)載均衡器監(jiān)控的路徑是: http://ip/lbmgr

  1. 重啟httpd使配置生效:
service httpd restart

應(yīng)用配置

要讓我們基于spring-mvc的遺留系統(tǒng)支持spring-session和redis的會(huì)話共享,需要對(duì)應(yīng)用進(jìn)行配置。

  1. 添加spring-session的配置
    先看配置代碼,再解釋:

@EnableRedisHttpSession
@PropertySource({"classpath:/com/aa/bb/config/properties/redis.properties"})
public class SpringSessionRedisConfig {
    
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    
    @Value("${maxInactiveIntervalInSeconds}")
    private int maxInactiveIntervalInSeconds;

    @Value("${maxTotal}")
    private int maxTotal;

    @Value("${maxIdle}")
    private int maxIdle;

    @Value("${host}")
    private String hostName;

    @Value("${port}")
    private int port;

    @Value("${timeout}")
    private int timeout;

    @Value("${usePool}")
    private boolean usePool;

    @Value("${maxWaitMillis}")
    private int maxWaitMillis;

    @Value("${testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${password}")
    private String password;
    
    @Bean
    public  redisHttpSessionConfiguration() {
        RedisHttpSessionConfiguration bean = new RedisHttpSessionConfiguration();
        bean.setMaxInactiveIntervalInSeconds(this.maxInactiveIntervalInSeconds);
        
        return bean;
    }
    
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig bean = new JedisPoolConfig();
        bean.setMaxIdle(this.maxIdle);
        bean.setMaxTotal(this.maxTotal);
        
        return bean;
    }
    
    @Bean(destroyMethod = "destroy")
    public RedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
        //單機(jī)版jedis
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(this.hostName);
        redisStandaloneConfiguration.setPort(this.port);
        redisStandaloneConfiguration.setDatabase(0);
//        redisStandaloneConfiguration.setPassword(RedisPassword.of(this.password));
        //客戶端配置
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
                (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        //指定jedisPoolConifig來修改默認(rèn)的連接池構(gòu)造器(真麻煩,濫用設(shè)計(jì)模式?。?        jpcb.poolConfig(jedisPoolConfig);
        JedisClientConfiguration jedisClientConfiguration = jpcb.build();
        
        //單機(jī)配置 + 客戶端配置 = jedis連接工廠
        return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
    }
    
    @Bean
    public StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}

1.1. 上述配置中,最關(guān)鍵的是:

    @Bean
    public RedisHttpSessionConfiguration redisHttpSessionConfiguration() {
        RedisHttpSessionConfiguration bean = new RedisHttpSessionConfiguration();
        bean.setMaxInactiveIntervalInSeconds(this.maxInactiveIntervalInSeconds);
        
        return bean;
    }

因?yàn)閟pring-session通過RedisHttpSessionConfiguration,提供了一系列的bean和相關(guān)配置,實(shí)現(xiàn)了用spring-session的會(huì)話管理器替換tomcat自己的session會(huì)話管理器,并存儲(chǔ)到redis中的效果。
這個(gè)bean必須和 @EnableRedisHttpSession 配合使用,否則不會(huì)生效。

1.2. 配置redis連接池
上述配置,只是讓spring-session將會(huì)話存儲(chǔ)到redis中,但并不知道如何連接到redis,因此需要添加必要配置,告知如何連接到redis。
實(shí)際上有多種連接器可用,我們這里使用了Jedis連接器,其他連接器的使用方式參看spring-session的官方文檔即可:

    @Bean
    public JedisPoolConfig jedisPoolConfig() {

這個(gè)配置提供redis連接池配置

    @Bean(destroyMethod = "destroy")
    public RedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {

這個(gè)配置創(chuàng)建redis鏈接工廠

    @Bean
    public StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {

這個(gè)配置提供redisTemplate。

好了,有了上述配置,到redis的鏈接就完成了。
需要注意的是,這里的方法名,就是最終生成的bean的名字,同時(shí)也是spring-session查找對(duì)應(yīng)bean時(shí),使用的名字。如果要自定義名字,那么就必須要提供全套配置,否則spring-session就找不到redis鏈接工廠等bean了。

1.3. 配置spring讀取SpringSessionRedisConfig這個(gè)配置bean
需要在spring的xml配置文件中,增加如下配置:

<context:component-scan base-package="com.aa.bb.config" />

這個(gè)配置讓spring去掃描包 com.aa.bb.config 下的@Configuratioin 注解了的配置類。

1.4. 配置spring-mvc filter,去攔截請(qǐng)求處理session
必須讓這個(gè)filter在其他filter的前面,否則可能導(dǎo)致其他filter工作時(shí)找不到正確的會(huì)話。

    <filter>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

這個(gè)配置會(huì)向spring-mvc注入一個(gè)名字叫 springSessionRepositoryFilter 的filter bean。
這個(gè)filter bean 是在前面配置的 RedisHttpSessionConfiguration 中創(chuàng)建的。

到此為止,配置就完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容