微信后端存储架构学习

学习了解一下微信的后端存储架构。使用微信的过程中就能发现微信不像QQ并没有漫游所有聊天信息,记录基本完全是在本地存储的,因此后台存储难度应该不大。
视频与ppt地址,演讲人微信基础平台组许家滔sunnyxu

主要介绍内部产品QuorumKV,具体关注kv系统的强一致性。

需求背景:微信全球数据布局分在上海,天津,深圳,香港,加拿大,乃至同城多园区分布等等

系统要求:分布式强一致性(不需要应用层再设计),同城园区灾备,类SQL查询

存储信息:聊天记录,通讯录,个人信息,朋友圈

存储介质:包含mem,ssd,sas

增加数据流程:实现方法为分组
序列号发生器:微信后台与终端交互使用序列号进行数据同步,偏序,实现方法为仅一个client操作
(如果还要实现后来这些需求,前面这些hack实现是否有必要?)

修改value:1.可以覆盖;2.可以根据条件修改;实现方法为每次变更选举(by key),分为1.检查版本号;2.向集群发出请求;3.收到请求检查版本号;4.返回选举结果;5.推送结果;(类似Raft?)

问题:容灾成本仍然高(预留机器空间)

权衡点:自治,负载均衡,扩散控制

解决方案:六台机作为一组(挂一台20%增长)跨园区跨机分组

数据sharding:均匀分布指定分段(先算好后直接用,更好可以用hash ring,为何不用一致性hash?可能不均匀与冲突,负载均衡问题),希望终端无状态可以方便的重启防止内存泄露

系统架构图

底层使用所谓bitcask(内存索引加顺序写),同时使用小表系统解决写放大问题

同步流量要求幂等,为每个数据块记版本号,在某个版本号进行某个操作,保底策略:某台机器刚启动问题会要求对端发完整数据块

通信包量:读写的动态合并

异步化:协程,libco

Zookeeper系统的优点

Zookeeper系统应用越来越广泛,在同一领域内开源软件方面基本没有其他选择处于垄断地位,但是实际用过的人都会觉得这个软件属于可用但又不那么好用的类型。本文是本人结合自己的实际使用经验与思考,同时参考真正大牛对这个系统的分析与评价进行的总结,主要还是想归纳一下真正的使用需求并思考相应对策与改进的办法。

1.常见应用场景

先归纳一下工程应用中常见的Zookeeper使用场景(以下简称ZK),这里按照个人感觉应用的频率从高到低排序说明。

  1. 可靠存储

    在实际使用中可以表现为配置管理、名字服务,这种应用完全是因为ZK多备份的可靠性强。当然也可以利用回调机制在数据变更时可以进行全体通知。实现起来非常简单而且很有效,所以是应用最广的场景。

  2. 集群管理

    利用ZK的通讯与回调机制完成分布式集群的机器状态监视,甚至很多系统中做主从备份时都会在ZK中注册以方便做热备切换。

  3. 服务注册发现管理

    由可靠存储加上通知回调机制其实满足了服务注册发现的最基本需求,某些在本人看起来不那么靠谱的应用场景,居然也在采用ZK实现。大有一统天下之势,所有类似的需求都开始采用ZK方案,比较出名的系统比如国内的Dubbo和国外的Kafka(居然还把ZK用在了负载均衡上面)、jStorm、Heron(twitter)等等

  4. 选主服务

    选主服务是ZK参考的原始系统Chubby设计出来最初的应用需求,当时是满足BigTable的master选主。ZK最初也是用在HBase里面,而后所有需要选主服务的都在采用,很多KV系统用来方便从多节点中选择一个中心节点(但是本人还真没找到什么)。
    需要注意的是有时选主服务在讨论里也被称为分布式锁的一种,很容易混淆概念。的确使用ZK来实现选主服务(实现方法最好跟分布式锁的方法完全一样,这里官方文档都曾经犯过错误)客观上遵循了时间优先原则,但是实际需求并非一定要满足这条,只要保证关键的唯一性就可以了,因此与同步意义上的锁很是有不同的。

  5. 分布式同步机制

    即真正的分布式锁,但是实际应用并不常见。本人实现过几次,目前准备运用在表单提交的同步上。

  6. 负载均衡

2.特性设计与优势

ZK主要使用场景远不是满足最初设计时对一致性调解的需求,这么受欢迎是因为其灵活的特性设计,只要简单组合就能满足很多种需求,同样将特性的受欢迎程度按照个人感觉从高到低进行说明

  1. 通知回调机制

    通过创建节点与设置Watcher可以很方便的建立回调通知。ZK的所有应用都基于这个特性,没有这个机制那么机器监控相关的应用都不能处理,也就不会诞生后来在服务注册发现相关的使用方法。实际上为分布式系统提供节点间回调通知方法的系统真的很少,甚至可能只有ZK(大家可以提供一些其他答案?)

  2. 可靠存储

    系统设计最初的需求之一,也是ZK特性中实现最好的部分,作为可靠存储ZK基本没出现过问题,仅此一项就可保证其的流行。

  3. 连接状态维护

    ZK自动维护了客户端所在的应用与服务器通信连接状态的变化,可以比较简单地维护系统中的成员通信情况。主要是不需要自己再去处理麻烦的通信状态监控问题,比如断线后自动释放节点并产生回调。

  4. 文件系统模型

    提供文件接口模型而不是锁接口,更具通用性。文件系统模型中文件与目录的概念可以映射多种含有层级关系的其他模型

  5. 自增长序列

    这点包含了锁的本质,但是因为zk的模型设计导致判断与仲裁需在客户端进行

3.实现技术选择与优点

zk本身的系统特性设计很出色,同时选择的实现技术也比较扎实,可谓蕴含相当的分布式系统工程经验在其中。下面结合个人理解讨论下这些实现技术有哪些特别优点与选择时可能的设计思路。

  1. 通讯机制与状态的实现
    基于jute进行编解码处理保证通用性,服务器端通信使用nio或netty都是标准选择。

  2. Zab协议与Paxos
    zk使用Zab协议保证部署的多台机器间构成的整体系统的一致性与可靠性。这个分布式协议类似Paxos但是更加具体有效,实际上Paxos工程实现会碰到很多协议中没有定义的问题,G家员工为在Chubby中使用Paxos算法甚至专门发了一篇文章来说明Paxos工程化踩了多少坑。
    Zab协议中将选主阶段与正常运行之间的阶段用catch up方式进行弥补,而关键的选主阶段使用了一个极其工程化的算法“fast leader election”(这个算法似乎没有经过形式化证明),这个算法足够粗暴有效,实现起来很简单。
    最近Paxos的工程简化版算法Raft很火,所有考虑使用Paxos的系统都在实现Raft协议,其过程与Zab协议很类似,但是选主算法更加简单(可能实现结果是比Zab选主更慢)而且无法如Zab一样简单替换这个部分的算法。个人看法是Zab协议比Raft更容易理解,而且容易工程实现。(为何没有Raft火爆?值得研究,但是Raft目前还没有工业级的系统验证!)

  3. 使用JVM
    zk作为一个以稳定性与一致性为主的系统,性能上面肯定有一点损失。相信大家实现这种系统首先都会考虑要利用语言本身的速度优势尽量弥补系统的性能损失,于是我们就能看到很多c++实现的类zk系统(比如Chubby),但是这些新系统却没有zk的普及率。
    可以说zk的流行中很重要的一点就是牺牲部分可能的性能使用JVM作为底层。正是因为虚拟机的使用屏蔽了各种异构系统底层,让zk可以很容易的稳定部署在多台配置性能都可能各异的机器上。个人理解这也是为什么现在那么多分布式系统都基于JVM技术栈,分布式系统需求的机器多,不可能所有配置都一样,而且机器都需要很容易进行物理替换或是系统升级,目前还只有JVM可以非常简单的提供这种等级的虚拟化屏蔽。
    当然最近docker容器技术大放异彩,轻量级虚拟化方案以极快的速度兴起,让各种异构系统有了更简单可定制的底层虚拟化方式,也许有可能改变分布式系统的底层技术栈。

4. 参考资料

  1. 可靠消息队列浅谈
  2. 为什么不应该使用ZooKeeper做服务发现
  3. 持续可用与CAP理论 – 一个系统开发者的观点
  4. Kafka深度解析
  5. Zookeeper架构设计与应用要点
  6. Zab vs. Paxos
  7. 架构师需要了解的Paxos原理、历程及实战

TCP/IP网络栈实现

参考 翻译:理解TCP/IP网络栈&编写网络应用一文内容。

1. TCP/IP的特性

  1. 面向连接
    这里的连接用什么结构管理?
  2. 双向字节流
    字节流是什么意思?
  3. 顺序投递
    能够完全遵循时间顺序投递?
  4. ACK实现可靠性
    怎么可靠?
  5. 流量控制、阻塞控制

2. 数据传输流程

网络栈很多层
image

内核层使用socket(因为抽象成文件,会走VFS路径)来管理从用户区拷贝过来的接收与发送的数据缓冲区,socket会关联一个TCP控制块,其包含TCP连接的所有状态数据。(基本回答问题1)

TCP中允许情况下会创建TCP segment,包含两个部分:TCP头+数据,注意TCP校验和不会中内核中算出,会offload到NIC中处理
image

创建的TCP分段进入IP层中增加IP头,然后执行IP路由(之后下一层是链路层增加链路头,至此形成完整报文)在执行IP路由时回选择一个NIC传输接口,这时会调用NIC驱动程序。如果此时有抓包程序则会在此层进行数据拷贝处理。驱动程序与内核通过请求NIC定义的通讯协议进行传输。

NIC会从系统内存中拷贝数据包,向数据包中增加帧间隙(Inter-Frame Gap,IFG),同步码(preamble)和crc校验和。帧间隙和同步码用于区分数据包的开始(NIC目前是在哪一层?)。NIC会在主机的CPU上产生中断。驱动程序在启动时会注册一个处理中断的函数。操作系统调用中断处理程序,之后中断处理程序会把已发送的数据包返回给操作系统。

除了应用程序直接调用write之外,内核也可以直接调用TCP传输数据,比如接收到ACK并且得知接收方的接收窗口增大之后,内核会创建socket缓冲区剩余数据的TCP片段并且把数据发送给接收者。

3.数据接收流程

NIC接收到数据包后计算CRC,然后拷贝到驱动提前向内核申请的缓冲区中,之后NIC发出中断。驱动程序会判断它是否能处理新的数据包。
image

驱动向上层发送数据包时,Linux的sk_buff,或者BSD系列内核的mbuf,或者windows的NET_BUFFER_LIST。驱动会把数据包包装成指定的数据结构,并发送到上一层。

之后数据链路层,IP层同样检查数据包是否有效,最后到TCP层查找到对应的TCB,socket接收缓冲区的大小就是TCP接收窗口。TCP吞吐量会随着接收窗口变大而增加。

4. 流量控制

image

步骤3即使用定时器超时机制

5. 中断处理

中断比较复杂,例如NIC接收数据产生中断,驱动在释放已经传输的数据包之后调用napi_schedule()函数去处理接收到的数据包,这个函数会请求软中断。
image

在中断上下文被执行之后,软中断的上下文会被执行。中断上下文和软中断上下文会通过相同的线程执行,但是它们会使用不同的栈。并且中断上下文会屏蔽硬件中断;而软中断上下文不会屏蔽硬件中断。

处理接收到的数据包的软中断处理程序是net_rx_action()函数。这个函数会调用驱动程序的poll()函数。而poll()函数会调用netif_receive_skb()函数,并把接收到的数据包一个接一个的发送到上层。在软中断处理结束后,应用程序会从停止的位置重新开始执行完成系统调用。所以才有多队列NIC以解决软中断并发处理瓶颈问题。

金融市场基础

##金融市场

  • 一级市场 即证券发行市场
  • 二级市场(security market) 即证券交易市场
  • 期货(futures)标准化交易合约,由期货交易所统一制定

    • 上期所 黄金白银、钢等金属、橡胶、燃料油
    • 郑商所 早灿稻、小麦等、玻璃
    • 大商所 玉米大豆、焦炭、焦煤
    • 中金所 股指、国债
  • 期货基本制度

    • 保证金
    • 每日结算
    • 实物交割
    • 强行平仓
  • 实物交割(physical settlement) 保证期现货价格趋向一致
  • 现金交割(Cash settlement) 股指期货可以现金交割
  • 杠杆交易(leverage)国际融资杠杆比例20~400
  • 保证金(margin) 仅为押金不作为合约金
  • 增补按金(margin-call) 同追加保证金,保证金按维持持仓金额的比例计算,要求在下一交易日前将保证金补足 ??保证金不是不参与交易吗??
  • 空头交易(short sale)即卖空交易
  • 定向增发(private placement)上市公司向少数特定投资者非公开发行股份,规定发行对象不能超过10人,发行价不能低于公告前20日交易市场价90%,12个月内不得转让
  • 衍生品(Derivative)远期(非标准化)、期货、期权、掉期
  • 实值期权(in-the-money)即价内期权,执行价与远期价相较有利的期权 期货价格高于执行价格的看涨期权以及期货价格低于执行价格的看跌期权为实值期权。
  • 虚值期权(out-of-the-money)即价外期权 期货价格低于执行价格的看涨期权以及期货价格高于执行价格的看跌期权为虚值期权。
  • 量化宽松(Quantative easing)中央银行在实行零利率或近似零利率政策后,通过购买国债等中长期债券,增加基础货币供给,向市场注入大量流动性资金的干预方式,以鼓励开支和借贷,也被简化地形容为间接增印钞票。量化指扩大货币发行,宽松指减少银行压力,通常在利率等工具不再有效时使用
  • 基本面分析 适用于周期相对比较长的证券价格预测、相对成熟的证券市场以及预测精确度要求不高的领域
  • 借壳上市 指一间私人公司(Private Company)透过把资产注入一间市值较低的已上市公司(壳,Shell),得到该公司一定程度的控股权,利用其上市公司地位,使母公司的资产得以上市。通常该壳公司会被改名。

宏观经济

  • GDP
  • CPI
  • 新兴市场
  • 同比 环比
  • 流动性
  • 金本位

交易规则

  • 深市时间:9:15 ~ 9:30开盘集合、9:30~11:30、13:00~14:57连续、14:57~15:00收盘集合
  • 接收会员竞价申请时间:9:15~9:25、9:30~11:30、13:00~15:00,只有连续竞价阶段允许撤销
  • 市价申报、限价申报
  • 100股为申报基本单位,债券、回购申报以10张为基本单位
  • 债券交易分为净价交易、全价交易
  • 盘中临时停牌复牌集合竞价
  • 集合竞价所有交易以同一价格成交
  • 协议大宗交易,指定交易对手方,9:15~11:30、13:00~15:30
  • 盘后定价大宗交易,当日收盘价逐笔连续撮合,15:05~15:30
  • 盘中停牌涨跌超过20%,临时停牌至14:57,复牌集合竞价再进行收盘集合竞价
  • 9:25前停牌,当日复牌实现开盘集合竞价,复牌后继续当日交易;9:30后临时停牌,盘中集合竞价,复牌后继续当日交易
  • 交易信息:即时行情、证券指数、证券交易公开信息

财务分析

利润表

营业收入-营业成本=毛利,最能反映盈利能力

  • 毛利率方便同行业比较,变动趋势及同行业对比是利润表分析的重点

  • 营业利润反应企业主要经营活动的盈利状况, 其中“公允价值变动损益+投资收益+汇
    兑损益”三个科目如果是损失的话,会在报表上以负数列示。资产减值损失为负表示资
    产减值损失的转回,是操纵利
    润的一个经典方法。

  • 营业利润+营业外收入-营业外支出=利润总额 反应企业总体的盈利水平

  • 利润总额-所得税=净利润,反正归属于政府的所得税费的部分,剩余可以供企业自己
    支配的盈利,该部分金额可用于支付股利等。

具体步骤:

  1. 从净利润入手,看盈利是正或是负,是哪些项目具体导致了净利润的正负
    水平
  2. 分解利润表为四部分(毛利率、营业利润、利润总额、净利润),看具体科目的“变动趋势+具体性质”来判断企业的经营状

盈利分析为什么相对重视毛利率而不是净利率

一个企业的投资回报取决于两个因素:效益(毛利率),效率(周转率)。

为什么要引入EBITDA EBITDA=净利润+利息+所得税+摊销+折旧,排除了非付现成本,资本结构以及政府因素的影响,可以看作是经营性现金流量的模拟,因此非常受到投资者的关注。实际工作中,我们会识别利润表中非经常性的项目,将EBITDA调节为正常化后的EBITDA, 用于企业价值的评估。

资产负债表

资产(流动资产+长期资产)=负债(流动负债+长期负债)+所有者权益
(净资产)

企业资产=债权人+股东

重点关注:

  1. 应收账款/存货: 减值风险与周转率、周转天数(营运能力分析)
  2. 长期资产(在建工程与固定资产):减值风险与折旧摊销(影响利润:如
    京东Non-GAAP收入)
  3. 负债分析:分析金融负债与非金融负债(偿债能力分析: 流动比率与资产
    负债率,国内50%左右,跟行业相关)

其他关注点:
a.资产报酬率
b.营运资本(流动资产-流动负债)与净营运资产(应收-应付)

现金流量表

与利润的关系

三大活动:经营,投资活动与筹资活动

利润表重点分析:

  1. 收入趋势与毛利/净利率变动分析
  2. 盈利质量分析

资产负债表重点分析:

  1. 营运能力:存货周转率/应收账款周转率
  2. 流动性与负债比例分析:资产负债率与金融负债率(短期借款);营运资金;
  3. 净营运资本分析:资金缺口
  4. 长期资产分析:减值风险/摊销折旧;投资政策分析(Capex)
  5. 资产减值风险

现金流重点分析:
三大活动占比分析

产品结构

银行

券商

基金

信贷

公募

私募

2015 shen JSconf总结(第二天) 

第二天干货非常多,全是实战经验,基本没有什么技术介绍。

##Part Two 2015-07-12

###1. 七牛前端测试实践 - 马逸清
angularjs dom隔离,测试不需mock;依赖注入可以mock (service, controller) 可以使用stub

stub适合返回值依赖,mock行为验证

官方jasmine
View状态测试

phantom,sinon(stub),fixture(karma)

###2. Node Profiler - 朴灵@阿里云alinode
hack了部分v8代码,跟CPU Profile相关

  • 常用工具: benchmark.js,node-webkit-agent,ab/wrk(压力测试),–prof & mac-tick-processor(v8)
  • v8以JIT方式执行js(产出机器码),以函数为单位处理
    Crankshaft架构(可以运行时优化 fulCompiler -> optimizeCompiler) P:bailout, deoptimize
  • Profiler: 更多函数状态,优化建议(v8能否优化) http://alinode.aliyun.com
  • (program) 系统空转

? 第一次访问测试

###3. P2P pipes - mafintosh(dat)

demo: multiplayer game(socket)
websockets, webrtc

**ndjson, nc, crypto, dupsh(two app in-out pipe), airpaste(udp multicast with pipe), blecat(blutooth with pipe), webcat(webrtc with pipe)

###4. 微服务架构下的服务通信 - 老雷leizongmin @ucdok.com/ superid.me一登
后台Node逻辑
SDK - 多进程?- API服务器(人脸识别模块)

=》 SDK - API服务器 -人脸识别进程(多线程)

=》 - 更多应用(后台微服务架构)

–> 服务注册(消息队列总线式 / P2P)+远程调用

实现原理

总线可以用redis实现,通信也用redis订阅机制(服务提供者可以动态加入)
vs amqp-rpc, eureca.io

未来:备份切换,数据量太大

服务发现 + 服务通信

ppt地址 github.com/leizongmin/clouds

etcd + k8s + docker

###5. 前端服务化之路 - Herman@阿里CXDC 客服中心

前后端分离-》前端给后端提供接口(服务化)-》web component
**flipper.js 支持IE8以上 – webcomponents.js 更好的隔离性

###6. JS lang - hax贺诗俊@百姓网
NodeJS + CommonJS -> ES6 module( class, arrow function[this bind], map/set, for..of..[for in] )

WebAssembly

babel(es6 compiler)

###7. JS on Fiber - 庄恒飞@孢子社区fibjs-> 那么社区named.cn
fibjs vs nodejs, Fiber-Driven,No Callback

  • Module lib: CommonJS,async require
  • coroutine.parallel 【改变nodejs单线程】多CPU利用率
    js,用
    brew install fibjs [http://fibjs.org]
    fibjs底层多种线程(fiber) -> js线程-》work线程池【实际改动了v8下一层,解决了nodejs的callback与计算密集】

##Lighting Talk

  1. tangrui.net (js in JVM: 1.6 ringo 1.8 nashorm(vert.x/avatar.js)) cde.io
  2. wangyan @oneapm.com (npm2dot) 转换dot格式
  3. dafeng @strikling.com “GraphQL & Relay”: restful api问题:依赖多次发送->custom endpoint-》 GraphQL帮忙管理
  4. homlinju @fontmin js方案的字体最小化
  5. 一狂 @阿里cxdc www.zouyesheng.com angular问题:不单单使用,模块化加载,自己的渲染机制,怎么合作?模块内定义dir最后手动触发bootstrap
  6. EvanYou @vue webpack vue-element.js
  7. xeodou crazyapp.net/#/explore

###8. Persistent data structure in JS-NiYue@splunk
persistent data structure [like COW] -> concurrency
real good:

  1. performance(判断状态是否变化)
  2. features on copy(undo/redo,recording/reply,time traveling)

实现策略:COW -> structual sharing
问题:内存消耗,内存回收

mori, Immutable

一页千级dom元素?
LightTable演示

###9. WebIDE with React - hulufei @coding.net
React - Flux - karma

Components: <WebIDE/>

1
2
3
4
5
var App = React.createClass({
render: function() {
<div><Menu/><Tree/></div>
}
})

Flux: Dispatchor -> store -> view -> action
<Editor/><SettingModel/> 通信:
SettingStore -> SettingAction

Addons: store或action引用API层

roit, ace rather than codemirror
QA:store划分标准:组件需要,共享; 数据放store里面方便做数据缓存,返回promise;Flux写太多模板代码;

###10. WebGL & WebVR - Martin @Zurich - archilogic.com @g33konaut

faces + vertices -> GL buffers -> shader code -> print

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var renderer = THREE.WebGLRenderer();
var box = new THREE.Mesh(
new THREE.BoxGeometry(100, 100, 100),
new Three.MeshBasicMaterial()
);


scene.add(box);

var light = new THREE.PointLight()
light.position.set();
renderer.render(function(){
box.rotation.y += Math.PI / 200;
});
//OBJMITLoader()

//VR
var vrEffect = new THREE.VREffect(render),
vrControls = new THREE.VRControls()

###11. maintainable nodejs - 死马 不四@天猫前端,dead-horse@github koa
提供固定的输出

异步try-catch -> promise 可以传递error
默认的错误监听函数,可以利用事件方式让外层感知

bluebird, co

2015 shen JSconf大会总结(第一天)

两个星期前7月11~12日在深圳前海举行了第四届中国jsconf会议,第一次参加纪录一下学习内容与个人思考。本次会议由李学斌(hk)推广,wiredcraft公司承办

##Part One 2015-07-11

###1. Database everywhere - EvanYou@Meteor

  • UI - Client data - Server data (sync)
    Solution: UI - Client data (react, angular, vue)
  • How about Client & Server data?
    REST (Backbone Model, ngResource, Restangular, Flux Stores)
    pull-centric imperative/ trouble with non-conventional APIs/ difficult managing optimistic updates
  • IDEA: UI - Server data (GraphSQL, JSON Graph, Om Next) not ready

METEOR: DDP, Tracker, minimongo(both cli& ser)
UI - minimongo - Server data

publish & subscribe? component-level template

$meteor.collection(new Mongo.Collection("Task"))
Tasks.find().fetch() ???

QA: actions record -> rollback

ppt地址 Slide.com [http://slides.com/evanyou/shenjs]

###2. ES6 generators - BIHOLT@Netflix
node 0.12
as ES2015

  • generators: async pro -> sync
    (Meteor, Babel use Regenerator)

a function return a generator obj which is iterable

1
2
3
4
5
6
7
8
9
const colorGenerator = function*() {
for (let color of colors) {
yield color;
}

}
let generator = colorGenerator();
//use generator.next();
//let values = Array.from(generator);

simulate ES7 asyc/await

1
2
3
4
5
6
7
8
co(function* (){ 
let user = yield promiseAjax.get("url");
handleUserData(user);
});

async function() {
let user = await promiseAjax.get("url"); handleUserData(user);
}

solution: gen store state between calls!

//for WebSockets or polling
function *poll() {
    while(true) {
        let id = yield;
        req.get(id).accept('json').end(function(err, data){
        logger.next(data);
        })
    }
}
let poller = poll();
//use poller.next(); poller.next(id++)

also call .return() or .throw()[inject into]

ppt地址 speakerdeck.com/btholt

##Lucky Draw
raffle.js漏洞百出

###3. Koa&Toa - Yan
vs express req, res, next P:异步流程控制

  • koa this, yield next generator 函数 每个中间件可以分为前后两部分,都可以终止 P:流程复杂,第三方暴露
  • toa vs koa this, yield 回到body this.body

异步原语:

  • promise 标准接口,链式返回promise,任意多promise组合(多异步)
  • thunk 新callback形式,返回thunk函数(thunk(function(callback){ return Promise //thunk}))
  • generator (function *() { yield promise })

###4. AngularJS real-time app - loddit(BohanLi)@BearyChat
demo: 二维码刷新 meteor

api server – RPC – keep-alive ser

Protocol: XMPP / IRC , DDP(Meteor)[quick demo], CRDT(Swarm.js)

Ping/pong to check, use object as singleton, push for everything

Q:分组,消息等信息:普通Obj, Array;事件类型太多(命名,gonn);

Q:交互性能:减少watch(改用ng-switch);消息丢失处理:长连接保证,update时序更需要保证;

###5. PM2 - alexandre@Keymetrics
a process manager dedicated to Node.js [distributed!]

##NodeBot Session - ajfisher
NodeBots stack [<3] IO Plugin – NodeJS (Johnny Five) – HTTP – clients

  • Adurino.cc IDE
  • npm install jornny-five -g
  • nodebotsday.com
  • github.com/jsconfcn/nodebots-session

##light talk

  1. undoZen (require('co'); co.wrap(fun);)
  2. zhangwenli.com/Polyvia vs Naive Random Method
    selected vectile (webgl sobel edge) -> dynamic -> center of mass 视频淘汰率
  3. pmq20 body.toString()
  4. socket 1000连接问题? ulimit 设置!默认1024
  5. 输入法 js
  6. Zearlin/重鱼

###6. NodeJS 分布式应用 - WenTianle@UCloud

C++ -> 分布式RPC架构(配置管理,服务自动发现,自动扩容,脚本)
umaster/zookeeper cluster 名称服务 -> rabbitmq/zookeeper 服务异构(扩容)/配置管理

node-amqp 3.4.1

遇到的问题

  1. nodejs [protobuf extension]
  2. 异步编程效率[Fibers]
  3. nodejs 内存泄漏(网络框架中回调函数导致)
  4. 异步超时处理(定时清理?)
  5. 异步中日志记录(Fibers包装为task queue,带上其id)
  6. rabbitmq ha(ser HA-》cli HA ip选择来解决100s定时断问题,heart beat时间约定机制)
  7. rabbitmq ha 网络闪断导致节点分区
  8. zookeeper session expired 网络断导致,client重连成功后由于session key不同导致server要求再次重连,同时产生一次session expired回调 容易导致内存泄漏

###7. JS Frameworks - Eyalarubas.com@EF
全是吹水,外国人包装能力真强!

###8. 前端可视化技术 - pissang @Echarts.baidu
Canvas vs SVG

  1. 性能考虑,特效绘制,像素操作
  2. demo:尾迹特效(保存上一帧,另一个canvas alpha值调整),热力图(像素操作)

问题: 没有图像对象(层级,样式,变换),事件

解决:图像对象管理(借鉴SVG方法),事件绑定(容器绑定代理,反向循环判断鼠标是否在某图像上,这时要将鼠标进行坐标变换-> 包围盒判断 / 路径的精确判断,js实现isPointPathisPointInStroke 不需要重新构建路径)

latest: Path2d

WebGL

  1. 加速二维图像绘制
  2. 问题:Shader计算动画小点位置

demo: lambertShading

2D图形处理:Meth -> canvas surface -> canvas -> 2D objects

9. NERD Disco - TimPietrusky@

  • web audio
var audio_context = new AudioContext();
var audio_anay = audio_context.analyser();

try ndAudio -> ndVisualization -> NeoMatrix Adafruit (nodejs server)

try web mini api

AnyNote数据库与API设计

参考Typecho设计数据库

note:

  • nid 自增
  • title
  • name
  • content
  • created
  • modified
  • date
  • order ?
  • uid
  • type 类型
  • template 使用的模版 ?
  • status
  • pwd
  • parent 多种用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `test`.`an_notes` (
`note_ID` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'note id',
`user_ID` BIGINT(20) NULL COMMENT '',
`note_title` TEXT NULL COMMENT '',
`note_name` VARCHAR(200) NULL COMMENT '',
`note_content` TEXT NULL COMMENT '',
`note_status` ENUM('publish', 'draft', 'private', 'static', 'object', 'attachment', 'inherit', 'future', 'pending') NOT NULL DEFAULT 'draft' COMMENT '',
`note_date` DATETIME NULL COMMENT 'publish time',
`note_modified` DATETIME NULL COMMENT '',
`note_created` DATETIME NULL COMMENT '',
`note_parent` BIGINT(20) NULL COMMENT 'can be used in many ways',
`note_type` VARCHAR(20) NOT NULL DEFAULT 'post' COMMENT 'revision, comment, chat, …',
`note_template` VARCHAR(45) NULL COMMENT '',
`note_mine_type` VARCHAR(100) NULL COMMENT 'image, doc…',
`note_comment_status` ENUM('open', 'closed', 'registerd') NOT NULL DEFAULT 'open' COMMENT '',
`note_inherit_status` ENUM('open', 'close') NOT NULL DEFAULT 'open' COMMENT '',
`note_pwd` VARCHAR(20) NULL COMMENT '',
PRIMARY KEY (`note_ID`) COMMENT '');

[wp怎么实现的post多版本?个人思路:type=”revision”]

Revisions are stored in the posts table.
Revisions are stored as children of their associated post (the same thing we do for attachments). They are given a post_status of ‘inherit’, a post_type of ‘revision’, and a post_name of {parent ID}- revision(-#) for regular revisions and {parent ID}-autosave for autosaves.
By default, WP keeps track of the changes to title, author, content, excerpt.

revisions:

  • rid
  • nid-revision-# / nid-autosave-#
  • uid
  • content
  • diff

post: [post与note的一对多 github?]

  • pid 自增
  • title
  • content 由cid生成,包括style信息
  • nid[] ? 这块比较复杂,是否允许临时修改(redis缓存)
  • status

meta:

  • mid 自增
  • name
  • type tag, category, board, …
  • desc
  • parent

notemeta: [] tags/books

  • mcid 自增 仅优化用?
  • mid
  • nid
  • order ?
  • count
  • status

postmeta:

  • pcid
  • pid
  • mid
  • order ?
  • count
  • status

options:

  • oid 自增
  • uid 对应uid
  • key
  • value

user:

  • uid 自增
  • name
  • pwd
  • url
  • mail
  • screenName
  • created
  • logged
  • group
  • authCode
  • privilige 权限系统
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE IF NOT EXISTS `an_users` (
`id` INTEGER NOT NULL auto_increment ,
`user_ID` BIGINT(20) NOT NULL,
`user_name` VARCHAR(60) NOT NULL,
`user_pwd` VARCHAR(20) NOT NULL,
`user_url` VARCHAR(100) NOT NULL,
`user_email` VARCHAR(100) NOT NULL,
`user_nickname` VARCHAR(50) NOT NULL,
`user_created` DATETIME NOT NULL,
`user_status` INTEGER NOT NULL,
`user_authcode` VARCHAR(80),
`user_privilige` INTEGER NOT NULL,
PRIMARY KEY (`id`)) ENGINE=InnoDB;

API设计

url(/user)

  • POST /user/signin
  • POST /user/signout
  • POST /user/logout

url(/notes/:id)

  • POST /notes 创建
  • GET /notes 列表,分页问题
  • GET /notes/:id 获得
  • PUT/POST /notes/:id 更新
  • DELETE /notes/:id 删除

创建你的hexo博客

目前由于hexo的升级。在github上搭建hexo博客的过程与网络上的文章指导内容会有少许变化。

第一步当然还是安装hexo,接着在本地创建自己的hexo博客目录

1
2
$ npm install hexo -g
$ hexo init <YOU_BLOG_DIR_NAME>

然后切换到那个目录下面,安装必备的node插件

1
2
3
$ cd <YOU_BLOG_DIR_NAME>
$ npm install
$ npm install hexo-deployer-git --save

这时你的博客已经准备就绪啦,接着按照自己的需求修改配置文件,需要注意的是deploy部分

1
2
3
deploy:
type: git
repo: <YOUR_GITHUB_REPO_URL>

万事大吉,可以使用hexo new <POST_NAME>来创建新文章,写完后使用

1
2
3
$ hexo server #本地查看博客效果
$ hexo generate #生成静态文件用于部署
$ hexo deploy #部署同步到Github的项目上

有些遗憾的是这个git的deploy插件有点傻,仅把博客的静态文件提交到了远程仓库的master分支,而没有提交原始配置文件。没办法,只能自己动手进行分支同步。

1
2
3
4
5
$ cd <YOU_BLOG_DIR_NAME>
$ git init
$ git add remote origin <YOUR_GITHUB_REPO_URL>
$ git commit -a
$ git push origin master:<YOUR_REMOTE_BRANCHNAME>

好啦,以后任何位置都可以利用Github同步文章写博客啦

JavaScript实用代码片段

最近抽空在忙小项目,总结了下一些项目中碰到的常见问题,搜集对应的实用JS代码片段,跟大家分享。

1.产生限定范围内不重复的随机数

在深js也碰到了完全相同的问题,即抽奖程序的核心算法,结果是bug频出。这里给出js抽奖程序,大家去鄙视一下。
一种思路是在给定大小数组中每次抽取一个随机位置的数进行剔除,这个程序的问题是必须始终维护抽取的数组,好处是不会重复抽取:

var originalArray=[];
for (var i=0;i<len;i++) { 
    originalArray[i]= i; 
} 
var getRandom = function(){
    var index=Math.floor(Math.random()*originalArray.length); //随机取一个位置 
    var value = originalArray[parseInt(index)];
    originalArray.splice(index,1);
    return value;
}
有什么其他好方法不妨分享一下。 ## 2\. 数字保留两位小数 数字进行截断保留两位小数只想到如下方法
floatNum = Math.round(floatNum*100)/100;
但是还有情况是仅展示两位小数,这时只要用原生的API方法就可以了
floatNum.toFixed(2)

3. 触发change事件

这是在使用AmazeUI中按钮组时碰到的问题,按钮组并没有对应的js封装,所以点击div模拟的按钮并不能触发实际单选按钮的change事件,因此需要jquery来手动触发。估计Bootstrap应该有进行更好的封装吧。

$button.children().attr('checked',true).trigger("change");
这里使用`children`仅是为了获得包含在外层`div`下的单选按钮,还得设置check状态 ## 4\. 单选按钮选择信息获取 按钮组中究竟选择了哪一个可以使用下面代码获得
$('input[name="radio-options"]:checked').val()

5. 中文编解码

在URL中传递中文就需要进行URI编码转为16进制的数字表示

location.href = "result.html?u="+encodeURIComponent(name)+"&b="+invest_status.profit+"&r="+invest_status.rounds;
展示也得使用相应的URI函数解码进行
user = decodeURI(name);
发现不少浏览器现在已经支持直接在URL中插入中文,估计这里有些变化了。 ## 6\. 转换为数字类型 两种方法,一种是
option = parseInt(IntNumStr);
另一种是
option = Number(IntNumStr);
注意单选按钮的选择值就可以用这个方法进行转换 ## 7\. 浏览器url信息处理 主要是处理GET请求的分隔符"&"与值的获得,也就是运用`.split("&")`和`.split("=")`
infos = url.split('&'), user = (infos[0].split('='))[1];
搜到一个大而全的[处理工具](https://github.com/websanova/js-url) ## 8\. 网页title设置 直接给`document.title`赋值即可 ## 9\. 异步加载与性能优化 promise ## 10.文件上传处理

window.Blob slice
file

11. 多场景管理

12. 简单模板与双向绑定

MacOS体验

在Y460老笔记本上面加装内存并安装了固态盘,然后花了两天折腾MacOS安装。其实真的挺简单的,主要是驱动啥的别人都帮着找好了。体验起来果然比Windows爽多了,就是显卡驱动似乎略有bug,可能会突然死机啥的。看来还是得赚钱弄台正版的才行。

本站总访问量