月度归档:2015年01月

2015 年 1 月 23 日云代码服务故障公告

  • 时间: 2015 年 1 月 23 日凌晨 01:30 到 上午 9:30 左右,持续 8 个小时
  • 现象:部分依赖于云代码的应用的云代码请求返回 502 状态码的应答,不依赖云代码的应用没有受到影响。
  • 原因:为了对云代码部署服务做扩容,我们增加了新的部署节点,但是因为配置文件没有同步,导致新节点的服务没有正常启用,分配到该节点的部分应用受到影响。
  • 解决:在意识到是配置文件之后,我们的工程师迅速同步了配置,并重新启动了受影响的应用,服务恢复。

这次故障持续时间较长,暴露了我们在监控和告警上的短板。我们很惭愧,将做如下一些改进:

  • 针对云代码服务 502 状态应答增加报警,提高告警优先级。
  • 改进部署流程,做配置复查。
  • 改进云代码的容灾,在极端情况下,可以将受影响服务自动迁移到新节点。

01/17 极客公园 2015 GIF 创新大会:江宏「创业中的认真与坦诚」

在充满泡沫和虚假数据的科技圈中,踏实做事,坦诚真实究竟还有没有必要?

产品数据的吹嘘很容易鉴别

产品数据,我们经常看到一些新闻,可能没怎么听说过的产品,上来就说自己有几千万甚至上亿用户,其实这是很少鉴别的,你只要想一想自己认识的人当中有几个是他的用户,再想一想中国有多少互联网用户,其实很容易得出结论。

不诚实会付出更大的代价

无论是融资,或者招聘,或者做产品,任何复杂的事情,往往都会分为几个阶段。在每个阶段,产出的价值一定是大于上个阶段产出的价值的,因为你投入了更多资源,如果价值反而变小了,就没必要去做这一步了。 这也就意味着,你在下个阶段发现问题,一定比上个阶段发现问题所带来的代价要大,浪费的资源更多。而不诚实带来的问题在于,比较容易的让你通过前面的阶段。事实毕竟是事实,问题会暴露出来,到那个时候会让你付出更大的代价。

虚报数字对创业者和公司都有损害

拿融资来说,在开始接触的阶段,双方就能坦诚相待、发现问题,其实对创业者和投资人来说,都是代价最低的。如果一开始虚报数字,到了尽职调查的阶段才发现问题,那时候双方已经投入了很多时间和精力,这个机会成本是非常大的。就算在这个阶段蒙混过关,融资之后如果投资人发现公司的发展跟预期非常不一样,被迫去行使一些保护性条款来止损,往往会对这个公司造成致命的伤害。现在的 VC 大部分都是有钱任性,现在不流行说人傻钱多了,不会管那么多。但其实,一个创业者如果拿了 VC 的钱,在一件不会成功的事情上努力很多年,其实对自己和团队都是一种极大的浪费。所以从这个角度看,一个本来不应该拿到投资的项目,侥幸拿到了投资,不一定是好事,或者说一定不是一件好事。

招聘也是一样,最好是双方都在比较早的阶段发现相互不匹配,各自做其他选择。最不好的就是入职一段时间再离职,这时候工作上的问题已经造成,而双方都已经投入了很宝贵的时间。

公开薪酬营造坦诚的氛围

在 LeanCloud,我们从一开始就希望能够营造一种坦诚的氛围,我们公开了我们计算薪酬的方式,这个公式里面每一类职位都有一个薪酬的基数,这些基数和系数都在公开的文档里面。所以,对内每个员工,他都知道自己的月薪是怎么计算出来的,对外我们每发出一个 Offer 会附上一个链接,然后告诉这个候选人。根据面试,我们把他的能力水平定在哪个级别,所以他的月薪应该是多少,我们不会去问他他以前拿多少钱,或者期望值是多少,所以也就没有谈判。

站在风口踏踏实实地做事

现在在互联网圈可能被引用最多的一句话,就是雷军说的站在风口猪都可以飞起来,这句话好象今天前面已经出现了两次,现在各种风刮的那么猛烈,北京创业氛围天空应该是这样子的,而雾霾的时候却是这样子的。现在确实有很好的创业机会,这点是没错的,但天下的聪明人很多,所以对每个机会都不会只有一个人看到,所以站在风口并取代不了踏踏实实做事情。我觉得,有很多人他们过度的关注了雷军顺势而为的成功,但没有关注到这背后的辛苦和认真。

公司和产品一样有自己的品牌和风格

对一个公司来说,在不同阶段可能会有多个产品,而同一个产品也可能面临多次转型。商业上的成功往往依赖于很多因素,而其中有很多并不是主观可控的。所以我认为,对一个创业者来说,他最重要的产品其实是他的公司,因为这家公司的文化、口碑,员工是不是喜欢这家公司,竞争对手和合作伙伴如何评价这家公司,往往是创始人可以几乎完全把握的。所以,经营一家公司,也要像做一个产品一样,要有自己的风格和品牌,要追求有所创新,也要敢于打破现状。每位创业者,都应该努力做一家好公司。

#002 LeanCloud 晨读推荐

晨读推荐

关于「晨读推荐」About

由 LeanCloud 的工程师和设计师,以周为单位进行阅读分享,包含每位工程师和设计师想加入自己读到的「有价值、有趣味、有分享意义」的文章以及推荐理由。

技术向 Geek Must Read

《Good logging practice in Python》
对于服务器线上代码,以及运行在用户机器上的客户端代码,如果有 bug 发生,日志唯一能够帮助我们定位 bug 的工具之一了。今天你用好 logging 了吗?

工具向 The best tool you have never seen

《Android 异步消息处理机制完全解析》
在 Android 开发中,Handler 和 AsyncTask 都很常用,本文介绍 Handler、Looper 的原理,并着重讲解其中的 MessageQueue 是怎样工作的?

设计向 Design More,Design Better

《WebP 探寻之路》
今年 WebP 图片格式得到越来越多的关注,很多团队也开始布道。借此热潮,在这里把上一年的探索过程以及今年 WebP 新的发展一同分享出来,同时也期待更多的人将其应用于实际业务中。

新知向 Ren chou jiu yao duo du shu

《Apple WatchKit 初探》
11 月 19 日,Apple 发布了第一版的 Watch Kit 的 API,对于开发者来说,这款新设备的一些更详细的信息也算是逐渐浮出水面。可以说第一版的 WatchKit 开放的功能总体还是令人满意的。Apple 在承诺逐渐开放的方向上继续前进。本文介绍了 Watch app 架构和主要的类等相关知识。

#001 LeanCloud 晨读推荐

关于「晨读推荐」About

由 LeanCloud 的工程师和设计师,以周为单位进行阅读分享,包含每位工程师和设计师想加入自己读到的「有价值、有趣味、有分享意义」的文章以及推荐理由。

技术向 Geek Must Read

《Zero Copy I: User-Mode Perspective》
Zero Copy I: User-Mode Perspective 一文解释了在 linux 中什么是零拷贝 (zero-copy),什么场景下使用,网络工程师必读。

工具向 The best tool you have never seen

《All in together: Android Studio, Gradle and Robolectric》
本文介绍 Android Studio,Gradle,Robolectric 集成使用的方法,一站式解决 android 项目的依赖管理、开发、测试的问题。

设计向 Design More,Design Better

《How to upgrade your app’s design from Holo to Material Design — A case study》
本文介绍了把一个 Android 4.x 风格 UI 的应用升级到 5.0 Material Design,可以从本文中升级的部分了解 Material Design 的关键点 。

新知向 Ren chou jiu yao duo du shu

《Writing a compiler in Ruby, bottom up》
教你如何使用 Ruby 从头开始写一个编译器。

LeanCloud 离线数据分析功能介绍

可能不少用户还不知道,我们上个月中旬就已经对外发布了离线数据分析功能。用户可以用它来做什么,它适用于哪些应用场景,有没有应用实例?若要回答这些问题,首先让我们看看部分用户曾经向我们提出过的一些痛点或需求。为了对用户数据保密,后面提到的应用名字与数据均为虚构。

  • 某应用 TestA 发布几个月之后,由于用户量暴涨,存储在我们这里的数据规模急剧上涨。这就导致了一个无法忽视的问题:他们在应用刚发布的那段时间会每天从我们这里导出数据,自己写程序做数据分析。而当数据规模(几十 GB)越来越大,受限于网络文件下载速度,每日导出数据再自己做分析已经变得越来越困难。因此,他们希望我们能提供数据分析服务,支持 SQL-like 的查询。
  • 某应用 TestB 每天都会针对应用数据做一些分析报告,主要目的是知晓应用当前的关键数据指标。按照最初的方案,他们需要每日导出数据,自己写脚本程序处理应用数据。实际上,这样的工作对一个需要快速迭代产品的团队来说颇为繁琐,也比较消耗时间。
  • 我们的 工单系统 也是构建在 Leancloud 之上,每一条工单数据都是通过我们的存储组件写入我们的云端数据库。工单系统同时也作为我们的一个示例公开了源代码,从源代码就可以了解到它和其他用户的应用没有本质区别(从数据存储这个角度看)。我们的工程师除了需要非常及时地处理用户提交的工单,也需要了解工单系统的一些统计指标,例如自己最近回复了多少工单、不同平台工单的处理速度等等。如果有一个支持 SQL-like 的查询服务,那么要统计这些指标就会变得很容易。

相信上面的例子对很多用户来讲都不陌生,它揭示的痛点无非是大量的数据无法通过便捷的手段进行分析。考虑到用户的需求,我们开发了支持 SQL-like 查询的离线数据分析服务。用户要做的不过是按照我们的 离线数据分析使用指南 开启离线数据分析服务,输入合法的 SQL 语句即可分析数据。顺便说一下,这个服务后端核心组件为 Spark SQLParquet

接下来,就以我们的工单系统为例子,介绍如何利用离线数据分析服务来解决我们日常工作中遇到的一些问题。当然,为了更好地了解工单系统内部的结构,你可以访问 这里 的源代码。

首先让我们看看整个界面:

bigquery-0

接下来就让我们针对一些统计指标分析工单系统数据:

  • 统计不同平台类型(type)的工单数量,并按大小排序
select count(*) as `count`, type from Ticket where type is not null group by type order by `count` desc

结果如图所示(如果图中文字不够清晰,请点击查看大图):

bigquery-1

  • 统计每个工单(Ticket)各有多少条回复(Thread),并按回复数大小排序
select Ticket.objectId, Ticket.title, count(Thread.content) as `count` from Ticket inner join Thread where Ticket.objectId=Thread.ticket.objectId group by Thread.content, Ticket.objectId, Ticket.title order by `count` desc

结果如图所示:

bigquery-2

若想知晓 iOS 平台的每条工单各有多少条回复,只需把上面的 SQL 语句做简单修改:

select Ticket.objectId, Ticket.title, count(Thread.content) as `count` from Ticket inner join Thread where Ticket.objectId=Thread.ticket.objectId and Ticket.type='ios' group by Thread.content, Ticket.objectId, Ticket.title order by `count` desc
  • 统计所有工程师最近一个多月处理了多少条工单(Ticket),并按处理数量排序。Admin、Thread、Ticket 这三张表参与了 join 计算,其中 Admin 存放了工程师的个人信息,它和回复(Thread)通过 cid 关联。而回复(Thread)与工单(Ticket)则是通过工单的 objectId 来做关联。
# 注:slackName 其实就是这个工程师的用户名,因为我们还使用 Slack 来实时接收消息。
select count(distinct Ticket.objectId) as `count`, Admin.slackName from Ticket inner join Thread inner join Admin where Thread.ticket.objectId = Ticket.objectId and Admin.cid = Thread.cid and Admin.slackName is not null and unix_timestamp(Ticket.createdAt) > unix_timestamp('2014-12-01T00:00:00.000Z') group by Admin.slackName order by `count` desc

结果如图所示:

bigquery-3

  • 统计所有工程师总共有多少次回复(Thread),并按回复数排序。同工单数的查询类似,这里也需要三张表做 join。
select count(distinct Thread.objectId) as `count`, Admin.slackName from Ticket inner join Thread inner join Admin where Thread.ticket.objectId = Ticket.objectId and Admin.cid = Thread.cid and Admin.slackName is not null group by Admin.slackName order by `count` desc

结果如图所示:

bigquery-4

  • 统计每天各有多少条回复(Thread)
# substr(createdAt, 1, 10) 用来获取回复的日期(yyyy-MM-dd)
select count(*) as `count`, substr(createdAt, 1, 10) as date from Thread group by substr(createdAt, 1, 10) order by date desc

结果如图所示:

bigquery-5

考虑到本文篇幅有限,就不再列举其他查询示例。如果您在使用离线数据分析服务的过程中遇到各种各样的问题,都可以通过工单或者邮件向我们反馈,我们会及时处理相关问题。

「Just Do IT!」Geekparty 企业联合黑客马拉松

weichat900x500

编程马拉松(Hackathon)由「编程(Hack)」和「马拉松(Marathon)」两部分组成。这个术语诞生于 1999 年。OpenBSD 于 1999 年 6 月 4 日在卡尔加里举办的一次密码学开发活动上第一次使用了该术语。在那次活动中,10 名程序员相聚到一起商讨如何避免由美国密码学软件出口规定引起的合法性问题。

再到后来 Hackathon 因为它的快节奏和竞技性,让黑客马拉松风潮已蔓延到传统的技术世界,成为了程序员们在一起分享经验、交流技术和迸发灵感的盛会。在世界各地各色主题的 Hackathon 中,产生过非常多伟大的产品,Facebook、Jawbone Up 等他们得早起原型都诞生在这些 Hackathon 里,我们相信怀揣着改变世界美好愿望的 geek 们始终愿意通过自己的大脑和双手为更多的人造轮子。

在这次的 Hackathon 中,LeanCloud、百姓网、Strikingly 和 一熊科技等几位惺惺相惜的小伙伴,不仅在业务上合作、品牌上认同,更希望彼此的研发团队能在轻松、开放和愉快的氛围下,进行更加深入的交流。同作为技术导向型的团队,希望给更多的开发者们展现我们各个公司的技术水平,相信这样一场「快节奏、高效率和灵感迸发」的 Hackathon ,无论是过程还是结果都会带来无限的惊喜!

活动日程

1 月 31 日2 月 1 日
09:00 AM 团队登记07:00 AM 早餐
10:00 AM 开幕式-集中开发时间12:00 AM 午餐
12:00 AM 午餐01:30 PM 集中开发结束,测试、提交 demo
01:00 PM 集中开发时间02:00 PM Talking 环节
06:00 PM 晚餐02:30 PM Demo 展示
12:00 PM 夜宵05:00 PM 优胜公布,颁奖
05:30 PM 合影,结束

活动注意项

  • 每家企业进行内部或联合组队,每支队伍 2-4 名成员,在 48 小时内进行集中开发,并在最后进行 demo 展示和评选;
  • 在 demo 展示前加入开放式 talking 环节,每家公司的研发团队派出一名成员,分享研发团队的相关信息或经验体会。

奖项设置

  • 一等奖(数量:1):iPhone 6 一部
  • 二等奖(数量:2):HHKB Pro 2 键盘一台
  • 三等奖(数量:3):Kindle Paperwhite 2
  • 创新作品奖(数量:1):Locket 双屏笔记本支架
  • 最高人气奖(数量:1):Cherry G80-3000 键盘一台
  • 阳光普照奖(数量:所有人):价值 400 元 的企业联合礼包

评分规则

  • 参赛作品必须在比赛现场和规定时间内完成开发,以在现场完成的实际成果参与演示和评选,不得以成型作品参赛;
  • 比赛结束后每个完成的作品都会得到一定的演示时间,并由评委从创新性(25 分)、技术(25 分)、完成度(25 分)、商业化潜力(25 分)等四个方面做出评分;
  • 「LeanCloud」、「百姓网开放 SDK」、「Strikingly」作为各个团队所研发的开发者工具,如参赛队伍使用了自己公司的开发工具,将在最终评分的基础上加 5 分,如果使用了除自己公司外其他开发工具,将在最终评分基础上加 10 分。例:百姓网团队的参赛作品使用「百姓网开放 SDK」,将加 5 分,使用 LeanCloud 或 Strikingly 额外加 10 分,加分不累计。

比赛细则与 Demo 提交

  • 代码审查 :根据活动安排,主办方或将审查获胜队伍的代码,以保证大部分代码都是在黑客马拉松比赛期间创建的;
  • 所有权和知识产权 :参赛队伍对于在黑客马拉松比赛期间创建的一切拥有完整的所有权,根据作者意愿自由使用;
  • 团队规模 :你可以个人参赛或和其他人一起组队参赛,建议参赛队伍的人数保持在 2-4 人;
  • 提交 :在活动中,每队都必须在规定时间内提交软件原型;
  • 演示程序 :可以通过实物投影展示你的作品,并进行主要功能的演示和讲解,请务自行准备带所有 demo 演示所需要的基本工具,并在演示前进行调试,不建议使用 PPT。

团队报名链接

点击此处

评审嘉宾

百姓网 联合创始人 & CTO 潘晓良
LeanCloud 联合创始人 & CTO 丰俊文
一熊科技 联合创始人 & CTO 曾凡禹
OurCoders 站长 Tinyfool 郝培强

实时通信云代码集成发布

大家好,我们又发布了一个坳口的功能,实时通信的 云代码集成 。简单地说,现在用户可以通过 自定义云函数 作为 hook,修改实时通信默认的执行流程,增加应用自定义的业务逻辑。

第一阶段我们支持两个 hook:_messageReceived(消息到达服务器)和 _receiversOffline(收件人离线)。

_messageReceived 发生在消息到达服务器,服务器解析完收件人 id 之后,消息存入离线队列之前。这个阶段云函数可以获得的信息包括消息内容、收件人 id 列表、时间戳、发件人等等,用户的云代码可以通过返回值修改消息内容,修改收件人列表甚至直接丢弃消息。这个 hook 可以帮助用户实现自定义的消息处理,甚至实现请求-响应式的模型。

潜在的用例:

  1. 更新数据库,例如记录用户最近发消息时间
  2. 修改消息内容,删除广告,敏感信息(尽管我们已经内置了敏感词过滤)
  3. 修改收件人列表,自动转发消息到他人
  4. 完全颠覆传统实时通信模型,执行服务器端业务逻辑

Screenshot from 2015-01-08 15:09:29

_receiversOffline 发生在消息发送完成后,离线通知触发前。这个阶段云函数可以获得消息内容,离线收件人 id,关联的群组 id 等。用户可以通过云代码返回值指定离线通知的内容,被通知的用户 id,或者直接跳过默认的推送通知(比如在 hook 中触发短信、邮件等其他通知方式)。这个 hook 可以解决之前大家反馈比较多的推送消息不能动态定义的问题。

云代码集成是可选功能,已有的功能不受此次升级影响。关于云代码集成更完整的参数列表和详细说明,请 参考我们的文档