2019年8月

上一篇文章的配置可以用来通用地部署php测试站点,但是有的时候部分应用程序只是暴露在本地端口,以下贴出反代版配置。

server
   {
        listen 80;
        listen 443 ssl http2;
        server_name ~(.+)\.port\.example\.com$;
        index index.php index.html index.htm;
        set $port $1;

        ssl on;
        ssl_certificate /path/to/your.cer;
        ssl_certificate_key /path/to/your.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        location /
        {
            proxy_pass http://127.0.0.1:$port;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Scheme $scheme;
            
        }

        access_log  off;

   }

有的时候想快速部署一个测试demo,还要新建一个nginx配置文件,再做一个域名解析,麻烦得很。突发奇想,将一个二级域名泛解析,然后写一份通用的nginx配置文件就可以免去烦恼了。

server
   {
            listen 80;
            listen 443 ssl http2;
                    
            server_name ~(.+)\.test\.example\.com$;
            index index.php index.html index.htm;
            set $path $1;
            root  /path/to/www/testwebsite/$path;

            ssl on;
            ssl_certificate /path/to/your.cer; # 需要野卡ssl
            ssl_certificate_key /path/to/your.key;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
            ssl_prefer_server_ciphers on;
            ssl_session_cache shared:SSL:10m;
            location ~ [^/]\.php(/|$)
            {
                alias  /path/to/www/testwebsite/$path;
                try_files $uri =404;
                fastcgi_pass  unix:/tmp/php-cgi.sock;
                fastcgi_index index.php;
                include fastcgi.conf;
            }

            access_log  off;

   }

如果把一个项目clone到了/path/to/www/testwebsite/x1,直接访问x1.test.example.com就可以了。

记那些踩过的坑:只能用一次的contextlib.contextmanager
最近想要实现一个需求,优雅地使用不阻塞的threading.Lock(),何谓优雅,就是基本不改动,继续使用with。

一开始我的代码是这样子的

def non_blocking_lock(lock: Union[threading.Lock, threading.RLock]):
    @contextmanager
    def _():
        locked = lock.acquire(blocking=False)
        try:
            yield locked
        finally:
            if locked:
                lock.release()

    return _()

测试通过,然而实际使用时却报错: AttributeError: args
翻了翻contextlib的源码,发现在contextlib.py:110,args属性被删除

def __enter__(self):
    # do not keep args and kwds alive unnecessarily
    # they are only needed for recreation, which is not possible anymore
    del self.args, self.kwds, self.func
    try:
        return next(self.gen)
    except StopIteration:
        raise RuntimeError("generator didn't yield") from None

当第二次使用该contextmanager,args已经是不存在的,所以才会抛出AttributeError
所以最后的解决方案很显然:

  1. copy一份contextmanager代码,去掉del那行代码
  2. 手写contextmanager