1. 项目背景与核心价值
最近在实验室折腾监控系统时,发现一个特别实用的组合方案:通过Go2RTC+EasyNVR实现本地化存储+局域网外访问。这个方案完美解决了监控视频的存储和远程查看需求,特别是在没有公网IP的情况下,用cpolar内网穿透工具实现了第761次成功穿透。整个过程踩过不少坑,也积累了一些实战经验,今天就把这个方案的完整实现过程分享给大家。
这个方案的核心价值在于:
- 本地化存储保障数据安全(不再依赖云服务商)
- 低延迟的局域网内访问体验
- 通过内网穿透实现随时随地查看
- 全部使用开源工具,零成本搭建
2. 工具选型与原理分析
2.1 核心组件功能解析
Go2RTC: 这是一个轻量级的RTSP/RTMP转WebRTC工具,实测延迟可以控制在200ms以内。它的优势在于:
- 直接浏览器访问,无需插件
- 支持H.264/H.265编码
- 低CPU占用(实测树莓派4B能带8路720P)
EasyNVR: 专业的视频管理平台,我们主要用它的:
- 录像存储管理(支持按时间/事件存储)
- 多协议接入(RTSP/RTMP/GB28181)
- 用户权限系统
cpolar: 内网穿透工具中的瑞士军刀,特点是:
- 无需配置路由器
- TCP/UDP/HTTP全协议支持
- 免费版足够监控使用
2.2 系统架构设计
典型部署拓扑如下:
[摄像头] -> [Go2RTC] -> [EasyNVR] -> [cpolar] -> [公网访问]关键数据流:
- 摄像头输出RTSP流
- Go2RTC进行协议转换
- EasyNVR负责存储和界面展示
- cpolar建立穿透隧道
3. 详细部署步骤
3.1 基础环境准备
推荐使用Ubuntu 20.04 LTS,硬件配置:
- CPU:至少4核(推荐Intel N5105级别)
- 内存:4GB起步
- 存储:根据摄像头数量和保存周期决定
先安装必要依赖:
sudo apt update sudo apt install -y ffmpeg git make gcc3.2 Go2RTC部署
从源码编译安装:
git clone https://github.com/AlexxIT/go2rtc.git cd go2rtc make ./go2rtc -host 0.0.0.0 -port 1984关键配置参数说明:
-host:监听地址(0.0.0.0表示所有网卡)-port:Web访问端口-log:日志级别(debug/info/warn/error)
测试访问: http://服务器IP:1984
3.3 EasyNVR配置
下载官方安装包后:
tar -zxvf easynvr-linux-amd64.tar.gz cd easynvr ./install.sh重点配置项:
[storage] path = /mnt/nvr_record # 录像存储路径 days = 30 # 保存天数 [rtsp] enabled = true port = 554注意:存储路径建议用独立硬盘,避免系统盘写满
3.4 cpolar穿透设置
注册账号后获取authtoken,然后:
curl -O https://www.cpolar.com/static/downloads/cpolar-stable-linux-amd64.tar.gz tar -zxvf cpolar-stable-linux-amd64.tar.gz ./cpolar authtoken YOUR_AUTH_TOKEN ./cpolar http 1984成功后会显示公网访问地址,类似: https://xxxx.cpolar.cn
4. 实战问题排查指南
4.1 常见错误代码速查
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| 504 Gateway Timeout | cpolar隧道中断 | 重启cpolar服务 |
| 401 Unauthorized | EasyNVR鉴权失败 | 检查用户名密码 |
| 流加载失败 | 摄像头编码不支持 | 改用H.264 Baseline Profile |
| 录像丢失 | 存储权限问题 | chmod -R 777 /mnt/nvr_record |
4.2 性能优化技巧
降低延迟:
- 在Go2RTC配置中添加:
webrtc: ice_servers: [] - 禁用TURN服务器可减少100ms延迟
- 在Go2RTC配置中添加:
节省带宽:
- 在EasyNVR中设置子码流:
[stream] main = rtsp://cam1:554/main sub = rtsp://cam1:554/sub # 低分辨率流
- 在EasyNVR中设置子码流:
存储优化:
- 使用硬链接避免重复存储:
ln /mnt/nvr_record/event/* /mnt/nvr_record/daily/
- 使用硬链接避免重复存储:
5. 高级应用场景
5.1 多摄像头接入方案
对于超过8路摄像头的场景,建议:
- 按区域划分Go2RTC实例
- 使用Nginx做负载均衡:
upstream go2rtc { server 127.0.0.1:1984; server 127.0.0.1:1985; }
5.2 移动端适配技巧
在EasyNVR配置中添加:
[mobile] hls_enabled = true hls_time = 2 # 分片时长(秒)这样手机访问时会自动切换为HLS协议,更省流量。
6. 安全加固措施
6.1 访问控制方案
IP白名单:
iptables -A INPUT -p tcp --dport 1984 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 1984 -j DROPHTTPS加密:
./cpolar https -hostname yourdomain.cpolar.cn
6.2 数据备份策略
推荐使用rsync做异地备份:
rsync -avz --delete /mnt/nvr_record/ backup@192.168.2.100:/backup/nvr/可以添加到crontab每天凌晨执行:
0 3 * * * /usr/bin/rsync -avz...7. 维护与监控
7.1 服务健康检查
编写监控脚本check_service.sh:
#!/bin/bash if ! pgrep -x "go2rtc" > /dev/null; then /path/to/go2rtc -daemon fi添加到crontab每分钟检查:
* * * * * /path/to/check_service.sh7.2 日志分析技巧
使用GoAccess分析访问日志:
goaccess /var/log/easynvr/access.log --log-format=COMBINED重点关注:
- 高频访问IP(可能异常)
- 404错误(配置问题)
- 大文件下载(耗带宽)
这个方案在我实验室稳定运行了半年多,经历了各种网络环境的考验。最大的体会是:内网穿透一定要做心跳检测,否则长时间空闲后隧道可能断开。现在我的配置是每5分钟发一次心跳包,再没出现过连接中断的情况。