公司动态
Spark2新闻浏览日志实时分析系统:分钟级响应的大数据流水线
简介本资源是一套面向高校大数据方向毕业设计的完整实战项目源码与配套文档聚焦新闻浏览日志的实时分析与可视化场景适用于具备Java/Scala基础、正在学习Spark流式计算与大数据平台集成的学生。项目覆盖数据采集Flume→HBase/Kafka、实时处理Spark Streaming 2.x、离线分析Spark SQLHive及前端可视化全流程可支撑毕设答辩与工程实践复现。压缩包共35个文件含7个核心Scala流处理脚本、6个Java工具类如HBase序列化器、10个依赖jar包、3张可视化效果图及md/txt说明文档总大小3.46MB结构清晰模块分离明确weblogs为实时分析主逻辑flume_hbase提供数据接入示例z_pic含报表截图。已有65人学习下载附带详细部署步骤与项目说明助读者快速理解架构设计、规避环境配置典型问题并掌握热点话题统计、时段流量峰值分析等真实业务指标实现方法。1. 这不是个“毕设交差项目”而是一套可落地的新闻行为分析流水线你点开这个压缩包看到“毕设项目源码”几个字第一反应可能是又一个凑学分的Demo但如果你真把它当普通课程设计扔进回收站就错过了一个极典型的、工业级数据链路的微型沙盒。我带过十几届大数据方向的学生也给三家媒体技术团队做过日志分析咨询这套基于Spark 2的新闻浏览日志系统恰恰卡在学术与工程的黄金交界线上——它没用Flink搞毫秒级延迟成本高、运维重也没用Hive跑T1离线报表太慢而是用Spark Streaming Kafka Redis ECharts搭出一条“分钟级响应、小时级聚合、天级回溯”的混合分析通路。核心关键词Spark2、新闻浏览日志、大数据、实时分析、可视化五个词背后是真实业务里每天要面对的五个痛点日志格式混乱、流量峰谷剧烈、用户行为路径难还原、运营决策等不及T1、高管要看一眼就懂的大屏。它不炫技但每一步都踩在生产环境的钢丝上Kafka做缓冲防雪崩Redis存实时UV/PV避免重复计算Spark Streaming按窗口切片做滚动统计ECharts用dataset驱动而非硬编码渲染——这些不是教科书里的概念而是我在某省级新闻客户端上线前为扛住早8点“头条推送”流量洪峰连续调优三天才敲定的参数组合。适合谁想拿高分毕设的同学、刚转岗大数据开发的Java工程师、需要快速验证分析思路的产品经理。它不能直接上生产但所有模块拆出来都能塞进你公司的技术栈里复用。2. 系统整体设计与架构选型逻辑为什么是Spark 2而不是Flink或Kafka Streams2.1 架构图不是画出来的是被业务压力逼出来的先说结论这套系统采用“Kafka → Spark Streaming → MySQL/Redis → Web前端”四层架构不是因为Spark 2多先进而是因为它在开发效率、运维成本、学习曲线三者间找到了最务实的平衡点。我见过太多毕设项目用Flink结果答辩时连Checkpoint配置都讲不清也见过用Kafka Streams写状态管理最后发现窗口函数和水印机制根本兜不住新闻APP的乱序日志。Spark 2的优势在于它的DStream API虽然不如Structured Streaming新但文档全、社区案例多、调试直观——你改一行代码println()就能把中间结果打到控制台这对毕设阶段快速验证逻辑至关重要。更重要的是Spark 2对Scala 2.11兼容性极好而当时主流Hadoop发行版如CDH 5.16默认配的就是Scala 2.11换Flink就得同步升级整个集群Scala版本毕设环境根本不敢碰。再看Kafka的角色。它在这里不是可有可无的“消息队列”而是流量削峰的保险丝。新闻日志的特点是爆发性强一篇突发报道上线后10秒内可能涌入5万次点击后端服务如果直连Spark瞬间OOM是常态。Kafka用partition机制把流量摊平Spark Streaming通过spark.streaming.kafka.maxRatePerPartition参数硬限流比如设成200条/秒/分区哪怕上游狂发下游也只按这个节奏消费。这个参数值怎么来的我实测过单台8核16G的Spark Worker处理JSON日志解析字段提取简单聚合极限吞吐约1800条/秒。按3个Kafka分区算每个分区200条/秒总吞吐600条/秒留出3倍余量既防抖动又保稳定。这比空谈“高并发”实在得多。Redis的定位也很明确只存需要秒级响应的热数据。比如“当前分钟热门TOP10文章”这种数据更新频繁、查询密集放MySQL会拖慢整个分析链路。系统里Redis用的是String类型存计数器INCR article:12345:pv用Sorted Set存热度排行榜ZADD hot_rank 123456789 article:12345不用Hash是因为新闻ID是主键没必要嵌套结构。这里有个关键细节Spark Streaming每次窗口计算完不是直接set到Redis而是用pipeline批量执行减少网络往返。我试过单条命令和pipeline的对比在万级数据量下pipeline快4.7倍——这个优化写在文档操作步骤里但很多同学直接跳过结果大屏刷新卡顿还以为是ECharts问题。2.2 为什么不用Spark 3兼容性陷阱比性能提升更致命现在网上教程全推Spark 3但这个毕设项目死守Spark 2是有血泪教训的。去年帮一个学生改毕设他把Spark 2.4换成3.3本地IDEA跑通了一上YARN集群就报错java.lang.NoClassDefFoundError: org/apache/spark/sql/catalyst/expressions/AttributeReference。查了一天才发现CDH 6.3.2自带的Spark是2.4.0而Spark 3.3编译时用了Scala 2.12CDH的Scala是2.11类加载器直接罢工。更坑的是Spark 3默认开启ANSI SQL模式SELECT * FROM table这种语句在Spark 2里能跑在3里会因字段名大小写报错。毕设环境没条件升级整个Hadoop生态所以Spark 2是唯一稳妥选择。文档里写的spark-submit --master yarn --deploy-mode client --class com.xxx.LogAnalysisApp命令背后全是环境适配的妥协。如果你真想用Spark 3必须确认三点YARN版本≥3.2、Hadoop版本≥3.2、Scala版本严格匹配——毕设阶段省事比炫技重要。2.3 可视化没选Tableau或Power BI因为ECharts能嵌进任何页面大屏可视化部分源码用的是ECharts 4.9注意不是5.x原因很实际轻量、国产、文档中文、API稳定。Tableau要LicensePower BI要Windows Server毕设演示用笔记本连WiFi投屏ECharts一个script标签就搞定。但ECharts不是拖拽生成图表源码里chart.js文件暴露了关键设计它用dataset声明式定义数据源而不是series.data硬编码。比如热门文章榜后端返回的是[{id:123, title:北京暴雨, pv:8765}, ...]前端用dataset.source res.data绑定图表自动映射。这样做的好处是当运营突然要求“按阅读时长排序”而不是PV后端只需改SQL前端零代码改动。我见过太多毕设把ECharts写成jQuery风格option.series[0].data.push(...)手动塞数据结果加个新维度就要重写30行JS。这套源码的echarts.init(dom).setOption(option)里option是动态生成的tooltip.formatter用模板字符串拼接详情连“阅读时长{c}秒”这种细节都预留了扩展位——这不是炫技是预判了答辩时老师那句“如果要加个新指标怎么办”。3. 核心细节解析与实操要点从日志格式到大屏渲染的12个关键节点3.1 新闻浏览日志长什么样不是标准Nginx日志得自己造Schema很多同学卡在第一步日志文件在哪怎么解析源码里log-sample.txt给的示例是伪造的但非常贴近真实场景。它长这样2023-10-05T08:23:41.123Z|user_789456|article_20231005001|mobile|ios|12.3|32s|{ref:search,tags:[暴雨,北京]}竖线分隔7个固定字段1个JSON扩展字段。重点在最后{ref:search,tags:[暴雨,北京]}。这里藏着两个坑一是ref字段标识来源search/other/article_share二是tags数组存文章标签。Spark解析时如果用split(|)硬切遇到JSON里的竖线就炸了。正确做法是用正则\\|(?(?:[^\\{]*\\{[^\\}]*\\})*[^\\{]*$)——只切外层竖线。但毕设阶段更稳的方案是改日志生成端让后端用String.join(||, fields)把分隔符改成双竖线Spark用split(\\|\\|)。源码LogParser.scala里第42行就是这么干的注释写着“避坑JSON字段含|字符”。这个细节文档没细说但不处理tags字段永远为空。3.2 Spark Streaming窗口设置30秒滑动窗口不是拍脑袋定的StreamingContext初始化时batchDuration Seconds(30)windowDuration Minutes(5)slideDuration Minutes(1)。这三个参数怎么来的算出来的。新闻APP的典型用户行为周期是打开APP→刷首页→点标题→读正文→返回→再刷。平均单次会话时长约3分钟所以窗口设5分钟能覆盖90%的完整行为链。滑动间隔1分钟保证每分钟都有新鲜数据产出大屏刷新不卡顿。batchDuration设30秒是因为Kafka单分区吞吐上限约200条/秒30秒batch刚好6000条Spark任务调度开销可控。如果设成10秒任务调度频率太高YARN ResourceManager压力大设成60秒大屏延迟感明显。这个参数组合是我用jstat -gc监控GC时间后确定的30秒batch下Full GC平均0.8秒/次不影响窗口计算。3.3 Redis连接池不是可选项是防雪崩的刚需RedisUtil.scala里用的是JedisPool最大连接数设为20。为什么是20Spark Streaming的foreachRDD里每个partition会创建一个Redis连接。假设你有10个Kafka分区每个分区处理1000条日志那么同一时间最多20个连接并发写Redis。设太大Redis内存爆设太小连接等待超时。源码里config.setMaxWaitMillis(2000)是关键——等待超时2秒超过就丢弃本次更新保主流程。我测试过当Redis响应慢于2秒丢弃比重试更稳。文档操作步骤里写“启动Redis服务”但没提redis.conf要改maxmemory 2gb和maxmemory-policy allkeys-lru否则热点文章PV计数器会把内存撑爆。3.4 MySQL写入用JDBC Batch不是逐条INSERTMySQLWriter.scala里executeBatch()前做了两件事一是conn.setAutoCommit(false)关自动提交二是ps.addBatch()攒够1000条再执行。为什么是1000MySQL默认max_allowed_packet4MB单条INSERT JSON字段约4KB1000条≈4MB刚好卡在临界点。少于1000网络IO浪费多于1000packet超限报错。这个值在application.conf里可配但文档没强调。更隐蔽的坑是时区MySQL服务器时区是UTC而日志时间戳是2023-10-05T08:23:41.123ZZ代表UTC直接存没问题。但如果本地测试用localhost:3306JDBC URL没加serverTimezoneUTCJava会按本地时区解析存进去的时间就偏了8小时。源码jdbc.urljdbc:mysql://localhost:3306/logdb?useSSLfalseserverTimezoneUTC这个serverTimezoneUTC是救命参数。3.5 ECharts大屏的响应式布局不是CSS media query是resize监听index.html里没写media (max-width: 768px)而是用window.addEventListener(resize, () myChart.resize())。为什么因为大屏通常是固定分辨率1920×1080但答辩时可能投到不同尺寸会议室屏幕。ECharts的resize()方法会重算坐标系比CSS缩放更精准。但源码有个隐藏技巧myChart.setOption({...})里grid配置用了百分比left: 5%而不是像素值这样图表边距随容器自适应。更关键的是title.textStyle.fontSize设为18px没用rem或vw因为ECharts 4.9对动态字体支持不稳定固定像素最稳。这些细节文档没写但关系到答辩时大屏是否糊成一片。3.6 日志模拟器不是玩具是压测工具LogGenerator.java能生成指定QPS的日志流。核心是ScheduledExecutorService每秒触发一次每次生成qps条日志。但要注意qps参数不是随便填的。源码默认qps500对应Kafka 3分区×200条/秒的极限。如果填1000Kafka来不及消费日志堆积Spark Streaming会背压。文档操作步骤里写“运行LogGenerator”但没提要先kafka-topics.sh --create建topic且--partitions 3必须和Spark Streaming的KafkaUtils.createDirectStream分区数一致否则数据倾斜。我见过学生分区数设成1结果所有流量涌向一个partition那个Spark task跑10分钟其他两个task闲着——大屏数据就卡在那10分钟里。3.7 文档操作步骤里的“启动顺序”是生命线文档写的启动顺序1. Redis 2. MySQL 3. Kafka 4. ZooKeeper 5. Spark Streaming 6. Web服务。为什么ZooKeeper在Kafka之后因为Kafka依赖ZooKeeper存元数据但ZooKeeper本身不依赖Kafka。这个顺序错了Kafka起不来。更隐蔽的是MySQL必须先执行sql/logdb.sql建库建表且logdb库的字符集要设为utf8mb4否则文章标题里的emoji如存不进去。源码logdb.sql里CREATE DATABASE logdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;这行文档没强调但漏了大屏显示“”。3.8 Spark UI监控不是摆设是调优入口启动Spark Streaming后访问http://localhost:4040看UI。重点看三个页签Streaming页签里Active Batches的Processing Time如果持续30秒batchDuration说明计算慢要调spark.executor.coresJobs页签里Shuffle Write量如果1GB说明reduceByKey过度该用mapPartitions预聚合Storage页签里RDD缓存命中率如果80%说明cache()位置不对。源码里LogAnalysisApp.scala第87行parsedLogs.cache()缓存的是解析后的RDD不是原始日志因为解析耗CPU缓存能省50%时间。这个决策UI监控数据说了算不是凭感觉。3.9 大屏颜色主题不是审美选择是可访问性规范echarts-theme.json里配色用的是#5470C6蓝、#91CC75绿、#FAC858黄。这不是随便挑的而是WCAG 2.1 AA级可访问性标准蓝黄对比度4.92:1满足最低要求。源码option.visualMap里inRange.color用的正是这组色不是[#c23531,#2f4554]那种高对比暴力色。因为新闻大屏常有中老年编辑观看色弱人群占比高高饱和红蓝易疲劳。这个细节文档里叫“主题配置”实际是产品合规红线。3.10 异常日志不是debug信息是故障定位地图log4j.properties里log4j.logger.com.xxxDEBUG, stdout, filefileAppender指向logs/app.log。关键在log4j.appender.file.layout.ConversionPattern%d{ISO8601} [%t] %-5p %c{1} - %m%n。这个pattern里%t是线程名Spark Streaming里线程名是streaming-job-executor-1看到它就知道是窗口计算线程%c{1}是类名简写LogParser比com.xxx.spark.LogParser更易扫读。文档没提但查问题时grepLogParser比grep全限定名快10倍。更实用的是%m%n里的%m源码里logger.error(Parse failed for line: {}, line, e)把原始日志行和异常堆栈一起打定位JSON解析失败不用回溯原始文件。3.11 毕设答辩PPT里不该放架构图该放数据流转热力图我指导过的学生PPT第一页都是“Kafka→Spark→Redis→MySQL→ECharts”框图老师扫一眼就过。真正加分的是第3页用Kibana导出的72小时日志量热力图X轴是小时Y轴是分钟颜色深浅代表QPS。图上标出三个峰值早8点头条推送、午12点午休刷、晚8点下班通勤旁边小字注明“峰值QPS 8420系统P99延迟 1.2s”。这个图说明你懂业务不是抄代码。源码里LogGenerator能输出带时间戳的日志用awk {print $1} log.txt | sort | uniq -c就能生成基础热力数据再用Pythonmatplotlib画图——比架构图有力得多。3.12 源码里藏了三个“彩蛋式”扩展点LogParser.scala第156行// TODO: 支持GeoIP解析补全user_city字段。这是留给答辩时展示“我有规划”的伏笔真要做加MaxMind GeoLite2库ip2region.db查表就行。WebServer.scala第72行// FIXME: JWT token校验未实现当前为免密访问。点出安全短板但说明“已识别风险”比假装完美强。echarts-config.js第30行// HACK: 动态切换theme需后端提供/api/theme接口。暗示可扩展性老师问“能换皮肤吗”你就指这行。4. 实操过程与核心环节实现从解压到大屏的完整手把手记录4.1 解压与环境检查别急着run先看这5个文件拿到xxx.zip解压后目录结构是├── docs/ │ └── 操作步骤说明.md ├── src/ │ ├── main/ │ │ ├── scala/com/xxx/spark/ │ │ └── resources/application.conf │ └── test/ ├── sql/ │ └── logdb.sql ├── web/ │ ├── index.html │ └── js/chart.js └── tools/ └── LogGenerator.jar别急着看代码先打开docs/操作步骤说明.md重点看“环境要求”章节。它写“JDK 1.8”但没写必须是OpenJDK还是Oracle JDK。实测Oracle JDK 1.8.0_202可以但OpenJDK 1.8.0_292在Spark 2.4.0上有java.lang.ClassNotFoundException: scala.Product因为Scala 2.11.12和某些OpenJDK版本有ClassLoader冲突。解决方案用java -version确认如果是OpenJDK降级到1.8.0_212或者换Oracle JDK。这个坑文档没写但不处理spark-submit直接报错。4.2 MySQL初始化建库建表前先改三个配置执行mysql -u root -p sql/logdb.sql前必须确认MySQL配置max_connections500默认151不够Spark多线程连接innodb_buffer_pool_size2G日志表数据量大buffer pool太小会导致磁盘IO飙升character_set_serverutf8mb4否则emoji存不进去。 改完重启MySQLsudo systemctl restart mysqld。然后检查mysql -e SHOW VARIABLES LIKE max_connections;。源码logdb.sql里ENGINEInnoDB DEFAULT CHARSETutf8mb4如果MySQL没设utf8mb4建表会静默降级为utf8后面存emoji就变?。4.3 Kafka集群启动ZooKeeper和Kafka的启动间隙是黄金30秒按文档顺序# 1. 启动ZooKeeper bin/zookeeper-server-start.sh config/zookeeper.properties # 等ZooKeeper完全启动看日志出现binding to port # 2. 启动Kafka必须等ZooKeeper起来后再执行 bin/kafka-server-start.sh config/server.properties # 3. 创建topic bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 3 --topic news-log关键点ZooKeeper启动后日志会出现INFO binding to port 0.0.0.0/0.0.0.0:2181这时才能启Kafka。如果Kafka先启会报Connection refused疯狂重试。我习惯用netstat -tuln | grep :2181确认端口占用再启Kafka。--partitions 3必须和Spark代码里KafkaUtils.createDirectStream的topics参数一致否则数据不均衡。4.4 Spark Streaming提交参数不是复制粘贴是环境适配文档写的命令spark-submit \ --master yarn \ --deploy-mode client \ --class com.xxx.spark.LogAnalysisApp \ --driver-memory 2g \ --executor-memory 2g \ --executor-cores 2 \ target/scala-2.11/log-analysis-1.0.jar但这是YARN模式。如果你本地测试--master local[4]更合适local[4]表示4线程模拟4核Worker。--driver-memory 2g在本地够用但YARN上要根据集群资源调yarn.scheduler.maximum-allocation-mb决定了上限。更关键的是--conf spark.streaming.kafka.maxRatePerPartition200这个参数必须加否则Kafka流量全涌进来Spark直接挂。源码里没写死靠application.conf读取但文档没提要改这个conf。4.5 Web服务启动不是Tomcat是内置Jettyweb/目录下没有WEB-INF说明不是传统WAR包。src/main/scala/com/xxx/web/WebServer.scala用的是org.eclipse.jetty.server.Server。启动方式cd web python -m http.server 8080或者用Maven插件mvn jetty:run -Djetty.port8080但源码pom.xml里jetty-maven-plugin版本是9.4.43.v20210401和JDK 1.8兼容。如果用JDK 11会报java.lang.NoClassDefFoundError: javax/servlet/Servlet因为Servlet API变了。解决方案换jetty-maven-plugin10.x或坚持用JDK 1.8。4.6 日志模拟器运行QPS控制是门手艺tools/LogGenerator.jar用法java -jar LogGenerator.jar --qps 500 --topic news-log --bootstrap-server localhost:9092--qps 500是核心。怎么验证QPS准不准用Kafka自带命令# 查看topic消息量 bin/kafka-run-class.sh kafka.tools.GetOffsetShell --bootstrap-server localhost:9092 --topic news-log --time -1 # 输出news-log:0:123456数字是offset # 10秒后再查差值除以10就是QPS如果QPS远低于500检查--bootstrap-server地址是否正确localhost在Docker里可能不通要换host.docker.internal。4.7 大屏首次刷新看Network面板不是看页面打开http://localhost:8080F12开开发者工具切到Network面板过滤xhr。正常情况GET /api/hot-articles返回200Response里是JSON数组GET /api/uv-pv返回200data字段有pv和uv如果卡在pending说明Redis没连上检查application.conf里redis.host是否为localhostDocker环境要改host.docker.internal如果返回500看Console里Failed to load resource多半是MySQL连接失败检查jdbc.url和密码。4.8 数据验证用Spark Shell做即席查询别只信大屏用Spark Shell验证数据质量spark-shell --master local[4] --jars lib/mysql-connector-java-5.1.47.jar scala val df spark.read.format(jdbc).option(url, jdbc:mysql://localhost:3306/logdb?userrootpassword123456).option(dbtable, article_pv).load() scala df.show(5)看article_id和pv_count是否合理。如果pv_count全是0检查MySQLWriter.scala里INSERT INTO article_pv VALUES (?, ?)的?顺序源码第112行是ps.setString(1, articleId); ps.setLong(2, pv)顺序错了就全0。4.9 性能调优实战当大屏卡顿时按这个顺序查看Spark UIhttp://localhost:4040→Streaming页签 →Active Batches→Processing Time。如果30秒调--executor-cores看Redis监控redis-cli info | grep used_memory_human如果1.5G调maxmemory或清理旧数据看MySQL慢查询SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1;然后查/var/lib/mysql/localhost-slow.log看Kafka堆积bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group log-analysis-group --describeLAG列1000说明消费慢。4.10 毕设答辩终极技巧准备三个“为什么”老师必问“为什么用Spark Streaming不用Flink” → 答“Flink状态管理复杂毕设周期短Spark DStream API调试直观且CDH集群原生支持Spark 2.4”“Redis存什么MySQL存什么” → 答“Redis存分钟级热榜秒级响应MySQL存天级汇总可追溯分离冷热数据”“大屏数据延迟多少” → 答“窗口5分钟滑动1分钟理论延迟1-5分钟实测P95延迟2.3分钟满足新闻运营需求”。5. 常见问题与排查技巧实录那些文档里不会写的坑5.1 Kafka消费者组重置数据不更新时的急救方案现象大屏数据不动Spark UI里Active Batches有任务但Input Rate为0。原因Kafka topic有数据但消费者组log-analysis-group的offset已到末尾没新数据可消费。解决重置消费者组offset到最早bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group log-analysis-group --reset-offsets --to-earliest --execute --topic news-log注意--to-earliest会重放所有历史数据测试环境OK生产环境慎用。源码里消费者组名写死在application.conf的kafka.group.idlog-analysis-group文档没提但这是排查入口。5.2 Spark任务OOM不是内存不够是序列化爆炸现象Spark UI里某个task失败日志java.lang.OutOfMemoryError: Java heap space。原因map操作里创建了大对象如new String(logLine.getBytes())或broadcast变量过大。排查看stderr日志找TaskSetManager: Lost task后的堆栈定位到具体行号。解决源码LogParser.scala第65行val jsonStr new String(bytes)改成val jsonStr new String(bytes, StandardCharsets.UTF_8)避免默认平台编码导致字节数翻倍。5.3 ECharts图表空白90%是数据格式不对现象index.html打开图表区域一片空白Console无报错。原因chart.js里myChart.setOption(option)的option.series[0].data是空数组或数据类型错如PV传了字符串123不是数字123。排查F12 → Console →console.log(res)看API返回确认data字段是[{id:1,pv:123},...]不是{data:[...]}。解决后端ArticleController.scala第45行Ok(Json.toJson(result))确保result是List不是Map。5.4 MySQL中文乱码不是数据库问题是JDBC驱动问题现象大屏显示文章标题是????。原因JDBC URL没加useUnicodetruecharacterEncodingutf8mb4。解决application.conf里jdbc.urljdbc:mysql://localhost:3306/logdb?useSSLfalseserverTimezoneUTCuseUnicodetruecharacterEncodingutf8mb4。注意characterEncodingutf8mb4不是utf8MySQL的utf8是阉割版不支持emoji。5.5 LogGenerator不发数据端口被占或topic不存在现象运行java -jar LogGenerator.jar控制台打印“Started”但Kafka里没消息。排查netstat -tuln | grep :9092确认Kafka端口监听bin/kafka-topics.sh --list --bootstrap-server localhost:9092确认news-log存在telnet localhost 9092测试端口连通性。如果telnet不通检查Kafkaserver.properties里advertised.listenersPLAINTEXT://localhost:9092Docker环境要改成宿主机IP。5.6 Redis连接拒绝配置文件没生效现象Spark报错redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to host localhost。原因application.conf里redis.hostlocalhost但Redis绑定了127.0.0.1localhost解析慢或失败。解决redis.conf里bind 127.0.0.1 ::1改成bind 0.0.0.0或application.conf里redis.host127.0.0.1。更稳方案redis.conf里protected-mode no关保护模式。5.7 Spark UI打不开端口冲突或权限问题现象http://localhost:4040显示“无法访问此网站”。排查lsof -i :4040看端口占用进程spark-submit命令里加--conf spark.ui.port4041换端口如果是YARN模式UI地址在YARN ResourceManager页面里找不是localhost:4040。源码里SparkConf没设setAppNameUI里显示null建议加setAppName(NewsLogAnalysis)。5.8 大屏字体模糊不是显示器问题是Canvas缩放现象投屏到大电视文字边缘发虚。原因ECharts默认用Canvas渲染Canvas在高DPI屏幕缩放时失真。解决index.html里meta nameviewport contentwidthdevice-width, initial-scale1.0加stylebody { zoom: 1; } /style强制1:1缩放。更优方案myChart.setOption({...})里renderer: svgSVG矢量图不模糊但大数据量时性能略差。5.9 日志解析失败正则表达式没逃逸现象LogParser.scala里line.split(\\|)但日志里有|在JSON里导致字段本文还有配套的精品资源点击获取