Tech

用Fabric描述区块链(Blockchain)

从2006年到现在,云计算、NOSQL、大数据、机器学习、人工智能……隔一年半载就会有某种技术成为热点,诡异的是当这种技术成为热点后,就变得看不懂了。比如区块链,这两年已经变成了“有巨大潜力颠覆行业,创造让人们参与其创造价值的繁荣世界”“彻底改变人类社会文明”的技术。关于区块链的原理网上有很多浅显易懂的文章、视频,本文只讨论技术上的使用,结合Fabric(v1.0-alpha2)来说明。 区块链用来保存记录,这些记录被称为block,每个block包含时间戳和上一个block的信息。所以技术上来说,区块链是一种分布式数据库。transaction可以类比数据库的查询操作,但只能创建和移动。在Fabric中,区块链数据由State和Ledger构成,State为key-value结构,支持put/get操作;Ledger保存所有对State的、成功的操作,每个Peer都有一份Ledger。 上文提到的Peer,是Fabric的一种节点,有Committer和Endorser两种角色。Fabric有三种节点:Client/Peer/Orderer。Orderer提供channel给Client和Peer,Client通过这个channel,根据endorsement policy,将transaction广播给角色是Endorser的Peer。 Peer收到transaction,执行chaincode——用户编写的程序,这是跟Ledger交互的唯一方式——对transaction进行签署,返回给Client。Client收到所有返回的transaction后,转给Orderer(由Peer做代理),写到State和Ledger。这个流程很类似pub/sub消息系统。 Install Fabric Fabric用GO语言编写,如果使用安装脚本而不是从源代码make,可以不安装GO编译器。安装环境如下: Ubuntu 16.04.2 docker 1.12.6 docker-compose 1.8.0 安装docker和docker-compose,创建fabric-sample文件夹,用curl下载安装脚本并执行:

执行结束后会创建release目录,包含根据系统生成的文件夹(例如当前环境是linux-amd64),也会下载docker镜像。镜像下载如果遇到问题,在release/linux-amd64目录执行这条命令可以继续下载:

脚本会列出下载的images,例如:

Fabric自带的脚本创建一个演示环境只需要两条命令:先用generateArtifacts.sh生成证书和配置文件,再用docker-compose根据docker-compose-cli.yaml启动镜像,docker会挂载crypto-config/channel-artifacts/chaincode这些包含证书和chaincode的目录。官方文档建议注释docker-compose-cli.yaml中cli部分的command(在volumns之前,当前版本是52行,内容是command: /bin/bash -c ‘./scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT’)。:

生成的文件在channel-artifacts和crypto-config文件夹中。再执行docker ps,可以看到启动了5个docker容器:

CLI 上文说过,Client和Peer的要通过channel来通讯,所以先创建channel。 在容器中执行peer channel create,指定orderer、证书、channel名称和配置文件:

执行成功会在当前目录生成.block文件,例如perchouli.block。接下来让Peer加入这个channel,程序会读取以下环境变量判断对哪个Peer进行操作:

默认是对peer0进行操作,执行peer channel join:

加入了channel,就可以通过chaincode操作了。使用cli容器中的示例chaincode,将它安装到各个Peer的/var/hyperledger/production/chaincodes目录下:

然后执行chaincode,也是要指定Orderer、channel、证书,还有之前安装的chaincode。以及,通过-P指定endorsement policy。-c以JSON的格式传参给chiancode:

执行需要一定的时间,现在a是100,b是200。通过查询操作进行验证:

Invoke操作可以更新State:

最后,如果需要停止服务、销毁容器、删除之前生成的证书:

Afterwords …

Continue Reading
Python Tech

GraphQL+Django提供基本API

GraphQL是Facebook去年开源的一套数据查询语言,对于大型系统,GraphQL提供一种灵活的访问通用数据的方式。当时正好有一个项目,需要前端调用后台的数据(Express+Postgresql)实现图表展示,我就从Postgresql里把数据导出成JSON文件(后来用Promise改成直接查询数据库),前端直接用GraphQL获取自己需要的数据,后台就省掉了制作API、写SQL的工作,运行至今基本稳定。 当时GraphQL还没有针对Django的modules,前两个月发布了graphene-django,做的事情不多,但可以搭配其他插件例如django-filters来实现更丰富的查询。GraphQL的优势在于查询语句的通用性和易读性,相比REST架构来说时间较短还不够成熟,如果是复杂需求后台的开发量仍然不小,现阶段在生产环境用Django做一个API服务还是rest framework等成熟的方案会更好。本文实现一个针对Django自带的User Model的简单API。 环境: Django 1.10.4 graphene-django-1.2.0 Setup 安装graphene-django,如果是新建Django项目,创建后执行migrate创建表,再创建admin用户:

Continue Reading
Front Python Tech

用django-webpack-loader实现Django和Webpack的绑定

django-webpack-loader是Django去年的热门App之一,实现Django和Webpack的绑定。做法很简洁,就是用一个nodejs模块处理Webpack的输出,Django再去读取这个模块生成的JSON文件,加载对应的bundle文件就行了。最近在cygwin里重新部署了一次,分享其中的关键点。环境是: Django 1.9.5 NodeJS v6.0.0 Win7(64)+Cygwin2.4.1 场景是将现有的一个Django项目,转成用Webpack来处理静态文件。因为没有执行npm init,安装时会提示找不到package.json。使用Webpack的人应该都知道自己在干什么,所以一些常见的基础配置、错误提示等本文不会涉及。 Install & Settings 首先用npm/pip安装相关的包:

然后设置Django(settings.py),把webpack_loader加到INSTALLED_APPS中,指定templates和static目录,新增WEBPACK_LOADER:

这样Django会从/static/js/dist/读取Webpack生成的文件。接下来配置Webpack,在目录中新建webpack.config.js,内容如下:

Usage 在当前目录执行webpack(全局或是项目),会自动读取/static/js/src/index.js,生成/static/js/dist/main.dev.js。当然,现在会报错提示找不到entry,要创建对应的js文件,以下只写了import语句来验证loader已经加载:

执行后在dist中生成js文件。现在要自动把生成的文件(bundle)加载到模板,django-webpack-loader使用template tag的方式来实现。创建一个模板文件,内容为:

这样生成的js文件就会以script标签的形式自动插入当前模板了。Webpack执行的结果(通过webpack-bundle-tracker)会写入webpack-stats.json文件中,Django运行时会读取这个json文件,如果出错会抛出500错误。 Extension render_bundle也接受参数来指定文件扩展,可以处理css文件。例如要在Django中使用AdminLET,执行以下步骤可以通过Webpack来加载:

上列命令安装AdminLET和需要的loader,因为css文件中通常都会指定图片文件(还是字体等),所以还需要url-loader/file-loader。extract-text-webpack-plugin用来把css合并到一个文件中。 修改webpack.config.js:

最后修改/static/js/src/index.js文件和模板文件:

可以看到按钮已经应用了样式。

Continue Reading
Tech

Python读取Outlook的日历

公司的会议预订系统使用Outlook,要读取这些预订记录传到部署在阿里云的数据库。Exchange服务器没办法从外网访问,就在内网某台机器上写了一个脚本,定时执行,来从Outlook中读取日历上的预订记录。 模块:pywin32 (http://sourceforge.net/projects/pywin32/) 环境:Windows 2008 + Outlook 2013 + Python 2.7.8 Filder & Items 因为从来没做过Windows开发,所以先看了一遍文档,主要的概念是Folder(https://msdn.microsoft.com/EN-US/library/ff866772.aspx)。 所以其实就是要读取Outlook中名为Calendar的Folder,要获得会议预订记录,取出Folder的Items进行迭代就可以了:

Continue Reading
Tech

Linux设置iBeacon支持微信摇一摇

今年微信的摇一摇开始支持iBeacon了,淘宝上冒出一堆卖iBeacon基站的店铺,价格也比之前便宜许多。只是在开发测试阶段,直接用现有的设备会更简单,手头有一个USB蓝牙适配器,于是用Linux机器改造成iBeacon基站了,本文记录设置的步骤。前两年iBeacon刚发布的时候,有篇很火的文章指导如何用Raspberry搭建iBeacon基站(DIY Beacon with a Raspberry Pi),本文有参考那篇文章,只想实现iBeacon基站,不关注微信设置,也建议直接看原文。 蓝牙设备需要支持BLE(Bluetooth Low Energy,低功耗蓝牙)且是4.0版,我买的这个是CSR8510芯片,淘宝价格30元以内。以下设置在Ubuntu 14.04,Openwrt(ZTE Q7+r47026)和Raspbian(cb799af)中测试通过。一些APP(例如beacon-toolkit)和脚本(例如linux-ibeacon)可以简化配置。 微信设置 首页进入微信摇一摇后台(https://zb.weixin.qq.com/nearby/index.xhtml),点击左侧『页面管理』进入页面点击,点击『添加页面』按钮新增一个页面,跳转到dmyz.org:

Continue Reading
Python Tech

Python,Javascript(NodeJS),PHP之间的AES加密解密

场景是现有的几个项目,微信企业号是PHP,广告数据处理平台是Python,其中的Web API部分是NodeJS。现在这几个应用之间要传递数据,基于安全考虑先用AES加密,接收后做解密处理。本来预想是一个很简单的工作,库都是现成的,但发现网上的代码要么是不全,要么是padding处理不一致,所以最后还是自己看文档来写的,分享其中的核心代码,有类似需求可以直接拿去用。 AES AES的介绍可以参看Wikipedia: 高级加密标准。这种加密方式需要指定Key(密钥)和IV(初始化向量),解密时使用同样的Key和IV进行解密。其次需要padding(填充字符),网上一些代码是用空格或者大括号做padding,解密后再用rstrip/rtrim/replace清掉,但用标准的PKCS会更好。

Continue Reading
Python Tech

Django+MySQL安装配置详解(Linux)[更新为1.8.2版]

Perface Django是一个开源的Web应用框架,由Python写成,并于2005年7月在BSD许可证下发布。Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django采用MVC设计模式注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don’t Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。本文介绍Django在Linux(Ubuntu 14.04.2)+MySQL(5.5.43)环境下安装、配置的过程,包括安装、运行、添加应用的所有流程,最终建立一个可以从MySQL读取文章并显示的Django应用。文章面向刚接触Python/Django的初学者,所以安装过程都以默认环境为主,用pip可以简化安装过程。 Install 首先下载Django,得到Django-1.8.2.tar.gz,后解压并安装 $ wget https://www.djangoproject.com/m/releases/1.8/Django-1.8.2.tar.gz $ tar xzvf Django-1.8.2.tar.gz $ cd Django-1.8.2 $ sudo python setup.py install 如果提示缺少setuptools还要下载安装setuptools(建议提前安上,因为在安装MySQL for Python的时候也会用到)。

Continue Reading
Python Tech

Django 1.7 自带migrations用法及源码

Django下一个版本是1.7,增加了类似South的migration功能,修改Model后可以在不影响现有数据的前提下重建表结构。这真是个千呼万唤始出来的feature了,所以做个简单的整理分享。文章包含部分源代码,对具体怎么实现不感兴趣可以忽略。 Prepare 从Django官网或直接pip下载1.7b版本,创建project和app: $ pip install https://www.djangoproject.com/download/1.7b2/tarball/ $ python manage.py startproject dmyz $ cd dmyz/ $ python manage.py startapp articles

Continue Reading
Python Tech

Python.org的相关技术

Python.org使用了Django框架,基于Python3.3开发,是在生产环境应用Python3+Django的好例子,所以clone了它的源代码来学习,使用的是868d254版,整理如下。 Deploy 搭建Python环境自然先想到virtualenv,但Python.org源代码根目录里有Vagrantfile文件,支持用vagrant来搭建环境。虽然之前做ROR的环境时都配好了,但Python.org的配置用vagrant 1.0.1版本运行会出错,升级成最新的vagrant 1.5.1就正常了,执行vagrant up命令会自动下载Ubuntu 12.04 64bit来部署:

Continue Reading
Tech

Hadoop(Pig)统计IP地理位置

很常见的分析需求:日志中记录有访客IP(国内),现在要根据IP地址得出访客的地理位置,精确到市县一级,数据量平均是每天15G,需要统计日、周、月的结果。 最后的实现方式是,先找到IP地理位置数据库,包含每个ip段对应的地址:1.1.0.0,1.1.0.255,福建省然后把它转成具体每个IP对应的地址,即:1.1.0.1,福建省。这样在Pig中用JOIN的方式,就可以获得这个IP实际对应的地址了。 IP Database 12年成立的中国广告协会互动网络分会IP地理信息标准委员会(简称IPB)已经发布了IP地理信息标准库,委员会成员和大广告公司都有一份。也可以下载全球城市ip库,取其中CN部分: 文件信息:cn.csv 大小:1.26MB 有效时间:永久 读取这个文件,把ip转成数字,起止ip的差,就是这个ip段所包含的主机数,用range函数生成,主要的python代码如下:

处理结果会保存在out.csv文件中,中国地区总共有3亿个IP,生成的文件是7.9G,gz默认压缩后是900MB左右,按Map需求进行分割。 Pig Latin LOAD保存在hdfs中的日志文件(*.log.gz)和IP数据库(ip*.tar.gz),將日志文件中的访客IP转成数字,用JOIN方法组合,再做GROUP和COUNT的操作,就可以得出该地区的访客数了:

耗时44分33秒,统计出一周的结果: (北京市,32174022) (保定市,4244694) (邯郸市,1062551) Job Name: PigLatin:ip.pig Job-ACLs: All users are allowed Job Setup: Successful Status: Succeeded Finished in: 44mins, 33sec Job Cleanup: Successful Afterword 之前尝试做一个Pig的UDF,用{IP : CITY}形式的字典来做IP到城市的匹配,但JAVA函数大小有限制,而且用UDF会影响性能,所以没有采用。如果是自己写REDUCE来支持类似传统SQL中JOIN BETWEEN的方法,就不需要生成这个3亿多条记录的文件了。以上是在一个很小的测试Hadoop架构中进行的处理,理论上在实际生产环境可以处理得更快。

Continue Reading