上周五回青岛了,让我不爽的是航班因为天气问题被取消了,然后回北京的时候,特么飞机起飞的时间又拖延了2个小时,特么真倒霉… …

在北京T3机场的时候,碰到几个屌丝,长那样就是个IT屌丝的样子… 本来没眯一会的,但是他们的声音有些大,各种python专业术语。搞得我有些心痒痒,就跟他们聊了会,原来这几个孩子是打算回青岛做一个类似浏览器代理的东西。 

因为青岛的外企很多,里面的员工是需要经常翻墙浏览一些资料的,最少是gmail和google搜索…  没办法,咱们就这样… 

关于shadowsocks相关开发的文章,http://xiaorui.cc/?p=1812

http://xiaorui.cc/2015/08/03/python%E7%89%88%E7%9A%84shadowsocks%E5%85%B3%E4%BA%8E%E6%B5%81%E9%87%8F%E5%8F%8A%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86%E5%BC%80%E5%8F%91/



话说shadowsocks这个bt的代理,我自己也经常用,我相信在看这篇文章的人,一定是或用过,或听过的… shadowsocks是个socketv5协议的代理,为了避开GFW针对纯ssh代理的封杀。 

开源的shadowsocks使用很简单,但默认不能很好的支持多用户管理和流量统计,及各种自动化管理的。 shadowsocks的作者在项目里面,没有描述过接口的使用,在readme里面也只是教你怎么用罢了。   有不少人开始用shadowsocks做个产品,也卖了不少钱。  看来要实现流量管理和多用户需要看他的源码了….    注:我曾经给作者发过一个邮件让他写点 shadowsocks api接口的文档。。。。

 现在有一好人贡献了shadowsock的扩展代码  https://github.com/mengskysama/shadowsocks/tree/manyuser ,让我舒心的是,这个python写得,能看懂。。。。呵呵   貌似现在shadowsocks各个语言版本都有,python和golang的用的普遍要多。     manyuser是支持多用户,多端口,流量,针对流量超出进行判断,至于性能方面我还没有测试,介于他支持增加了功能模块,性能应该不受影响。 

他这边对于用户的管理和流量统计及阈值判断都在mysql做的,如果有兴趣的人,可以把她改成redis的模式,其实用mysql只做最基本的用户验证及统计结果存储,一些临时累加计算的就用redis来做就用了。  

这边的代码是python写得。   filename shadowsocks/db_transfer.py   ,db_transfer.py里面的逻辑大多数是用户管理相关的。 

@staticmethod
def thread_db():
    import socket
    import time
    timeout = 60
    socket.setdefaulttimeout(timeout)
    while True:
        #logging.warn(‘db loop’)
        try:
            #更新每个用户的流量到mysql里面。
            DbTransfer.get_instance().push_db_all_user() 
            #对于流量超出的用户,进行下一步操作。
            rows = DbTransfer.get_instance().pull_db_all_user()  
            DbTransfer.del_server_out_of_bound_safe(rows)
        except Exception as e:
            logging.warn(‘db thread except:%s’ % e)
        finally:
            time.sleep(15)

我们可以在mysql里面,获取该用户在数据库中记录的上次流量信息。 

last_transfer = self.last_get_transfer
通过调用server_pool里的 get_servers_transfer()信息,比如当前的使用流量。 
curr_transfer = ServerPool.get_instance().get_servers_transfer()

在 shadowsocks/server_pool.py文件有个new_server函数,这是用来增加新用户的链接 , 也是多用户的相关逻辑。 

def new_server(self, port, password):
    ret = True
    port = int(port)

    if ‘server’ in self.config:
        if port in self.tcp_servers_pool:
            logging.info(“server already at %s:%d” % (self.config['server'], port))
            return ‘this port server is already running’
        else:
            a_config = self.config.copy()
            a_config['server_port'] = port
            a_config['password'] = password
            try:
                logging.info(“starting server at %s:%d” % (a_config['server'], port))
                tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver, False)
                tcp_server.add_to_loop(self.loop)
                self.tcp_servers_pool.update({port: tcp_server})
                #udp_server = udprelay.UDPRelay(a_config, self.dns_resolver, False)
                #udp_server.add_to_loop(self.loop)
                #self.udp_servers_pool.update({port: udp_server})
            except Exception, e:
                logging.warn(e)

先这样吧,还有几个模块没有来得及看,有时间再把那几个模块分享下。 



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品