美文网首页
Nginx+SpringMVC 负载均衡中遇到的坑

Nginx+SpringMVC 负载均衡中遇到的坑

作者: IATNEH1900 | 来源:发表于2018-12-26 20:54 被阅读0次

引言

最近对公司的项目进行改造实施负载均衡,以便可以方便的进行横向扩展,提升性能,于是在项目中引入了SpringSession,来实现不同服务器上同一个项目的Session共享。

改造过程

由于项目较老,SpringMVC所使用的版本是3.1.4.RELEASE

负载均衡

  1. 在pom.xml中引入SpringSession
        <!-- Jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!-- Spring Data Redis -->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>1.2.1.RELEASE</version>
        </dependency>
        <!-- Spring Session -->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
            <version>1.2.1.RELEASE</version>
        </dependency>
  1. application.xml中增加redis的配置


    <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="600" />
    </bean>
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="100" />
        <property name="maxIdle" value="10" />
    </bean>

    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
        destroy-method="destroy">
        <property name="hostName" value="${redis.host}" />
        <property name="password" value="${redis.pwd}" />
        <property name="port" value="${redis.port}" />
        <property name="database" value="${redis.database}" />
        <property name="usePool" value="true" />
        <property name="poolConfig" ref="jedisPoolConfig" />
    </bean>
  1. 修改web.xml新增过滤器
    <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>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
  1. Nginx配置改造
    upstream demo-site {
            server 192.168.0.1:86; #服务器A
            server 192.168.0.2:86; #服务器B
    }
    server {
        listen       80;
        server_name  host;
        location / {
            proxy_pass   http://demo-site;
        }
    }

改造完毕后,通过域名访问项目,会轮询访问这两台服务器上的应用,Session也会在这两个应用上进行共享。

文件共享

两台服务器通过NFS协议挂载了同一个NAS云盘,路径统一为/nas,文件上传路径都配置这个路径就可以了。

  1. 前端的post请求 后端Controller中使用request.getInputStream()获取到流为空
  • 原因:SpringSession中获取SessionId的操作使用了request.getParameter()方法具体代码位置在CookieHttpSessionStrategy类中
    public String getRequestedSessionId(HttpServletRequest request) {
        Map<String, String> sessionIds = getSessionIds(request);
        String sessionAlias = getCurrentSessionAlias(request);
        return sessionIds.get(sessionAlias);
    }

    public String getCurrentSessionAlias(HttpServletRequest request) {
        if (this.sessionParam == null) {
            return DEFAULT_ALIAS;
        }
        String u = request.getParameter(this.sessionParam);
        if (u == null) {
            return DEFAULT_ALIAS;
        }
        if (!ALIAS_PATTERN.matcher(u).matches()) {
            return DEFAULT_ALIAS;
        }
        return u;
    }

request.getParameter()操作会读取流信息,从而导致流被掏空,以致请求到达Controller时没数据可以读取。

20160803175011173.jpg
  • 解决办法
    调用方使用接口时contentType 指定为'application/json;charset=UTF-8'或其它,只要不是application/x-www-form-urlencoded就可以
  1. Log日志写入混乱。
  • 应用使用Log4J记录日志,因为做了文件共享,所以考虑到日志查看方便,所以也都写到同一个文件,运行了几天才发现日志有丢失问题,估计是多个log4j进程同时写文件有冲突。
  • 解决方法
    日志配置中增加变量log4j.appender.E.File=/folder/path/info.${log4j.logtype}.log
    服务器A Tomcat配置bin/catalina.sh中增加参数JAVA_OPTS='-Xms512m -Xmx2048m -Dlog4j.logtype=1'
    服务器B Tomcat配置bin/catalina.sh中增加参数JAVA_OPTS='-Xms512m -Xmx2048m -Dlog4j.logtype=2'

建议

项目中尽量不要使用Application/Session存取数据。

相关文章

网友评论

      本文标题:Nginx+SpringMVC 负载均衡中遇到的坑

      本文链接:https://www.haomeiwen.com/subject/ylrklqtx.html