打造個人多媒體服務器之二
背景:
我家里有台服務器存儲了好多的數據,N多的資源.主要是學習視頻. 有時候人不在家的時候就看不到了,這當然不能阻止我 學習(
瞎折騰)的熱情, 而且還不能下載下來觀看,因為存儲和時間的關系. 最好還得能倍速播放. 反正一陣折騰后,可以美滋滋看視頻了.
相關架構:
- 內網資料服務器:中國大內網之稱的
中國移動寬帶
[100m下行,20m上行] [移動贈送] - [備用]中專(轉發)服務器1: 阿里雲 5m那種學生機. [學生機 100多塊]
- [主用]中國電信家用寬帶1條:500m下載,20m上傳. [親戚家閑置,]
技術/軟件:
流媒體服務器 Nginx+Nginx-rtmp-module
打洞或轉發 frp
跳轉電信寬帶中專 flask
服務器ip更新 Zabbix
[因為之前搭建了zabbix,所以就用zabbix獲取ip好了]
上一部分:https://www.cnblogs.com/lovesKey/p/11027348.html
一個簡單的流程圖 (實在不會畫)
使用效果:
家用電信ip轉發 2m/s 的樣子,看視頻完全沒問題.而且還很爽!!!
阿里雲ip轉發 600k/s 的樣子,正常看也沒什么問題,有時候快進需要緩沖一小下. 而且播放視頻的時候把帶寬用盡了,影響到其它服務了. [學生機 一百多文一年,5M寬帶還是很便宜的呢.]
看圖:
客戶端使用
之前的問題: 如flv,mpeg編碼的mp4文件
都沒辦法直接點擊播放的.(自己也不會寫前端播放器.)
現在實現是這樣的.(右鍵點擊鏈接就可以播放,而且其他視頻流文件也可調用vlc
很爽)
調用了 vlc 播放器
看可以播放了.
最贊的是 vlc幾乎可以播放所有格式的視頻了. 而且也可以Linux下使用的.
現在架構的簡述
服務端Nginx+frp(打洞轉發工具,把內外的服務器暴露到外網)
高可用:用flask來切換,阿里雲或家用電信寬帶轉發
客戶端火狐瀏覽器(Chrome也是可以的)+插件Open in VLC media player
+vlc播放器
服務端相關的配置文件:
內網服務器:
兩個frpc服務需要管理,一個使用supervisord,一個使用systemd管理.
- supervisor管理
supervisor配置文件(管理鏈接到電信ip的frpc服務)
vim /etc/supervisor/supervisord.conf
[program:frpc]
directory = /home/makeit/apps/frp_0.27.0_linux_amd64/
command = /home/makeit/apps/frp_0.27.0_linux_amd64/frpc -c /home/makeit/apps/frp_0.27.0_linux_amd64/frpc.ini
autostart = true
startsecs = 10
autorestart = true
startretries = 3
user = root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /home/makeit/apps/frp_0.27.0_linux_amd64/frac.log
#用來動態重啟frpc服務. 因為家庭電信ip經常會有變化,當變化的時候需要修改frpc配置文件並重新啟動frpc服務是之可用.
[program:keepSV]
directory = /home/makeit/apps/
command = /usr/bin/python3 /home/makeit/apps/keepSV.py
autostart = true
startsecs = 10
autorestart = true
startretries = 3
user = root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 2
stdout_logfile = /home/makeit/apps/keepSV.log
- systemd管理
vim /lib/systemd/system/frpc.service
[Unit]
Description=Frp Client Service
After=network.target
[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
ExecStart=/usr/bin/frpc -c /etc/frp/frpc.ini
ExecReload=/usr/bin/frpc reload -c /etc/frp/frpc.ini
[Install]
WantedBy=multi-user.target
vim /etc/frp/frpc.ini
[common]
server_addr = 阿里雲的ip
server_port = 9000
log_file = /var/logs/frpc.log
# trace, debug, info, warn, error
log_level = info
log_max_days = 3
# for authentication
token = 2019
[rtmp_udp]
type = udp
local_ip = 127.0.0.1
local_port = 1935
# if remote_port is 0, frps will assign a random port for you
remote_port = 1935
[testnginx]
# tcp | udp | http | https | stcp | xtcp, default is tcp
type = tcp
local_ip = 127.0.0.1
local_port = 8080
# true or false, if true, messages between frps and frpc will be encrypted, default is false
use_encryption = true
# if true, message will be compressed
use_compression = true
# remote port listen by frps
remote_port = 6088
# frps will load balancing connections for proxies in same group
#group = test_group
# group should have same group key
#group_key = 123456
# enable health check for the backend service, it support 'tcp' and 'http' now
# frpc will connect local service's port to detect it's healthy status
health_check_type = tcp
# health check connection timeout
health_check_timeout_s = 3
# if continuous failed in 3 times, the proxy will be removed from frps
health_check_max_failed = 3
# every 10 seconds will do a health check
health_check_interval_s = 10
frpc鏈接電信ip的配置文件
# [common] is integral section
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
server_addr = 電信ip
server_port = 8088
# if you want to connect frps by http proxy or socks5 proxy, you can set http_proxy here or in global environment variables
# it only works when protocol is tcp
# http_proxy = http://user:passwd@192.168.1.128:8080
# http_proxy = socks5://user:passwd@192.168.1.128:1080
# console or real logFile path like ./frpc.log
log_file = /var/logs/frpc.log
# trace, debug, info, warn, error
log_level = info
log_max_days = 3
# for authentication
token = 20192019
[rtmp_udp]
type = udp
local_ip = 127.0.0.1
local_port = 1935
# if remote_port is 0, frps will assign a random port for you
remote_port = 1935
[testnginx]
# tcp | udp | http | https | stcp | xtcp, default is tcp
type = tcp
local_ip = 127.0.0.1
local_port = 8080
# true or false, if true, messages between frps and frpc will be encrypted, default is false
use_encryption = true
# if true, message will be compressed
use_compression = true
# remote port listen by frps
remote_port = 6088
# frps will load balancing connections for proxies in same group
#group = test_group
# group should have same group key
#group_key = 123456
# enable health check for the backend service, it support 'tcp' and 'http' now
# frpc will connect local service's port to detect it's healthy status
health_check_type = tcp
# health check connection timeout
health_check_timeout_s = 3
# if continuous failed in 3 times, the proxy will be removed from frps
health_check_max_failed = 3
# every 10 seconds will do a health check
health_check_interval_s = 10
Nginx 部分配置文件 相關參考 https://www.cnblogs.com/lovesKey/p/11027348.html
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
server {
listen 8080;
server_name localhost;
charset utf8;
#access_log logs/host.access.log main;
location / {
root /mnt/s2t;
autoindex on;
auth_basic "needAuth";
auth_basic_user_file /usr/local/nginx/conf/passwd.db;
index index.html index.htm;
}
監視電信ip變動,將變動后的ip寫到frpc配置文件內后重啟frpc服務.
vim /home/makeit/apps/keepSV.py
#
# by:lvusyy
#
import json
import os
import time
import requests
import sys, argparse
class Zabbix_Api:
def __init__(self):
self.url = 'http://zabbix服務器ip/zabbix/api_jsonrpc.php'
self.header = {"Content-Type": "application/json"}
self.id = 1
self.auth=self.user_login()
def json_obj(self,method,auth=True,params={}):
obj = {'jsonrpc': '2.0',
'method': method,
'params': params,
'auth': auth,
'id': self.id}
if not auth:
del obj["auth"]
return obj
def user_login(self):
data=self.json_obj(method="user.login",auth=False, params={"user": "zabbix賬號", "password": "zabiix密碼"})
return json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)["result"]
def get_host(self):
data=self.json_obj(method="host.get",
params={
"output": ["hostid", "name"]
},
auth=self.auth)
return json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)
def get_mem_total(self,hostid):
data=self.json_obj(method="item.get",
params={
"output": "extend",
"hostids": hostid,
"search": {
"key_": "vm.memory.size[total]"
}
},
auth=self.auth)
return int(json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)["result"][0]["lastvalue"])/1024/1024/1024
def get_ip(self,hostid):
data=self.json_obj(method="item.get",
params={
"output": "extend",
"hostids": hostid,
"search": {
"key_": "ip"
}
},
auth=self.auth)
return json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)["result"][0]['lastvalue']
def getIP(sv,tgName=''):
tgHostId = 0
hosts = sv.get_host().get('result', {})
for _host in hosts:
if tgName in _host.get('name', ''):
tgHostId = _host.get('hostid', 0)
break
return (sv.get_ip(tgHostId)) # '10269'
def changeConf():
'修改配置文件,使用模板方式替換,替換后重啟frpc服務然后把新ip地址傳給阿里雲'
confPach='/home/makeit/apps/frp_0.27.0_linux_amd64/frpc2.ini'
os.system('cp '+confPach+' '+confPach.replace('frpc2','frpc'))
os.system('sed -i s/wutoon\.com/'+ip+'/g /home/makeit/apps/frp_0.27.0_linux_amd64/frpc.ini')
os.system('supervisorctl restart frpc')
time.sleep(3) #sleep 3 s
requests.get('http://flaskip:88/ip?ip='+ip) #when fail do nothing
ip='阿里雲的ip地址'
def keepSVOnline(sv,tgName):
'保持服務可用'
global ip
while True:
if ip not in getIP(sv,tgName):
ip=getIP(sv,tgName)
changeConf()
time.sleep(8)
if __name__ == '__main__':
sv=Zabbix_Api()
tgName='pxcnnet'
keepSVOnline(sv,tgName) #multi thread
阿里雲配置
flask服務 負責跳轉(高可用?)
flask 安裝 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple flask
#by:lvusyy
from flask import Flask
from flask import request
from flask import redirect
app = Flask(__name__)
IP = '阿里雲服務器的ip.com'
@app.route('/')
def hello_world():
return redirect("//"+IP+":6088")
@app.route('/ip')
def ip():
global IP
_ip=request.args.get('ip',default='',type=str)
if _ip:
IP=_ip
return 'ok'
return 'fail'
if __name__ == '__main__':
app.run(host="0.0.0.0",port=88)
frps.ini
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = 9000
# udp port to help make udp hole to penetrate nat
bind_udp_port = 9001
# udp port used for kcp protocol, it can be same with 'bind_port'
# if not set, kcp is disabled in frps
kcp_bind_port = 9000
token = 2019
#!/bin/bash
#push ip temp fan data to zabbix,使用被動方式 zabbix服務端需要建立對應的采集器
test $(($RANDOM%2)) && zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "ip" -o `curl -s ip.cip.cc` &>/dev/null || zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "ip" -o `curl -s iiip.co` &>/dev/null
zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "temp.cpu" -o $(sensors -u coretemp-isa-0000 |grep temp1_input:|cut -c 16-55) &>/dev/null
zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "fan.cpu" -o $(sensors |grep fan2 |awk '{print $2}') &>/dev/null
客戶端軟件下載和配置:
火狐瀏覽器
下載地址:http://www.firefox.com.cn/
Open in VLC media player
插件地址:https://addons.mozilla.org/zh-CN/firefox/addon/open-in-vlc/
vlc播放
下載地址:http://get.videolan.org/vlc/3.0.7.1/win64/vlc-3.0.7.1-win64.exe
Open in VLC media player
設置
上面配置vlc路徑如果是默認安裝路徑就不用修改即可.
調用組件下載:https://github.com/andy-portmen/native-client/releases
到此所有操作都已經完成了. 找到一個鏈接點擊右鍵 open in vlc
就可調用vlc播放器播放了.
Linux用戶的話.其實Linux用戶都是大神.(不需要特殊說明, 解壓Linux.zip 運行install.sh即可.)
On Linux and Mac, you can define custom root directory by adding --custom-dir=
to the installer script
Example: ./install.sh --custom-dir=~/Desktop/
enjoy!!!