部署生产环境时踩到的一些坑
nginx转发丢失session的问题
问题描述: 在Nginx配置反向代理的时候,需要将一个特定的URL请求转发到一个带有页面的Web后台管理系统。部署完成之后发现该后管系统无法正常登陆,输入正确账号密码后报错密码错误,后台错误日志为:
java.lang.IllegalStateException: Cannot create a session after the response has been committed
**原因及解决: **
nginx在每次传递请求时,如果没有传递cookie,即上述添加项,服务器将视为两次请求,因此会重新生成一个新的session,致使session数据丢失。
解决方法: 在 location / {}中添加 proxy_cookie_path /XXX/ /;即可。
Tomcat配置JVM内存参数没有生效的问题
首先要知道怎么修改Tomcat的JVM内存参数,大体上分为两种:
- 直接修改startup.sh 这个脚本
- 修改Catalina.sh脚本,因为执行startup.sh这个脚本时会去读Catalina.sh这个脚本里面配置的参数,配置的时候直接在注释
# JAVA_OPTS (Optional) Java runtime options used when any command
# is executed.
下追加JVM参数即可。
JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
JAVA_OPTS="$JAVA_OPTS -Xms2048M -Xmx4096M -XX:PermSize=2048m -XX:MaxPermSize=4096m"
JAVA_OPTS="$JAVA_OPTS -Xloggc:/applog/log/gc-myapplication.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails"
JAVA_OPTS="$JAVA_OPTS -XX:-OmitStackTraceInFastThrow -XX:ErrorFile=/applog/log/hs_err_%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/applog/log/"
JAVA_OPTS="$JAVA_OPTS -Ddruid.registerToSysProperty=true"
问题描述: 部署时碰到的问题是采用第二种方式配置时没有生效,具体表现时执行 ps -ef | grep tomcat 这条指令时看不到进程信息中的jvm参数。
**原因及解决: ** 简单来说就是之前因为为了解决数据库连接池问题时修改了catalina.sh这个脚本,当时插入的代码是
set JAVA_OPTS="-Ddruid.registerToSysProperty=true"
经过大牛指点,使用set JAVA_OPTS修改参数时会没办法正常读取后面的“ JAVA_OPTS=”配置的参数,同样修改为一样的
JAVA_OPTS="$JAVA_OPTS -Ddruid.registerToSysProperty=true"
就可以了。
web应用启动Druid数据源报错“unregister mbean error”的问题
问题描述: Tomcat中部署了两个web应用,启动时报错抛异常
ERROR [com.alibaba.druid.stat.DruidDataSourceStatManager] – unregister mbean error
javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean………
原因及解决: 这个问题在搜索时发现很多人都碰到过,推测原因一说是当tomcat中部署了两个web项目时且均有数据源的连接时就有问题(与我部署项目的情况相符),另一说时版本问题,暂时原因悬而未决...
修改Tomcat 下的 catalina.sh: 在最后面,不要放在前面或者中间的逻辑判断附近 增加此句代码: set JAVA_OPTS="-Ddruid.registerToSysProperty=true"
或者在开头JAVA_OPTS处添加 JAVA_OPTS="$JAVA_OPTS -Ddruid.registerToSysProperty=true"
编写JSP使NFV监测应用是否健康的问题
**问题描述:**项目上线后客户要求在每个web容器里面都要做应用的健康检测和数据库的健康检测。因为集群中大概有8台服务器上都部署了web应用,每个应用都是双机部署。而用户请求又是通过NFV负载均衡机到达的web应用集群,所以客户要求在负载均衡机转发请求的时候需要做服务器和应用以及数据的健康检测,即一个请求过来经过负载均衡机时要判断该服务器web端口是否还通,web应用是否还能正常访问,以及数据是否还能通过web应用正常连接(后来该条要求去掉了)。 JSP写法(注释部分为测试数据库是否正常连接)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page info="database handler"%>
<%@ page import="java.util.*"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.servlet.*"%>
<%@ page import="javax.servlet.http.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
/* String driver = "oracle.jdbc.driver.OracleDriver";
String url = "JDBC:oracle:thin:@120.24.101.229:1522:orcl";
String user = "idsp_ifp";
String password = "123456"; */
out.print("success");
/* try {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, password);
Statement statement = conn.createStatement();
String sql = "SELECT 1 FROM DUAL";
ResultSet rs = statement.executeQuery(sql);
if (rs.next()) {
out.print("success");
}
rs.close();
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} */
%>
</body>
</body>
</html>
解决: 其实解决方法很简单,服务器健康检测只需要监听tomcat使用的web端口即可。而应用的健康检测则需要我们单独写一个jsp,只需要简单的打印一个关键字,而NFV负载均衡机只需要一直检测这个jsp即可,当JSP不能正常访问时将请求转发到另外一台服务器即可。