Parse 关停与开发者服务健康发展

Parse 关停 2016年1月28日,Parse 官方宣布将于1年后关闭 Parse 服务。这应该是这几天以来开发者服务市场,或者移动互联网开发者圈子里最为震撼的一个消息了。 Parse 在开发者服务领域里很有影响力,有很多的使用开发者,产品也比较完整、专业,就拿他们的开发者文档来说,对我的两次创业都产生了很大的影响。当初 Parse 被 Facebook 收购也引起了很大的关注。 种种原因,让我们听到 Parse 将被关停的消息后,都会觉得特别突然。 在冷静思考几天后,我试图理解为什么 Facebook 会在 Parse 成长迅速的情况下,依然选择了关停它。 猜测大概有几个原因: 虽然 Parse 的确发展得很快,但是 AWS 这些原来的云计算服务商也在不断地推出更多的服务,也逐渐覆盖了 Parse 的后端服务范围。看起来 Parse 也没有足够的能力与 AWS 这些行业巨头正面竞争。 Parse 的用户数量增长得很快…

poolboy的坑

poolboy是Erlang中运用非常广泛的进程池库,它有很多优点,使用简单,在很多项目中都能看到它的身影。不过,它也有一些坑,使用时候需要注意。(本文对poolboy的分析基于1.5.1版本) worker创建不能失败 当poolboy初始化的时候,或者当前进程池的worker数量超过默认值,都会新建worker。我们看一下新建worker的代码: new_worker(Sup) -> {ok, Pid} = supervisor:start_child(Sup, []), true = link(Pid), Pid. 可以看到,supervisor:start_child 的时候是不能失败的,也就是说worker创建如果失败,会导致poolboy这个gen_server挂掉,导致整个进程池崩溃。 这会有什么影响呢,我们看一下用poolboy管理eredis的例子,参考其中的一个实现eredis_pool。 创建worker失败,pool无法启动 看eredis初始化代码,如果连接失败,eredis直接退出。如果用eredis_pool的话…

InfoQ 报道

InfoQ 对云巴的相关报道: 2014年11月24日 云巴创始人兼CEO张虎访谈:推送服务架构选型与程序员成长 2014年8月19日 演讲视频 实时系统架构与实践 …

Erlang 内存泄漏分析

随着项目越来越依赖Erlang,碰到的问题也随之增加。前段时间线上系统碰到内存高消耗问题,记录一下troubleshooting的分析过程。线上系统用的是Erlang R16B02版本。 问题描述 有几台线上系统,运行一段时间,内存飙升。系统模型很简单,等待网络新连接,pool中找新可用process进行处理。top命令观察,发现内存都被Erlang进程给吃完了,netstat命令查看网络连接数,才区区几K。问题应该是Erlang内存泄漏了。 分析方法 Erlang系统有个好处,可以直接进入线上系统,在生产现场分析问题。我们系统是通过Rebar管理的,可以用不同方法进入线上系统。 本机登录 可以直接登录到线上机器,然后通过以下命令attach到Erlang系统里面 $ cd /path/to/project $ rel/xxx/bin/xxx attach (node@host)> 通过remote shell 获取Erlang系统的cookie $ ps -ef |grep beam %%找到参数 --setcookie 新开一个shell,使用同样的cookie…

Go vs Erlang

因为 云巴 系统对高并发、低延迟的需求,我们对各个语言、平台做了很多的调研比较工作。这自然就包括致力于开发高并发应用的 Go 和 Erlang。 并发 Go 对高并发的支持通过 goroutine 实现。goroutine 可以理解为轻量级的 线程(thread)。同一个 Go 应用创建的 goroutine 共享地址空间。 Erlang 的高并发通过轻量级 进程(process)实现,每一个进程都有独立的状态记录。 另外,使用 goroutine 要注意,goroutine 运行完毕后,占用的内存放回内存池备用,不会释放。 对于每一个任务都需要有独立状态的场景,Erlang 的 process 更有优势。 抢占式调度 Erlang 的任务调度器有一个 reduction budget 的概念。进程的任何操作都会造成预算消耗…

Go实践

最近在一个项目中使用了Go语言,当然不可避免的遇到了一些问题,记录这些问题的解决方法,也是Go实践的一部分了。 项目中的需求很简单,从RabbitMQ读数据,然后写入Redis当中,当然这个量比较大,似乎用goroutine是一个好的解决办法。 所以刚开始的逻辑是,从MQ读取数据,然后对每个数据都用一个goroutine处理。goroutine从Redis Pool里面取Redis connection,然后写数据到Redis。Redis go library redigo,库中提供Redis Pool的API,可以很方便的管理Redis connection。 func HandlePackage(data){ redisConn := getConnFromPool() wirteRedis(data) } func main(){ for package from MQ { go HandlePackage(package) } } 问题1: no such host 结果一跑,就出现很多 "no such host" 错误…