
1. 项目概述作为一名长期从事Java开发的工程师我最近完成了一个基于Spring Boot的新疆旅游攻略系统。这个项目源于我在新疆旅行时的亲身经历——面对广袤的新疆大地我发现现有的旅游信息平台要么信息零散要么功能单一无法满足自由行游客的全面需求。这个系统采用B/S架构前端使用Vue.js微信小程序双端适配后端基于Spring Boot 2.7框架数据库选用MySQL 8.0实现了旅游信息整合、个性化路线规划、酒店预订、特产商城等核心功能。特别值得一提的是我们通过MyBatis-Plus的动态SQL特性实现了多条件智能筛选让用户能快速找到符合自己需求的旅游信息。2. 技术选型与架构设计2.1 后端技术栈选择Spring Boot作为后端框架主要基于以下几个考量快速开发Spring Boot的starter依赖和自动配置大大减少了样板代码生态丰富与MyBatis、Redis等中间件集成简单性能稳定内嵌Tomcat容器默认配置即可满足生产环境要求我们特别使用了以下技术点// 示例使用Spring Cache抽象实现景点数据缓存 Cacheable(value scenicSpots, key #city_#type) public ListScenicSpot getSpotsByCityAndType(String city, String type) { return spotMapper.selectList( new QueryWrapperScenicSpot() .eq(city_name, city) .eq(spot_type, type) .orderByDesc(recommend_score) ); }2.2 前端技术方案考虑到用户使用场景的多样性我们采用了混合开发方案管理后台Vue 3 Element Plus用户端Uni-app跨平台方案同时支持微信小程序和H5这种架构设计的优势在于代码复用率高80%的业务逻辑可共享用户体验一致维护成本低2.3 数据库设计数据库设计遵循了以下原则适度冗余旅游信息类表增加了冗余字段减少联表查询垂直分表将热点数据如酒店基础信息与低频数据如详细政策分离软删除所有表都包含del_flag字段而非物理删除核心表关系如下CREATE TABLE hotel_info ( id bigint NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL COMMENT 酒店名称, city_code varchar(6) NOT NULL COMMENT 城市编码, address varchar(255) NOT NULL, star_level tinyint DEFAULT 3 COMMENT 星级1-5, min_price decimal(10,2) DEFAULT NULL COMMENT 最低价, cover_url varchar(255) DEFAULT NULL COMMENT 封面图, score decimal(3,1) DEFAULT 4.5 COMMENT 评分, open_status tinyint DEFAULT 1 COMMENT 营业状态, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, del_flag tinyint DEFAULT 0, PRIMARY KEY (id), KEY idx_city (city_code), KEY idx_price (min_price) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3. 核心功能实现3.1 智能路线规划这是系统的核心创新点实现逻辑如下基于用户选择的景点自动计算最优路线考虑景点间距、开放时间、推荐停留时长等因素使用改进的Dijkstra算法实现路径规划核心算法片段public ListScenicSpot generateRoute(ListScenicSpot selectedSpots, LocalDate travelDate) { // 构建邻接矩阵 double[][] graph buildDistanceGraph(selectedSpots); // 考虑景点开放时间约束 int[] timeWindows calculateTimeWindows(selectedSpots, travelDate); // 使用带时间窗的最短路径算法 return optimizedDijkstra(graph, selectedSpots, timeWindows); }3.2 多维度搜索功能搜索功能实现了以下特性多条件组合可按地区、价格、评分、设施等20维度筛选智能推荐基于用户历史行为推荐相关结果拼音搜索支持酒店/景点名称的拼音首字母检索实现关键点!-- MyBatis动态SQL示例 -- select idsearchHotels resultMaphotelResultMap SELECT * FROM hotel_info where if testparams.cityCode ! null AND city_code #{params.cityCode} /if if testparams.minPrice ! null AND min_price #{params.minPrice} /if if testparams.keyword ! null AND (name LIKE CONCAT(%,#{params.keyword},%) OR name_pinyin LIKE CONCAT(%,#{params.keyword},%)) /if if testparams.starLevel ! null AND star_level #{params.starLevel} /if /where ORDER BY choose when testparams.sortBy pricemin_price/when when testparams.sortBy scorescore DESC/when otherwiserecommend_score DESC/otherwise /choose /select4. 性能优化实践4.1 缓存策略我们采用三级缓存架构本地缓存Caffeine缓存基础配置信息分布式缓存Redis缓存热点业务数据HTTP缓存对静态资源设置Cache-Control缓存配置示例Configuration EnableCaching public class CacheConfig { Bean public CacheManager cacheManager() { CaffeineCacheManager manager new CaffeineCacheManager(); manager.setCaffeine(Caffeine.newBuilder() .initialCapacity(100) .maximumSize(1000) .expireAfterWrite(30, TimeUnit.MINUTES) .recordStats()); return manager; } }4.2 数据库优化针对旅游系统的特点我们实施了以下优化措施索引优化为所有查询条件创建合适索引读写分离使用Sharding-JDBC实现SQL监控集成Druid监控慢查询5. 安全防护方案5.1 认证与授权采用JWTSpring Security的安全方案密码加密存储BCrypt接口级权限控制敏感操作二次验证安全配置核心代码Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .antMatchers(/api/user/**).hasRole(USER) .antMatchers(/api/admin/**).hasRole(ADMIN) .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } }5.2 数据安全敏感数据加密身份证、手机号等字段AES加密存储日志脱敏使用自定义Appender实现日志敏感信息过滤防SQL注入严格使用预编译语句6. 部署与运维6.1 环境搭建推荐的生产环境配置服务器4核8G以上根据预估访问量调整中间件Nginx 1.20负载均衡静态资源Redis 6.2缓存会话MySQL 8.0主从架构6.2 监控方案我们集成了以下监控组件Spring Boot Admin应用健康监控PrometheusGrafana性能指标可视化ELK日志收集与分析7. 踩坑经验分享在开发过程中我们遇到并解决了以下典型问题7.1 微信小程序兼容性问题问题现象在部分Android机型上页面渲染异常解决方案避免使用较新的CSS特性对真机进行分级降级处理增加错误边界处理7.2 高并发下的缓存击穿问题场景热门景点信息查询解决方案public ScenicSpot getSpotDetail(Long id) { // 使用Redis分布式锁防止缓存击穿 String lockKey spot:lock: id; String cacheKey spot:detail: id; try { // 尝试获取锁 while (!redisTemplate.opsForValue().setIfAbsent(lockKey, 1, 30, TimeUnit.SECONDS)) { Thread.sleep(100); } // 双重检查缓存 ScenicSpot spot (ScenicSpot)redisTemplate.opsForValue().get(cacheKey); if (spot ! null) { return spot; } // 查询数据库 spot spotMapper.selectById(id); if (spot ! null) { redisTemplate.opsForValue().set(cacheKey, spot, 1, TimeUnit.HOURS); } return spot; } finally { redisTemplate.delete(lockKey); } }8. 项目扩展方向根据实际运营情况未来可以考虑以下扩展智能推荐基于用户画像的个性化推荐AR导览集成AR技术实现景区实景导航社交功能旅行轨迹分享与社区互动这个项目从技术选型到架构设计都充分考虑到了旅游行业的特性在实际运行中经受住了黄金周流量高峰的考验。特别在缓存策略和数据库优化方面的一些实践希望能给类似项目的开发者提供参考。