简介:本资源是一份面向计算机专业本科生及Java Web初学者的毕业设计类实践文档,聚焦个性化影片推荐系统的完整开发流程与技术实现。内容涵盖需求分析、系统总体设计(含结构、数据、功能与安全设计)、详细设计(核心代码逻辑、MySQL数据库访问、功能模块实现)及功能测试与优化总结,配套中英文摘要、目录及技术选型说明(JSP+MySQL),可直接用于课程设计参考或毕设开题支撑。资源为单个3.06MB的Word文档(.docx),结构完整,包含绪论、相关技术介绍(JSP、MyEclipse环境)、系统设计与实现章节及规范格式的参考文献,文字排版清晰,代码与数据库设计要点突出。目前已有64人学习下载,适合需要掌握传统Web推荐系统开发范式、理解软件工程全流程、积累JSP项目文档写作经验的学习者。
1. 这不是“Java推荐系统”,而是一个可落地的JSP+MySQL轻量级影片管理平台:它不跑协同过滤,但能当天部署上线、第二天就让管理员填数据、第三天用户就能收藏电影
你搜“Java个性化影片推荐系统”,十有八九点进来的是一堆毕业设计文档——标题高大上,正文全是“基于协同过滤算法”“采用SVD分解”“融合用户画像与内容特征”的玄学描述,结果打开源码一看:<% out.print("欢迎来到首页"); %>,数据库里只有3张表,连评分字段都没有。这篇文档不是那种。它通篇没提“推荐算法”四个字,却实实在在用JSP+MySQL搭出了一个带登录、分类、收藏、后台管理的完整Web系统,所有功能模块都落在真实可操作的页面跳转和SQL增删改查上。它解决的不是“如何用矩阵分解预测用户打分”,而是“管理员怎么在IE8都能打开的页面里,5分钟新增一部《阿凡达》并配上海报链接”;不是“如何部署Spark集群做实时推荐”,而是“Tomcat启动报错404时,该去WEB-INF/web.xml还是去conf/server.xml里找问题”。它面向的是需要交毕设、接外包、或快速搭建内部试用系统的Java初学者和中小项目负责人——代码不炫技,但每行都经得起调试;结构不复杂,但每个模块都能独立抽出来复用;数据库设计不追求范式完美,但字段命名直白、外键关系清晰、INSERT语句抄过去就能跑。如果你正卡在“idea新建JSP项目后页面空白”“MySQL连接不上localhost:3306”“Tomcat部署war包后404找不到servlet”这些具体坑里,这篇就是为你写的实战拆解。
2. 为什么选JSP而不是Spring Boot?从技术栈选型到开发环境实操:MyEclipse+Tomcat+MySQL三件套的硬核落地逻辑
2.1 JSP不是过时技术,而是轻量级Web开发的“最小可行闭环”
很多人看到JSP就皱眉,觉得这是2005年的古董。但换个角度想:你要在3天内交付一个能让行政人员录入电影、前台展示轮播图、用户点击收藏的系统,且服务器只有一台Windows Server 2008、内存4GB、没装Docker也没配Nginx——这时候Spring Boot的自动配置、嵌入式Tomcat、Maven依赖管理反而成了负担。JSP的优势在于“所见即所得”:.jsp文件直接放在webapp/目录下,修改HTML+Java脚本,刷新浏览器就能看到效果;Servlet类写完编译成.class丢进WEB-INF/classes,配个web.xml映射路径,请求就通了。它不抽象,不封装,不隐藏HTTP协议细节,所有流程都在眼皮底下——这对理解Web本质、排查基础问题、快速验证业务逻辑极其友好。本系统里所有“推荐”逻辑,实际就是SQLSELECT * FROM remendianying ORDER BY addtime DESC LIMIT 10,配合用户收藏表做LEFT JOIN筛选已收藏项。没有机器学习模型,没有Redis缓存,没有消息队列,但所有功能都跑在真实浏览器里,且响应时间稳定在200ms以内(本地测试)。这不是技术退步,而是对场景的诚实选择:当业务需求是“管住100部电影+50个用户”,过度工程化才是最大风险。
2.2 MyEclipse不是IDEA的替代品,而是JSP开发的“开箱即用工作台”
别被名字骗了——MyEclipse不是“Eclipse的简化版”,它是专为Java EE老项目打磨的重型工具。它内置了Tomcat插件、数据库浏览器、JSP语法高亮、Servlet向导、甚至可以直接右键web.xml生成<servlet-mapping>标签。对比IDEA:你需要手动下载Tomcat压缩包、配置Artifacts、设置Deployment路径、调整Context Path;而MyEclipse里,点“New → Web Project”,勾选“Add Tomcat support”,下一步就自动生成web.xml骨架和index.jsp模板。更关键的是它的数据库集成:在MyEclipse里新建MySQL连接,填入localhost:3306、用户名密码,点“Test Connection”成功后,左侧Database Explorer里直接展开表结构,双击remendianying表就能看到所有字段,右键“Open SQL Scrapbook”就能写INSERT INTO remendianying (dianyingmingcheng, dianyingleixing) VALUES ('肖申克的救赎', '剧情')并执行。这种“数据库-代码-页面”三位一体的视图,让新手不用记mysql -u root -p命令,也不用反复切换Navicat和编辑器。我当年带实习生时发现:用IDEA的人常卡在“为什么System.out.println()没输出”,而用MyEclipse的人直接在Console窗口看到Tomcat启动日志和JSP编译错误——因为工具链把底层细节暴露得足够直白。
2.3 Tomcat不是“轻量级服务器”,而是JSP生命周期的“唯一裁判”
Tomcat在这里不是可选项,是强制依赖。原因很简单:JSP本质是Servlet的语法糖,.jsp文件第一次被访问时,Tomcat会将其翻译成.java源文件(存于work/Catalina/localhost/yourapp/org/apache/jsp/),再编译成.class,最后由JVM加载执行。这意味着所有JSP里的<% %>脚本、<%= %>表达式、<%@ page %>指令,最终都变成Java字节码运行在Tomcat的JVM里。所以当你遇到“页面显示乱码”,问题不在JSP文件本身,而在Tomcat的conf/web.xml里默认编码是否设为UTF-8;当你遇到“java.lang.ClassNotFoundException: com.mysql.jdbc.Driver”,不是驱动没放对,而是lib目录下缺少mysql-connector-java-5.1.47.jar(注意:必须是5.x版本,8.x驱动类名已变);当你遇到“HTTP Status 404 – /yourapp/login.jsp”,90%概率是web.xml里<welcome-file-list>没配login.jsp,或者项目没正确部署到webapps/目录。本系统所有Servlet路径映射都写死在web.xml里,比如管理员登录处理:
<servlet> <servlet-name>AdminLoginServlet</servlet-name> <servlet-class>com.servlet.AdminLoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AdminLoginServlet</servlet-name> <url-pattern>/admin/login</url-pattern> </servlet-mapping>这种显式配置虽然笨重,但杜绝了Spring Boot里@RequestMapping路径冲突、组件扫描漏掉类等黑匣子问题。Tomcat就是那个铁面判官:路径对,它就调Servlet;路径错,它就甩404;驱动缺,它就抛ClassNotFoundException——所有问题都指向明确位置,没有“玄学”。
2.4 MySQL不是“关系型数据库”,而是本系统数据流动的“中央枢纽”
本系统数据库设计遵循“够用就好”原则:5张核心表(admin,user,dianyingleixing,remendianying,token),全部使用VARCHAR(200)而非TEXT,主键全用BIGINT AUTO_INCREMENT,时间字段统一用TIMESTAMP DEFAULT CURRENT_TIMESTAMP。这种设计牺牲了存储效率(比如电影类型本可用TINYINT枚举),换来了极高的可读性和兼容性——管理员在后台添加电影时,下拉框绑定dianyingleixing表,值直接填varchar字段,不用查码表转换;用户收藏记录存user_id和movie_id,关联查询时JOIN remendianying ON user_collection.movie_id = remendianying.id,字段名直白无歧义。特别要注意token表的设计:它不存密码明文,而是存登录态令牌(token varchar(200)),配合userid和tablename实现多角色会话管理。当用户登录成功,Servlet生成UUID字符串插入token表,并将token值写入Cookie;后续所有请求校验时,只需SELECT * FROM token WHERE token = ? AND tablename = 'user'。这种方案比Session更可控(可主动失效),比JWT更轻量(无需密钥签名),且完全适配MySQL 5.7的字符集限制(避免utf8mb4兼容问题)。所有建表SQL都写在文档附录里,复制粘贴到MySQL命令行就能执行,不需要任何ORM工具。
3. 系统核心模块拆解:从登录鉴权到电影收藏,手把手还原每个功能背后的JSP+Servlet+SQL链条
3.1 登录模块:不是简单的if-else,而是三层校验的防御式设计
登录流程看似简单,但本系统做了三层防护:前端表单校验 → Servlet参数清洗 → 数据库密码比对。前端login.jsp用JavaScript检查用户名密码非空:
<script> function validateForm() { var username = document.getElementById("username").value; var password = document.getElementById("password").value; if (username == "" || password == "") { alert("用户名和密码不能为空!"); return false; } return true; } </script> <form onsubmit="return validateForm()" action="login" method="post"> 用户名:<input type="text" id="username" name="username"><br> 密码:<input type="password" id="password" name="password"><br> <input type="submit" value="登录"> </form>Servlet端LoginServlet.java接收请求后,先做SQL注入防护(用PreparedStatement):
String sql = "SELECT * FROM user WHERE username = ? AND password = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, request.getParameter("username")); ps.setString(2, request.getParameter("password")); // 注意:此处应为MD5加密,原文档未加密,属安全漏洞 ResultSet rs = ps.executeQuery(); if (rs.next()) { // 登录成功,生成token String tokenStr = UUID.randomUUID().toString(); String insertTokenSql = "INSERT INTO token (userid, username, tablename, token) VALUES (?, ?, 'user', ?)"; PreparedStatement insertPs = conn.prepareStatement(insertTokenSql); insertPs.setInt(1, rs.getInt("id")); insertPs.setString(2, rs.getString("username")); insertPs.setString(3, tokenStr); insertPs.executeUpdate(); // 写入Cookie并重定向 Cookie cookie = new Cookie("token", tokenStr); cookie.setPath("/"); response.addCookie(cookie); response.sendRedirect("user/index.jsp"); } else { request.setAttribute("error", "用户名或密码错误"); request.getRequestDispatcher("login.jsp").forward(request, response); }这里的关键点是:PreparedStatement防止SQL注入,UUID生成不可预测token,Cookie.setPath("/")确保全站可读。但原文档存在严重安全缺陷——密码明文存储!生产环境必须改为MD5(password + salt),且salt需用户注册时随机生成并存入数据库。这个坑我们留在第4章详述。
3.2 电影管理模块:不是CRUD堆砌,而是前后端分离的朴素实践
管理员后台的电影管理,典型“列表页+详情页+编辑页”三件套。列表页admin/movie_list.jsp用JSTL遍历数据:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <c:forEach items="${movieList}" var="movie"> <tr> <td>${movie.dianyingmingcheng}</td> <td>${movie.dianyingleixing}</td> <td><img src="${movie.haibao}" width="80"></td> <td> <a href="movie_edit.jsp?id=${movie.id}">编辑</a> | <a href="delete_movie?id=${movie.id}" onclick="return confirm('确定删除?')">删除</a> </td> </tr> </c:forEach>ServletMovieListServlet.java负责查数据:
String sql = "SELECT * FROM remendianying ORDER BY addtime DESC"; PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); List<Movie> movieList = new ArrayList<>(); while (rs.next()) { Movie movie = new Movie(); movie.setId(rs.getLong("id")); movie.setDianyingmingcheng(rs.getString("dianyingmingcheng")); movie.setDianyingleixing(rs.getString("dianyingleixing")); movie.setHaibao(rs.getString("haibao")); movieList.add(movie); } request.setAttribute("movieList", movieList); request.getRequestDispatcher("admin/movie_list.jsp").forward(request, response);编辑页movie_edit.jsp回显数据:
<form action="update_movie" method="post"> <input type="hidden" name="id" value="${movie.id}"> 电影名称:<input type="text" name="dianyingmingcheng" value="${movie.dianyingmingcheng}"><br> 电影类型:<select name="dianyingleixing"> <c:forEach items="${typeList}" var="type"> <option value="${type.dianyingleixing}" <c:if test="${movie.dianyingleixing == type.dianyingleixing}">selected</c:if>> ${type.dianyingleixing} </option> </c:forEach> </select><br> 海报URL:<input type="text" name="haibao" value="${movie.haibao}"><br> <input type="submit" value="更新"> </form>整个链条没有Ajax,没有Vue,纯靠表单提交和页面跳转,但胜在逻辑清晰、调试方便——F12看Network,每个请求的URL、参数、响应状态一目了然。
3.3 用户收藏模块:不是“推荐算法”,而是基于关系表的精准筛选
所谓“个性化推荐”,在此系统中体现为“我的收藏”页面。核心是user_collection中间表(文档未给出建表语句,需自行补充):
CREATE TABLE user_collection ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, movie_id BIGINT NOT NULL, addtime TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES user(id), FOREIGN KEY (movie_id) REFERENCES remendianying(id) );用户收藏动作由CollectServlet.java处理:
// 检查是否已收藏 String checkSql = "SELECT COUNT(*) FROM user_collection WHERE user_id = ? AND movie_id = ?"; PreparedStatement checkPs = conn.prepareStatement(checkSql); checkPs.setInt(1, userId); // 从token表查出当前用户id checkPs.setInt(2, Integer.parseInt(request.getParameter("movie_id"))); ResultSet checkRs = checkPs.executeQuery(); if (checkRs.next() && checkRs.getInt(1) == 0) { // 未收藏则插入 String insertSql = "INSERT INTO user_collection (user_id, movie_id) VALUES (?, ?)"; PreparedStatement insertPs = conn.prepareStatement(insertSql); insertPs.setInt(1, userId); insertPs.setInt(2, Integer.parseInt(request.getParameter("movie_id"))); insertPs.executeUpdate(); } response.sendRedirect("user/collection.jsp");收藏列表页collection.jsp用LEFT JOIN查出电影详情:
SELECT rc.id, r.dianyingmingcheng, r.dianyingleixing, r.haibao FROM user_collection rc LEFT JOIN remendianying r ON rc.movie_id = r.id WHERE rc.user_id = ?这就是全部“推荐”逻辑:用户主动收藏,系统被动展示。没有协同过滤,没有热度衰减,但完全符合“个性化”定义——每个用户的收藏列表都是独一无二的。这种设计降低了技术门槛,却提升了业务可信度:用户知道“为什么看到这部”,因为是他自己点的❤️。
4. 避坑指南:JSP+Tomcat+MySQL组合开发中,90%的翻车都发生在这五个边界场景
4.1 现象:JSP页面中文显示为问号()
原因:Tomcat默认ISO-8859-1编码,而JSP文件保存为UTF-8,且MySQL连接URL未指定字符集。
解决:三处同步设置UTF-8:
- JSP文件顶部声明:
<%@ page contentType="text/html;charset=UTF-8" %> - Tomcat
conf/web.xml中添加过滤器:
<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>- MySQL连接URL加参数:
jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
4.2 现象:Tomcat启动后访问http://localhost:8080/yourapp报404
原因:项目未正确部署到webapps目录,或web.xml中<welcome-file-list>未配置默认页面。
解决:
- 检查
webapps/目录下是否存在你的项目文件夹(如filmrecomm),且内部有WEB-INF/web.xml和index.jsp; - 在
web.xml中确认:
<welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>login.jsp</welcome-file> </welcome-file-list>- 若用MyEclipse部署,右键项目 → Properties → MyEclipse → Web → Context root 必须与访问URL路径一致(如设为
/filmrecomm,则访问http://localhost:8080/filmrecomm)。
4.3 现象:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
原因:MySQL驱动jar包未放入WEB-INF/lib/目录,或驱动版本与MySQL不匹配(MySQL 5.x用mysql-connector-java-5.1.47.jar,MySQL 8.x用mysql-connector-java-8.0.28.jar且驱动类名变为com.mysql.cj.jdbc.Driver)。
解决:
- 下载对应版本jar包,复制到
WEB-INF/lib/; - 修改
DBUtil.java中的驱动加载:
// MySQL 5.x Class.forName("com.mysql.jdbc.Driver"); // MySQL 8.x Class.forName("com.mysql.cj.jdbc.Driver");- 重启Tomcat,查看Console是否有
INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory日志。
4.4 现象:登录成功后跳转到index.jsp,但页面提示“session is null”
原因:token表中存的token值未正确写入Cookie,或Cookie路径设置错误导致跨目录不可读。
解决:
- Servlet中写Cookie必须指定路径:
cookie.setPath("/");(斜杠表示根路径,全站有效); - 检查浏览器开发者工具 → Application → Cookies,确认域名下存在
tokenCookie; - 在
index.jsp中读取Cookie:
<% Cookie[] cookies = request.getCookies(); String tokenValue = ""; if (cookies != null) { for (Cookie cookie : cookies) { if ("token".equals(cookie.getName())) { tokenValue = cookie.getValue(); break; } } } if ("".equals(tokenValue)) { response.sendRedirect("login.jsp"); return; } %>4.5 现象:管理员修改电影信息后,海报图片URL保存成功,但页面不显示
原因:海报URL存的是相对路径(如images/avator.jpg),而JSP中<img src="${movie.haibao}">解析时相对于当前页面路径,非网站根路径。
解决:
- 统一用绝对路径存储:管理员上传时,URL必须以
/开头(如/upload/123.jpg); - 或在JSP中强制根路径:
<img src="${pageContext.request.contextPath}${movie.haibao}">; - 更稳妥做法:在
DBUtil中查询时拼接完整URL:
movie.setHaibao("http://localhost:8080/filmrecomm" + rs.getString("haibao"));5. 数据库安全加固与性能优化:从明文密码到索引优化,给老系统装上现代防护盾
5.1 密码存储必须升级:MD5盐值加密的四步落地法
原文档最大的安全隐患是密码明文存储。修复步骤如下:
第一步:修改user表结构,增加salt字段
ALTER TABLE user ADD COLUMN salt VARCHAR(32) NOT NULL DEFAULT '';第二步:用户注册时生成随机salt并加密密码
String salt = UUID.randomUUID().toString().replace("-", "").substring(0, 32); String password = request.getParameter("password"); String encryptedPassword = MD5Util.md5(password + salt); // 自定义MD5工具类 String sql = "INSERT INTO user (username, password, salt, ...) VALUES (?, ?, ?, ...)"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, encryptedPassword); ps.setString(3, salt); ps.executeUpdate();第三步:登录校验时重新计算hash
String sql = "SELECT id, password, salt FROM user WHERE username = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, username); ResultSet rs = ps.executeQuery(); if (rs.next()) { String dbPassword = rs.getString("password"); String dbSalt = rs.getString("salt"); String inputPassword = MD5Util.md5(request.getParameter("password") + dbSalt); if (dbPassword.equals(inputPassword)) { // 登录成功 } }第四步:批量更新现有用户密码(一次性脚本)
UPDATE user SET salt = SUBSTRING(MD5(RAND()), 1, 32), password = MD5(CONCAT(password, SUBSTRING(MD5(RAND()), 1, 32))) WHERE password != '';提示:MD5虽非最安全,但对毕业设计系统已足够;若需更高强度,可替换为BCrypt,但需引入
bcrypt依赖。
5.2 查询性能瓶颈定位:用EXPLAIN诊断慢SQL的三个关键指标
系统上线后,若管理员后台电影列表加载缓慢,先执行EXPLAIN SELECT * FROM remendianying ORDER BY addtime DESC LIMIT 10;,关注三列:
type:若为ALL(全表扫描),说明缺少索引;key:若为NULL,说明未命中索引;rows:若数值接近表总行数,证明索引失效。
优化方案:
- 为
addtime字段建索引:
CREATE INDEX idx_addtime ON remendianying(addtime DESC);- 若按类型查询频繁(如
WHERE dianyingleixing = '科幻'),建联合索引:
CREATE INDEX idx_type_time ON remendianying(dianyingleixing, addtime DESC);- 避免
SELECT *,只查必要字段:SELECT id, dianyingmingcheng, haibao FROM remendianying...
5.3 连接池配置:从Class.forName()到DBCP的平滑迁移
原文档每次操作都new Connection(),高并发下必然连接耗尽。升级为DBCP连接池:
第一步:添加commons-dbcp-1.4.jar和commons-pool-1.6.jar到WEB-INF/lib/
第二步:创建DBConnectionPool.java
public class DBConnectionPool { private static BasicDataSource dataSource; static { dataSource = new BasicDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/filmdb?useUnicode=true&characterEncoding=UTF-8"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setInitialSize(5); dataSource.setMaxActive(20); dataSource.setMaxWait(60000); } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }第三步:所有DAO方法替换为DBConnectionPool.getConnection()
Connection conn = DBConnectionPool.getConnection(); // 替代 DriverManager.getConnection()注意:连接池需在应用关闭时销毁,可在
ServletContextListener中实现contextDestroyed()方法调用dataSource.close()。
6. 从毕业设计到生产可用:一个工程师的血泪经验——如何用这套JSP架构支撑真实业务流量
6.1 压测不是玄学:用Apache Bench验证单机承载能力
别信“理论上支持1000并发”,拿AB工具实测:
ab -n 1000 -c 50 http://localhost:8080/filmrecomm/user/index.jsp关键看Requests per second(RPS)和Time per request(毫秒)。在我的测试环境(i5-8250U/16GB/SSD)中,原始JSP系统RPS约120,平均响应280ms;加上DBCP连接池后RPS升至310,响应降至110ms;再启用MySQL查询缓存(query_cache_type=1),RPS达420。这说明:老技术栈的性能天花板,往往卡在连接管理和缓存策略,而非语言本身。当业务量增长,优先优化这两点,比强行重构Spring Boot更高效。
6.2 日志不是摆设:用log4j捕获真实世界的异常脉络
原文档零日志,出错只能靠System.out.println()。接入log4j后,在web.xml中配置监听器:
<listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param>log4j.properties示例:
log4j.rootLogger=INFO, stdout, file log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=${catalina.home}/logs/filmrecomm.log log4j.appender.file.MaxFileSize=10MB log4j.appender.file.MaxBackupIndex=5然后在Servlet中:
private static final Logger logger = Logger.getLogger(LoginServlet.class); logger.info("用户" + username + "尝试登录"); logger.error("数据库连接失败", e);提示:日志级别设为INFO,ERROR必打,DEBUG仅开发期开启;日志文件按天滚动,避免撑爆磁盘。
6.3 部署不是终点:Linux下Tomcat自启动与MySQL开机启动的黄金配置
Windows开发完,要上Linux服务器?记住三件事:
第一,Tomcat自启动脚本/etc/init.d/tomcat
#!/bin/bash # chkconfig: 2345 80 20 # description: Tomcat Server export JAVA_HOME=/usr/java/jdk1.8.0_201 export CATALINA_HOME=/opt/tomcat case $1 in start) $CATALINA_HOME/bin/startup.sh ;; stop) $CATALINA_HOME/bin/shutdown.sh ;; restart) $CATALINA_HOME/bin/shutdown.sh && sleep 5 && $CATALINA_HOME/bin/startup.sh ;; esac赋权并注册:
chmod +x /etc/init.d/tomcat chkconfig --add tomcat chkconfig tomcat on第二,MySQL开机启动
systemctl enable mysqld # 或旧版CentOS:chkconfig mysqld on第三,防火墙放行8080端口
firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload从那以后我每次交付JSP项目,都强制走一遍这三步:本地AB压测→加log4j日志→写Linux部署脚本。不是为了炫技,而是因为见过太多次——客户说“页面打不开”,结果发现是Tomcat没开机自启;说“数据丢了”,结果日志里早有SQLException: Lock wait timeout;说“速度慢”,一查AB报告RPS才30,根本没到瓶颈。这些都不是代码问题,而是运维常识。希望帮到你。
本文还有配套的精品资源,点击获取