历经多次宽带因为单一运营商垄断,价格高到离谱,之前在学校测过4G是可以跑到100Mbps的下行速率的,买过4G路由器做接入,后来因为SIM卡不够用就出掉了
在5G时代,闲置的4G手机完全可以用来作为网络接入设备,我用刷了OpenWrt的小米R3G有线连接退役的iPhone SE做了一个简单的4G路由器,找个4G信号好的地方固定,测速还行就可以开始用了
因为有部分模块依赖于内核,加上平时编译不太方便,所以采用官方固件,参考官网教程 Smartphone USB tethering
我记录的一些需要装的包
# 换源
sed -i 's_downloads\.openwrt\.org_mirrors.ustc.edu.cn/lede_' /etc/opkg/distfeeds.conf
# 装包
opkg install kmod-usb-net-ipheth kmod-usb-net kmod-usb-ohci kmod-usb-uhci kmod-usb2 libimobiledevice-utils libusbmuxd-utils usbmuxd
opkg install luci-compat
用了一段时间后发现了如下问题,当然也还有其他的手机可以尝试,但是我觉得4G的问题更大:
ios更新14之后,以上教程提到的方法就失效了,后续就没有在ios上再尝试过了;随着第一代5G手机在2022年陆陆续续退役,5G手机USB共享网络给OpenWrt路由器却没有达到预想中的那么快,考虑到在手机上经过了一次NAT,存在硬件开销以及调度和功耗限制,这还是不适合作为一个长期方案
于是开始关注5G CPE,恰好就遇到了2020年刚上市的华为的5G CPE Pro 2 (型号H122-373,以下简称H122),幸好买的早,后来芯片荒价格一路水涨船高,直到后来智选的5G CPE铺货
当时刚好手上有可以跑千兆5G卡,至少在下载速率上可以超过绝大多数家庭宽带了,缺点也还是有的:
写出来有点多,但不可否认的是在很长一段时间里H122就是能买到的最强的5G CPE,在我这稳定运行了三年,因为是价格低位购入,还能直接用天际通物联网卡(23年已经限速到200Mbps,没有了5G SA,只能用4G)
这里使用的是DJI增强图传模块连接OpenWrt路由器USB接口接入的4G网络
2022年大疆在Mavic3发布之后发布了与之配套的4G图传模块(DJI Cellular),然而自带的增强图传服务只有一年的套餐,后续如果要继续使用就需要以每年99续费增强图传服务,对于只是想超视距飞行过把瘾的人来说,增强图传服务到期之后模块自然就闲置了(大疆2023年新品不兼容该模块),二手市场上挂出的非常多,感觉出手比较困难(原价699,2023.11二手大把的450),而全新的同规格的Cat4速率的4G USB网卡120可以买到,既然如此,还不如留着当4G网卡发挥余热
该方法在ImmortalWrt 23.05.1的ARM和MT7621的路由器上测试成功
opkg install qmi-utils usb-modeswitch kmod-mii kmod-nls-base kmod-usb-core kmod-usb-ehci kmod-usb2 kmod-usb-net kmod-usb-wdm kmod-usb-net-qmi-wwan wwan uqmi luci-proto-qmi
ls /dev/
应该看到cdc-wdm3
这个设备了
echo "2ca3 4006 0 2c7c 0125" > /sys/bus/usb/drivers/qmi_wwan/new_id
/dev/cdc-wdm3
(最关键,下图是借用的其他教程的截图作为参考),其余的信息保持默认; 在防火墙设置,给这个接口分配防火墙区域为wan
,保存设置即可
如果此时4G图传模块上的灯是绿色的,即模块正常连上了4G网络,很快能看到刚刚创建的接口已经获取到了IPv6的地址,并且系统自动生成了名为DJI_4的IPv4地址的虚拟接口,此时路由器应该就能通过4G模块访问互联网
第一次成功驱动并设置好QMI拨号的接口后,可以将命令
echo "2ca3 4006 0 2c7c 0125" > /sys/bus/usb/drivers/qmi_wwan/new_id
添加到开机启动脚本中(网页LuCI界面->系统->启动项->本地启动脚本),添加到文本框中exit 0
这一行之前即可,后续重启也无需任何的操作,随时插入4G模块后一段时间就能正常上网了
在大疆论坛上有用户尝试了Windows上驱动并成功让PC能接入4G网络,后续大疆又发布了模块的Windows驱动,其中主要提供了以下的信息:
搜索OpenWrt上驱动模块的资料,发现在OpenWrt上移植EG25驱动的经验是空白的,主要都是移植EC2X的,其中《挂载移远EC20、EC21、EC25、AG35等4G模块》参考了官方的Linux驱动文档,EG25在文档发中和EC25的PID和VID是相同的(2C7C, 0125),但是与4G图传模块的(2CA3, 4006)不同,即使移植了EG25的驱动也未必能识别到4G图传模块
直到看到论坛里有人发了4G图传模块用于Linux系统上网尝试,用到了将USB设备的PID和VID写入/sys/bus/usb/drivers/…/new_id处理驱动识别的方法,另外又查到了23年11月的OpenWrt 下实现移远 4G 模块上网 中提到在OpenWrt 22.03在无需改内核代码就能驱动EC20
在运行echo "2ca3 4006 0 2c7c 0125" > /sys/bus/usb/drivers/qmi_wwan/new_id
后,可以用cat /sys/kernel/debug/usb/devices
查看到4G模块被qmi_wwan驱动(设备对应的信息出现Driver=qmi_wwan字样)
在/dev
目录下可以看到/dev/cdc-wdm[0-3]
一共4个设备,最开始尝试了/dev/cdc-wdm0
发现无法拨号就差点放弃,最后尝试了下/dev/cdc-wdm3
发现拨号可以获取到IP了
uqmi
命令可以与模块通信并输出一些状态的信息,其中个人比较关注的主要是信号
root@XDR6088:~# uqmi -d /dev/cdc-wdm3 --get-signal-info
{
"type": "lte",
"rssi": -55,
"rsrq": -6,
"rsrp": -79,
"snr": 14.800000
}
4G模块的速率标准为Cat4(下行速率最高150Mbps,上行最高为50Mbps),实测在以上信号强度的电信4G上下行均为50Mbps左右,日常用这速率也算能接受吧,联想到我测试过最快的4G是2018年在iPhoneSE(4G Cat6最高下行速率300Mbps)上跑出了100Mbps的下行
关于IPv6,首先路由器时可以获取到公网IPv6地址的(以及64位前缀的PD),并且在LAN默认的IPv6设置下,可以向下分配地址,另外就是传入连接的连接性,实测发现有运营商的差异:移动的IPv6地址无法外网访问,联通和电信的地址可以外网访问
由于CPE和4G模块获取的IPv6地址是不含短于64位的前缀的,所以在使用二级路由的情况下,二级路由下的设备无法获取公网IPv6地址,这个时候需要配置“IPv6中继+NDP代理”,OpenWrt 23.05的LuCI界面的设置过程如下:
ip -6 neigh
和LuCI上的系统->路由表->IPv6邻居看IPv6地址对应的接口来观察NDP代理的效果)我的网络结构是CPE做一级路由,OpenWrt做二级路由,因为华为5G CPE本身防火墙的原因,二级路由下面的设备可以获取到IPv6地址,但是无法从外网访问
但是如果CPE或者4G模块支持桥模式,那么OpenWrt路由器大概率是不受CPE或者4G模块的防火墙影响的,放开OpenWrt的防火墙之后,只剩下运营商屏蔽了传入连接的可能性
局域网肯定还是要用一台OpenWrt路由器作为主路由,如果一台主路由能解决问题是最好,列出来的要求有点多:
在从2020年到2023年这一段时间里,涌现了一大批可以刷OpenWrt的WiFi6路由器:Qnap-301w、红米AX6,AX6000、中兴NX30 Pro,以及可能有QSDK固件的小米万兆路由,对比以上的要求有明显的短板,直到某一天看到B站上有人给TP-LINK XDR6088刷机的教程:TP-link路由器XDR6088、6086、4288刷openWRT,我终于发现了一台有潜力的机器:
可以查到的获取终端操作权限刷入U-boot(bootloader)的方法源于:TP-LINK XDR6086/XDR6088 反弹 SHELL 并开启 SSH
综合亲手实践以及上面的视频教程,有几点需要特别注意
{"error_code":0}
nc -l -p 9995 > backup.img
),不能用Powershell(备份传输完成后,校验的话就会发现用Powershell运行同样的命令会得到不一样的文件),因为这一条操作失误导致我刷OpenWrt后刷回原厂系统的过程中导致变砖我只刷了视频教程的固件,基本上是截至到当时最新的R23.5.1,2.5G网口和WiFi稳定的运行两周,这里先放下收集到的参数的对比,至少CPU的参数在当前WiFi6末期可刷机硬路由中基本上是第一档的
路由器 | CPU | RAM | ROM |
---|---|---|---|
Newifi Y1 | MT7620 1C@580MHz | 128MB | 16MB |
K2P | MT7621AT 2C4T@880MHz | 128MB | 16MB |
XDR6088 | MT7986A 12nm 4*A53@2.0GHz | 512MB DDR3 | 128MB |
NX30 Pro | MT7981B 12nm 2*A53@1.3GHz | 256MB DDR3 | 128MB |
Qnap-301w | IPQ8072A 12nm 4*A53@2.2GHz | 1GB DDR3-1600 | 4GB |
K3 | BCM4709 40nm 2*A9@1.4GHz | 512MB DDR3-1600 | 128MB |
N1 | S905D 28nm 4*A53@1.5Ghz | 2GB | 8GB |
上文提到Powershell下使用nc命令重定向的备份大小异常的问题,相关的原因查明在:Powershell与bash的重定向的差异,在搞清楚其中的原理后,我理解无法通过简单的操作使得备份还原,于是在论坛找到了别人的备份的mtdblock9尝试救砖,参考
因为我之前给T440s修改BIOS买了CH341A编程器和8pin的夹子,所以就鼓起勇气拆机,经过艰难的掰卡口后,很快就遇到了问题:
红米AX6000救砖中提到建议改CH341的输出电压为3.3v,这个要飞线,我没有工具:
店家给的CH341的编程器刷写软件不支持F50L1G41LB,红米AX6000救砖中提到“NeoProgrammer不知道如何写入单独分区,我选择了SNANDer”:
最棘手的问题在于,F50L1G41LB相比W25Q32V,夹子的触点难以夹到芯片的针脚,无法稳定连接就无法写入,红米AX6000救砖中用的漆包线飞线
在OpenWrt官方23.05正式版支持XDR-6088的固件后,参考了TL-XDR6088/6086 刷入官方 Openwrt/Immortalwrt,原文已经记录的相当的详细,此处仅摘录用到的步骤(因为独立博客的域名过期之后就很可能找不到原文了)
本文写作时,最新的是 23.05.0-rc3 版。将来请用更新的稳定版本,目前 Immortalwrt 已经支持:
- 双 2.5Gb 网口的正常驱动(但LED灯还不亮)
- WiFi6 160Mhz
- 硬件流量分载
- WED (Wireless Ethernet Dispatch) 无线加速
- 硬件 NAT 加速
- Fullcone NAT
4.2 如果路由器已经刷了其它版本的 Openwrt
在 Openwrt 中运行
cat /proc/mtd
,得到mtd设备的真实命名,再用命令来写入(将下面的BL2或FIP改成你在上面看到的名字,注意大小写)md5sum /tmp/preloader.bin mtd erase BL2 mtd write /tmp/preloader.bin BL2 mtd verify /tmp/preloader.bin BL2 md5sum /tmp/bl31-uboot.fip mtd erase FIP mtd write /tmp/bl31-uboot.fip FIP mtd verify /tmp/bl31-uboot.fip FIP
注意查看上传的两个文件 md5 并和本地文件对比,查看两次 mtd verify 最后是否输出输出 Success,没问题才可进行下一步。
5. 通过 tftp 载入 recovery 镜像
这时候你可以拔掉路由器的电源,然后插上。直接拔电源可能是最安全的,因为如果你用 reboot 命令,可能会有一些后台程序运行(包括可能你之前在慌乱中没有杀掉的误操作了的 dd)导致路由器变砖。别问我是怎么知道的。
此时 tftp 服务器上应该已经有提示了,路由器在请求的文件名为 openwrt-mediatek-filogic-tplink_tl-xdr6088-initramfs-recovery.itb 。你只需要把结尾为 recovery.itb 的文件,改名为这个就行了。
如果没动静,你可以拔下电源,然后顶住 reset 孔不放,同时插入电源,应该会看到 LAN 口的灯齐闪一下。大约10秒钟,应该就会进入 recovery 模式。确保网线插在 1Gb LAN 口上,网口的灯应该会亮的。
前面提到了WiFi6 160MHz普及之后,局域网传输的瓶颈主要在千兆的有线网口上,考虑到外置USB网卡(USB 3.0外置网卡最大速率为5Gbps)可能因为发热等因素不稳定,首选的话还是PCIe的网卡,而且由于数据中心万兆网卡下架,市面上有较多的低成本的选择,在网络讨论的最多的是浪潮X540-T2拆机卡,价格大概70左右,特别之处在于PCIE插槽是X8+X1,如果要用的话x1要绝缘屏蔽,我实际使用发现卡兼容性不太好:
最后捡到一张180的带华为物料编码的x540,有几乎覆盖整个卡面的黑色散热片,插上群晖DS1621可以直接用,对于装了驱动的Z370-I也是
简单测了下,这张x540的空载功耗大约是8w,看卡背面的便签写着silicom PE210G2I40E,查到了silicom官网关于电口万兆网卡的功耗,找到了“电口功耗高”的依据:
PE开头的NIC(网卡)均为silicom官网上的网卡的功耗数据(均为所有端口Link/Idel 的功耗的整卡功耗),可以看到x540的功耗一骑绝尘,考虑到网卡的成本以及长期电费,最后我找了一张AQC107的网卡LREC6880BT,也把数据列到了下面:
NIC | Controller | 无Link | GE | XGE | |
---|---|---|---|---|---|
PE310G2I50-T | X550-AT2 | 4.62W | 5.4W | 8.16W | x4 pcie 3.0 |
PE210G2I40-T | X540 | 7.23W | 7.92W | 14.28W | x8 pcie 2.1 |
PE310G2I71-T | X710-AT2 | 3.6W | 5.52w | 8.28W | x8 pcie 3.0 |
PE310G2I71 | X710BM2 | 3~4W | 4.6~4.8W | x8 pcie 3.0 | |
PE210G2SPI9A | 82599ES | 4~6W | 6W | x8 pcie 2.0 | |
LREC6880BT | AQC 107 | 网卡4.7W | x4 PCIe v2.1 |
数据中心下架的卡基本上都有些年头了,关于网卡的控制器、发布时间、制程、TDP,2022年末的二手价如下:
NIC | Controller | TDP | Release | Process | Price |
---|---|---|---|---|---|
华为SP230电 | X540-AT2 | 12.5W | 12Q1 | 40nm | 250左右 |
Intel X550 | X550-AT2 | 11W | 15Q4 | 28nm | 1200左右 |
Intel X710-T4 | XL710-BM1 | 7W | 15Q4 | 28nm | 2450 |
X520-DA1 | 82599ES | 09Q2 | 65nm | ||
LREC6880BT | AQC107 | 6W | 17Q4 | 28nm |
在网上看到说Intel的X540和X550在群晖的DSM系统中是免驱的(其实是DSM的Linux带了驱动),因为X550太贵,所以把目光投向了价格和功耗都合适的AQC107,因为群晖E10G18-T1 10G等群晖官方的万兆电口卡也是用的AQC107,我天真的以为第三方AQC107也是免驱的
网上我能找到两个中文的经验:
详细的要二次编译成功再补充,大概是下次DSM系统版本/内核版本更新
因为不涉及到后面的修改BIOS文件就能上64GB内存,这里直接上结论:
实测在华硕Z370-I的1410版本的BIOS,可以识别到64GB内存并开机正常使用,使用的内存是2条金士顿Fury DDR4 32GB 3200MHz
在我的平台上,用最新的3005的BIOS反而会导致莫名其妙的自动重启
关于CMD运行命令“wmic memphysical get maxcapacity会显示最大支持的内存”,实测是不准确的
华硕这块ITX的主板的BIOS文件的 最大内存限制的二进制位 与 已有经验反馈的ATX主板BIOS文件的不同,所以最后还是实践出真理
因为在互联网上找不到Z370-I成功实践的经验,所以这里留个记录:
Asus Z370-I是一块ITX主板,只有两个内存插槽,装机的时候切好碰上DDR4内存天价,所以很长一段时间里只有双通道16GB 3000MHz,这块主板在官网上参数写着最大支持32GB内存,也就是2X16GB,然而随着内存降价,发现23年单条32GB的内存已经很便宜了,想着直接上到双通道64GB,以后这台机器退役也能当服务器用
于是我搜到了CHH的帖子:首发!Z170/Z370 突破内存64g可用的上限限制,精华在评论里,总结如下:
如何使 H310C/B365/Z370 的 BIOS 支持最大 128G 内存:
1.UEFITool提取SiInitPreMem模块,GUID为A8499E65-A6F6-48B0-96DB-45C266030D83
2.UEFITool搜索“C786….000000….00”,其中“..”为任意HEX值
3.第一处“….”不用理会,第二处“….”如果是“8000”那么就是最大64G,如果是“0001”就是最大128G
4.将“8000”修改为“0001”可破除64G限制
5.100/200系BIOS内也有此内容,理论上6-9代的IMC支持的内存没差,6700+Z170也能128G内存(已测试可行)
6.我这边看,MSI的Z370,18年底的BIOS还是8000,19年4月的BIOS就是0001了,ASUS的BIOS一水的都还是8000
7.ME 需要禁用(修改Flash Descriptor的HAP Bit,但要注意部分主板有校验不允许这么改,改后无法开机)
8.部分BIOS需设置 Chipset->System Agent (SA) Configuration->Above 4GB MMIO BIOS assignment->Disabled 不同 BIOS 位置不同,且可能被隐藏,无法直接修改
注:参考后面的引用,第七步为:将 0x102h的位置 +1
限制内存大小的字段,在我的主板上看到的是
# 3005 BIOS (2000 我觉得是单条16G,或者单DIMM 32G)
#Hex pattern "C786....000000....00" found as "C7866F25000000200000" in TE image section at header-offset 388FCh
C7 86 6F 25 00 00 00 20 00 00 EB 20
6A 00 56 E8 B4 E0 FE FF 59 59 0F B6
# 纯血的370ROG已经提供了128G的bios( 2021-2-15 )
# 3004 BIOS 2021-04-16 发生了变化,没有了老版的第二行
C7 86 6F 25 00 00 00 20 00 00 EB 20
# 1802 BIOS
C7 86 6F 25 00 00 00 20 00 00 EB 0A
C7 86 6F 25 00 00 00 80 00 00
# 1410 BIOS
Hex pattern "C786....000000800000" found as "C7866F25000000800000" in TE image section at header-offset 384ACh
C7 86 6F 25 00 00 00 20 00 00 EB 0A
C7 86 6F 25 00 00 00 80 00 00 8B C3
“18年底的BIOS还是8000,19年4月的BIOS就是0001了”的这一行去掉发生3004(更新日志:主要是添加了Win11的支持,没有提内存上线变化),我找了M10H ROG MAXIMUS X HERO BIOS变更日志中有内存上限修改(Support Max DRAM Total Capacity up to 128 GB.)的新老BIOS看了下,也是去掉了8000这一行
]]>之所以要刷BIOS,是因为T440s大部分的BIOS有网卡白名单,基本完全限制住了自行升级网卡,自带的AC7260是Intel最早的2x2 AC网卡,信号和速度已经远远落后如今的AX网卡,T440s现在主要是处理器跟不上了,其他方面放到现在也是非常优秀的:
另外还有几个比较有意思的地方:
在如今是市场里确实很难找到合适自己用的笔记本(定位高,接口丰富,不用拓展坞),所以还是想多延续下T440s的使用期,一直比较头痛的就是更换网卡的问题,之前并非没有查过刷BIOS,但是教程太复杂,时过境迁,2020年搜到有不少人都能自己刷了,下面进入正题
虽然写的是T440p,但是实测对T440s基本适用,本文对以上的材料做下补充:
BIOS芯片的位置
夹上编程器的样子
用工具读取到的BIOS芯片型号和教程可能不同,以卖家附赠的工具为准
教程还带有解锁高级菜单的部分,但是实测貌似没什么用(主要想解锁功耗,15w下散热还是压得住的)
换了AX200的网卡之后在160MHz下实测无线可以跑满1000Mbps,另外一个在2020年的新闻就是Intel的网卡在MacOS下终于可以日常使用了:itlwm,因为手头空闲的机器不多,所以就尝试给T440s上黑苹果试一试,好在Clover的EFI不难找
实测黑苹果日常使用确实比Win10流畅不少(主要是少了一些莫名其妙的高占用),但是多开还是有些吃力的
缘起于之前为了收一个小机箱和MATX主板,被学长捆绑了一颗ES版的CPU,最开始说是E3,用CPU-Z看也是志强,但是根据顶盖上的四位编号QEDH,在某宝上搜索指向的是i7-4770s的ES版本,4c8t @ 3.0GHz,TDP 83W,并且带核显;尝试过作为家用win10主机使用过,但是核显实在太鸡肋,单核心主频低导致部分应用速度比较慢
最后我还是决定装一台低功耗的Mini Server,准系统选择了Haswell时代的M73(相比戴尔的9020散热更好),M73可以用ThinkPad系的方口电源也是一大优势(家里方口电源多…)
准系统的安装很简单,但是这里有些插曲,一个是CPU的散热问题,相比带T后缀的45W的低功耗CPU,以及家用台式机的65W标压处理器,QEDH的83W还是很吓人的,之前在B85 ATX主板上实测,解锁功耗烤机满载也确实可以跑到80W以上,所以对于65W以下的准系统M73,我选择了把顶盖到Die的导热材料换成液金,然后测试下M73能否在编译时跑满这颗CPU
这里选择CentOS下,初次编译OpenWrt作为负载,编译时,温度抵近90度,基本上就是达到默认风扇下的上限了,如果把风扇转速拉满,温度大概80左右,但是噪音太大了;使用s-tui可以在软件层面查看功耗和频率信息,CPU功耗接近60W,主频2.8GHz,因为可以用Type-C的方口诱骗线供电,所以也顺带看了下整机的功耗,基本在65W以下(用95W的电源);编译的时间对比win10下使用WSL2的i7-8700K,M73这套平台耗时是其两倍,可以接受的水平;另外日常待机功耗12W左右
之前用NAS时,用的比较多的就是Docker版本的qBittorrent以及网络共享功能,其实在Linux下实现这些并不难,M73用这一套的优势是相比传统NAS噪音很小,且小体型放置随意;这里使用和NAS上一样的容器镜像源,主要是qBittorrent作为下载软件
以下设置仅针对CentOS 7.9,其他发行版可能不同,其中Docker启动命令如下(记得建立挂卷的目录):
docker run -d \
--name=qbittorrent \
--network=host \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Europe/London \
-e WEBUI_PORT=8080 \
-v /home/qbittorrent/config:/config \
-v /home/downloads:/downloads \
--restart unless-stopped \
linuxserver/qbittorrent
可能遇到的问题
3.1X的内核可能存在qbt启动异常的问题,/usr/bin/qbittorrent-nox: error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory
参考群晖
Linux的防火墙可能会阻止访问8080端口
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
部分运营商的家用宽带也会在上游阻隔8080端口的访问,此时建议将Docker启动命令的监听端口修改为8081
添加证书设置开启HTTPS访问后无法打开网页
需要修改证书的key的权限为所有人可读
chmod +044 keyfilepath
这个在使用供应商的证书 对比 通过ACME申请的Let’s Ecrypt证书发现的差异,因为ps -ef | grep -i qbit
可以看到实际使用证书的程序的UID是abc而不是root,acme在使用root权限执行申请到的证书key对abc用户是不可读的
root 255 1 0 18:26 ? 00:00:00 s6-supervise qbittorrent
abc 333 255 1 19:15 ? 00:00:00 /usr/bin/qbittorrent-nox --webui-port=8081
基于系统的用户创建SMB用户
设置SMB共享目录
关闭SELinux(否则只能看到目录而看不到文件)
临时关闭(不用重启机器)
setenforce 0
修改/etc/selinux/config 文件
将SELINUX=enforcing改为SELINUX=disabled
重启机器即可
在使用SMB作为局域网内的文件共享方式有以下的缺点:
优点:
首先说WebDav协议,这个最早在群晖的NAS上只要安装就能使用,主要就是用于公网访问文件,然而我在很长一段时间,都没有在Linux上寻找一款配置简单,易用的服务端,在此期间用gohttpserver作为多端访问服务器文件的方式
之前听闻Alist可以挂载云盘后对外提供WebDav协议的访问,所以就看了下文档,其简介为:“一个支持多种存储的文件列表程序”,打开发现其实也是支持挂载本地存储的,又有网页端,完全可以实现gohttpserver的功能,初次之外页面上的分享功能也方便将Alist本身作为网盘分享文件
这里因为考虑到方便的挂载本地目录(主要是qbittorrent的下载目录)以及使用HTTPS(证书周期性的需要更换),所以使用了本地直接部署的方式,采用官网的一键脚本
curl -fsSL "https://alist.nn.ci/v3.sh" | bash -s install
特别留意首次安装后,日志会显示默认的随机密码
之后就是用nPlayer等播放器挂载webdav目录了,留意url的路径http[s]://domain:port/dav/
中的dav,如果是Android的话,nPlayer可能常年没有更新了,推荐Reex
Nextcloud挂载SMB提供多种外部访问方式,体验下来还是SMB为主,Nextcloud的优势在于有完善的移动APP,2022年发现还是Alist更轻量好用
docker run -d \
--name=nextcloud \
--network=host \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Shanghai \
-v /home/nextcloud/config:/config \
-v /home/nextcloud/data:/data \
--restart unless-stopped \
linuxserver/nextcloud
可能遇到的问题:nextcloud会识别首次登陆的IP之类的信息,导致无法二次访问
解决办法:需要到docker指定的config目录下修改才可以换用域名或者新的IP访问
vi ./nextcloud/config/www/nextcloud/config/config.php
<?php
$CONFIG = array (
'memcache.local' => '\\OC\\Memcache\\APCu',
'datadirectory' => '/data',
'instanceid' => 'xxx',
'passwordsalt' => 'xxx',
'secret' => 'xxx',
'trusted_domains' =>
array (
0 => '192.168.8.114',
1 => preg_match('/cli/i',php_sapi_name())?'127.0.0.1':$_SERVER['SERVER_NAME'],
),
'dbtype' => 'sqlite3',
'version' => '21.0.0.18',
'overwrite.cli.url' => 'https://192.168.8.114',
'installed' => true,
);
主要就是网络环境,之后的所有工作是围绕网络环境来的
网络环境:这里用的是Google Cloud Platform(GCP)的VPS,DigitalOcean的打开注册页面为502(可能是用的人太多了,Do类似的情况很常见)
为了复制粘贴方便用的PC端的浏览器(必要的话开无痕模式),不同的平台流程可能不一样
网络上有那种地址身份信息生成器,据说地址,注册IP以及验证的电话在相关的时候比较省事,所以这里就从网络到地址一步步来
首先是根据之前的IP得到的经纬度信息,在Google地图中找到具体的位置,可以得到申请需要的:州,城市,街道,邮编
之后再在经纬度周边找到一个有提供电话信息的位置,后面需要用到其区号
据说会用短信验证(我并没有走这个流程),这里选择用TextNow提供的虚拟电话号码,提供地理位置(区号)就行
我手上的双币卡是无法直接做为支付方式的,但是据说可以买官网上的礼品卡,然而面额都有些大,所以就在淘宝上找小面额的礼品卡,这里要注意的是,因为盗刷信用卡情况的比较多,网上不乏有那种特别便宜的软件激活码和充值方式,切记不能贪小便宜(据说重则封号)
设置密保问题,完善个人信息之类的,之后登陆就可以看到英文的Apple Store,貌似下载软件的速度有点慢
之前也是试过好几次,但是搞不清楚的问题实在是太多了,一时半会处理不完
于是假期花点时间尝试一下
这里先要提一下配置情况:
目前来看最终的效果还是要回到学校,换DP输出和无线网卡,测试一段时间
下面来梳理安装的思路
后续解决的问题:
最主流的应该还是Clover,OpenCore是未来的趋势,但是现在可以找到的即用的资料比较少;在黑果小兵或者远景可以下载到带有Clover的安装镜像,之后使用Etcher写到U盘,再在上面提到的站点搜索EFI做替换就好,然而这里会遇到一些问题:
所以这里第一步就是要收集EFI,既然10.15的相对难找,我找了10.14.x的EFI,先安装上再说,毕竟有了Clover Configurator配置起来会方便很多,这里又遇到了无法进入安装界面的问题,根据-v
的启动参数都没查到确切的原因,直到把HDMI接到独显上才成功进入了安装界面
独显自然是无法完美驱动的,显而易见的有顶栏和底栏无法开启透明效果,而且移动鼠标都可以感受到卡顿;于是可以大致锁定是HDMI输出的问题,之后就搜索到了黑苹果需要调整下才能输出HDMI,我自己探知的方法是在Clover Configurator->Device中勾选UseIntelHDMI,之后显示器接主板的HDMI,重启即可(Clover Configurator居然有中文,部分选项还有提示)
按照网络上的说法,升级10.15.x需要:升级Clover,更新Kext到比较高的版本,然而我并没有这么一帆风顺,然后又找了一些EFI,反复对比和修改了下,最后对黑果小兵的EFI分区的driver和kext做了删减,把10.14的config修改了下放了进去,终于成功安装了10.15.2,因为之前的文件系统是HFS,所以直接重新抹盘安装了
推测是Clover以及kext还有driver需要高度适配才行,config可以从外部导入
之前10.14可以正常识别和使用USB 3.0,然而10.15只认2.0了,查了下得知是需要定制USB,按照网络上的教程尝试了下,又没有成功,之后把10.14的SSDT-UIAC-ALL.aml
直接替换了过来就好了
风扇的声音和在BIOS界面一样,因为接了一个风扇在主板的水泵接口上,所以在此之前都是全速运转,然后按照查到的结果,安装了Macs Fan Control以及HWmonitor,然而什么都没有,之后发现需要安装VirtualSMC或者FakeSMC的一系列kext才行,貌似前者维护得更好,但是只有后者能用,吸取前面的教训,这次依然从镜像配套的EFI里提取文件
确实是只要硬件OK,找到合适的EFI的情况下,黑苹果安装几乎没有什么难度,我算是走了一套流程,和大部分装黑苹果的人差不多,对Clover这些配置依然是一头雾水,记录也是为了留下一点信息
最后还是走到了这一步,按照惯例,回馈下已知的信息
下面做的主要是:
必要的配置信息:i7 8700K UHD630 Asus Z370-I,原装的网卡RTL8822BE在黑苹果下无法驱动,加上我一直觉得瑞昱的网卡不太可靠(尽管这块已经是其比较好的网卡了),最后还是决定换为博通以支持黑苹果
Asus Z370-I的网卡插在主板背板边缘,网卡拆开WiFi Go的盒子才看得见,规格为m.2 2230 NGFF E key,盒子有两个可拆卸的天线的接口,网卡必须是2X2的,拆卸网卡具体情况看:我的 ITX Hackintosh / PC 购买、组装、安装系统心得
弄清楚规格之后就是选网卡了,主要的网卡可以看攒了一台 4K 视频剪辑黑苹果中的表格和参考文章
大多数人会选择BCM94360CS2这块免驱的网卡(150+),但是最后我还是相中了DW1820A,一方面是因为规格,再一个就是价格(90+),最重要的是经过查阅资料,这块网卡被研究的差不多了,另外黑果小兵也有相关文章:
DW1820A(BCM94350ZAE) 的子型号说明和一些研究,19年8月终极更新,看99楼
按照上面的教程就可以把Win10以及MacOS下的驱动都装好了,然而我测试的时候发现,这张网卡在win10下,5G有1%的丢包,主要是上传丢包,这显然是有点难以接受的,但是暂时就这样吧(因为我把之前的8822BE拆坏了一个天线引脚),最后发现是网卡的抗干扰能力不行(信号差)
有人称这个为黑苹果洗白,来看下B站的可以在黑苹果登录AppleID吗?怎么激活iMessage
在浏览黑苹果相关问题的过程中,发现序列号其实是很重要的东西,这里的序列号还和机型有关,我选的机型是Mac Mini 18,据说这样就可以打开核显加速,序列号不宜频繁更换,会导致Apple ID设置出问题(一个序列号就是账号下的一台设备),进而导致后续的SideCar无法使用
这个问题困扰了我很久,网上能查到的解释和解决办法比较杂乱,具体的表现是Windows关机一段时间后,再开机发现时间停留在上次关机的时间点,以及开机状态下休眠,时间会停止在休眠的时间点;历经多次搜索终于从RTC综述-RTC的问题表现:电脑时钟不走,或者睡眠唤醒后时钟不走找到了答案,我从文档中主要获得的信息是:
Apple公司使用自己定义的Apple RTC,Apple RTC记录的内存范围可能不被我们普通的主板所支持
这让我想起了OS是可以写时间信息到主板的,如果格式不一样确实可能导致Windows无法写入主板上的时间,文档中的解决办法主要是针对OpenCore引导的黑苹果的,我还停留在Clover而且没有动力去折腾了,最终找到的解决办法是启动一次Ubuntu之后再启动Windows就正常了
之前怎么也没想到使用SideCar居然和iCloud有关,最开始我觉得只要有线能用就行,之后换好网卡之后发现SideCar居然还是不能用:出现了连接超时还有只能有线连接的情况(远景上有各种问题的讨论)
最后在苹果的官网Sidecar的其他要求找到了答案,主要就是要开二重认证,经过一番倒腾之后,终于可以用了,我也这才发现:副屏居然不能触摸!!还需要Apple Pencil??
不过多一块屏幕还是方便很多,具体MacOS还是不太会用,这就当体验一下吧
]]>计算机网络的教材对VLAN一笔带过,作业的却要用到交换机互联,之前看的VLAN的文章貌似都对应不到OpenWrt上去,也就很难有实践的机会;下面根据个人在宿舍组网上遇到的问题,一步步来探究VLAN的用法
后面又看到了N1盒子基于VLAN的单臂路由,又做了一些补充
宿舍是上床下桌,每一张桌子下面有一个百兆的网口,通过负载均衡,很早就可以把网速跑到100Mbps了,这显然不够啊,因为宿舍WiFi是共用的,自然而然想到连接相邻的两个床位的网口,这样就有300Mbps了,这也是多线拨号的第一步
上图就是将LAN3与LAN4作双线接入,通过VLAN分别对应到eth0.3和eth0.4
此时LAN4与WAN是“直通”的,效果上来说,就是LAN4也可以插网线用电脑拨号了,如果是要给路由器做双线接入的话,则需要添加VLAN,再把一个LAN口添加到新VLAN中,最后建立接口拨号即可
然而舍友还是需要网口拨号的,所以如果需要长期占用的话偶尔肯定是不太方便的,所以需要交换机来扩展一下网口,这一步已经可以通过简单的修改下OpenWrt路由器的Switch来实现,將LAN4和WAN划到同一个VLAN,两个接口就相当于在同一交换机下:
然而,仅仅通过untagged只能实现多条线路的“汇聚”,能够达到100Mbps+的只有一台路由器而已,并没有实现“互通”,即每一台路由器都可以上到100Mbps+;不仅如此,还要实现相邻床位的路由器之间只用一根线连接就可以达到同样的网速,更具体的就是在一根网线传输不同的来源(网口)的数据
而VLAN的一个重要的功能恰好就是实现交换机之间的互通
这个需求源于有一台N1,之前看过VLAN的接入网络的方法,觉得网络结构更清晰,以此可以解决主路由算力不足的问题,但之前一直没有刷上OpenWrt,刷完之后发现居然没有交换机的Switch选项,赶紧翻出了之前看到的帖子:N1做主路由,新3做AP的最正统vlan连法教程,想起之前文档刚好有部分没看懂,刚好可以补充上
首先还是OpenWrt的文档:VLAN,很早就读过,但是因为缺少具体的有解释的例子,当时没弄清楚VLAN tagged的机制
所以这里先结合华为的文档了解下基础的概念
首先需要理解VLAN标签是被添加到以太帧内部的一个4个字节的片段,其中VID也就是常说的VLAN ID
在一个VLAN交换网络中,以太网帧主要有以下两种形式:
常用设备中:
VID也就是数据帧中的12bit的VLAN ID,表示该数据帧所属VLAN的编号,而PVID(Port Default VLAN ID)又称为缺省VLAN,可以用于和VID做比较来判断Tag的情况
最主要的应用是划分广播域,这部分可以参考图文并茂VLAN详解,然而和本文的关系不是很大
为了提高处理效率,设备内部处理的数据帧一律都是Tagged帧,例如在交换机内部的,在数据帧进入交换机的时候可能会按照一定的规则被打上VLAN Tag以方便下一步的处理,OpenWrt的Old Wiki的一张图很好地体现了这一点:
以太帧进入端口后被打上VLAN Tag,之后在传输的CPU的线路内(Port5-CPU),就同时传输带两种VLAN Tag的包
另外在交换机之间,可以在一条链路上使用两个VLAN也叫做Ethernet trunking,也有人称作单线复用,常见的应用:
这里参考的是上面的华为的交换机的文档,不同交换机可能有些不一样
以收发的设备作为主体,指的是数据帧到达接口而没有完全进出交换机内部,举个例子:
配置VLAN:为了适应不同的连接和组网,设备定义了Access接口、Trunk接口和Hybrid接口3种接口类型,以及接入链路(Access Link)和干道链路(Trunk Link)两种链路类型,如下图所示
根据接口连接对象以及对收发数据帧处理的不同,以太网接口分为:
Access接口一般用于和不能识别Tag的用户终端相连,只能收发Untagged帧,且只能为Untagged帧添加唯一VLAN的Tag
Trunk接口一般用于连接交换机、路由器、AP以及可同时收发Tagged帧和Untagged帧的语音终端。它可以允许多个VLAN的帧带Tag通过,但只允许一个VLAN的帧从该类接口上发出时不带Tag(即剥除Tag)
Hybrid接口可以允许多个VLAN的帧带Tag通过,且允许从该类接口发出的帧根据需要配置某些VLAN的帧带Tag(即不剥除Tag)、某些VLAN的帧不带Tag(即剥除Tag)
Hybrid接口和Trunk接口在很多应用场景下可以通用,但在某些应用场景下,必须使用Hybrid接口。比如一个接口连接不同VLAN网段的场景(如图所示的Router连接Hub的接口)中,因为一个接口需要给多个Untagged报文添加Tag,所以必须使用Hybrid接口。
OpenWrt对VLAN Tag的处理机制见后文引用文档的加粗部分,此处暂作为理解的参考
OpenWrt的文档没怎么提及接口类型的概念,OpenWrt对VLAN设置的组织形式和普通的交换机有所不同,从机制介绍来看是比较接近Trunk端口的:发出的数据帧只有一个VLAN的数据帧不带Tag
OpenWrt文档所提到的:An untagged port can have only 1 VLAN ID 反映在:OpenWrt中的Switch设置VLAN时单个untagged Port无法再再其他VLAN上为Untagged,否则回提示:LAN 1 is untagged in multiple VLANs!
故抛开之前的端口类型,遵守VLAN的规则,兼容且实用就行
另外,不是所有OpenWrt设备都有Switch这个LuCI的配置选项,比如N1就没有,但是照样可以配置VLAN,位置在Interface的接口物理配置部分,由于无法像Switch那样有Tag之类的选项,
官方文档对Tag机制的介绍如下(散落在两处):
- Tagged on “CPU (eth0)” means that the two VLAN ID tags used in this example (1, 2) are sent to the router CPU “as tagged data”. Remember: you can only send Tagged data to VLAN-aware devices configured to deal with it properly.
- Untagged means that on these ports the switch will accept only the incoming traffic without any VLAN IDs (i.e. normal ethernet traffic). The switch will remove VLAN IDs on outgoing data in such ports. Each port can only be assigned as “untagged” to exactly one VLAN ID.
- Off: no traffic to or from the tagged ports of this VLAN ID will reach these ports.
Ports can be tagged or untagged:
- The tagged port (t is appended to the port number) is the one that forces usage of VLAN tags, i.e. when the packet is outgoing, the VLAN ID tag with vlan value is added to the packet, and when the packet is incoming, the VLAN ID tag has to be present and match the configured vlan value(s).
- The untagged port is removing the VLAN ID tag when leaving the port – this is used for communication with ordinary devices that does not have any clue about VLANs. When the untagged packet arrives to the port, the default port VLAN ID (called pvid) is assigned to the packet automatically. The pvid value can be selected by the switch_port section.
特别指出,但是一般也用不上,在LuCI界面上看不到的PVID设置,设置具体在uci network switch_port部分:
Port PVID; the VLAN tag to assign to untagged ingress packets
官方文档的位置在 Creating driver-level VLANs 一节,配置方式是通过在接口设置,选择自定义接口,在名称在做文章:如在物理网卡eth1上,通过自定义eth1.2接口的方式建立一个VLAN ID为2的接口,在使用Switch设置VLAN,如添加VLAN ID为3的VLAN之后,接口处也会出现eth0.3,逻辑上还是统一的;下面来看下文档对处理机制的描述:
If the incoming packet arrives to the interface with software VLANs (incoming packet to eth1) and has a VLAN ID tag set, it appears on the respective software-VLAN-interface instead (VLAN ID 2 tag arrives on eth1.2) – if it exists in the configuration! Otherwise the packet is dropped. Non-tagged packets are deliveded to non-VLAN interface (eth1) as usual.
即处理流入的包:接口只接收有相应Tag的包,相当于Switch中的VLAN在该接口设置为Tag
这样一来,一个物理网口可以同时收发带Untagged帧和Tagged帧,故使用VLAN来实现单臂路由也就很好理解了,配置的方式也不唯一
回到本文开头提到的问题,仿照上面的Switch内部VLAN机制的图的形式,画了一张两台OpenWrt路由器通过VLAN互通,进而实现让两台路由器可以得到宿舍三个网口合计300Mbps的接入
需要说明的是:
最后的在宿舍的书桌背后的路由器如图
]]>因为偶然发现了Linux内核中的ECMP这种负载均衡的方法,然后查了些资料,这里整理下(业余水平);文末留下了当时发现ECMP的记录
ECMP在工程方面用的很多,能找到的多是说明文档,介绍特性和成套的解决方案,但是基础的材料并不是那么好找,个人也是刚刚接触到ECMP,水平有限,这里先给出本文的主要参考文献
关于负载均衡,[译] 现代网络负载均衡与代理导论(2017)有一个较为全面的介绍,其中作者提到
关于现代网络负载均衡和代理的入门级教学材料非常稀少(dearth)。我问自己:为什么会这样呢?负载均衡是构建可靠的分布式系统最核心的概念之一。因此网上一定有高质量的相关材料?我做了大量搜索,结果发现信息确实相当稀少。 Wikipedia 上面负载均衡 和代理服务器 词条只介绍了一些概念,但并没有深入 、这些主题,尤其是和当代的微服务架构相关的部分。Google 搜索负载均衡看到的大部分都 是厂商页面,堆砌大量热门的技术词汇,而无实质细节。本文将给读者一个关于现代负载均衡和代理的中等程度介绍,希望以此弥补这一领域的信息缺失。
对此个人在经历一番搜索之后也是感同身受,所以才有了总结的想法;如果觉得上文过于“导论”(和本文的关系不大),华为的文档更贴近本文的主题一些,尽量看英文:Introduction to Load Balancing
Jakub Sitnicki’s Blog的系列博文:对Linux内核中的ECMP的实现深入浅出地做了介绍,如果感兴趣的话可以看看
最后是一篇相对详尽的中文资料,重点是ECMP在内核中的变更历史:ECMP在Linux内核的实现
ECMP也就是下面的路由表的情形,就是到某一个目的地址可以有多个下一跳路径可选
root@K2P:~# ip r
default metric 1
nexthop via 10.170.72.254 dev pppoe-VWAN21 weight 1
nexthop via 10.170.72.254 dev pppoe-VWAN22 weight 1
nexthop via 10.170.72.254 dev pppoe-VWAN31 weight 1
nexthop via 10.170.72.254 dev pppoe-VWAN32 weight 1
root@K2P:~# ip -6 r default
default metric 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN21 weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN22 weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN31 weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN32 weight 1 pref medium
看起来很简单,要弄清楚这个具体能做到什么程度就需要了解下具体的实现,这里一步一步来看
Packet对应的是IP分组(数据报、数据包),是数据在L3上传输的单元
对路由器而言,流(Flow)是共享某些特性的packet序列,比如同一个请求(连接)的packets有相同的路由路径
根据负载均衡的对象分:有Per-Packet和Per-Flow两种方式,文档中的两张图对此有个直观的对比
自然而然的会想到L4 Per-Packet负载均衡:每一个的Flow的Packets会被分流,可以实现多拨对看直播都可以加速的效果,然而本文并不会涉及:
Existing Multipath Routing implementation in Linux is designed to distribute flows of packets over multiple paths, not individual packets. Selecting route in a per-packet manner does not play well with TCP, IP fragments, or Path MTU Discovery.
故默认下文都是Per-Flow负载均衡,这就需要利用Packet的header fields信息把一个个的Packet和Flow联系起来,再进行下一跳的路由选择:
IPv4 L3 hash
{ Source Address, Destination Address }
IPv4 L4 hash
{ Source Address, Destination Address, Protocol, Source Port, Destination Port }
IPv6 L3 hash
{ Source Address, Destination Address, Flow Label, Next Header (protocol) }
IPv6分组因为有Flow Label的存在,IPv6即使只用到L3 Hash也可以实现L4负载均衡
IPv6 Flowlabel IPv6数据报(packet)中有一个20字节的字段:流标号(流标签);进而可以用流标号取代路由表来处理流的路由,加速路由器对分组的处理;在ECMP中却提供了Flow的信息,故IPv6 ECMP是比较容易做的
更关键的还是负载均衡的层级,比如在多拨的情况下使用策略路由也可以做“负载均衡”,下面的命令往往提高BT的速度,这属于L3 Per-Flow负载均衡(左图):只在IP地址层级分流
ip rule add table 916
ip route add 10.173.0.0/16 via 10.170.72.254 dev pppoe-VWAN31 table 916
ip route add 10.170.0.0/16 via 10.170.72.254 dev pppoe-VWAN32 table 916
类似的方法对HTTP多线程下载并没有加速作用,对连接分流,需要L4负载均衡:多线程下载的请求之间source port不同,故L4 hash值基本不同,故会被分到不同的路径上,这样一来L4负载均衡是面向连接的就很好理解了,而内核在IPv4/IPv6上实现到一步有一段很长的历史:
Linux内核的Git Commit,对发展历程感兴趣的还可以参考博文Celebrating ECMP in Linux,其中还讨论了设备的出站流量和转发流量的ECMP效果的不同,这里把ECMP的变更历史整理到一张表格中,以及对应时间的OpenWrt的内核版本信息:
Linux Kernel | OpenWrt 内核版本 | ECMP变更 | ECMP形式 |
---|---|---|---|
1997 | 2.1.68 | IPv4 ECMP 加入内核 | L3 Per-packet + route cache -> L3 Per-flow | |
2007 | 2.6.23 | IPv4 multipath cached 移除 | L3 Per-packet + route cache -> L3 Per-flow | |
2012.9 | 3.6 | IPv4 route cache 被移除 | L3 Per-packet -> L3 Per-packet | |
2012.10 | 3.8 | IPv6 ECMP 加入内核 | IPv6 Flowlabel -> IPv6 L4 Per-flow | |
2015.9 | 4.4 | 15.05 | 3.18 | IPv4 ECMP:使用L3 Hash | L3 Per-packet + L3 hash -> L3 Per-flow |
2016.4 | 4.7 | IPv4 ECMP: 增加邻居健康检查 | ||
2017.2 | 17.01 | 4.4 | ||
2017.3 | 4.12 | IPv4 ECMP: 增加 L4 Hash | L3 Per-packet + L3/L4 hash -> L3/L4 Per-flow | |
2017.11 | 4.14 | IPv6 ECMP: ICMPv6 修复 | ||
2018.1 | 4.16 | IPv6 ECMP: 支持指定权重 | ||
2018.4 | 4.17 | IPv6 ECMP: 增加 L4 Hash | ||
2018.7 | 18.06 | 4.9/4.14 | ||
2018.10 | 4.19 | |||
2019.11 | 19.07 | 4.14.151 |
这里可以推出(实际早期版本我也没有测试过),在默认的编译选项和内核版本下,较为实用的L4负载均衡,IPv4需要在18.06及之后的版本
IPv6由于使用了Flowlabel作为Hash的对象,根据表格,OpenWrt在15.05之后的版本就可以启用L4负载均衡
本文考虑更多的还是OpenWrt中的应用,更多信息参考本博客中的Speed_Up
准备部分是从排查问题的角度来看的
在启用之前可以确认下编译内核时的下面选项,即IP: equal cost multipath,ECMP支持,较新版本的OpenWrt默认是打开的
暂时不清楚使用下面的多个nexthop命令添加ECMP路由的依赖,只知道命令ip route
的源于iproute2,如果出现如下报错:
Error: either “to” is a duplicate, or “nexthop” is a garbage.
可以尝试:
route
命令多次添加静态路由,可以启用IPv6的ECMP(详见文末的后记),实测在原版的OpenWrt可行
route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2
route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3
这里直接引用iproute2的user Guide的Multipath routing部分:
ip route add ${addresss}/${mask} nexthop via ${gateway 1} weight ${number} nexthop via ${gateway 2} weight ${number}
Multipath routes make the system balance packets across several links according to the weight (higher weight is preferred, so gateway/interface with weight of 2 will get roughly two times more traffic than another one with weight of 1). You can have as many gateways as you want and mix gateway and interface routes, like:
ip route add default nexthop via 192.168.1.1 weight 1 nexthop dev ppp0 weight 10
Warning: the downside of this type of balancing is that packets are not guaranteed to be sent back through the same link they came in. This is called “asymmetric routing”. For routers that simply forward packets and don’t do any local traffic processing such as NAT, this is usually normal, and in some cases even unavoidable.
If your system does anything but forwarding packets between interfaces, this may cause problems with incoming connections and some measures should be taken to prevent it.
可以补充的是如果用的多个等带宽的PPPoE Interface的话,可以使用多个nexthop dev ${pppoe-dev}
仅仅是上一步的话,可以见到在使用P2P下载时已经有负载均衡了,但是对HTTP的多线程下载并没有加速效果,因为一些Linux内核对IPv4的ECMP默认设置到L3 Hash,而且也没有开启邻居健康检查,所以需要修改下内核的运行参数,相关的具体的参数说明如下:
fib_multipath_hash_policy - INTEGER Controls which hash policy to use for multipath routes. Only valid for kernels built with CONFIG_IP_ROUTE_MULTIPATH enabled. Default: 0 (Layer 3) Possible values: 0 - Layer 3 1 - Layer 4 2 - Layer 3 or inner Layer 3 if present
fib_multipath_use_neigh - BOOLEAN Use status of existing neighbor entry when determining nexthop for multipath routes. If disabled, neighbor information is not used and packets could be directed to a failed nexthop. Only valid for kernels built with CONFIG_IP_ROUTE_MULTIPATH enabled. Default: 0 (disabled) Possible values: 0 - disabled 1 - enabled
echo "net.ipv4.fib_multipath_hash_policy=1" >> /etc/sysctl.conf
echo "net.ipv4.fib_multipath_use_neigh=1" >> /etc/sysctl.conf
sysctl -p
其他相关的内核运行参数(IPv6 Flowlabel等)可以参考ip-sysctl.txt
熟练的话完全根据上面的方法做了,以下是在校园网PPPoE接入下实践的,如果PPPoE拨号多播数量较多可以参考如何提高网速
CONFIG_IP_ROUTE_MULTIPATH=y
(OpenWrt 18.06之后的版本默认已经开启)OpenWrt安装kmod-macvlan
后就可以添加虚拟网卡到不同的VLAN上
opkg update && opkg install macvlan
路由器上的RJ45网口是绑定到VLAN上的,如果是添加虚拟网卡到一个VLAN上就是单线多拨,添加到多个VLAN上就可以做多线多拨了
这里的eth0.2
对应于WAN口(在Interface -> Switch
可以看到WAN绑定在VLAN 2上),不同的设备可能有些许不同,这里在eth0.2
上添加两个虚拟网卡
for i in `seq 1 2`
do
ip link add link eth0.2 name veth$i type macvlan
done
还是用脚本省事,填上用户名和密码即可,拨数为2,填下账号密码
#!/bin/sh
username=
password=
for i in `seq 1 2`
do
uci set network.VWAN$i=interface
uci set network.VWAN$i.proto='pppoe'
uci set network.VWAN$i.username="$username"
uci set network.VWAN$i.password="$password"
uci set network.VWAN$i.metric="$((i+1))"
uci set network.VWAN$i.ifname="veth$i"
uci set network.VWAN$i.ipv6='1'
done
uci commit network
添加所有PPPoE接口到wan zone(担心影响到其他的网络环境的话手动也可以)
for i in `uci show network | grep pppoe | awk -F. '{print $2}'`
do
uci add_list firewall.@zone[2].network=$i
done
uci commit firewall
只用nexthop dev ${pppoe-dev}
:
#IPv4
ip route replace default metric 1 nexthop dev pppoe-VWAN1 nexthop dev pppoe-VWAN2
#IPv6
ip -6 route replace default metric 1 nexthop dev pppoe-VWAN1 nexthop dev pppoe-VWAN2
做完这一步就可以使用ip r
和ip -6 r
命令检查下路由表
echo "net.ipv4.fib_multipath_hash_policy=1" >> /etc/sysctl.conf
echo "net.ipv4.fib_multipath_use_neigh=1" >> /etc/sysctl.conf
sysctl -p
通过东北大学IPv6测速以及IPv4测速测试负载均衡的速度叠加效果,或者使用iftop命令查看各个接口上路由的实时速率
添加ECMP路由之后传入连接偶尔连的上,偶尔连不上,但是PT的上传之类的貌似又没有问题(可能因为上传也可以是主动发出的连接),如果有这方面需求的话需要添加策略路由,为某一接口上的地址指定路由规则,下面是IPv4的,完成之后可以从外部访问之类的,但是对其他的影响就不太清楚了,IPv6部分暂时没有测试条件…
ip rule add perf 20 from IP table 20
ip route add default table 20 dev INTERFACE
此处参考自Linux 平台上之 Multipath Routing 應用,非常难得的详细的文章,还是2001年的
这里保留当时的发现过程:(当时发现了这个功能非常开心,现在来看部分内容不准确,但是文末的脚本的效果要好于ECMP默认的方法)
只在K2P OpenWrt 18.06上面实践过,对LEDE 17.01无效
下面是在操作一番之后的路由表,对IPv6的测速显示网速翻了四倍
root@OpenWrt:~# ip -6 route | grep pppoe
default from 2001:250:1006:dff0::/64 via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN4 proto static metric 512 pref medium
2000:::/3 dev pppoe-VWAN4 proto static metric 256 pref medium
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-wan weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2 weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN4 weight 1
大致可以看出这已经是做了负载均衡,需要的只是安装好luci-app-mwan3,简单操作一下路由表,这里的网关地址和dev需要看具体情况
2000::/3 就是IPv6的单播(Unicast)地址了,在不做任何操纵的情况下,无PD的路由表(单拨)
default from 2001:250:1006:dff0::/64 via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 proto static metric 512 pref medium
2001:250:1006:dff0::/64 dev pppoe-VWAN3 proto static metric 256 pref medium
...
之后通过下面两条常规的添加路由表条目的命令:
route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2
route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3
发现路由表就出现了nexthup和负载均衡中的weight标记
root@OpenWrt:~# ip -6 route | grep pppoe
default from 2001:250:1006:dff0::/64 via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 proto static metric 512 pref medium
2000::/3 dev pppoe-VWAN3 proto static metric 256 pref medium
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2 weight 1
nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 weight 1
...
类似的网关添加过程对IPv4效果并不好,这里稍后再细说
之后还需要修改一下防火墙,这里用的还是NAT6中的那条命令
因为对路由表的修改在路由器重启之后会重置,所以还是要添加到开机的启动脚本或者添加到自定的防火墙规则之中,如果已经在NAT6配置过程中配置好了的话这一步就可以忽略了
ip6tables -t nat -I POSTROUTING -s `uci get network.globals.ula_prefix` -j MASQUERADE
实测的峰值速度可以到达双网口的满速,但是一样的问题,在UT,IDM,Thunder这种多线程下载软件下轻松满速,而在YouTube视频应用下,只有半速(甚至包括用IDM下载的情况下)
目前最新版本的mwan3也开始支持IPv6多拨了,但是个人还是觉得日常使用的话用以上的方法更加快捷,不过需要对网络有一定的了解,下面是一段针对IPv6 NAT的多拨hotplug脚本,用了一些OpenWrt开发时推荐的写法,比较实验性
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
ifaces=$(ubus call network.interface dump | jsonfilter -e '$.interface[@.proto="dhcpv6" && @.up=true].interface')
for iface_6 in $ifaces
do
[ "$INTERFACE" = $iface_6 ] || continue
devices=$(ubus call network.interface dump | jsonfilter -e '$.interface[@.proto="dhcpv6" && @.up=true].device')
ipv6_gw=$(ifstatus $iface_6 | jsonfilter -e '$.route[1].nexthop')
for ipv6_dev in $devices
do
status=$(route -A inet6 add 2000::/3 gw $ipv6_gw dev $ipv6_dev 2>&1)
logger -t NAT6 "Gateway: $ipv6_dev: Done $status"
done
exit 0
done
Tensor-Train Recurrent Neural Networks for Video Classification
需要复现的部分是使用TT_RNN处理UCF11的数据集(使用新版本的UCF11数据集,旧版本的文件有点乱)
最开始还是梳理下论文和代码的逻辑
通过注释和前后文猜测作者的想法…
本来在Linux环境下使用Python2是没什么问题的:
这些显然是无故添加了很多麻烦的,在Conda环境下使用Python2成功运行后就尝试使用Pyhton3配置环境,尽管有些warning,但是一次性就解决了上述问题
2to3 - 自动将 Python 2 代码转为 Python 3 代码主要是转换TTRNN.py,其他的手动改就好(真的只转换了print…)
默认使用了Tensorflow作为了Keras的后端,然而在Linux下默认只用了一个核心,还好使用Python3时给出了提示,按照提示找到了:Tips to Improve Performance for Popular Deep Learning Frameworks on CPUs
如果您有一个可以在内部并行化的操作,例如矩阵乘法(tf.matmul())或归约(例如tf.reduce_sum()),TensorFlow将通过在具有线程的线程池中调度任务来执行该intra_op_parallelism_threads操作。因此,此配置选项控制单个操作的最大并行加速。请注意,如果并行运行多个操作,则这些操作将共享此线程池。
如果TensorFlow图中有很多独立的操作-因为在数据流图中它们之间没有直接的路径-TensorFlow将尝试使用带有线程的线程池并发运行它们inter_op_parallelism_threads。如果这些操作具有多线程实现,则它们(在大多数情况下)将共享同一线程池以进行操作内并行操作。 这两个参数在Tensorflow的性能指南也有说明,其中提到了默认设置往往就有比较好的训练效果,但是为了缩短训练时间,经过几次测试之后选择调高:
#some option to improve performance in linux
import tensorflow as tf
from keras import backend as K
config = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=18, inter_op_parallelism_threads=36, allow_soft_placement=True)
session = tf.compat.v1.Session(config=config)
K.set_session(session)
使用OpenCV提取视频帧序列,基本上做视频处理都要做这一步,因为逐个读写文件需要几分钟有点不太方便,看for循环部分可以设置并行就试了下,可以缩短运行时间到几秒(看硬盘速度~)
训练的代码Experiment_UCF11.py根据预处理的代码做了相应的修改,在导入训练和测试数据部分,因为导出视频帧使用的是list结构,而原作者的做法是导出的array,故在导入后多了一步list转array的操作
另外论文中提到的输入是RGB的通道矩阵,而OpenCV默认读取BGR,这里还用了matplot查看了下
最后导出的数据大小是16.4G
import os
import pickle
from multiprocessing.dummy import Pool as ThreadPool
import matplotlib.pyplot as plt
import numpy as np
import cv2
workspace ='./'
clips_path = workspace+'Datasets/UCF11_updated_mpg/'
frames_path = workspace+'processed_data/'
if not os.path.isdir(frames_path):
os.mkdir(frames_path)
classes = ['basketball', 'biking', 'diving', 'golf_swing', 'horse_riding', 'soccer_juggling',
'swing', 'tennis_swing', 'trampoline_jumping', 'volleyball_spiking', 'walking']
def get_clips(class_name):
files = os.listdir(clips_path + class_name)
files.sort()
clip_list = []
for this_file in files:
if '.DS_Store' not in this_file and 'Annotation' not in this_file:
clips = os.listdir(clips_path + class_name + '/' + this_file)
clips.sort()
for this_clip in clips:
if '.DS_Store' not in this_clip and 'Annotation' not in this_file:
clip_list.append( clips_path + class_name + '/' + this_file + '/' + this_clip )
return clip_list
# iterate through all clips and store the length of each:
def process(par_input):
item=par_input[1:]
classes_name=par_input[0]
for l in range(len(item)):
#print(str(item[l]))
cap = cv2.VideoCapture(item[l])
ret = True
clip_frames = []
count = 0
while(ret):
k
ret, frame = cap.read()
if ret:
#if count%2==0:
rgb_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
frame_resized = cv2.resize(rgb_frame,(160,120))
clip_frames.append(frame_resized)
count = count + 1
#data.append(clip_frames)
class_index=classes.index(classes_name)
clip_index_in_class=clips[class_index].index(item[l])
head_index_of_class=int(sum(class_sizes[:class_index]))
length_array_index=head_index_of_class+clip_index_in_class
length_of_frames[length_array_index]=count
save_name = str(classes_name) + '/' + str(l)
if not os.path.isdir(frames_path + str(classes_name)):
os.mkdir(frames_path + str(classes_name))
write_out = open(frames_path + save_name +'.pkl', 'wb')
pickle.dump(clip_frames, write_out)
write_out.close()
clips = [None]*11
#labels = [None]*11
class_sizes = np.zeros(11)
for k in range(11):
class_clip_paths = get_clips(classes[k])
clips[k] = class_clip_paths
class_sizes[k] = len(class_clip_paths)
#labels[k] = np.repeat([k], class_sizes[k])
n_all_clips=int(class_sizes.sum())
length_of_frames = np.zeros(n_all_clips)
par_input=[]
for i in range(11):
temp_list=[]
temp_list.append(classes[i])
temp_list.extend(clips[i])
par_input.append(temp_list)
pool = ThreadPool()
pool.map(process,par_input)
pool.close()
pool.join()
print("total "+str(length_of_frames.shape[0])+" clips")
print("The lengths of frame sequences is vary from: "+str(length_of_frames.min())+" to "+str(length_of_frames.max()))
print("The average length is:"+str(length_of_frames.mean()))
其中还统计了每个片段的长度,用于训练做截断用,大大减少训练的数据量(内存占用)和运算量(训练时间)
a resolution of 320 X 240. We generate a sequence of RGB frames of size 160 X 120 from each clip at an fps(frame per second) of 24, corresponding to the standard value in film and television production. The lengths of frame sequences vary therefore between 204 to 1492 with an average of 483.7.
片段的帧序列长度和论文中的陈述有些出入,比实际统计的最大值900要大得多,论文使用的片段转换到24FPS,貌似需要使用ffmpeg做插值,感觉必要性不大(OpenCV可以跳帧,但是训练的结果不太好看)
源代码中默认的统一的输入长度是GLOBAL_MAX_LEN=1492,前面提到实际只有900,却给计算带了些希望,设置成900,内存占用只需要110G+,如果参考平均200左右将输入长度减半到450的话,仅仅需要50G+的内存就足够了,训练时间也可以缩短到一天左右
为了复现TTRNN在UCF11上的出彩的性能,选择使用TT,GRU是默认的
use_TT = 1 # 0 for non-TT, 1 for TT
速度最快的TT_MLP的帧提取部分貌似不太清楚,这里就不做了
迭代次数按照论文提到的100 epochs把iter_range设置为101(初始代码写的1001?),论文的结果,一个Epoch需要30分钟,一百个也就是50小时,两天,这个速度和输入长度为900的情形是接近的
Linux和Windows下都使用了Anaconda构建的Python3.7环境,主要安装最近版本的Keras,OpenCV,scikit-learn,其他的倚赖都会自动安装,windows下跑小数据集用于测试(内存太小了),Linux使用VSCode的SSH-Remote调试和运行(Tmux居然会随着VSCode断开而终止?)
论文貌似使用CPU跑的,这里也一样,把后端从Theano换成了Tensorflow,主要的瓶颈在于内存
还是用Tmux挂在init进程下运行:tmux new -s UCF11_L450
python ***.py | tee UCF11.out
运行代码之后再切出来,从文件查看输出或者使用tmux a -t UCF11_L450
切入
个人不太了解调参,仅仅是让代码可以运行,半天时间可以跑完的一个设置:以隔帧采样的帧序列作为输入,取截断长度为200
运行了几次,给出一个参数,占用,训练时长和效果的参考表格
内存占用(GB) | epoch_time(s) | 100 Epochs(about) | Epochs - Accuracy | |
---|---|---|---|---|
跳帧-L200 | 30 | 120 | 4hour | 99 - 0.4 |
L450 | 60 | 400 | 12hour | 77 - 0.38 |
L900 | 130 | 1700 | 2days | 14 - 0.25 |
初次接触到PT的概念是在初中,EACDY论坛的站长在115网盘链接失效后毅然决定要开办PT站,但是因为那是家里的带宽极为有限,没能提供多少的上传量;之后偶然在东南大学的虎踞龙盘PT见识到了教育网PT的繁荣,于是定了一个之后要去一所有PT的大学的目标,最后如愿以偿,却发现IPv6才是打通教育网和公网PT的关键;之后又是一次偶然的机会,接触到了PT站的一些技巧后…决定把本文放到博客上(仅涉及国内的PT站)
个人的PT站账号不多,数据仅仅是咸鱼水平,对公网PT知之甚少,内容多是引用以及摸索的经验,仅供参考
rhilip对国内的PT站数据有一个详细的统计分析,可以作为发展PT的参考:
PT实用工具&脚本分享:感谢给我发过邀请的yezi1000,顺着简介找到了博客,下面这篇文章介绍了搭建PT盒子的一些经验(和普通的娱乐用户关系不大)
torrentinvites.org:据说是一个卖PT邀请码的网站,该网页有PT站的数据统计及站点的分析,可以为进入某个公网PT提供了部分参考
ipv6 NAT后配置端口转发:使用IPv6 NAT的可以看下,说不定可以改善连接性,进而大大提高上传速度
这里还有一个用得上但是有些古老的软件,v6speed,类似于某种P2P点播软件:使用种子利用P2P传输就可以观看电影,一时半会还真的没找到同类型的软件,据说有解码能力有限的问题,最后一次更新在2015年
PT站最关注的点:保种以及搜索下载
reseed:方便的跨站辅种工具,进到新的PT站,一个个搜索辅种往往需要花掉相当多的时间,这个几分钟就解决了,天津大学的同学开发的,注册账号需要北洋的Passkey,国内的部分站点可用
PT-Plugin-Plus:支持Chrome和Firefox的插件,提供站点数据概览,搜索聚合以及辅助下载功能;向往PT的一大原因就是简单且高质量,这个插件对此贡献也很大,比如在网页上看到有人推荐某个纪录片,右键搜索,下载一气呵成
如果要发电影(转种可能也用得上),PT Gen可以帮助生成信息
如果网络通畅的话下载热门的种子即可,但是如果上传速度很糟心的话,还是选择大量的保种路线,使用保种得到的积分换上传量比较好,所以打听好PT站点的生存策略和弄清楚自身的网络状况是很关键的
首先要搞清楚0day资源的概念,自行搜索,这里说下蓝光电影的发布时间的一个参考:blu-ray.com中的电影详情页面中可以看到蓝光碟片的发布时间,一般PT站可以提前一点点发出资源,不同的站点的一个区别就在于首发的速度,但顶级站点往往转种都是很快的
至于更普遍的WEB版或者TV版资源,看首播的时间就好,可以留意的是:
特别一点的是动漫,动漫资源的发布往往依赖于字幕组,就我所在的大部分PT站动漫更新都不是很及时,BT站 动漫花园,部分动漫字幕组出资源会第一时间放出来
因为学校往往带宽比较贵,学生购置大容量硬盘也不太划算(刷数据和看电影是两回事),随意挂代理和购置盒子可以提高速度和节约流量,需要注意的事部分站点是限制这种方式的,尤其是刚进入站点的时候,如果一不小心被识别为盒子(挂代理的VPS供应商有时候会被识别),可能上去下载免费资源就会出现分享率爆炸的情况,所以此处需格外谨慎(尤其是路由器上挂透明代理)
因为电脑上没有安装3.5寸盘的空间,在经历过路由器挂BT的初等玩法后,还是组建了一台NAS用于个人的数据存储和下载管理
NAS自带的下载软件源于Transmission:
于是就转而使用了Docker的linuxserver\qBittorrent
默认设置需要修改的主要是下载任务数量和连接数
docker如果使用桥接网络是默认不支持IPv6的,个人安装网上的修改参数之类的方法最终也失败了,最后还是使用了hosts网络多尝试了几次成功了
比如说在0day资源出来之前可以先写好订阅,待到资源出种就可以第一时间自动下载好,查看下载列表就可以得知已经出种而不需要再去反复的检索
一般的NexusPHP架构的PT站都在搜索栏的右侧有个订阅的icon,设置好筛选就可以通过RSS获取种子的信息进而实现自动的下载
主要是弥补自带RSS的设置自由度不足以及给Docker的qBittorrent提供自动下载支持,为了省事,采用了Docker:wiserain-flexget,挂载一个qbittorrent可以访问的文件夹作为qbittorrent的种子监测文件夹,运行后就可以从网页打开FlexGet的界面,填写config即可
若是用户之前都是公网IP且防火墙规则开放的情况就不多说了,主要是做种的时候看到有人在下载而本地的种子又没有上传就很折磨
Tracker是PT用户都可以访问,用于上传BT客户端的IP及端口信息以方便用户之间的相互连接,试想一下这样的一个过程,当一个客户端A,得知客户端B正在做种,于是A直接向B发起了一个连接请求,也就是对B而言,该连接是一个传入连接,然而残酷的现实是:
阻止传入连接不会影响正常的上网,因为日常的上网连接都是由内网的设备发起或是请求,好比开门发快递和收快递,而PT的传入连接呢?就好比一个陌生的快递突然送了过来,现实中可能是“来者不拒”,但是网络的世界往往要危险的多
至于防火墙这一级,如果可以管理的话,开放UT的监听端口即可,如果不行的话可以尝试设置uPnP做自动端口转发
PT站上显示的“可连接”仅仅是可以连接到Tracker服务器,实际的效果可以靠UT、qbittorrent的用户标识(Flag)判断
Flag所代表的意义:
D = 当前正在下载 (感兴趣且没有被阻塞)
d = 本级客户端需要下载, 但是对方没有发送 (感兴趣但是被阻塞)
U = 当前正在上传 (感兴趣且没有被阻塞)
u = 对方需要本机客户端进行上传, 但是本机客户端没有发送 (感兴趣但是被阻塞)
O = 开放式未阻塞
P = 使用μTP协议连接,兼具TCP的可靠性及UDP的连接性
S = 对方被置于等待状态
I = 对方为一个连入连接
K = 对方没有阻塞本机客户端, 但是本机客户端不感兴趣
? = 本机客户端没有阻塞对方, 但是对方不敢兴趣
X = 对方位于通过来源交换获取到的用户列表中 (PEX)
H = 对方已被通过 DHT 获取.
E = 对方使用了协议加密功能 (所有流量)
e = 对方使用了协议加密功能 (握手时)
L = 对方为本地/内网用户 (通过网络广播发现或位于同一网段中)
NAT类型概述以及提升NAT类型的方法对NAT类型做了简要的介绍
NAT对PT的影响是很大的,如基于OpenWrt的Linux路由使用netfilter的MASQUERADE实现的NAT的默认类型是Symmetric NAT,或者称为NAT4,是对传入连接最不友好的一种NAT,IPv4的解决办法:
Chion82/netfilter-full-cone-nat写了从DNAT到netfilter内核子系统,浅谈Linux的Full Cone NAT实现,而LGA1150为OpenWrt做了Netfilter and iptables extension
然而,教育网主要还是IPv6,IPv6的Full Cone NAT还没见过,暂时只有ipv6 NAT后配置端口转发
]]>最初为了写LaTeX而使用 Atom + 插件 来作为代码编辑器(积累了些经验之后转而使用TeXStudio),之后也就顺其自然的用Atom写了作业的大部分代码(装插件还要看网络环境),之后就是遇到了幽灵和熔断漏洞的影响,笔记本的性能越来越力不从心,使用Atom打开大文件特别慢,运行也并不流畅,才发现Atom的性能问题被诟病已久,有人推荐了微软的VSCode —— 和Atom的主题、插件基本通用,但是性能好太多,于是我就换下了Atom,一直用到了现在
现代代码编辑器最基本的功能:Git,多语言支持,丰富的效率插件,VSCode都是有的,而它出彩的地方还是在于开发方面(其实我就是写下作业)
安装VSCode的时候记得勾选使用VSCode打开文件夹,因为VSCode的对工作空间要求比较严格的,另外对于Atom迁移而来的,可以选择Atom主题“One Dark Pro”以实现一个“平缓的过渡”
在调试代码和使用方面,常用的插件有:
考虑到配置繁杂,重装或者有多台电脑迁移配置不便,可以用Setting Sync插件通过Github提供的服务以实现配置的同步
常规插件其实各大代码编辑器都差不多,对于VSCode来说,个人接触到的,最惊艳的插件当属Remote-SSH:
开发环境或者说代码运行的环境在远程或者其他的系统上,需要使用SSH客户端连接到远程,使用SCP或者SFTP来传输文件,这里面SSH客户端是一个重要的角色,最开始使用Atom编辑加上脚本完成“本地编辑,远程调试”的过程,后面遇到了一度让我觉得“相见恨晚”的FinalShell,解决了SSH时的一些列问题,但是作为一个独立开发者维护的闭源软件,稳定性和安全性是一般般的
而Remote-SSH相当于把VSCod搬到了服务器上,同时解决了运行环境和文件传输两个问题,尽管类似的问题可能早就有成熟的方案,但是在常用的代码编辑器中就能实现还是相当感动的,安装完成本地的客户端之后在VSCode的左下角有一个蓝色的标记,点击之后按照提示添加服务器就好(遇到SSH的config文件权限的问题,换用另外一个ssh的config文件就好),初次使用连接服务器之后会在服务器端自动下载和安装VSCode的相关组件(常用的LInux发行版没什么问题,也不需要root权限,ARM架构也支持),之后再手动把需要的插件安装下就好
初次连接时打开文件夹需要重连,直接打开另外一个文件夹也会重连,感觉不方便的话,可以在打开文件夹之后再添加另外一个文件夹到工作空间中(会重新连接),文件夹一栏会变成了工作空间,之后添加文件夹就不需要重连了,工作空间的配置可以保存以便下次使用;文件的上传下载分别是拖拽和右键菜单,体验算是很好了
如果在远程跑代码可以安装Resource Monitor用于监测CPU和内存占用,其他的细枝末节的部分搜索下就有
这里就不造轮子了,已经有人做的很好了,Dev on Windows with WSL,其中主要使用了Remote-WSL插件,虽然个人一度觉得WSL是未来,但是使用了一段时间之后还是觉得不如Docker或虚拟机来得方便,尤其是和Remote-WSL一起推出的Remote-SSH诞生之后
无意中又看到Remote插件多了一个Docker,之前的docker插件在VSCode侧边栏可以方便的查看镜像容器的情况,而Remote插件可以直接把VSCode的运行环境放到容器内,并且可以直接接入正在运行的容器(也就是不需要预先安装SSH和开放端口),尤其对编译环境下修改代码比较方便
另外还有个有趣的地方,可以让Win下的Docker支持图形化界面(勉强可用)
这里直接把IP保存为变量了:
$DISPLAY=(ipconfig|findstr "IPv4")[1].split(" ")[-1]+":0.0";
docker run -it --net=host -e DISPLAY=$DISPLAY ....
VSCode全称Visual Studio Code,调试代码方面算是对得起Visual Studio之名了,权威的配置过程还是参考VSCode官方文档,本文介绍的是个人配置在Windows下的配置尝试,点几下就配置好了,故分享出来,仅供参考
有些作业要求用C语言写,最开始追求新奇,用的Visual Studio 2015以及Clang,看中的是强大的调试功能,但是对于写个简单的作业来说太费事,Clang的报错常常不理解
之后转而使用了更常见的Dev C++,基于GCC,照抄书上的代码也不会莫名报错了,在很长一段时间里都是用Atom写代码,Dev C++做运行和调试,
到了VSCode当然会想要接近Visual Studio的体验,编译器肯定不用Clang了,至于GCC,WSL里有,Win上的GCC的版本不知道用哪个好,看网上的博客配置tasks.json (build instructions),launch.json (debugger settings)依然颇为繁琐
直到后面遇到了Scoop,安装就很简单了:scoop install gcc
,查看版本后发现是MinGW的GCC,安装CodeRunner扩展后就可以运行代码了
注:代码及工作目录的路径不要有中文
调试功能则需要C/C++扩展,Debug功能在VSCode的左侧应该是自带的,对新目录来说Debug一栏的左上角绿色三角形旁边会显示”No COnfiguration”,Debug时配置gcc.exe作为代码的编译器,GDB作为代码的调试器的关键就在这里了:
Add Configuration的时候选C++(GDB/LLDB),之后再选gcc.exe build and debug active file设置完成后会在工作目录下生成一个.vscode/launch.json的文件,文件定义了gdb作为exe的调试器,需要注意的是这里的preLaunchTask,定义了在执行调试在前需要使用gcc对代码进行编译,也就是下一步
回到C的源文件,点击Debug一栏的左上角绿色三角形开始调试,会提示Could not find the task ‘gcc.exe build active file’ ,点击Configure Task,再选gcc.exe debug active file,软件就会创建并打开.vscode/task.json,其中定义了gcc.exe编译的过程,也就是上一步的preLaunchTask
以上的文件在做了选择之后就自动生成好了,之后该文件夹内的C代码都可以透过VSCode的Debug来调试了,设置断点,查看变量体验还是比较现代的~
已知问题
自带的运行代码和调试的terminal窗口对部分编码支持的不太好,调试的时候会闪退
使用WSL GCC可以参考下面的链接(和上个链接的WSL Remote还是有些不同的): VSCode使用WSL环境开发C语言配置
首先在VSCode窗口的左下角,可以设置当前使用的Python解释器,运行依然是CodeRunner,在代码编辑窗口右键选择各种运行方式包括交互式。重点还是调试,这个时候可以选择创建一个新文件夹了(平时把Python代码都放到一个文件夹…),在新文件夹的情况下,点击调试会提示选择Debug Configuration:包括了Python File和Module以及其他没见过的类型
显然对于只会用调试Python File的情况,每次都做一次选择显然不太方便,那么可以选择Add Configuration,工作目录下会生成一个.vscode/launch.json的文件:
{
"name": "Python: 当前文件",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
在Debug的选项中也就有“Python: 当前文件”的选项了,如果想要在已经有launch.json的文件夹中调试,添加这一段到其中即可
调试Python文件的时候比较慢,比如调用Python还需要先激活Conda环境(选择Python解释器)
在编辑器窗口的右键选项中还有使用Jupyter-notebook作为交互式运行的选项,需要在Conda环境中准备:
conda install ipykernel
python -m ipykernel install --user --name 环境名称 --display-name "Python (环境名称)"
有上面的Remote-SSH,加上VSCode也是基于electron的,自然会想到能不能在浏览器中使用,偶然的一次机会还真的看到了这样的一个项目:Code-Server
这样一来,只要有一台配置OK的Linux的服务器,使用iPad之类的设备也可以在VSCode中看/写代码(随着iPad逐渐强调生产力,对键鼠支持的越来越好)
Name: Vibrancy
Id: eyhn.vscode-vibrancy
Description: Vibrancy Effect for Visual Studio Code
拖动有些卡顿,打开的时候窗口大小有些异常,不过,不影响代码体验~(笔记本上可能对GPU负担太大从而影响续航)
最近发现有个网站收集了很多微软的壁纸:Wallpaper Hub
最重要的是,网站有一些Fluent Design的元素,最明显的就是Acrylic的效果了
缘起于Win10显示的图书馆的WiFi信息
5GHz,165信道,WiFi 4???这个是什么情况呢,是不是有哪里显示错了?然后就是速率最高只有144MHz,这个速率又是怎么来的?
这里以802.11AC 1T1R MCS9 HT80 带宽Short GI为例计算网络连接速率,由上面的公式以及下面的引用可以知道:
\[Rate HT80 = (234MHz* 8bit *5/6 )/(3.2us + 0.4us)= 433.33Mbps\]这个也就是最常见的单天线的5G WiFi速率,大概的解释如下
80MHz中一个符号有234个数据子载波,使用256QAM时每个子载波每次传输8bits数据,编码率为5/6,而传输时间等于符号持续时间加上保护间隔
从OpenWrt主页的Associated Stations右侧的字段的含义又是什么呢?
650.0 Mbit/s, 80MHz, VHT-MCS 7, VHT-NSS 2, Short GI
650.0 Mbit/s, 80MHz, VHT-MCS 7, VHT-NSS 2, Short GI
我按照个人理解的通信流程整理下,水平有限…
把速率计算公式根据后面的原理部分化简一下: \(\begin{align}Rate & =(N_{sub}\times log(N_{QAM}) \times R_{coding})/(N_{sub}/N_{HT}+GI) \\& =\frac{log(N_{QAM}) \times R_{coding}}{1/N_{HT}+GI/N_{sub}}\end{align} \\\) 其中$N_{sub}$为子载波数,$N_{HT}$为频宽
提高网络速率的方法可以粗略的归结到各个子项上面
WiFi所用的频段主要是三个,下图也列出了不同的频宽下选择某个信道对频段的占用情况
802.11n: 2.4G频段
每相邻的2个信道之间的频宽就是5Mhz,最大频宽为40MHz,对于国内的2.4G只有1-13信道可以用,用1信道,频宽为20Mhz,则信道2,3,4,5都被占用了;如果是40Mhz,侧信道2,3,4,5,6,7,8,9也被占用了,当然只在传输数据时才会占用的。这就为什么在家附近因有大量wifi造成网络堵塞缓慢的原因了。
802.11ac: 5G频段
中国WIFI设备在5GHz下可以使用的信道有36,40, 44, 48, 52, 56, 60, 64, 149,153, 157, 161, 165。而每个信道频宽为20Mhz,如果信道为149,当要用80Mhz时,则153,157,161都要被占用了
802.11ad: 60G频段,近距离高速无线传输专用,现在基本上见不到了
802.11ax: WiFi 6的频段依然是之前的2.4G和5G频段,主要是把最大频宽定在了160MHz
比较有趣的是某个WiFi对频宽的占用越大,有效的传输距离越短,对环境的干扰越小,最后又作用与可以占用更大的频宽来做近距离的高速传输,故各种规格的WiFi是可以和谐共处的
通过多条通道来发送数据,常用 nTnR,或者 n x n 来表示,比如说2T2R也就是2x2 MIMO,以及OpenWrt上用的NSS:Number of spatial streams后接数字表示空间流的数目
看起来是最简单粗暴的提高无线速率的方式,然而实际上会遇到多径效应导致高误码率,最终还是采取了一系列的措施来尽量克服多径效应
FEC (Forward Error Correction):按照无线通信的基本原理,为了使信息适合在无线信道这样不可靠的媒介中传递,发射端将把信息进行编码并携带冗余信息,以提高系统的纠错能力,使接收端能够恢复原始信息。
正交幅度调制(QAM,Quadrature Amplitude Modulation)是一种在两个正交载波上进行幅度调制的调制方式。这两个载波通常是相位差为90度(π/2)的正弦波,因此被称作正交载波,这种调制方式因此而得名
802.11n所采用的QAM-64的编码机制可以将编码率(有效信息和整个编码的比率)从3/4 提高到5/6。所以,对于一条空间流,在MIMO-OFDM基础之上,物理速率从58.5提高到了65Mbps(即58.5乘5/6除以3/4)
QAM编码是用星座图(点阵图)来做数据的调制解调,实际应用中是2的N次方的关系。比如说16-QAM ,16是2的4次方,一次就可以传输4个bit的数据;802.11n是64-QAM ,是2的6次方,因此在64个点阵的一个星座集合里面,用任意一个点可以携带六个bit的数据信息
到了802.11ac,就变成了256-QAM,是2的8次方,802.11ac相对于802.11n在编码上面的速率提升了33%。802.11ax之后引入了更高阶的编码,就是2的10次方,1024-QAM
我们都知道从8到10的提升是25%,也就是相对于802.11ac来说,802.11ax的性能又提高了25%,变成了1024-QAM,一个符号可以携带10个bit的数据
在室内等典型应用环境下,由于多径效应的影响,信号在接收侧很容易发生(ISI),从而导致高误码率。OFDM调制技术是将一个物理信道划分为多个子载体(sub-carrier),将高速率的数据流调制成多个较低速率的子数据流,通过这些子载体进行通讯,从而减少ISI机会,提高物理层吞吐。
用于Wi-Fi通信的有OFDM和OFDMA技术:802.11a/g/n/ac无线电当前使用正交频分复用(OFDM)用于802.11频率上的单用户传输,将比特串流对应到QAM调制的符号
OFDM有三种类型的子载波,如下所示:
数据子载波:这些子载波将使用与802.11ac相同的调制和编码方案(MCS)以及两个新的MCS,并添加1024-QAM
导频子载波:导频子载波不携带调制数据;它们用于接收器和发射器之间的同步
未使用的子载波:剩余的未使用的子载波主要用作保护载波或空子载波以抵抗来自相邻信道或子信道的干扰
例如:20 MHz 802.11n/ac 信道由64个子载波组成——52个子载波用于承载调制数据; 4个子载波用作导频载波;8个子载波用作保护频带;每个OFDM子载波的宽度是20MHz/64=312.5KHz。
不同频宽的数据子载波的数量(第三列)关系见下表
把每个子载波传输的内容是一个符号(比如QAM调制的结果),由于把一个载波分为了多个子载波并行处理,符号持续时间隔也就是处理单个子载波的时间, 为实现最大频谱效率,一般取符号持续时间=1/子载波间隔 ,对802.11 n/ac,符号持续时间为 3.2us=1/312.5
Short Guard Interval (GI),由于多径效应(即使单路传输也存在)的影响,信息符号(Information Symbol)将通过多条路径传递,可能会发生彼此碰撞,导致ISI干扰。为此,802.11a/g标准要求在发送信息符号时,必须保证在信息符号之间存在800 ns的时间间隔,这个间隔被称为Guard Interval (GI)。802.11n仍然使用缺省使用800 ns GI
当多径效应不是很严重时,用户可以将该间隔配置为400ns(=0.4us即Short GI),对于一条空间流,可以将吞吐提高近10%,即从65Mbps提高到72.2 Mbps。对于多径效应较明显的环境,不建议使用Short Guard Interval (Short GI)
分别对应802.11 n/ac/ax,指的是高、超高吞吐,高效无线网络(High-Efficiency Wireless - HEW),后接数字指示频宽
MCS (Modulation Coding Scheme)调制和编码方案
在802.11a/b/g时代,配置AP工作的速率非常简单,只要指定特定radio类型(802.11a/b/g)所使用的速率集,速率范围从1Mbps到54Mbps,一共有12种可能的物理速率。
到了802.11n时代,由于物理速率依赖于调制方法、编码率、空间流数量、是否40MHz绑定等多个因素。这些影响吞吐的因素组合在一起,将产生非常多的物理速率供选择使用。比如基于Short GI,40MHz绑定等技术,在4条空间流的条件下,物理速率可以达到600Mbps(即4*150)
为此,802.11n提出了MCS的概念。MCS可以理解为这些影响速率因素的完整组合,每种组合用整数来唯一标示,于是就有了下表
至于802.11ax暂时作为上面的补充,添加了MCS10,11
把本文最开始的OpenWrt的截图中的VHT-MCS 9对应过来就可以很方便的查到是866.7Mbps的速率
对于斐讯K3的5G速率可以由 256-QAM 4ss 80MHz SGI来计算1024QAM的速率,即由8bit到10bit,增加25%的速率,大约2100Mbps
144Mbps的由来,可以在Spatial Streams = 2的几行中找到对应的HT20-MCS 15 SGI以及VHT20-MCS 7 SGI,也就是说两种都有可能,后面我还是拿专业点的软件测试了下,确实是5G的WiFi,参考下表就有该5G WiFi不符合WiFi 5的标准,降为WiFi 4情有可原,只是后面那个802.11n就有些尴尬了
学校的AP是双频的,因为AP数量比较多,组网的时候几乎全频段都有,所以每个频段的频宽都设置的比较低以避免互相干扰,144Mpbs的协商速率对单设备限制50Mbps的情况足够了
另外有了上面的一些基础概念之后,方便选择合适的路由器和网卡,尤其是在当前这个向WiFi 6 过渡的阶段
▲802.11ax技术构成模块示意图
TP-LINK的官网已经有比较简洁美观的介绍了,本文就接着上文提到的部分加以延伸
MU-MIMO 即Multi-User Multiple-Input Multiple-Output 的缩写,直译为“多用户 多输入 多输出”, 是最新Wi-Fi技术标准802.11ac Wave 2(即802.11ac 2.0标准)的最重要特性之一
802.11ax设备借鉴了802.11ac的部署经验,将使用波束成形技术同步将数据包发送至不同空间的用户。 换言之,AP会计算每个用户的信道矩阵,并同时将波束导向不同的用户——每路波束包含针对其目标用户的特定数据包。 802.11ax一次可支持8个多用户MIMO传输包的发送,而802.11ac一次可支持4个MIMO数据包。 而且,每次MU-MIMO传输都可能有自己的调制和解码集(MCS)和不同数量的空间串流。 以此类推,当使用MU-MIMO空间复用时,接入点会与以太网交换机进行比较,将冲突域从大型计算机网络缩小至单个端口。
作为MU-MIMO上行方向的新增功能,AP将通过一个触发帧从每个STA发起上行同步传输。 当多个用户及其数据包同时响应时,AP将信道矩阵应用于所接收的波束并将每个上行波束包含的信息分开, 同时它还可能发起上行多用户传输,从而接收来自所有参与STA的波束形成反馈信息
至于MU-MIMO的实际情况可以参考有关的测试:ACWIFI
802.11ax无线电可以利用正交频分多址(OFDMA) ,其是OFDM数字调制技术的多用户版本。OFDMA将信道细分为较小的频率分配,称为资源单元(RU)。
OFDM和OFDMA都通过称为逆快速傅立叶变换(IFFT)的数学函数将信道划分为子载波。子载波的间隔是正交的,因此尽管它们之间缺少保护带,它们也不会相互干扰。
通过细分信道,可以同时发生小帧到多个用户的并行传输。每个资源单元内的数据和导频子载波在OFDMA信道内都是相邻且连续的
802.11ax引入了更长的12.8μs的OFDM符号时间,这是传统符号时间3.2μs的四倍。子载波间隔等于符号时间的倒数。由于符号时间较长,子载波大小和间隔从312.5KHz降低到78.125KHz。窄子载波间隔允许更好的均衡并因此增强信道鲁棒性。
上面提到的OFDMA规格对理论速率提升约为10%
802.11ax标准借鉴4G蜂窝技术的技术进步,在相同信道带宽中服务更多用户的另一技术是: 正交频分多址(OFDMA)。 基于802.11ac已经使用的现有正交频分多路复用(OFDM)数字调制方案,802.11ax标准进一步将特定的子载波集分配给个体用户, 即,它将现有的802.11信道(20、40、80和160MHz频宽)分为带有预定义数量的副载波的更小子信道。 802.11ax标准还借用现代LTE术语,将最小子信道称为资源单元(RU),最少包含26个副载波。
密集用户环境下,许多用户通常无力争夺信道的使用机会,现在正交频分多址使用更小巧——但更具专用性的子信道同时服务多个用户,因此提升了每个用户的平均数据吞吐量。 802.11ax系统可能通过不同的资源单元规模实现信道的多路复用。注意,对于每20MHz带宽,信道的最小部分可容纳9个用户
AP依据多个用户的通信需求决定如何分配信道,始终在下行方向分配所有可用的资源单元。 它可能一次将整个信道仅分配给一个用户——与802.11ac当前功能相同——或者它可能对其进行分区,以便同时服务多个用户。
BBS(Base Service Station) Color, 基于色码的空间复用,为了改善密集部署场景中的系统层级性能以及频谱资源的使用效率,802.11ax标准实现了空间重用技术。 STA可以识别来自重叠基本服务集(BSS)的信号,并根据这项信息来做出媒体竞争和干扰管理决策。
这部分和速率关系不大
一般我们都会有个信号强弱的标准,比如常用的WiFi和Cellular的Icon上被填满的图标面积,然而打开一些调试工具看到的是dbm这个单位,例如在OpenWrt的Wireless详情中有: Tx-Power: 23 dBm Signal: -64 dBm | Noise: 0 dBm Tx-Power指的是路由器信号的发射功率,无线功率一般以mw为单位,但是因为WiFi信号的能量通常为mw级,因此业界将WIFI信号大小表示为与1mw的强度比,用dbm来表示,对应关系是 \(signal=10log(\frac{P}{1mw})\) 这就有个非常方便的计算方式:
降低3dBm,是指信号强度降低到原先的1/2(二分之一)。
降低10dBm,是指信号强度降低到原先的1/10(十分之一)。
降低30dBm,是指信号强度降低到原先的1/1000(千分之一)。
有了这个之后,可以对信号的强度做一个大致的判断: 下图来自RSSI等级和信号强度
使用上图来源的网站提供的软件可以绘制出一个大致的信号强度分布图,可以参考来的调整AP的位置
除了dbm表示无线的收发功率之外,还要考虑到信道中的信噪比(SNR),噪声也可以使用dbm为单位,所以计算dbm为SNR单位的时候把二者相减即可
首先是会影响到协商速率,在发射端的信号到接收端,中间存在衰减和损失,其对通信的影响就是会产生高误码率,故为了达到可靠通信的需求需要采取高纠错性能的编码和调制方式,也就是影响到MCS,进而影响到协商速率和实际传输速率,而调整的标准就看设备的厂商的调教了
有了上述的铺垫,就有了一些改善无线网络质量的途径,但是最重要的还是认清现实,理性对待
因为某一个频段内的信道容量有限,在拥挤的时候噪声也多,故在选择频段的时候,尽可能的避开当前区域拥挤的信道,可以使用路由器的无线桥接功能(wireless scan)工具,查看路由器附近的信道占用的情况,或者用Netspot工具检测当前区域网络情况
特别说明的是2.4G频段已经相当的拥挤了,对于有高可靠性网络环境要求的情况,建议还是网线或者使用5G频段
这里可以说是个经验上的技巧,首先,路由器的发射功率是受到国家标准的严格限制的,但是对于某些可以切换无线地区的路由器来说,可以通过该途径来提高发射功率,或者使用某些频段进而提高发射功率
使用高增益的天线,使用内置信号放大器的AP也是同样的逻辑
Mesh,信号放大器,主路由+AP,无线漫游都是类似的途径,高端的设备往往配备了更好的硬件和算法,这点也是毋庸置疑的
Github:lukesampson/scoop的README对Scoop有了大概的介绍,我初次接触到是读到了 再谈谈 Scoop 这个 Windows 下的软件包管理器
需要注意的是如果Scoop安装的软件和Powershell的命令或者别名重合,Powershell的命令依然被优先使用
可以使用管理员模式打开powershell运行
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
# or shorter
iwr -useb get.scoop.sh | iex
部分软件源在Github之类的连接性不太好的地方,偶尔下载很慢而且易报错,现在Scoop推荐默认使用aria2进行多线程下载,只需要安装aira2即可开启多线程下载
scoop install aria2
参考SpencerWoo的文章添加的软件仓库基本上够用了
scoop bucket add extras
scoop bucket add java
scoop bucket add dorado https://github.com/h404bi/dorado
scoop reset
,可以便捷的切换环境变量下的JDK除去上面介绍的一些,其实想得到软件都可以在Scoop中使用scoop search
找下看看
$ scoop list
Installed apps:
7zip 19.00
chromedriver 76.0.3809.126
cmder-full 1.3.11
concfg 0.2019.03.09
ffmpeg 4.1.3 #编码工具
gawk 3.1.7
gcc 8.1.0
gdrive
git 2.21.0.windows.1
grep 2.5.4
innounp 0.48
iperf3 3.1.3 #网速测试工具
nodejs 12.5.0
pshazz 0.2019.04.02
R 3.6.0
sed 4.2.1
tesseract 4.1.0.20190314 #OCR工具
vim 8.1.1302
youtube-dl 2019.05.20 #偶尔下载视频
trafficmonitor #任务栏网速,CPU内存占用监测
screentogif #Gif录屏软件
ntop #类似htop的的终端下的资源监视器(但是做不到htop那么强大)
glow #终端下的Markdown Render
openjdk #添加java仓库后,默认安装最新版的openjdk
openjdk9 #java9
部分命令是无法在普通模式下运行的,一般的方法是打开一个新的管理员模式的窗口,相对来说不太方便,scoop可以安装sudo来实现对单一命令的赋权
比如设置禁用eth0接口的别名
scoop alias add ethd 'sudo netsh interface set interface eth0 disabled' 'disable eth0'
输入scoop ethd
之后就会弹出用户账户控制的弹窗,提示需要管理员权限,用键盘确认就好,省去了再开一个窗口的麻烦(如果是长串命令都需要管理员权限的话还是开一个吧)
只介绍常用的简单指令
面对没有加密的m3u8直播录制,IPTV用的较多,m3u8的地址可以通过浏览器的检查工具找到
ffmpeg -i m3u8 'test.ts'
现在越来越多的网站选择把音频和视频分开,使用IDM下载两个文件可以直接用ffmpeg做快速的合并(复制)
ffmpeg -i v.mp4 -i a.mp4 -c copy output.mkv
当然如果youtube-dl支持视频网站的话使用youtube-dl更方便
常用于提取BGM,不做重编码的情况
ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
-vn没有视频 -acodec copy说使用已经存在的相同的音频流
scoop依然有许多不成熟的地方,在高可靠性要求的环境下依然是不推荐的,最经常遇到的莫非是软件安装因为网络等问题终端,安装状态会返回成功,如果需要重新安装的话需要先进行卸载
再一个就是环境变量的问题,scoop可以在安装的时候配置好一些环境变量,但是卸载却不一定会移除,这就导致一些重要的软件在Scoop卸载之后再在其他位置安装会出现环境变量错误的问题
部分高度依赖于安装目录,权限以及关联众多的软件不推荐使用scoop安装,如Chrome
Powershell的别名设置不方便,直接使用WSL的自定义别名(.bashrc)调用Windows下的程序又不能直接在Powershell中运行,直到发现Scoop可以自由的添加“环境变量”,想起来Scoop alias来设置程序运行的scoop别名
本来的用法应该是为Scoop内的操作添加别名:
# Install app
scoop alias add i 'scoop install $args[0]' 'Innstall app'
scoop alias add add 'scoop install $args[0]' 'Install app'
# Uninstall app
scoop alias add rm 'scoop uninstall $args[0]' 'Uninstall an app'
scoop alias add remove 'scoop uninstall $args[0]' 'Uninstall an app'
# List apps
scoop alias add ls 'scoop list' 'List installed apps'
# Update
scoop alias add u 'scoop update $args[0]' 'Update apps, or Scoop itself'
scoop alias add upgrade 'scoop update $args[0]' 'Update apps, or Scoop itself'
但是这个格式看起来就很自由:
比如说给WinMTRCmd添加一个scoop mtr
的别名
scoop alias add mtr '~/winMTRCmd $args[0]' 'MTR tools for Win CMD'
之后使用scoop mtr [host]
就可以愉快的使用mtr工具了
这里以切换Java版本为例,例如在安装了openjdk和openjdk9之后,从默认的openjdk9切换到openjdk16
$ java -version
openjdk version "9.0.4"
OpenJDK Runtime Environment (build 9.0.4+11)
OpenJDK 64-Bit Server VM (build 9.0.4+11, mixed mode)
$ scoop reset openjdk
Resetting openjdk (16.0.1-9).
Linking ~\scoop\apps\openjdk\current => ~\scoop\apps\openjdk\16.0.1-9
$ java -version
openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment (build 16.0.1+9-24)
OpenJDK 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)