Cloverstd's blog

Just do it.

记一次 Python 转 Java 的心血历程

由于公司的一系列(拥抱)变化,导致公司需要将原来的 Python 为主的技术栈,用 Java 全部重写替换掉,于是乎,去年 10 月份,我就跳出来从这个 Java 化大潮中,接了一部分 Python2Java 的活,主要原因当然是因为我想写 Java 啦。然后我就顺理成章的 owner 了这部分服务的 Java 化工作。 因为我们组有 8 个人力可以出来投入 Java 化,所以我自信满满的觉得我们能在 19 年 12 月底完成我这部分服务的 Java 化,并且全部上线,后来发现我是太 naive 了,最终延迟到了

Docker

Bamboo 原理分析

原理简介 Bamboo 为了 DO/CS 系统提供了服务自动发现的功能,当 Marathon 上部署了一个应用,Bamboo 能够将应用下所有的容器的端口更新到 HAProxy 的配置文件中,并且 reload HAProxy,从而实现应用的服务自动发现,并且利用 HAProxy 做应用中容器的负载均衡。 Bamboo 主要的原理就是利用 Marathon 的 Event-Bus API,当 Marathon 上的应用发生改变(scaling)时,Event-Bus 会通知对应的 Subscriber (Bamboo),然后 Subscriber 会做出对应的操作。 除了 Bamboo,还有 Marathon-lb 也是类似的原理。 源码分析

Docker

减小 Docker 镜像体积

最近遇到了 Docker 镜像体积过大的问题,对于部署、移交相当麻烦和慢。于是就抽点时间研究下了怎么减小 Docker 镜像的体积。 下面我以手动编译 nginx 镜像作为例子来减小镜像体积,nginx 的版本是 1.10.2,并且下载到了当前目录。 下图是各种 Dockerfile 制作出镜像的效果 替换基础镜像 基于 centos 的镜像 基于 Alpine 的镜像 移除 build 依赖的文件 centos 基础镜像的依赖 Alpine 基础镜像的依赖 减少镜像层级 centos Alpine 大文件测试 通过 COPY 通过 wget 其他 Python

Nginx

使用 Nginx Upload Module 上传文件

从开始会写程序开始,一直都很讨厌处理上传文件,因为总觉得在自己写的 controller 里面从 HTTP Body 里读文件,然后再写到本地磁盘的过程是一件非常不(易)靠(出)谱(错)的事,总怕文件没有正确写入,而且常用的框架对于上传文件,都是直接将整个文件加载到内存中,当处理大文件上传时,内存岂不是要爆炸了。 后来知道了七牛和又拍云之类的云服务,顿时感觉对于文件上传的过程的瞬间简化了。类似与七牛之类的文件储存云服务一般都会提供文件直传的接口,直接在前端就把文件上传到了七牛的服务器,而不经过业务服务器,然后当文件上传成功后,可以选择让七牛通知(回调)到业务服务器。 但是一般只有『互联网』企业才会选择七牛之类的云服务,可惜我就没怎么待过『互联网』企业,所以一直都没有正式的使用过文件直传这种方式,甚是伤心。如果你没有用过七牛,强烈推荐你试用一下,这里有我的邀请链接,你注册成功,我将收到 40G 的免费流量

Docker

Docker Registry V2 Auth Server

由于工作原因,最近研究了下 Docker Registry V2 (以下内容如无特别说明,Registry 均指 Docker Registry V2)的私有化(这里所指的私有化并不是指的私有仓库,而是在私有云里面面向内部的共有仓库,并且对外隔离的)的定制化开发。 Registry 是 Docker 官方提供的镜像仓库,官方的 Docker Hub 就是基于 Registry 的,Registry 分为 V1 和 V2,V1 是我大爱的 Python 的写的,V2 是我现在大爱的 Golang 开发的,由于 V1 已经被官方抛弃了,所以目前的定制化是基于 V2

Docker

用 Docker 部署 Python Web Application

Tips: 下面的部分链接中带有小尾巴,谨点 去年的时候从阿里云捻过一次羊毛(云翼计划,如果愿意,可以是用我的阿里云推荐码,z9xy74 ),如今一年已过,这个服务器也过期了,但是上面跑了一个微信企业号的应用在,由于有一直在使用的需求,不能停止,但是阿里云的羊毛是青岛节点,延迟高,而且现在到期了,默认变成了按流量付费,顿时觉得随时会少一套房子了。于是重新买了一个阿里云的华东节点,准备迁移过来,并且也准备把 DigitalOcean 上的部分应用迁移回国。 Docker 环境的准备 镜像的初始化 MySQL Redis Web Application Nginx 和之前的比较 一些问题 参考 # Docker 环境的准备 使用阿里云提供的 [docker-engine](http://mirrors.aliyun.com/help/docker-engine)

Tornado

使用 Tornado 实现 Docker 容器的 exec

因为工作项目的需求,研究了一下 WebSSH。 实现原理 通过 Docker cli 运行 bash 通过 Docker API 运行 bash 创建一个 exec 实例 执行 exec 实例 与前端结合实现 WebSSH 参考 # 实现原理 由于某些时候,需要通过某种方式进入到容器内部里面去执行一些操作,一般容器并没有提供 SSH 服务,但是有些容器提供了 `bash`,可以通过执行 `bash` 进入到一个交互式的 `shell` 中,执行一些操作。 # 通过 Docker cli 运行 bash 首先,是可以通过

Docker

Docker Cluster with Swarm

最近因为工作的原因,需要用到 Docker,并且搭建 Docker Cluster(集群),然后首先学习了一下 Docker Swarm,这里做一下记录。 准备工作 制作基础镜像 初始化多台虚拟机 Docker Swarm 发现服务 Docker Hub Consul 参考 #准备工作 由于是在本机模拟集群,所以我采用的是 Vagrant 和 VirtualBox 创建虚拟机来模拟集群。 假设本机已经装好了 Vagrant。 ##制作基础镜像 本次模拟我采用的虚拟机系统是 Ubuntu 14.04,本来是应该通过下面命令完成的 ```bash vagrant init ubuntu/trusty64; vagrant up --provider

Tornado

为 Tornado 增加 Session

Tornado 是我非常喜欢的一个框架,但是它缺失了很多功能模块,比如说 Session,正因为它啥都没有,所以我就爱上它了,这样可以方便自己撸轮子。:D Session 原理 为 Tornado 添加 Session SessionMixin 结合 Tornado Session Storage 感谢 # Session 原理 Session 是由于 HTTP 协议是无状态的,所以需要一种机制来保持客户端和服务器之间的会话。 HTTP 协议的流程是 Client -> Send Request -> Server -> Return Response 上述过程,是一次性的,

Flask

Flask 用户权限划分

最近学习了下用户权限划分的数据库结构,并且结合到了 Flask 和 SQLAlchemy 中 基础表 用户表 角色表 权限表 菜单表 关联表 用户角色表 角色权限表 角色菜单表 SQLAlchemy 与 Flask 结合 首先是数据库的整体结构图(简化版) ### 基础表 #### 用户表 class UserModel(db.Model): __tablename__ = 'user' username = db.Column(db.String(50)) password = db.Column(db.String(128)) email = db.Column(

Tornado

tornado.ioloop 学习(一)

Tornado 是一个 Python 的 Web 框架和一个异步网络库。 Tornado is a Python web framework and asynchronous networking library 单纯作 Python 的 Web 框架,Tornado 并没有啥特色,和 Web.py 的接口类似。话说我学的第一个 Python Web 框架就是 Web.py,导致我对相似的 Tornado 恋恋不忘。于是乎,我就开始阅读 Tornado 的源代码了。 就像上面的介绍,Tornado 除了是一个 Web

生活

麻辣香锅自制记

自从在上海吃过麻辣香锅之后,从此爱上了这个,原谅我这土包子没吃过好的。 昨日在张大妈白菜党看到了二手东海底捞麻辣香锅特价,19.04RMB,加上我二手东钻石会员,每个月有2张免运费券,用也用不完。果断下单入手,于是开始了下面的麻辣香锅之旅。 食材采购 首先就是选购食材了,根据在知乎和下厨房看到的教程,以及平时在外面店里吃的结合起来,列出了如下菜单(只有做这种事,才想到了印象笔记的好处,买一个勾一个) 土豆 藕 笋尖 里脊肉 鸡胸肉 鸡翅 骨肉相连 红薯 牛肉 腐竹 黑木耳 茶树菇 香菇 金针菇 火腿 虾 葱 五花肉 培根 大葱 郫县豆瓣酱 牛蛙 最终根据实际情况,删除掉的都是没有买(比如难得处理虾)

反向代理

内网穿透-SSH 反向代理

最近搬了新家,4个人合租,办了上海电信的 30MB 的光纤,说是 30MB,上行才 2MB,好在下行是实打实的 30MB,于是就准备把吃灰的树莓派找出来继续做下载机下电影美剧看。 之前在寝室住的时候,直接在路由器上拨号上网,有公网 IP,用的路由器可以做端口转发,配合 DDNS,可以很方便的从外面访问控制树莓派,但是现在这边搬的光纤,必须用电信『强制』租给我们一个光猫,押金200元,说好一年之后可以凭光猫退200块,但是之前来给我们办理网络的师傅说甭指望了,退不了的,我直接告诉他,退不了就去工信部投诉,合同上写好了可以退(其实我也没看合同上到底有没有写,不是我去办理的)。『强租』也就算了,拨号的账号密码都写在光猫里,不给我们,超级管理员密码也不知道,问电信的师傅,说他也不知道,导致我们不能用自己的光猫,这也引发了此片文章。 通过curl ip.

Tornado

扇贝打卡 RSS 源

扇贝打卡只有分享到微博、微信、QQ,然而还要手动分享,这样不利于监督。 于是我就想利用 IFTTT 来实现自动化操作,因为 IFTTT 并没有提供扇贝的 channel,所以曲线救国,就考虑到了通过 RSS,然后扇贝也没有提供打卡的 RSS 源,于是就只能手动生成 RSS 源了。 在很久很久以前,我记得扇贝有提供一个公开的个人打卡记录的页面,貌似是这个 http://shanbay.com/checkin/user/4539052/ ,但是现在这个 URL 必须登录后才能访问,本来想着模拟登录的,但是发现打卡的公共排行榜可以访问,例如『最受欢迎打卡』,那就说明还是有办法可以不登陆访问个人的打卡记录的嘛,于是辗转曲折的找到了『XX 最近打卡日记』,例如 http://shanbay.

Tornado

Tornado with AngularJS

XSRF 处理 POST 参数处理 XSRF 处理 最近在学习 AngularJS 中遇到了一个问题,因为 AngularJS 用的是一个单页面,所以所有的访问其实都是走的 AJAX,而一般的 Web 框架都会有 CSRF 保护,如果是使用 jQuery 来发送 Ajax 请求,在官方文档有给出例子。但是我现在用的 AngularJS,在我的 templates 里只有一个 index.html 文件,所有的页面都是 AngularJS 的ngView。 在官方给出的 jQuery 例子中,是利用的 Cookie 中存的_xsrf附加在 AJAX

微信二维码扫描登录

很多网站都多出来了微信二维码扫描登录,微信官方也有提供网站应用微信登录,然后在DAOClOUD看到了他们的微信扫描登录跟其他地方不一样,于是研究了一下,发现是利用生成带参数的二维码和扫描带参数二维码事件来实现的。 下面是我的实现过程,用的是Tornado实现的。 用户登录实现 二维码扫描登录 结尾 用户登录实现 首先是实现用户登录功能,这里我为了偷懒,就没有用实际的用户登录认证,而是只匹配用户名 主要代码如下 首先创造1000个假用户(名) for i in xrange(1000): q.put(i) users.append(dict(username=str(i), openid=None)) 然后是登录 class IndexHandler(tornado.web.RequestHandler): def get(self): self.

life

2014 年小结

2014 年完结了,大学生活(虽然这不是我所想的生活)也跟着一起完结了,今年是第一个没有回家的暑假,从春节后来学校,就没有回去过一次。 上半年,在纠结是否要考研,最后决定放弃了,主要是估摸着自己是坚持不下来的,就不去折磨自己了。然后在学校借了一台 rMBP,第一次开始使用 OS X,然后从此爱上了 OS X 了。由于有了 rMBP,也做了一个简单的 App,虽然最终还是没有上架,但是也学习了一下 iOS 的开发,算是入门了一下,从最开始的用 Storyboard 画 UI,到后面慢慢的手写部分小 UI,也是一点小进步了。 下半年(从暑假开始),就开始了正式的实习了,下面是实习以及找工作小记。 首先在 V2EX

raspberry pi

树莓派结合3G 无线网卡发送短信

设备信息: Raspberry pi Model B 版 华为 E173s Raspbian 初始化 3G 网卡 由于我的树莓派插上 E173s 这个 3G 网卡,没有在 /dev 下出现响应的 USB 端口,并且通过lsusb查看发现 modem 是 off。 所以需要安装 usb-modeswitch 来切换模式 sudo apt-get install usb-modeswitch 安装完后,需要手动设置 mode 切换的配置文件,配置文件在 /usr/share/usb_modeswitch,需要解压 configPack.

IFTTT

IFTTT Webhook

Update: 请使用 https://ifttt.com/maker 闲来无事,逛了下IFTTT,发现IFTTT的 iOS 客户端已经支持了一些事件了(以前客户端只可以管理 Recipes,但木有事件支持) 看到了其中的 iOS Location,我就想可以设一个离开学校,自动发一条微博『主银离开学校了,不知去向拉拉』,于是就开始动手起来。 据说IFTTT有提供微博的 channel,可是还没有开放,只在内测中,我又申请不到。 由于IFTTT木有提供 API 接口,于是只能曲线救国了,找到了这个ifttt-webhook,利用的是 Wordpress 的 XMLRPC,可惜是 PHP 版的,不过还好逻辑比较简单,于是简单改一下,就成了 Python 版了。

vagrant

Vagrant synced folders failed

Vagrant 选择 virtualbox 作为 provider 时,会默认使用 VirtualBox shared folders 作为同步文件夹的工具,但是最近遇到了一个大坑:无法在 host 里挂在共享文件下,然后把 virtualbox 从4.3.14降到4.2.24,然后又把 ubuntu 从12.04 换到 14.04 结果还是出现这个问题。 当vagrant up时,会出现下面的错误 Failed to mount folders in Linux guest. This is usually because

Tips

时间段记录小技巧

今天看代码的时候,遇到了一段奇怪的的语句 (`Campaigns`.`time_target` & :h1) = :h2 上面是一段 SQL 的条件语句,今天首先看到后,我就开始琢磨了,这一段是干什么的,然后顺着这条 SQL 做的事情,一直摸到了前端,才发现了这是一段时间段的查询语句。 举个例子,有一个需求,需要用户从0-23这段时间段中选择每个小时记录来做某些事。 我看到这个需求,我会在数据库里建一个单独的表来存每个时间段,或者存在一个数组(长度为24),选中就为1,未选中为0,然后序列化一下存到数据库里。而上面那段 SQL 的做法我觉得更醋一些,效率也应该更高一些。 其实在查询语句前还有一个操作,例如用户选择了2,3,18这三个时间段,那个就做下面的操作 h1 = 2**2 + 2**3 + 2*

OS X

OS X 英文环境终端乱码

看到一个朋友的 OS X 是英文环境,然后我也切换过来了,顺带重启一下系统(平时几乎不关机的)。之前在 Ubuntu 下是全英文环境,后来换到了 OS X,苹果的中文化比较好,所以就没有用英文,现在觉得英语还是有必要的,起码可以强迫自己学英语。 然后就遇到了中文乱码的问题了,尼玛,这是在 Linux 上最常见的问题之一了,没想到在 OS X 下竟然也会有这个问题。 其实我是在 tmux 里遇到乱码的问题,然后搜到了这篇,按照设置了 LC_* export LANG="zh_CN.UTF-8" export LC_ALL="zh_