替换右键文件夹的“在此处打开Powershell窗口”和.bat .cmd的默认打开方式为Windows Terminal

替换右键文件夹的“在此处打开Powershell窗口”为打开Windows Terminal

计算机\HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command

的权限为可写
– 将右侧的默认字符串修改为

wt -p "命令提示符" -d "%V "

此处命令提示符可修改为Windows PowerShell等。
– 注意%V后面有一个空格,这个空格是必须的,不然某些路径下(如磁盘根目录)最后一个字符\会和引号一起成为转义字符,使Windows Terminal出错。

替换右键文件夹的“在此处打开Linux shell”为打开Windows Terminal下的wsl

计算机\HKEY_CLASSES_ROOT\Directory\Background\shell\WSL\command

的权限为可写
– 将右侧的默认字符串修改为

wt -p "Debian" -d "%V "

此处Debian可修改为Ubuntu等。
– 注意%V后面有一个空格,这个空格是必须的,不然某些路径下(如磁盘根目录)最后一个字符\会和引号一起成为转义字符,使Windows Terminal出错。

使.bat .cmd文件默认打开Windows Terminal

修改

计算机\HKEY_CLASSES_ROOT\batfile\shell\open\command
计算机\HKEY_CLASSES_ROOT\cmdfile\shell\open\command

的默认字符串为

wt -p "命令提示符" "%1" %*

即可。

注意:此方法修改过后,和之前不同的是,运行bat cmd文件时,工作目录不在当前目录。对于大多数大佬写的脚本,通常会自动处理这个问题。但对于自己编写的脚本,如想运行本目录下的程序,需要在第一行加入:

cd /d %~dp0

这行命令来切换到当前目录。

突破低性能路由器限制,大流量高并发SS透明代理实践

0. 前言

天朝的程序员,由于我国国情的特殊性,基本都需要科学上网。由于功夫网的封锁,所以都会选择当今配置简单、相对稳定的科学上网方案-“ShadowSocks”(简称ss)。而且我们还比较懒,所以希望把ss做在路由器里,成为透明代理。目前智能路由器的主流系统是OpenWRT,主流架构是MIPS,性能成为了较大瓶颈。即使是性能较强的MT7621方案,单线程也只能跑到50-70M左右,这对于大带宽宽带(比如说我的500M联通),简直是小的可怜。由于以上的原因,促成了本文。

部署了本文的方案之后,路由器的性能不再会成为瓶颈,只要拥有一个优良线路的大带宽服务器,就可以跑满带宽。(本人的500M带宽实测可以跑满)

1. 开始之前

为了部署本文的方案,你需要以下的设备及资源:

  • MT7621及以上性能的OpenWRT智能路由器(简称:路由器)
  • 一台拥有千兆网卡的电脑、平板或嵌入式设备,要求常年开机(简称:客户端,我使用的是RK3399的开发板,RockPi 4)
  • 一台线路优良、大带宽的境外服务器
  • 网线若干、千兆交换机(非必须)

注意:
本文的方案不涉及UDP转发,也无法做到UDP转发,游戏玩家请绕道。
服务器选购、TCP优化、BBR、锐速等不在本文讨论范围之内。
本文由于不可抗力原因省去ss服务器搭建部分,请大家自己寻找教程部署服务器(我想能来看这篇文章的dalao也应该会配置吧,笑)
本文所述方法同样可以适用于ssr、v2ray、trojan等。

2. 本文用到的开源项目

  • openwrt-shadowsocks (请自行解决)
  • luci-app-shadowsocks (请自行解决)
  • shadowsocks-libev (客户端使用,请自行解决)
  • https://github.com/xsm1997/KumaSocks

3. 在客户端中部署ss

请在客户端中部署ss-local,本文中,监听1080端口,如果有条件请开启–fast-open和–no-delay。部署方法由于某些原因不再赘述。

注意:由于现在封锁很严,部署ss时请采用AEAD协议(如chacha20-ietf-poly1305),如采用其他非AEAD协议导致服务器被日,本人概不负责。

本文只用ss来举例,也可使用ssr、v2ray、trojan等,注意要使用socks5(入站)协议,并监听1080端口。

4. 编译路由器可用的KumaSocks

KumaSocks为我的自用项目,现已在github上开源,是一个轻量级透明代理转socks5代理的转换器,仅适用于linux系统。

虽然Github Release界面有预编译的包,但还是推荐自行编译,因为这样才能享受到最新Golang版本(可能)带来的性能优化。

  • Golang官网下载最新的go语言安装包并且运行。Windows需要安装git for windows。以下代码以Windows为例。
  • 设置GOPATH环境变量到某目录,如D:\go
  • 打开cmd窗口,切换到你的GOPATH目录。
go get github.com/xsm1997/KumaSocks
cd src\github.com\xsm1997\KumaSocks
SET GOOS=linux
SET GOARCH=mipsle
go build

linux下的编译命令为:

go get github.com/xsm1997/KumaSocks
cd src/github.com/xsm1997/KumaSocks
GOOS=linux GOARCH=mipsle go build

若路由器的储存空间吃紧,可以用以下命令替换上述命令中的go build

go build -ldflags "-s -w"

如果体积还是大,就要祭出我们的神器upx!

upx --best KumaSocks

实测可以把KumaSocks压缩到700k左右,而且没有显著的性能问题。

  • 在目录下,找到linux可执行文件KumaSocks,上传到路由器中,本文为/root/kumasocks-mipsle,赋予可执行权限。

5. 设置路由器ss

请在路由器中按照普通方法设置ss,达到可以科学上网即可。当然防DNS污染也要做。

6. 魔改脚本

注意:本部分仅以luci-app-shadowsocks作为举例修改,目的是替换ss的执行命令为KumaSocks,同样思路可用于修改其他脚本,如luci-app-ssr-plus、luci-app-passwall等。

  • 执行/etc/init.d/shadowsocks stop停止ss。
  • 用你喜欢的编辑器修改/etc/init.d/shadowsocks
    注释掉129行的
pidof ss-redir > /dev/null || return 0

(为了停用ss启动的检测)
注释掉135-138行的ss-redir命令启动。
– 由于luci-app-shadowsocks的更新,行号可能不对应,请根据语句内容修改。
– 新建/etc/init.d/kumasocks文件,内容为:

#!/bin/sh /etc/rc.common
START=90
STOP=15
start() {
/root/kumasocks-mipsle 1>/dev/null 2>&1 &
}
stop() {
kill -9 $(pidof kumasocks-mipsle)
}

其中/root/kumasocks-mipsle为KumaSocks可执行文件的完整路径。
– 赋予可执行权限。

chmod a+x /etc/init.d/kumasocks
  • 编辑或创建/etc/kumasocks.toml,内容为:
listen-addr = "0.0.0.0:1234"
proxy-addr = "socks5://192.168.1.210:1080"

这里1234为第5步ss透明转发的端口,192.168.1.210为内网中客户端的IP,1080为客户端ss的监听端口。

7. 运行!运行!

/etc/init.d/shadowsocks start
/etc/init.d/kumasocks start

添加开机自启

/etc/init.d/shadowsocks enable
/etc/init.d/kumasocks enable

当然别忘了启动服务器和客户端上的ss!

8. 出现问题怎么办

  • 首先保证在第五步时可以科学上网。
  • 其次在路由器中运行ps,查看是否有kumasocks-mipsle和ss-redir进程。正常情况下应该有kumasocks-mipsle、没有ss-redir,当然ss-local也没有。
  • 如果正常的话请在win下连接客户端的代理,查看是否可连通外网。
  • 如果还是没有问题的话,请查看iptables规则以及ipset是否正常。

9. 总结

由于客户端的性能远远强于路由器,所以这里一般不会是性能瓶颈。

众所周知,go语言的特点就是高并发性能优良,所以在MT7621的双核四线程CPU中,KumaSocks会自动负载均衡到4个线程占满CPU,性能极强。如果出了性能问题,你可以给路由器轻微超频一下,我的K2P超频到1.1Ghz跑200MCPU负载在50%左右,性能绰绰有余。

新版本的Golang编译的KumaSocks,默认启用了splice系统调用来实现零拷贝(zero copy)转发,使数据无需多次复制,效率甚至赶超C写的转发程序。但splice有时会在一些魔改系统上出问题(例如Pandorabox),这时请参照KumaSocks的Github Readme禁用这一功能。

10. 后记

作者本人已经更换软路由,目前并没有继续使用KumaSocks的需求了。但是在有需要时,还是会继续维护KumaSocks。文章中的魔改脚本方法可能已经过时,请根据实际情况进行修改。如有需要,请联系Tg @kumakitami,让我们共同进步!

设计模式–为了更好地使用面向对象

设计模式–为了更好地使用面向对象

  • 一个优秀程序的四个目标:
    • 可维护
    • 可复用
    • 可扩展
    • 灵活性好
  • 通过封装、继承、多态把程序的耦合度降低,使用设计模式使得程序更加灵活,容易修改,并且易于复用。
  • UML几个关系–聚合、合成
    • 聚合,Aggregation,表示一种弱的”拥有”关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分
    • 合成,Composition,是一种强的”拥有“关系,体现了严格的部分和整体关系,部分和整体的生命周期一样。
  • 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

策略模式

  • 策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换。此模式让算法的变化,不会影响到使用算法的客户。
  • 策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以一相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
  • 策略模式的Strategy类层次为Context定义了一系列的可供宠用的算法或行为。继承有助于析取出这些算法的公共功能。
  • 策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
  • 当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。
  • 策略模式就是来封装算法的,但是在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同业务规则,就可以考虑使用策略模式处理这种变化的可能性。
  • 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。
  • 任何需求变更都是需要成本的。

单一职责原则

  • 单一职责原则–就一个类而言,应该仅有一个引起它变化的原因。
  • 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
  • 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。
  • 如果你能够想到多余一个的动机去改变一个类,那么这个类就具有多于一个的职责。

开放-封闭原则

  • 开放-封闭原则,是说软件实体(类、模块、函数等)应该可以扩展,但是不可修改。对于扩展是开放的,对于更改是封闭的。Open for extension, Closed for modification.
  • 怎样的设计才能面对需求的改变却可以保持相对稳定,从而使得系统可以在第一个版本以后不断推出行的版本呢?开闭原则给了我们答案。
  • 无论模块多么封闭,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应该对哪种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。
  • 等到变化发生时立即采取行动。
  • 在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化。
  • 面对需求,对程序的改动时通过增加新代码进行的,而不是更改现有的代码。
  • 我们希望的是在开发工作展开不久就知道可能发生的变化。查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难。
  • 开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。