Comments

极光推送 是国内最早的第三方消息推送服务,官方提供了多种语言的 SDK 和 REST API,详情见 官方文档。遗憾的是缺少一个 Go 语言版本的 SDK,于是我就动手造轮子,封装了一个 Go 的版本。

实际上这个项目在今年 3 月份就完成了主要的推送相关的接口,在 GitHub 上也收获了几个 star 和 fork. 最近今天突然兴起,又翻出来把 device, tag, alias, report 的一些相关接口也封装完成了。

啰嗦了一大推,差点忘了最重要的东西,下面给出链接:

欢迎使用,并 反馈 issues创建 pull request.

Read on →
Comments

前一篇 Blog 简单介绍了 Celery 及其用法,现在我们看看在 Flask 项目中如何使用 Celery.

注意,这篇 Blog 严重参考了这两篇文章:

  1. Using Celery With Flask: 写了一个完整而且有意义的例子来展示如何在 Flask 中使用 Celery.
  2. Celery and the Flask Application Factory Pattern: 是上文的姊妹篇,描述的是更为真实的场景下,Celery 与 Flask Application Factory 的结合使用。

Read on →
Comments

Introduction

分布式任务队列

Celery 是一个分布式任务队列,下面是 官网 的一段描述:

Celery is an asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.

Celery 简单、灵活、可靠,是一个专注于实时处理的任务队列,同时也支持任务调度。

何为任务队列?

摘自 Celery 官方文档的 中文翻译

任务队列是一种在线程或机器间分发任务的机制。

消息队列的输入是工作的一个单元,称为任务,独立的职程(Worker)进程持续监视队列中是否有需要处理的新任务。

Celery 用消息通信,通常使用中间人(Broker)在客户端和职程间斡旋。这个过程从客户端向队列添加消息开始,之后中间人把消息派送给职程。

Celery 系统可包含多个职程和中间人,以此获得高可用性和横向扩展能力。

Read on →

写 API 的时候,总是会想着如何能提升性能。在一般的 Web 应用里,基本上没什么 CPU 密集型的计算,大部分时间还是消耗在 IO 上面:查询数据库、读写文件、调用第三方 API 等。有些可以异步的操作,比如发送注册邮件、手机验证码等,可以用任务队列来处理。在 Python 的生态里,Celery 就是一个很成熟的解决方案。但是对于很多查询请求,还是需要同步返回的。

如果真的遇到性能问题,正确的做法是先找出性能瓶颈,然后对症下药。比如优化数据库索引、优化数据库查询语句、优化算法和数据结构,加速查询和计算。但是最快的计算就是不算——或只计算一次,也就是把计算(查询)的结果缓存起来,以后相同条件的计算(查询)直接从缓存里获取,而不需要重新计算(查询)。

对于耗时的计算,缓存是一种非常有效的优化手段。但缓存也不是万能的,引入缓存的同时,一些其他问题或需要注意的事情也随之而来,比如数据同步、缓存失效、命中率、分布式等。这里不深入探讨这些问题,仅针对下面这种场景,使用缓存来优化 API 性能:

  • GET 查询
  • 查询很耗时
  • 相同条件、不同时间(或某段时间内)的查询结果是一致的

比如获取静态页面(也可以通过 Nginx 直接返回),查询某些元数据列表(如国家列表、产品分类等)。

Read on →
Comments

在一个 Web 应用里,不管是为了业务逻辑的正确性,还是系统安全性,做好参数(querystring, form, json)验证都是非常必要的。

WTForms 是一个非常好用而且强大的表单校验和渲染的库,提供 Form 基类用于定义表单结构(类似 ORM),内置了丰富的字段类型和校验方法,可以很方便的用来做校验。如果应用需要输出 HTML,集成到模板里也很容易。对于 JSON API 应用,用不到渲染的功能,但是结构化的表单和校验功能依然非常有用。

Read on →
Comments

遵循良好的编码风格,可以有效的提高代码的可读性,降低出错几率和维护难度。在团队开发中,使用(尽量)统一的编码风格,还可以降低沟通成本。

网上有很多版本的编码规范,基本上都是遵循 PEP8 的规范:

除了在编码时主动遵循规范,还有很多有用的工具:

  • IntelliJ IDEA 和 PyCharm 的格式化代码功能
  • Google 开源的 Python 文件格式化工具:github.com/google/yapf
  • pyflakes, pylint 等工具及各种编辑器的插件

本文的内容主要摘自互联网上各种版本的规范,因为公司有些小伙伴代码风格不太好,所以整理了一份算是团队的编码规范。

Read on →
Comments

写完代码测试通过之后,终于松一口气,然后可以愉快的部署上线了。但是问题随之而来:如何部署?或者如何能更自动化的部署?

部署应用是一系列的操作,就环境而言,分为本地和远程服务器,就操作而言,大概包括提交代码、备份代码、更新代码、安装依赖、迁移数据库、重启服务等流程。其中除了提交代码这一步是在本地完成,其余操作都需要在服务器环境执行。

上面的流程当中,有一个很重要的,就是如何同步代码(提交、备份、更新)。就我的经验,了解或用过这些方式:

  • rsync: rsync 是一个文件同步的工具,如果配置好使用起来体验也不错。但是有很多缺点:
    • 配置复杂,命令行参数多
    • 需要在服务器上运行 rsyncd,默认监听 873 端口(可能会有防火墙)
  • scp: scp 底层用的是 SSH 协议,所以只要服务器上运行了 sshd 就可以双向 copy 文件。对于文件传输来说,scp 比 rsync 体验差的地方有:
    • 不能增量更新,每次都是全部传输
    • 不能配置忽略文件(.git 怎么办?)
  • git: 就个人而言,git 是最方便的部署方式了,有版本控制,可以增量更新,可以配置忽略文件,使用简单。实际上只要有可能,都推荐用 git 来发布代码。但问题在于,很多公司的 git 服务器都是在内网的,所以在服务器上无法访问。

很幸运的是,我们有一个公网可以访问的 git 服务器,所以可以用 git 来发布代码。发布完代码后就是后续的一系列操作了,最原始的方式,是登录到服务器,然后一步一步敲命令执行下来。但是如果要频繁部署的话(快速迭代时肯定要经常更新代码),这就变成了繁复的体力劳动,而且容易出错(漏了流程,看花眼了)。于是就想到了脚本,把这些操作写成 shell 脚本,然后执行脚本就好了。这是一个很大的进步,然而仍然存在一个问题:从本地环境到远程环境,需要登录,导致了流程上的阻断。

Fabric 是 Python 编写的一个可以实现自动化部署和系统维护的命令行工具,只需要写一些简单的 Python 代码就能轻松解决上面提到的所有问题。Fabric 底层用的是 SSH 协议,提供了一系列语义清晰的 API 来组合实现部署任务。

Read on →

Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。

安装

Supervisor 可以运行在 Linux、Mac OS X 上。如前所述,supervisor 是 Python 编写的,所以安装起来也很方便,可以直接用 pip :

sudo pip install supervisor

如果是 Ubuntu 系统,还可以使用 apt-get 安装。

Read on →
Comments

缘起

GFW 早已经是臭名昭著,路人皆知的了,因为它的存在,使得整个大陆的用户都只能在「局域网」里活动。政治敏感的内容就不说了,很多技术性的网站也被墙掉,导致查找问题浏览网页时经常网络被重置。

我是个重度 Google 用户,虽然经常用到的 Google 的产品基本上只有 Google 搜索和 Gmail,但只需要这两项就让我离不开 Google。此外,还有很多网站使用 Google 的 OpenID 登录,引用 Google 的字体文件和其他资源文件,这些网站也都几乎无法正常访问。我曾经使用过一些手段来实现翻墙,在大学时得益于教育网免费的 IPv6,毕业后使用了很久的 GoAgent,手机上用过 fqrouter,然而都不是很稳定和一劳永逸的解决方案。

有很多人使用 VPN,有购买的,也有自己搭建的。在 GoAgent 无法使用后,我开始正式考虑使用 VPN 了,但不想买 VPN,主要原因有:

  1. 很多人使用的 VPN 容易被盯上而面临被干掉的危险(应该是多虑了)
  2. 出于信息安全和隐私的考虑,不希望自己的信息有被第三方获取的风险(所以也不想用 fqrouter 了)
  3. 想自己折腾

所以就选择了国外 VPS + Shadowsocks 的解决方案。

Read on →
Comments

平时需要经常用到 SSH,比如登录远程服务器,用 Git 推送和更新代码等。建立一次 SSH 连接可能并不需要多久长时间,但是如果要频繁登录同一台服务器,就未免显得有些繁琐和浪费时间。如果是用用户名和密码登录,每次都要输入密码就更加让人崩溃。还有使用 Git 的时候,短时间内可能需要经常 git pullgit push,如果每次操作都需要重新建立连接,等待过程就让人心生厌恶了。

实际上,SSH 有个「鲜为人知」的特性可以做到重用连接,只有在第一次登录的时候会创建新的连接,后续的会话都可以重用这个已经存在的连接。这样,后续的登录就会非常快,而且不需要输入密码认证。配置也很简单,直接上代码。

修改 ~/.ssh/config 文件,添加如下配置:

Host *
    ControlMaster auto
    ControlPath /tmp/ssh_mux_%h_%p_%r
    ControlPersist 600

Read on →
getElementsByTagName('BODY')[0]).appendChild(s); }()); getElementsByTagName('BODY')[0]).appendChild(s); }()); getElementsByTagName('BODY')[0]).appendChild(s); }());