B站为什么使用CDN/PCDN
B站作为一个视频网站,网络流量是海量的,如果只靠B站的单一服务器很难支撑海量的请求与流量。
CDN(Content Delivery/Distribution Network)内容交付/分发网络的作用就是分散这些海量流量到众多节点之上,比如这样:
而PCDN则是(P2P CDN),作用和CDN其实是一样的,但是由于P2P的节点无法保证质量,且某些环境网络会屏蔽一部分的P2P连接,比如校园网络中。所以PCDN会造成一定程度的卡顿,但是PCDN的价格相比于CDN会下降很多,会省下来很多成本
B站的CDN/PCDN分布
- 服务商CDN:由第三方提供的CDN服务,这种CDN会相当稳定高速
域名:upos-sz-mirror****.bilivideo.com
腾讯:cos, cosb, coso1, coso2, bos
金山:ks3, ks3b, ks3c, ks32
七牛:kodo, kodob
华为:hw, hwb, uphw, js
阿卡迈(海外):akamai
- 自建CDN:B站自行建设和维护的服务器网络
域名:cn-****.bilivideo.com
从其域名结构可以推测,该CDN可能按照地区进行了部署,其中的标识符代表了各个省份和城市的首字母缩写
- MCDN:与京东云相关的CDN类型
域名:xxxxx(ip地址).mcdn.bilivideo.com
从其IP地址分配来看,可能与家用宽带网络有关,与京东云的无线宝产品存在某种关联,这种其实也算是PCDN的范畴了
- PCDN:B站自行建设和维护的服务器网络
域名:****.v1d.szbdyd.com
B站所采用的PCDN,可能会受到各种因素的影响,如用户之间的距离、上行带宽差异等
B站卡顿原因
在没有IPV6地址的情况下,我们很容易分配到PCDN节点,但是PCDN天然的劣势,播放的效果会有很大的差异,b站播放卡顿的很多情况都是由于这个造成的
在PC网页端我们可以右键->视频统计信息,很容易的看到我们当前的视频域名信息
比如我现在的节点就是xy111x51x181x119xy.mcdn.bilivideo.cn:4483,使用的是京东云,这样就会造成一定的卡顿概率
PC端解决方案
在PC端浏览器我们可以使用浏览器插件来进行拦截指向这种PCDN的请求
浏览器插件安装
点击对应的连接进行安装
ADGUARD(推荐)
使用这个广告拦截器,在浏览器安装对应的插件之后,打开设置界面在用户过滤器中填入以下规则
||*pcdn*.biliapi.net^$important
||mcdn.bilivideo.cn^$important
||szbdyd.com^$important
#||cn-*.bilivideo.com
||*pcdn*.biliapi.net^$important
: 这条规则意味着拦截所有子域名中含有pcdn
且顶级域名为biliapi.net
的请求,并标记为重要。
||mcdn.bilivideo.cn^$important
: 这条规则意味着拦截所有指向mcdn.bilivideo.cn
的请求,并标记为重要。
||szbdyd.com^$important
: 这条规则意味着拦截所有指向szbdyd.com
的请求,并标记为重要。
#||cn-*.bilivideo.com
: 这条规则前面有一个#
号,通常在配置文件中用来注释掉某行规则,使其无效。如果没有#
号,它将会拦截所有子域名以cn-
开头,顶级域名为bilivideo.com
的请求。
然后重启浏览器或者刷新b站页面,就可以看到拦截日志中确实拦截了PCDN链接
篡改猴
安装之后进入脚本搜索页面,https://www.tampermonkey.net/scripts.php
搜索,Make BiliBili Great Again,或者直接点击这个https://greasyfork.org/zh-CN/scripts/415714-make-bilibili-great-again,点击安装按钮
只不过这个脚本中有很多功能会让你感觉不舒服,所以我们打开编辑界面
长这样
可以按住Alt,然后鼠标贴着边将除了”去 P2P CDN“进行一下注释,或者直接全部删掉,替换成我下面的脚本
// ==UserScript==
// @name Make BiliBili Great Again
// @namespace https://www.kookxiang.com/
// @version 1.5.4
// @description useful tweaks for bilibili.com
// @author kookxiang
// @match https://*.bilibili.com/*
// @run-at document-body
// @grant unsafeWindow
// @grant GM_addStyle
// @grant GM_notification
// @downloadURL https://update.greasyfork.org/scripts/415714/Make%20BiliBili%20Great%20Again.user.js
// @updateURL https://update.greasyfork.org/scripts/415714/Make%20BiliBili%20Great%20Again.meta.js
// ==/UserScript==
// 没用的 URL 参数
const uselessUrlParams = [
'buvid',
'is_story_h5',
'launch_id',
'live_from',
'mid',
'session_id',
'timestamp',
'up_id',
'vd_source',
/^share/,
/^spm/,
];
// Block WebRTC,CNM 陈睿你就缺这点棺材钱?
try {
Object.defineProperty(unsafeWindow, 'webkitRTCPeerConnection', { value: undefined, enumerable: false, writable: false });
} catch (e) { }
// 移除鸿蒙字体,系统自带它不香吗?
window.addEventListener('load', function () {
document.body.classList.remove('harmony-font');
})
// 去 P2P CDN
Object.defineProperty(unsafeWindow, 'PCDNLoader', { value: class { }, enumerable: false, writable: false });
Object.defineProperty(unsafeWindow, 'BPP2PSDK', { value: class { on() { } }, enumerable: false, writable: false });
Object.defineProperty(unsafeWindow, 'SeederSDK', { value: class { }, enumerable: false, writable: false });
if (location.href.startsWith('https://www.bilibili.com/video/') || location.href.startsWith('https://www.bilibili.com/bangumi/play/')) {
let cdnDomain;
function replaceP2PUrl(url) {
cdnDomain ||= document.head.innerHTML.match(/up[\w-]+\.bilivideo\.com/)?.[0];
try {
const urlObj = new URL(url);
const hostName = urlObj.hostname;
if (urlObj.hostname.endsWith(".mcdn.bilivideo.cn")) {
urlObj.host = cdnDomain || 'upos-sz-mirrorcoso1.bilivideo.com';
urlObj.port = 443;
console.warn(`更换视频源: ${hostName} -> ${urlObj.host}`);
return urlObj.toString();
} else if (urlObj.hostname.endsWith(".szbdyd.com")) {
urlObj.host = urlObj.searchParams.get('xy_usource');
urlObj.port = 443;
console.warn(`更换视频源: ${hostName} -> ${urlObj.host}`);
return urlObj.toString();
}
return url;
} catch (e) {
return url;
}
}
function replaceP2PUrlDeep(obj) {
for (const key in obj) {
if (typeof obj[key] === 'string') {
obj[key] = replaceP2PUrl(obj[key]);
} else if (typeof obj[key] === 'array' || typeof obj[key] === 'object') {
replaceP2PUrlDeep(obj[key]);
}
}
}
replaceP2PUrlDeep(unsafeWindow.__playinfo__);
(function (open) {
unsafeWindow.XMLHttpRequest.prototype.open = function () {
try {
arguments[1] = replaceP2PUrl(arguments[1]);
} finally {
return open.apply(this, arguments);
}
}
})(unsafeWindow.XMLHttpRequest.prototype.open);
}
然后ctrl+S进行保存
参考博文:https://blog.suysker.xyz/archives/301
好文,收藏了
很不错 收藏了
PS:难怪每次B站看视频的时候总感觉不大顺畅~