一键搭建ssr服务器并开启bbr加速

一键搭建shadowsocksR 1 下载ssr搭建脚本 git clone -b master https://github.com/flyzy2005/ss-fly 2 运行ssr搭建脚本 ss-fly/ss-fly.sh -ssr 3 输入对应参数 4 相关命令 启动:/etc/init.d/shadowsocks start 停止:/etc/init.d/shadowsocks stop 重启:/etc/init.d/shadowsocks restart 状态:/etc/init.d/shadowsocks status 配置文件路径:/etc/shadowsocks.json 日志文件路径:/var/log/shadowsocks.log 代码安装目录:/local/shadowsocks 5 卸载ssr服务 ./shadowsocksR.sh uninstall 一键开启bbr加速 ss-fly/ss-fly.sh -bbr 重启,输入以下命令查看是否成功开启bbr sysctl net.ipv4.tcp_available_congestion_control 如果返回值为: net.ipv4.tcp_available_congestion_control = bbr cubic reno 则说明开启成功 转载自这里

August 13, 2019 · 1 min · Egbert Ke

git 放弃本地修改

Look1: git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态 git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。 git reset --hard HASH #返回到某个节点,不保留修改。 git reset --soft HASH #返回到某个节点。保留修改 git reset HEAD^ #撤销上一次commit,回到没有add的状态 git clean -df #返回到某个节点 git clean 参数 -n 显示 将要 删除的 文件 和 目录 -f 删除 文件 -df 删除 文件 和 目录 也可以使用: git checkout . && git clean -xdf CSDN ↩︎

August 9, 2019 · 1 min · Egbert Ke

为什么使用object.__setattr__

werkzeug 0.6.1中Local的初始化是这样的: class Local(object): __slots__ = ('__storage__', '__lock__') def __init__(self): object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__lock__', allocate_lock()) 我当时很奇怪为什么要用object.__setattr__, 而不是直接用self.__storage__, 当我直接用self.__storage__ = {}实现的时候才发现问题: self.__storage__会调用__setattr__,而__setattr__中会调用self.__lock__.acquire(),因为此时self.__lock__还没有定义, 所以会调用self.__getattr__,而self.__getattr__中也会调用self.__lock__.acquire(), 此后就会一直调用self.__getattr__,最终导致StackOverflow。 而显示调用object.__setattr__就不会触发Local内部的__setattr__,从而避免上述情况。而且两者的效果是一样的,object.__setattr__的第一个参数是self,也就是这个实例,所以并不用担心是不是在父类定义了一个公共属性。 类似的还有使用object.__getattribute__的情况,一般也是为了避免无限递归。

July 23, 2019 · 1 min · Egbert Ke

理解werkzeug中的Local对象

ThreadLocal是线程级别的local,如果在greenlet或者协程这种微线程环境下,或者在多个请求共用一个线程的情况下,线程级别是不够的。ThreadLocal是thread-safe和thread-specific的, 而有些情况需要greenlet-safe和greenlet-specific或者request-safe和request-specific。 werkzeug 0.1版中Local的实现是这样的: try: from py.magic import greenlet get_current_greenlet = greenlet.getcurrent del greenlet except (RuntimeError, ImportError): get_current_greenlet = lambda: None try: from thread import get_ident as get_current_thread from threading import Lock except ImportError: from dummy_thread import get_ident as get_current_thread from dummy_threading import Lock from werkzeug.utils import ClosingIterator def get_ident(): """ Return a unique number for the current greenlet in the current thread. """ return hash((get_current_thread(), get_current_greenlet())) class Local(object): def __init__(self): self....

July 18, 2019 · 2 min · Egbert Ke

ThreadLocal

TheadLocal 用于多线程环境下,线程之间可以使用相同的变量,而这个变量只与当前线程环境有关。werkzeug中有类似的实现,使每个路由处理函数都可使用相同的request变量,而这个对象的内容只与当前请求有关。 例如:1 import threading # 创建全局ThreadLocal对象: local_school = threading.local() def process_student(): # 获取当前线程关联的student: std = local_school.student print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name): # 绑定ThreadLocal的student: local_school.student = name process_student() t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A') t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B') t1.start() t2.start() t1.join() t2.join() 执行结果: Hello, Alice (in Thread-A) Hello, Bob (in Thread-B) 廖雪峰的官方网站 ↩︎

July 17, 2019 · 1 min · Egbert Ke

git 切换 tag

有一种源码学习的方法是这样的:从最初的版本开始看,有的很大的开源项目最初可能就只有几百行。我们可以先把项目clone到本地,然后切换到最初般。 列出所有版本: git tag 若一个tag都没有,则可能是因为你先fork了这个项目,然后本地再pull下来的,这种情况得先执行: git fetch 然后,切换到指定版本: git checkout tagname 切回到主分支: git checkout master

July 12, 2019 · 1 min · Egbert Ke

Python中的async/await

async/await是实现异步IO的语法糖,是Python3.7新出的关键字。async def可创建协程,而await可用来等待一个可等待对象的执行完成。这大大简化了协程的创建(在Python2中创建协程需要yield和send协同操作) 下面这个例子很简洁的说明了什么是异步IO1: import asyncio async def count(): print("One") await asyncio.sleep(1) print("Two") async def main(): await asyncio.gather(count(), count(), count()) if __name__ == "__main__": import time s = time.perf_counter() asyncio.run(main()) elapsed = time.perf_counter() - s print(f"{__file__} executed in {elapsed:0.2f} seconds.") 运行结果: $ python3 countasync.py One One One Two Two Two countasync.py executed in 1.01 seconds. gather会等待所有协程都返回后再返回一个结果列表,as_completed会当协程返回后立即返回: >>> import asyncio >>> async def coro(seq) -> list: ... """'IO' wait time is proportional to the max element....

July 9, 2019 · 1 min · Egbert Ke

crontab 记录

crontab 时间说明 # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR #sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * command to be executed minute:代表一小时内的第几分,范围 0-59。 hour:代表一天中的第几小时,范围 0-23。 mday:代表一个月中的第几天,范围 1-31。 month:代表一年中第几个月,范围 1-12。 wday:代表星期几,范围 0-7 (0及7都是星期天)。 who:要使用什么身份执行该指令,当您使用 crontab -e 时,不必加此字段。 command:所要执行的指令。...

July 5, 2019 · 2 min · Egbert Ke

mysql中的varchar

长度范围是0到65535 varchar(255) 和 varchar(256)的区别 长度超过255时,用2个字节存储列的实际长度,未超过时用一个字段

July 5, 2019 · 1 min · Egbert Ke

Python 中的协程

Python 中的协程 函数也叫子程序,其调用过程一般为:Main中调用A,等待A结束后调用B,等待B结束后调用C… 函数的调用一般是单入口。 相比于函数,协程可以有多个入口来暂停(切换到其他协程执行)和恢复协程的执行。另外,协程的调用不像函数调用需要主函数按照特定顺序依次调用子程序,协程之间是协作关系,可以来回切换。 相比于线程,他们都是通过切换达到协作的目的。线程是由操作系统调度来实现切换,而协程是语言级别的切换,开销更小。 Python中,可以用生成器中的yield实现协程(支持不完全) 协程实现生产者/消费者模型1 import time def consumer(): r = '' while True: n = yield r if not n: return print('consuming {}'.format(n)) time.sleep(1) r = '200 OK' def produce(c): next(c) # 启动协程,Python2写法: c.next() n = 0 while n < 5: n = n + 1 print('producing: {}'.format(n)) r = c.send(n) print('consumer return: {}'.format(r)) c.close() # 关闭协程 c = consumer() produce(c) 运行结果: producing: 1 consuming 1 consumer return: 200 OK producing: 2 consuming 2 consumer return: 200 OK producing: 3 consuming 3 consumer return: 200 OK producing: 4 consuming 4 consumer return: 200 OK producing: 5 consuming 5 consumer return: 200 OK 用连接协程的方式创建管道2 def producer(sentence, next_coroutine): tokens = sentence....

July 5, 2019 · 1 min · Egbert Ke