精华 重写了node版本的ss
发布于 4 年前 作者 oyyd 5967 次浏览 来自 分享

链接:github

之前在v2ex上发过同样的话题

对于服务器和路由而言,最适合的版本肯定是用 c 写,但用脚本写的很适合在原有的 ss 基础上做各种尝试及试错,并且对于大多数脚本语言来说node又有性能和并发上的优势(跟python版本对比的benchmark)。

当时重写最主要的目的还是因为被各种限制搞得痛苦不堪,作为程序员还是希望自己至少懂得一种办法,亲手解决这个问题。原作者当时不再维护node版本真的让人觉得非常遗憾。并且这对网络相关的编程而言也是一个不错的入门途径。

相比于原来的node版本,核心代码(应该)没有太大的变化,我加上了简单的CLI、守护进程、log以及一个pac文件服务器。最大的问题是udp relay因为我自己没有找到比较好的实用工具来进行测试,所以真的用到udp relay可能还存在很多问题。我平时自己用的话主要是用自己的ss server和ss org提供的客户端,浏览twitter和youtube。

之前在v2ex上发帖感觉了解到了不少大家关心的问题,还帮自己打开了思路。感觉果然写代码还是不能一个人闷头写

15 回复

其实感觉 ss 的服务端真的很适合用 node 来写,这种 io 重的东西,个人用用并发也不算高,上 c 的话有点过重了吧?

可惜当年 node 的 gc 不争气,现在就你的 benchmark 来说,看起来这个 gc 问题不存在了。

不过我看原来作者在 node repo 的 issue 来说,那个内存增长的原因是因为 v8 的 gc 倾向于比较晚的回收对象,能拖则拖。这个特性至少在 node v4 的时候也还是存在的吧?

好吧。。。这方面的细节我也搞不懂。。

我倒是愿意一起来优化这个项目,请帮我加进项目 协作者 里面,@oyyd

node 在v0.12 的版本惰性 GC,可以导致 50%以上的内存一直保留,alinode 对此做了优化。 目前 node LTS 也版本中做了修正。v6也是如此。@alsotang

不错,很好的项目。

“v8 的 gc 倾向于比较晚的回收对象,能拖则拖”到v6版本的gc策略也还是这样的,跑一下这个issue里面的例子也还是会得到同样的结果。不做额外处理的话(手动调用gc,手动清除buffer),rss的数值很会很快涨到200mb左右。有意思的是在我的benchmark中,当每次传输为5kb的时候(小于8kb),rss可以一直保持在30mb以下。

老实说我并不是很清楚内存的问题,特别是这种策略导致的高rss会有什么不良影响。但我个人还是赞同这个issue里面的这句话:It’s not a bug, it’s a conscious time/space trade-off. 至少从结果来看,维持更高数量的链接也不对导致rss继续上涨,事实上单个进程的node是要比单个进程的python可以维持更高并发的链接的(好像说了句废话,但绝无引战的意思)。

@yjhjstz 非常感激!但是现阶段可能的话还是提交PR吧,因为我现在代码里有不少写的很糟糕的地方,测试写的也不多,并不是很适合别人直接提交代码进来。

Node.js回收buffer堆外空间依赖GC时机。为buffer提供一个函数,可以先手工将buffer堆外内存释放掉,这样是不是更好?

@classfellow “为buffer提供一个函数”是指?我现在理解是需要用一些cpp addons才能做到这件事

@oyyd 假如给Buffer提供方法freeBuffer,释放管理的堆外空间,但得改node源码才行。

@oyyd 支持楼主。我之前用typescript自己翻写过一遍nodejs的ss,那时候感觉挺适合用node来写的。先不管gc怎么样,node的生态就比目前很多语言好很多。有这么生态环境在那,完全可以先完善项目的骨架,然后慢慢优化性能,以及等待虚拟机的完善。

@classfellow 我觉得你指的应该是和https://github.com/trevnorris/buffer-dispose这个类似的功能吧。我有在考虑这么做,但这么做一方面效果如何很难说,另一方面如果要真的要加入cpp代码的话,事实上直接用shadowsocks-libev处理才是最好的主意。

当年看到作者弃坑心都凉了,楼主燃起了新的希望

回到顶部