AberSheeran
Aber Sheeran
RSS feed
51 让一份代码同时支持同步与异步

在一般代码里,无论是同步还是异步,对于业务参数与返回结果的处理逻辑应当是一致的。有的时候我们为了同时支持同步和异步调用而不得不写两份代码,这会带来许多处理不一致的问题。单纯的把处理逻辑抽离出来作为独立函数,也不是特别能解决,在一个超大代码量的项目里其实很容易出现复制粘贴漏调用处理函数的情况。本文旨在提出一种思路,用于解决实际项目中不得不写同时维护 asyncsync 代码的问题。

众所周知,生成器(Generator)可以将一个完整函数,拆成多次调用执行。如果我们将 …

50 在 1C 1G 的服务器上跑 mastodon

Oracle 给了我两个 1C 1G 的永久免费服务器,正好用来搭建 mastodon,也把 fuckyou.plus 这个域名用上。

mastodon 给出的 docker-compose.yml 里有三个服务,其中较为吃内存的是使用 ruby 编写的 web …

49 SO_REUSEADDR 和 SO_REUSEPORT

版权申明

本文从 StackOverflow 里 How do SO_REUSEADDR and SO_REUSEPORT differ? 的回答翻译而来。

欢迎来到奇妙的可移植性世界......或者说缺乏可移植性的世界。在我们开始详细分析这两个选项并深入研究不同操作系统如何处理它们之前,应该注意到BSD的套接字实现是所有套接字实现之母。基本上所有其他系统都在某个时间点上复制了BSD的套接字实现(或者至少是它的接口),然后开始自行演化。当然,BSD的套接字实现也是在同一时间进化的 …

47 Windows 同时访问内外网

这在大部分公司都属于违规行为,请询问自家公司 IT 部门获得允许后谨慎使用。

先连上内网,然后使用 USB 或无线网络共享手机网络给电脑。按照如下步骤手动指定路由。

  1. 使用 ipconfig 查看各网卡信息,可以得到内网的网段和网关信息。
  2. 使用 route add {内网网段} mask {内网网段对应的网络掩码} {内网网关地址 …
46 Python 匿名函数的妙用

在设计 MíngShé 的字典解构赋值语法时,我遇到了一个问题,在半年之后的今天终于想到了如何解决。

字典解构赋值语法右侧的表达式是十分自由且无法控制的,它可以是一个简单的变量名,也可以是一个复杂的管道和偏函数运算结果,有的时候其计算成本十分的高。作为一个编程语言,肯定不能愚蠢地重复计算右侧的值。那么如何保存变量的值且不把作用域扩散到单条语句外?

由于当时已经写完了空值合并语法,我思维上出现了明显的路径依赖,不停在想如何使用 := 绑定右侧对象,但始终没有想出来。直到昨天漫无目的的刷新着 Telegram Group …

45 URL Query Parameters

URL Query Parameters (有时候也叫 URL Parameters)并没有明确的 RFC 规范来指明其如何传输数组或对象,在实践中不同的客户端、服务端能够轻松构造或者解析的方式也不同。

以下格式均无对错 …

44 WSGI 项目的 Lifespan

经过大概几年的使用,我深深感受到 Python 的 asyncio 生态还是跟闹着玩的一样,于是打算 CURD 业务部分还是迁回同步比较好,使用 gevent 包装,性能也并不弱。

而 ASGI 迁回 WSGI,面临最大的问题就是如何把 ASGI Lifespan …

43 Type hint 在定义数据模型时的应用

在 Python 里,使用 type hint 定义一个数据模型似乎都采用了 dataclass 类似的方式,也就是下面这样的代码。这种代码确实是可以的,但是会出现一个问题,当你直接使用 Data.value 时,它会出现本不该出现的类型推导行为——Data.value 会被视作一个 …

42 基于抢占式 Keepalived 的健康检查设计

Keepalived 有两种模式,抢占式与非抢占式。抢占式遵循优先级高者得 Virtual IP 的理念,当本机健康检查失败、优先级下降后,如果网内存在其他优先级更高的主机,则 Virtual IP 发生转移。非抢占式则是一台服务器始终占据 Virtual IP 直到出现自身关机、断网等情况。

为了让 …

41 写函数式的 Python

这是一个老生常谈的话题。在此不介绍什么是函数式编程之类的教条,因为我觉得那偏离了函数式编程的本意——函数式编程应当是让人节约脑细胞而不是浪费脑细胞的。

简单来说,函数式编程就是你将一些重复的过程编写成名称清晰的函数,通过不断地调用函数来完成工作的一种编程方式。每个老程序员几乎都有一点相关的心得。所以,放轻松。函数式编程并不是全是 lambda、组合子、Monad 这类东西。

很多人讲函数式喜欢从 λ 演算开始,确实,那是函数式编程的理论基础 …

40 K8S 中控制 Pod 内容器启动顺序

如何控制 K8S 单个 Pod 中容器的启动顺序?

其实只要把这个问题放到谷歌里一搜,就可以得到一个有效的、让人满意的答案。但是,为什么呢?没有人讲过。无论我使用中文、英文进行搜索,都没有人提到为什么在 postStart 执行当前容器的健康检查代码就可以控制容器的启动顺序,包括官方文档(甚至一度误导了我)。

在官方文档里有这么 …

39 四行代码实现 Python 管道

在我编写从 HBase 读取并分析数据的代码时候,遇到了一个问题——多重循环嵌套。

众所周知,HBase 本身是没有二级索引的,所有的数据分析都只能靠扫描 rowkey 读出一整个列表的数据,然后再自己提炼加工。而提炼加工的过程就是不断地循环数据列表,对每个数据项进行筛选、修改的过程。

这让我写的很痛苦,我不得不反复不断地嵌套循环。于是我想起了管道,然后我自己实现了一下 Python …

38 Django 禁止用户多客户端登录

本文全部基于 Django 默认的用户模型和会话(session)引擎。

在某些特殊项目里,会有一种需求——限制用户同时仅能在同一台设备登录,或者说同时仅能在同一个客户端内保持登陆状态。就像 QQ 一样,在一个手机客户端里登录后,另一个手机客户端中的账号就自动退出。

在 Django 里,每次登陆时,都会签发一个新的 Session …

37 Django 数据库自动重连

在非 Django web 服务里使用 Django ORM 的时候,时常会出现 (2006, 'MySQL server has gone away') 这样的报错。在一番查询之后,发现网上并没有出现什么好的解决办法,一般都是教你使用 django.db …

35 Traefik 与多 network

Traefik 是一个很好用的反向代理服务器,它可以自动发现 Docker 容器中的服务,然后进行反向代理(不再需要手动指定映射到宿主机端口再去配置代理服务器),并且还可以自动申请 TLS 证书,自动提供 HTTP2 服务。十分爽。

但一旦 Traefik 和多个 network 的服务一起工作,它就会随机的出问题 …

34 搭建自己的 PyPi 镜像

在国内,有许多厂商的 PyPi 镜像,或许是为了监管,他们均选择了定时拉取同步的设计。这就会经常出现很多新的库/版本没有同步到的问题,并且有时候速度并不是很理想(毕竟那么多人在用)。

用自己处于大陆外的闲置服务器带宽搭建一个反向代理 PyPi 不仅能做到高实时性,还能通过正常的网站来掩盖某些特殊流量

搭建镜像

使用 PyPi-mirror 这个仓库来搭建。执行 …

33 ys.zsh 的 Python 虚拟环境显示

oh-my-zsh 里的主题,我最喜欢是 ys,它简洁优雅,没有非 ASCII 符号。

但唯一的问题是 Python 虚拟环境提示符不能正常显示,在 poetry 创建的虚拟环境下,它总是会把 (.venv) 输出到每个命令的结果之后。

一番搜索之下先是找到了 https://github …

32 OneDrive 右键菜单不显示

之前偶然发现 Windows10 上的 OneDrive 文件夹里右键菜单没有了,一阵谷歌搜索之后按照微软的社区网站里微软工作人员的方法,一顿操作并没有用。

时隔多天,今天心血来潮再去搜一下,搜到了一个一看就是爬虫爬到的文章网站里的一篇回答。

OneDrive 没有右键菜单——也就是释放空间等操作,除了未连接微软账号之外的原因就是 UAC 被打开了。至于为什么我能搜到这篇文章,我也记得不清了……有的时候莫名其妙就搜到了。

操作过程 …

31 代理 IP 供应商

由于程序需要,购买了一些提供代理 IP 的服务。本文会持续更新,直到买到合适的代理 IP 服务为止。另外,本文不是做推广骗黑心钱的,不信你看我下面贴的地址,只贴了官网,不是推广链接。

最后更新时间请看上面。

阿布云

最开始买的就是这家,原因是 PM 的朋友推荐的。这家代理用起来很简单 …

30 更好看的滚动条

浏览器自带的滚动条相当丑,我在一段时间之前魔改了一下perfect-scrollbar的CSS代码,做了一个更好看的滚动条,我现在的博客代码块用的就是它。

使用方法

先引入JS与CSS:

<script src="https://abersheeran.com/templates/static/components/prefect-scrollbar/main.min …
29 漂亮的 Windows Terminal

微软官方出的Windows Terminal,我从第一个上架商店的版本开始用起,到现在终于等到一个使用了一段时间后没发现BUG的版本。

今天改了一下整体的配置,分享一下这个淡灰、比较护眼的主题。(另外吐槽一下,黑底白字、黑底绿字,真的对眼睛不好)

配置

首先,globals里的requestedTheme改成dark

然后向 schemes …

28 os.system在Docker中的坑

最近在忙项目的同时,也想把自己的小工具用自己的index.py重写一下。为了从实践中完善index.py。

但在尝试使用docker运行index.py的时候,出了问题。

问题

众所周知,docker容器在正常终止时会向主进程(pid 1)发送一个SIGTERM信号。一般来说,程序是能正常接收这个信号,并且退出的。

但 …

27 加速Python的asyncio

Python的asyncio模块带来了语言本身的异步功能,不再需要gevent之类的猴子补丁。但速度上,asyncio有点慢。

不过这个库设计之初,就允许了使用自定义的loop代替默认loop。这给更好的性能,带来了可能。

非 Windows

libuv 是一个跨平台的,高性能异步IO库。Node.js被人吹鼓的性能,一半的功劳来自于它。

于是有大佬以它为基础,用Cython写了uvloop,使用的时候只需要两行代码就可以使用性能更好的loop代替原生asyncio默认loop …

26 Python的元类

关于什么是元类(metaclass)、怎么用元类,我查了很多资料。中文的英文的都有,但是似乎都是讲理论,没有实际的给出一个整体的代码。

理论

几乎所有教程里都会谈到这一点:

类也是一个对象,元类就是创建这个对象的类。

参考metaclass的官方文档

By default, classes are constructed using …

25 Python文件的热重载

在创造Index.py的时候,我思考了一个问题——如何使得Python程序像一个传统PHP服务一样,在保证现有的请求不变的情况下,新请求使用更新后的代码进行处理。

一开始我是为了模拟PHP一样的热重载,所以处理方式就如同PHP一样,在被请求时重新装载一遍文件。但这样的问题就是,非处理请求的文件不会被重新加载。

然后我想到了watchdogimportlib这两个库。

前者能监听指定路径下的文件系统事件,后者可以通过模块名来导入 …

24 文件自动同步七牛云

由于服务器的带宽与存储问题,图片不得不上七牛云了。

模型

以下是一个很简单的图片模型,之前我有写过一篇Django多图片上传,所以在此不赘述如何处理图片上传部分了。

class Image(models.Model):
    file = models.ImageField(upload_to='upload/', verbose_name="路径")
    message …
23 清理 Django 的迁移文件

这个问题其实要分两步,第一步是清理数据库中django_migrations这张表,第二步是重新生成迁移文件并且在不影响现有数据库结构的情况下实施到数据库中。

清理数据库中迁移记录

这里要分两种情况讨论,当你的迁移文件不小心丢失了一部分或者全部没了的时候,你需要手动去数据库里清空django_migrations这张表。

而如果你本地拥有完整的迁移文件,就可以使用Django自带的命令manage.py migrate --fake APP_NAME zero进行清理 …

22 给CharField定义更优雅的Choice

在Django官方文档中,它们提供了两个关于如何使用预定义选项作为特定字段选择的示例

官方文档的例子

第一个例子中定义choices是用一个元组包裹的元组,里面元组的第一个元素的值是设置在model的值, 第二个元素的值是它的字符串表示。

YEAR_IN_SCHOOL_CHOICES = [
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
]

另一个例子, 官方建议我们定义选项为model类的常量。

from django.db …
21 Windows创建右键菜单

Windows右键菜单的管理是用的注册表。

选中文件后的右键菜单的管理路径在HKEY_CLASSES_ROOT\Directory\shell,在文件夹中空白处右键菜单在HKEY_CLASSES_ROOT\Directory\Background\shell

例子

以创建“在当前目录打开Ubuntu子系统”为例

  1. 使用Win+R运行regedit,打开路径 …

20 WSL连接远程服务器乱码问题

用WSL很爽, 但是SSH连到其他服务器上改代码会出现文件内容乱码的问题。查了一下解决方案,做一下记录。

解决方案

使用如下命令修改Ubuntu子系统的LANG

sudo vim /etc/default/locale

之前的LANG为:

LANG=C.UTF-8

改为:

LANG=zh_CN.UTF-8

然后安装对应的语言包 …

19 Django部署后查看详细日志

Django部署到线上之后,出现一些奇怪的500错误。但是关了DEBUG,uwsgi里没得详细日志可以看。于是谷歌了一番,发现有这个疑惑的不止我一个。

stackoverflow.com关于此的问答中可以看到,配置很简单。在settings里配置

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters' …
18 uwsgi日志分割

uwsgi是一个很棒的程序,它能轻易的驱动任何支持WSGI协议的应用程序。但它默认的日志系统不能配置按天分割。那么我稍微查了一下资料,写了这篇文章以做记录,方便他日再用。

首先,最重要的是uwsgi配置的touch-logreopen选项,它指定监听一个文件,当这个文件的修改日期有变化时,就会重新打开日志文件。

uwsgi配置类似于

[uwsgi]
socket = %d%n/django.sock …
17 Django CSRF保护问题

Django自带的CSRF保护是一个是十分棒的插件。在使用Django开发的过程中,它仅仅只需要你引入一行代码,就可以保护你的表单不受CSRF攻击的困扰。

但在开发Api时,它会困扰着许多程序员,接下来我们分两个情况来解决它(都是基于你在使用 Cookies 进行身份验证的时候,不是用 Cookies 也就没有 CSRF 防护的需要了,直接删掉 Django 中对应的中间件即可)。

同源请求

对于同源网站而言 …

16 Coding-WebHook

由于我写的网站样式在频繁的更改,每次我都要去服务器上执行git pull,很麻烦,于是查了一下Coding的文档写了WebHook。

WebHook是什么?

WebHook 是Coding/Github之类的网站,提供的一个服务。

以Coding为例,它可以为你的库设定五种监听事件,在这些事件发生的时候就会发送一个POST请求到最上方指定的网址。

编写

根据Coding开发者文档,在项目的settings.py …

15 Django静态文件访问错误

我们在开发pdk365的时候,前端开发的机子突然无法访问他本机架起的Django服务器的静态文件了。

报错就类似于下面的,但我遇见的问题不同的是,它们的根路径是一样的。

The joined path (/var/folders/t9/7v8mki3s3h39fzylxfpsk9640000nn/T/tmpmvb9wxq6) is located outside …
14 HTML字体解码错误

手撸maltose.py的时候,发现了一个奇怪的问题

Failed to decode downloaded font: If2RXTr6YS-zF4S-kcSWSVi_szLgiuE.woff2
OTS parsing error: Failed to convert WOFF 2 …
13 pip更新后报错

使用python -m pip install --upgrade pip更新pip到最新版后,再次使用pip产生了报错

Traceback (most recent call last):
  File "/usr/bin/pip", line …
12 微软 C++ Build Tools

在 Windows 上安装 Python 的某些第三方包时,需要用到 Visual Studio Build Tools,如果你没有安装,会出现如下报错信息:

Microsoft Visual C++ 14.0 is required.

为了解决这个报错 …

10 Django多图片上传

最近有个需求,用Django的Form实现上传任意张图片。然而四下查找,没有人写过Django的多文件上传,于是花了一点时间去看Django文档,才优雅的实现出来。

先看一下我们的models结构

from django.db import models
from django.contrib.auth import get_user_model


class Message …
9 Offic2016-只安装Word三件套

新装的Office2016全家桶其实我只需要W/X/P三件套,于是花了点时间查如何解决。

首先我们需要从微软官网下载需要的部署工具。双击运行之后,会释放两个xml文件和一个setup.exe文件(可以删掉这两没有什么用的xml文件)。再下载一个Office2016的安装镜像,挂载。

一番查阅之后发现似乎很难找到好的ISO镜像资源,于是自己传了一个到谷歌云盘上,能翻墙且网速好的可以考虑下载这个 …

8 Sticky效果

最近有个需求,让nav在正常的时候正常显示,当页面滚动下去,nav要停靠在页面顶。

CSS实现

MDN关于position的定义里提到过有一种position: sticky;,可以得到这种效果。必须要设置top的值,才能有效。

Sticky
父元素
7 下移动画

在使用JQ的fadeIn()的时候,发现了它是通过指定元素的透明度来实现的。然后就自己玩了一下JS动画制作

setTimeout

虽然这个函数名带timeout,但是设置的却是在指定时间之后异步执行任务。
其函数定义的伪代码为setTimeout(handler, timeout=0, *args)

  • handler可以是一段JS代码的字符串,也可以是一个函数。

  • timeout是指定的时间,单位是毫秒 …

6 Python的import

引入(import)是Python最强大的部分,它可以让你轻松的使用其他Python模块里的对象。

两种引入

所谓相对引入,便是类似于from .main import app或是from . import main
绝对引入,类似于from os import …

5 站内搜索

经过友人的一再催促,终于打算在端午开始写站内搜索。至于为什么要自己写而不是用别的——谷歌站内搜索没法定制,百度的看都没看,反正百度不录我博客。
一开始以为站内搜索很复杂,我做好了花整整三天的时间来搞的准备,然而Python并不打算给我这个机会(Python大法好),Whoosh+Jieba两个库就满足了我的需求。

按照惯例,首先pip install whoosh jieba装好两个库。然后可以愉快的写代码了 …

4 socket.SO_REUSEADDR

最近在手写分布式爬虫的时候遇到一个问题,就是负责任务分发的服务器在关掉试图重启的时候总显示端口被占用,但又查不到端口被占用的进程号。

[ERROR] Address already in use

一番谷歌之后得知,操作系统的网络栈会非常谨慎的处理连接的关闭,仅仅用于监听的服务器套接字是可以立即关闭并操作系统忽略的,但是对于实际与客户端进行通信的连接套接字就不行了。即使客户端和服务器都关闭了连接并向对方发从了FIN数据包,连接套接字也无法立即取消。为什么呢?因为即使网络栈发送了最后一个数据包将套接字关闭,也还是无法确认该数据包是否可以被接收。如果数据包正好被网络丢弃了,那么另一方无法得知该数据包长时间无法传达的原因,可能会重新发送FIN数据包 …

3 Uwsgi部署Django

下载Nginx,uwsgi, Mysql

我用的是CentOS7和Python3.5,所以如下(安装新版Python参照我另一篇CentOS7安装Python3

yum install -y nginx
yum install -y mariadb mariadb-devel mariadb-server
pip3 install …
2 CentOS7上安装Python3

使用yum安装Python3

经过测试,在腾讯云的CentOS7服务器上使用这种方法可以直接安装Python3

yum -y update
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-libs …
1 Apache部署Django

安装Python,mod_wsgi,Apache

使用Apache直接部署Django,版本搭配很重要。

在好心人已经帮我们编译好之后的包的发布网站可以找到需要的版本。

因为我的系统是64位,Python是35,所以选择mod_wsgi‑4.5.17+ap24vc14‑cp35‑cp35m‑win_amd64.whl …