java web 项目多服务器部署

目录

spring与redis配置:

Jar包

spring-redis.Xml中配置

Spring-dao.xml

序列化ClassCastException问题

maxActive和maxWait没有找到


最近做公司项目,项目结构大体完成,自己在这里做个记录,怕自己忘记!

项目想做前后端分离,多个项目组合成一个项目,但是用户感觉是一个项目,用户登录之后不需要在其他项目重复登录,根据权限用各个项目的功能。根据客户需求可以多个项目任意组合卖,这就需要项目可以部署在一个或多个tomcat并且该项目需要部署在一台电脑或者多台电脑上。

 

先说下大体用到的技术,前端angularjs,服务端ssm+redis+mysql+nginx,大体这些。

客户端与服务端通讯方式是http,传输数据是json格式。项目遇到主要问题是会话的共享和跨域。

http协议是无状态的,为了浏览器和服务器保持联系两边建立了cookie和session机制,浏览器第一次请求到tomcat,tomcat进行响应并设置cookie(tomcat设置的是jsessionid)保持在浏览器,自己保持session,这样两边建立联系。

现在问题来了,用户使用项目,但这个项目由两个Tomcat发布,用户访问a项目,Atomcat建立一套会话,当用户访问b项目Btomcat又建立一套会话,这样系统分不清是否是一个用户登录,用户可能频繁登录体验很差,为了解决这个问题我在项目中加入redis进行解决。

 

加入redis想要解决的是session共享问题,想了两个实现方式:我采用第二个(有点懒)

1. 用户第一次登陆成功时自己做一个token相当于sessionid,user是用户信息,将token作为key,user作为value存到redis数据库并设置存入时间,response时将token放入cookie中;客户端再次请求时检查请求的cookie中token和本次请求的时间,请求时间和存入时间对比不符合告诉用户超时并重新登陆,符合便根据token获取redis中的value,value存在返回信息重置存入时间,不存在则从新登陆。

2. 有一种spring封装好的代替原始session的方式,用这种方式直接设置session的同时自动往redis中存储信息。

spring与redis配置:

首先安装redis,之后spring与redis进行配置。

 

Jar包

jedis-2.9.0.jar  :redis关于java客户端的jar包;

spring-data-redis-1.7.1.RELEASE.jar :spring自己封装的redis的jar;

commons-pool2-2.5.0.jar :与redis相配合的连接池;

spring-session-1.2.0.RELEASE.jar :spring配合redis实现的session封装(突然发现spring已经有一个session封装,所以直接拿来用自己就不写cookie、session这种机制了)

 

spring-redis.Xml中配置

<beans xmlns="http://www.springframework.org/schema/beans"

     xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"

     xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"

     xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:task="http://www.springframework.org/schema/task"

     xsi:schemaLocation="

     

       http://www.springframework.org/schema/beans

       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

       http://www.springframework.org/schema/tx

       http://www.springframework.org/schema/tx/spring-tx-4.3.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

        http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-4.3.xsd

       http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd

        http://www.springframework.org/schema/task

       http://www.springframework.org/schema/task/spring-task-4.3.xsd

       http://mybatis.org/schema/mybatis-spring

       http://mybatis.org/schema/mybatis-spring.xsd

        ">

 

     <bean id="poolConfig"class="redis.clients.jedis.JedisPoolConfig">

         <!--最大空闲数 -->

         <property name="maxIdle"value="${redis.maxIdle}" />

         <!--连接池的最大数据库连接数 -->

         <property name="maxTotal"value="${redis.maxTotal}" />

         <!--最大建立连接等待时间 -->

         <property name="maxWaitMillis"value="${redis.maxWaitMillis}" />

     </bean>

 

     <!-- redis链接工厂,并配置ip、端口、密码等 -->

     <bean id="connectionFactory"

         class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

         p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"

         p:pool-config-ref="poolConfig" />

 

     <!--redis操作模版,使用该对象可以操作redis -->

     <bean id="redisTemplate"class="org.springframework.data.redis.core.StringRedisTemplate">

         <property name="connectionFactory"ref="connectionFactory" />

 

         <!-- RedisTemplate中注入序列化等属性 -->

         <property name="keySerializer">

              <bean

                   class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

         </property>

         <!-- json序列化-->

         <property name="valueSerializer">

              <bean

                   class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>

         </property>

     </bean>

 

     <!-- 设置spring-session相关 -->

     <bean id="defaultCookieSerializer"

         class="org.springframework.session.web.http.DefaultCookieSerializer">

         <!-- 设置请求时获取的项目路径 -->

         <property name="cookiePath"value="/"></property>

         <!-- 设置存入浏览器的sessionid名称 -->

         <property name="cookieName"value="NVWEBSESSIONID" />

     </bean>

 

     <!-- 将session放入redis -->

     <bean id="redisHttpSessionConfiguration"

         class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">

         <!-- 设置超时时间 -->

         <property name="maxInactiveIntervalInSeconds"value="1800" />

     </bean>

 

</beans>

Spring-dao.xml

 

<!-- 引入外部属性文件,加密 -->

    <bean class="com.nv.common.util.EncryptPropertyPlaceholderConfigurer">

    <property name="ignoreUnresolvablePlaceholders"value="true" />

    <property name="locations">

        <list>

            <value>classpath:dbconfig.properties</value>

            <value>classpath:redis.properties</value>

        </list>

    </property>

 

 

 

Web.xml:

<!--spring-session配置 -->

    <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>

spring-session这插件利用的是filter,所以需要在web.xml中进行配置,

配置完成后,测试时遇到一点问题,问题和解决问题方法如下(提出问题并解决才不是耍流氓!):

 

序列化ClassCastException问题

https://blog.csdn.net/zt_fucker/article/details/74408609

 

maxActive和maxWait没有找到

jedis的版本问题,有的属性不对应

https://blog.csdn.net/u011410529/article/details/50802397

 spring-session封装后在使用request.getSession().setAttribute()类似方法的时候其实已经存进 redis了。

经过以上配置就可以解决在一个域下(一个ip,主意127.0.0.1和localhost不是一个域)多个tomcat集成的session共享问题,也就是在一个电脑上配置多个tomcat,这几个tomcat发布的项目就可以获取共同的session信息了!

但是并不能解决在不同ip下的跨域问题,为什么呢?因为我们这种方式其实还是cookie和session这种方式,而浏览器存储cookie时是和一个域绑定的,什么意思?也就是百度存储的cookie不会到淘宝服务器上,所以当tomcat部署在不同电脑上发布项目,用户第一次访问127.0.0.1:8080建立联系,第二次再访问localhost:8081时不会向localhost发送127.0.0.1存储的cookie信息,这个时候就是之前所说的跨域问题。

提出问题,就要解决。

下面我们用Nginx的反向代理进行解决:

思路就是,浏览器存储的域是Nginx的,而Nginx集成tomcat,这样多个tomcat就可以分享一个域下的cookie信息了,

1.安装Nginx

2配置如下

 

完成以上配置,就可以完成在多个主机下多个web服务器发布多个项目合并成一个项目的简单思路。

问题:

1. 如果是ajax跨域,请自行搜索一下,ajax和spring跨域设置。

2. spring-session的问题,这个问题导致不能实现跨域共享,具体描述与解决如下:

    https://blog.csdn.net/f987002856/article/details/54970760 

我按照这个博主进行修改并没有成功,或者说有点复杂,spring出的插件是不是应该有spring的感觉呢?我又查了很多资料最后找到如下配置:

 

这样解决了获取路径不统一问题,以上是java web 项目多服务器部署的简单思路,深入的后续会写。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值