绑定本地出口IP

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因 最近公司有一批数据要备份到对象存储中。机房为3线机房,为了充分利用机房的出口带宽,我只能轮流绑定源IP(本机有3个IP,分别是联通、移动、电信) 源码如下: # -*- coding: utf-8 -*- import socket import requests class BindAddress(object): def __init__(self, ip): self.ipbind = ip self.real_socket = socket.socket def __enter__(self): def bound_socket(*a, **k): sock = self.real_socket(*a, **k) sock.bind((self.ipbind, 0)) return sock socket.socket = bound_socket def __exit__(self, type, value, trace): socket.socket = self.real_socket ip= 'xxx.xxx.xxx.xxx' with BindAddress(ip): r = requests.get('http://ip.vearne.cc:8080/') print r.content 我在峰云大神的基础上做了进一步封装,使得bind操作变得更简单 另外代码中用到了我在 快速获取本机出口IP 一文中搭建的服务,以判断bind是否生效。 额外的说明1 其实我们在爬虫的时候,也有用这种方法,在增加客户端IP,以减少被封杀的概率。只需要在一块网卡上绑定多个公网IP即可。 额外的说明2 由于以上的做法修改的是模块的函数,因此对于多线程的场景,它不是线程安全的。 ...

January 19, 2018 · 1 min

快速获取本机出口IP

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因 原来一直用ip.cn, 来探测本机的出口IP,最近发现不能使用了,自己搭建了一个,搭建方法可以参考,参考资料1. 直接使用 curl ip.vearne.cc 或 curl http://ip.vearne.cc/ 参考资料 1.nginx lua获取客户端ip 请我喝瓶饮料

January 19, 2018 · 1 min

Amazon S3 上传限速

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 引言 最近公司有一批数据要上传到白山云的对象存储中,白山云的对象存储兼容AWS S3的API 因此我使用的是boto3, 然而网络管理员要求对上行带宽有限制 解决方法 1. 使用Trickle 见参考资料1 2. 使用iptables 见参考资料2 3. 使用SDK 使用Trickle,要求上传程序只对使用Glibc库应用有效, 而使用iptables,配置还是比较麻烦的,而且iptables只能按照对端的IP进行限制,而我们访问对象存储,实际使用的是域名,如果域名解析的IP发生变化,我们无法及时感知。 仔细阅读代码和文档之后,我发现boto3原生已经支持限速了 max_bandwidth: The maximum bandwidth that will be consumed in uploading and downloading file content. The value is in terms of bytes per second. # -*- coding: utf-8 -*- import boto3 from boto3.s3.transfer import TransferConfig # from s3transfer.manager import TransferConfig access_key = "xxx" secret_key = "xxx" cli = boto3.client( 's3', aws_access_key_id=access_key, aws_secret_access_key=secret_key, endpoint_url='http://ss.bscstorage.com' ) config = TransferConfig( multipart_threshold=30 * 1024 * 1024, multipart_chunksize=8 * 1024 * 1024, max_concurrency=10, ) # 50MB/s # 单位是byte config.max_bandwidth = 50 * 1024 * 1024 resp = cli.upload_file( '/tmp/VSCode-darwin-stable.zip', 'test', 'test-key-xx2', ExtraArgs={ 'ContentType': 'text/plain', # 请替换为合适的文件类型 'ACL': 'private', }, Config=config ) 参考资料 Linux 下使用Trickle限制下载/上传带宽 linux下使用iptables和tc限制流量 请我喝瓶饮料

January 18, 2018 · 1 min

程序hang住的问题的追踪

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 引子: 我这里说的hang住,并不是指死锁,在真实的工作场景中,死锁的情况其实并不很多见。在我工作的几年中,有遇到好几次都是程序hang在某个IO请求上的。 1. 排查 排查hang住的最有用的命令是strace和lsof命令 比如我们有一个服务叫 atm-client 1.1 首先查出服务对应的进程 ps -ef| grep atm-client| grep -v grep 输出结果 root 5 1 0 2017 ? 01:05:39 atm-client 1.2 对于多线程的程序可以先列出进程的所有线程 ps -mp 5 -o THREAD,tid 输出结果 USER %CPU PRI SCNT WCHAN USER SYSTEM TID root 0.3 - - - - - - root 0.0 19 - poll_s - - 5 root 0.0 19 - sk_wai - - 11 root 0.0 19 - sk_wai - - 12 root 0.0 19 - sk_wai - - 13 root 0.0 19 - sk_wai - - 14 root 0.0 19 - sk_wai - - 15 root 0.0 19 - sk_wai - - 16 root 0.0 19 - sk_wai - - 17 root 0.0 19 - sk_wai - - 18 root 0.0 19 - sk_wai - - 19 root 0.0 19 - sk_wai - - 20 root 0.0 19 - sk_wai - - 21 1.3 strace 可以跟踪进程或者线程的系统调用 跟踪线程 ...

January 8, 2018 · 4 min

python 使用multiprocessing需要注意的问题

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 我们在编写程序的时候经常喜欢这样写代码 import MySQLdb import time from multiprocessing import Process conn = MySQLdb.connect('localhost', 'vearne', 'xx', 'test') def f(name): for i in xrange(10): cursor = conn.cursor() sql = "insert into car(name) values(%s)" param = [(name)] print param #time.sleep(1) n = cursor.execute(sql,param) cursor.close() conn.commit() if __name__ == '__main__': for i in xrange(10): p = Process(target=f, args=('bob',)) p.start() 上面的程序有问题吗? 以上的程序在单进程的情况下,应该是没有问题,但是在多进程的情况下,它是有错误的。 首先看看下面的源码 class Process(object): ''' Process objects represent activity that is run in a separate process The class is analagous to `threading.Thread` ''' _Popen = None def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): assert group is None, 'group argument must be None for now' count = _current_process._counter.next() self._identity = _current_process._identity + (count,) self._authkey = _current_process._authkey self._daemonic = _current_process._daemonic self._tempdir = _current_process._tempdir self._parent_pid = os.getpid() self._popen = None self._target = target self._args = tuple(args) self._kwargs = dict(kwargs) self._name = name or type(self).__name__ + '-' + \ ':'.join(str(i) for i in self._identity) def run(self): ''' Method to be run in sub-process; can be overridden in sub-class ''' if self._target: self._target(*self._args, **self._kwargs) def start(self): ''' Start child process ''' assert self._popen is None, 'cannot start a process twice' assert self._parent_pid == os.getpid(), \ 'can only start a process object created by current process' assert not _current_process._daemonic, \ 'daemonic processes are not allowed to have children' _cleanup() if self._Popen is not None: Popen = self._Popen else: from .forking import Popen self._popen = Popen(self) # -- 创建 Popen 对象 -- _current_process._children.add(self) # 省略部分代码 ... ... def _bootstrap(self): # -- _bootstrap 函数 -- from . import util global _current_process try: self._children = set() self._counter = itertools.count(1) try: sys.stdin.close() sys.stdin = open(os.devnull) except (OSError, ValueError): pass _current_process = self util._finalizer_registry.clear() util._run_after_forkers() util.info('child process calling self.run()') try: self.run() # -- 调用run函数 -- exitcode = 0 finally: util._exit_function() except SystemExit, e: if not e.args: exitcode = 1 elif isinstance(e.args[0], int): exitcode = e.args[0] else: sys.stderr.write(str(e.args[0]) + '\n') sys.stderr.flush() exitcode = 0 if isinstance(e.args[0], str) else 1 except: exitcode = 1 import traceback sys.stderr.write('Process %s:\n' % self.name) sys.stderr.flush() traceback.print_exc() util.info('process exiting with exitcode %d' % exitcode) return exitcode from .forking import Popen 定义 ...

January 1, 2018 · 4 min

https 原理简析

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 起因:周四下午要在公司做关于https的分享,就顺便结合已经写好的PPT,在CSDN 中也分享下。 参考资料: 加密与解密 电子工业出版社 HTTP Over TLS RFC2818 The Transport Layer Security (TLS) Protocol RFC5246 https://en.wikipedia.org/wiki/Transport_Layer_Security 大型网站的 HTTPS 实践 http://blog.jobbole.com/86660/ 上面的参考资料都挺好的,尤其后面4个,如果想彻底了解https必须得读一下 HTTPS是什么? HTTPS (also called HTTP over TLS, HTTP over SSL and HTTP Secure) is a protocol for secure communication over a computer network which is widely used on the Internet. HTTPS consists of communication over Hypertext Transfer Protocol (HTTP) within a connection encrypted by Transport Layer Security or its predecessor, Secure Sockets Layer. ...

January 1, 2018 · 2 min