转:HAR(HTTP Archive)规范

三月 14th, 2014 评论关闭
HAR(HTTP Archive)规范

HAR(HTTP Archive),是一个用来储存HTTP请求/响应信息的通用文件格式,基于JSON。这个格式的出现可以使HTTP监测工具以一种通用的格式导出所收集的数据,这些数据可以被其他支持HAR的HTTP分析工具(包括Firebug,httpwatch,Fiddler等)所使用,来分析网站的性能瓶颈。目前HAR规范最新版本为HAR 1.2。HAR文件必须是UTF-8编码,有无BOM无所谓。

HAR数据结构:

一个HAR文件就是一个JSON对象,如下:

{ "log": { "version" : "1.2", "creator" : {}, "browser" : {}, "pages": [], "entries": [], "comment": "" } }
  • version [string] – 版本,默认为1.1。
  • creator [object] – 创建HAR文件的程序名称和版本信息。
  • browser [object, 可选] – 浏览器的名称和版本信息。
  • pages [array, 可选] – 页面列表,如果应用不支持按照page分组,可以省去此字段。
  • entries [array] – 所有HTTP请求的列表。
  • comment [string, 可选](new in 1.2) – 注释。

注:每个页面对应一个 对象,每个HTTP请求对应一个对象。如果HTTP的监测分析工具不能把请求按照page分组,那么为空。

<creator> & <browser>

这两个对象的结构是一样的

"creator": { "name": "Firebug", "version": "1.6", "comment": "", } "browser": { "name": "Firefox", "version": "3.6", "comment": "" }
  • name [string] – HAR生成工具或者浏览器的名称。
  • version [string] – HAR生成工具或者浏览器的版本。
  • comment [string, 可选](new in 1.2) – 注释。
<pages>

这个对象保存了页面列表,格式如下:

"pages": [ { "startedDateTime": "2009-04-16T12:07:25.123+01:00", "id": "page_0", "title": "Test Page", "pageTimings": {...}, "comment": "" } ]
  • startedDateTime [string] – 页面开始加载的时间(格式ISO 8601 – YYYY-MM-DDThh:mm:ss.sTZD, 例如2009-07-24T19:20:30.45+01:00)。
  • id [string] – page的唯一标示,entry会用到这个id来和page关联在一起  阅读全文...

转:Linux内核管理风范

二月 27th, 2014 评论关闭
1. 中译.Linux内核管理风范 1.1. 导言

Linus Torvalds 在2004年把一篇讲”Linux内核的管理风格”的文章放在了内核源码文档里。这篇文章有意对应他以前写的关于编码 风格的文章(比如烧书仪式),也有技术人员熟悉的Dilbert卡通的影子。 Henrik Ingo 写”Open Life: The Philosophy of Open Source“一书的时候,拿这篇文章作了后记。

这篇文章其实是总结了Linus十几年里领导开源运动的经验。更重要的是,它讲述了一种与传统不同的做事理念,一种后互联网时代的、尊重技术和自由的理念。

Linus的写作诙谐生动,完全不同于ESR的《大教堂和市集》。所以我作了比较自由的翻译。以下是译文。

1.2. Linux内核的管理风格

(Linux kernel management style, by Linus Torvalds. Retrieved from http://openlife.cc/node/43, Jan-28-2008)

这个简单文档描述Linux内核偏爱的(或编造的,取决于你问谁)管理模式。它在一定程度上是编码风格文档的影子,主要写来避免一遍又一遍回答同一类问题*。

  • 管理风格是很个人化的,比起简单的编码风格条例更难量化,所以这个文档跟现实可能沾边也可能不沾边。它开始于游戏,但是不见得就不作数。你只有自个儿决定。
  • 顺便说一下,我们说到”内核管理者”的时候,完全是说技术带头人,不是公司里那些作传统管理工作的人。如果你是在订单上签名的人或者对你们组的预算知道一丁半点,你几乎一定不是个”内核管理者”。这些建议对你可能适用也可能不适用。
  • 首先,我建议你买一本《高度成功人士的七个习惯》,不-要读它,烧了。表一下决心。
    • (*) 这个文档不见得”回答”多少问题,更大程度上是展示我们的无知,让提问者死了这条心。

不管怎样,开讲了:

1.2.1. 第一章:决定

每个人都觉得管理者是作决定的,作决定是很重要的。决定越大、越艰难,管理者就越伟大。这一点很深刻、很明显,但不见得正确。

  • 事情的要义是避免-作决定的必要性。特别是,当有人告诉你”是甲还是乙,我们需要你来作决定”,你作管理的麻烦就来了。你手下的人一般比你更懂具体问题,所以要是他们找你作一个技术性的决定,你死定了。要替他们作决定,你显然水平不够。

(推论:如果你手下的人不比你更懂具体  阅读全文...

微博平台的RPC服务化实践

一月 27th, 2014 评论关闭

微博平台的RPC服务化实践

 

2014年第一分钟,新浪微博的发布量以808298条再次刷新记录,第一秒微博发布量相较去年提升55%。(数据来源:新浪科技 http://tech.sina.com.cn/i/2014-01-01/02409059293.shtml )这是微博平台 RPC 框架 “Motan” 上线后第一次抗峰值,整体表现平稳,基本达到最初的“应用方无感知”的目标。

 

在RPC服务化这个事情上,微博平台不是第一个吃螃蟹的:早的有亚马逊和eBay等国外先驱,近的有Twitter的finagle,淘宝的dubbo等等,网上各种公开的资料铺天盖地。另一方面,单纯的RPC调用功能实现,从技术上看其实并不复杂:client 发起调用,框架拦截调用信息,序列化,传输,server端收到调用信息,反序列化,根据调用信息发起实际调用获取结果,再原路返回。实现这些功能可能也就三五天的事情,但在一个复杂的业务环境下,稳定可靠的应用它,才是最大的挑战。

 

微博平台的 RPC 服务化拆分历程始于2013年7月。在此之前,我们花了很长的时间讨论服务化的目标,主要是项目的范围:哪些问题不属于服务化项目需要解决的问题。 实际的框架代码开发花了三个工程师(王喆@wangzhe_asdf9 陈波@fishermen 麦俊生@麦俊生)大约一个月时间,然后花了将近两个月的时间推动在第一个业务上线:调整工程师的开发模式,调整测试流程,修改上线系统,添加监控和报警,小流量测试,灰度发布,最后才是全量上线。然后又花了一个月,在微博平台主要业务中全部上线。

 

微博RPC的一些基本的数据指标:

  • Motan 框架:2w+ 行 Java 代码,1w 行 test 代码,UT行覆盖率超过 70%(当前 Motan 实现中,与微博平台内部多个系统都有功能绑定,还不具备开源条件,但开源是我们从一开始就设立好的目标之一)
  • 支持 2 种调用方式:inJVM 和 TCP远程调用。inJVM 方式类似 loopback 网卡:数据经过了协议栈流程处理,但没有流经真正的网络设备。inJVM方式主要用来支持开发调试和测试,以及在RPC服务上线初期作为Fail-Back降级使用
  • 典型业务场景下单实例 tps 极限 20k,微博平台一般采用单机双实例,即单机极限 40k
  • 典型业务场景下平均响应时间 <3 ms,框架层额外消耗 < 0.01 ms
  • 最大的单个核心业务日调用量超过 800亿次

 <  阅读全文...

微博关系服务与Redis的故事

一月 25th, 2014 评论关闭

微博关系服务与Redis的故事

 

新浪微博的工程师们曾经在多个公开场合都讲到过,微博平台当前在使用并维护着可能是世界上最大的Redis集群,其中最大的一个业务,单个业务使用了超过 10T 的内存,这个业务就是微博关系服务。

 

2009年微博刚刚上线的时候,微博关系服务使用的是最传统的 memcache+mysql 的方案。Mysql 按 uid hash 进行了分库分表,表结构非常简单:

tid fromuid touid addTime 自增id 关系主体 关系客体 加关注时间

 

业务方存在两种查询:

  • 查询用户的关注列表:select touid from table where fromuid=?order by addTime
  • 查询用户的粉丝列表:select fromuid from table where touid=?order by addTime

两种查询的业务需求与分库分表的架构设计存在矛盾,最终导致了冗余存储:以 fromuid 为hash key存一份,以 touid 为hash key再存一份。memcache key 为 fromuid.suffix ,使用不同的 suffix 来区分是关注列表还是粉丝列表,cache value 则为 PHP Serialize 后的 Array。后来为了优化性能,将 value 换成了自己拼装的 byte 数组。

 

2011年微博进行平台化改造过程中,业务提出了新的需求:在核心接口中增加了“判断两个用户的关系”的步骤,并增加了“双向关注”的概念。因此两个用户的关系存在四种状态:关注,粉丝,双向关注和无任何关系。为了高效的实现这个需求,平台引入了 Redis 来存储关系。平台使用 Redis 的 hash 来存储关系:key 依然是 uid.suffix,关注列表,粉丝列表及双向关注列表各自有一个不同的 suffix,value 是一个hash,field 是 touid,value 是 addTime。order by addTime 的功能则由 Service 内部 sort 实现。部分大V的粉丝列表可能很长,与产品人员的沟通协商后,将存储限定为“最新的5000个粉丝列表”。

 

需求实现:

  • 查询用户关注列表:hgetAll uid.following ,then sort
  • 查询用户粉丝列表:hgetAll uid.follower,then sort
  • 查询用户双向关注列表:hgetAll uid.bifollow,then sort
  • 判断两个用户关系:hget uidA.following uidB && hget uidB.following uidA

后来又增加了几个更复杂的需求:“我与他的共同关注列表”、“我关注的人  阅读全文...

密码保护:再见2013

十二月 27th, 2013 评论关闭

这是一篇受密码保护的文章。您需要提供访问密码:

密码:

阅读全文...

“关注” 互联网

十一月 7th, 2013 评论关闭

从 2000 年开始接触互联网,到后来工作在这个行当,摸爬滚打已经十余年。这十年还正好是互联网风起云涌的十年,各路英雄你方唱罢我登场,自己却一直是舞台下的一个看客,即使后来在一个也可以算是引领潮流的产品里工作,也积累了少许知名度,但依旧是依托平台的高度,而且是作为技术人员,对产品本身的贡献微乎其微。实际上,我一直觉得自己对产品是有一些理解和想法的,也想过转去做一个懂技术的产品人员,只是缺乏一个机会而已。

最近,在思考一些类似个人或部门的明年规划之类的问题的时候,也对自己理想中的微博产品的未来做了一些思考,在此记录一下。

简单的来说,我个人觉得,微博目前的仅“用户”为第一层次概念,用户可以关注和被关注的模式,太过单薄,需要将第一层次概念扩张到所有的互联网对象,即所有对象都可以关注和被关注。整个互联网应该是一个关注和被关注的网络,而微博,应该成为这个网络的基础设施平台。当前的互联网已经完全进入了“眼球”时代,用户的注意力是所有互联网产品争夺的终极目标。而目前已有的各种产品模式,都处于低层次的无序竞争状态,没有统一的迹象。从眼下来看,微博是最有希望成为“基础设施平台”的了。

如果把微博上的“用户”扩展到互联网所有的对象,我们可以想象一下会发生什么:每一个Web1.0网站的每一个频道或分类都可以被“订阅”到微博,就像RSS被订阅到昔日的GoogleReader一样,反过来,微博上的Feed流也可以成为它们的一个频道或分类;每个Web2.0网站上的每个用户,每个Page或每个企业,也都可以被微博账号“关注”,就像他们也是一个微博账号一样,反过来,它们也可以直接在自己的网站上关注微博用户;如果再往外扩展到物联网的对象,所有能产生动态的物体——家里的微波炉空调,附近的气象站摄像头,高速路上一百米范围内的其它车,都可以在微博上进行关注,反过来,这些物联网对象也能关注一些微博用户账号,接收用户的指令;如果关注的概念再进一步细化,用户关注的不是一个对象本身,而是这个对象的某些我感兴趣的动态,或符合我设定的规则的某些对象(而不是一个特定的对象),事情就更好玩了:我可以只关注我附近一公里内的星巴克,我也可以只在早上8点到10点间接受这些星巴克推送的优惠信息,我可以只关注气象站发布的低温或大风警告,也可以只关注摄像头视频通过一定的后端处理后,发布的堵车信息(而不是裸的视频流数据)。  阅读全文...

一种新的 OpenAPI 设计思想(草稿)

十月 29th, 2013 评论关闭
Open API V3 接口设计规范草案 问题

在 v2 版本的接口中,我们发现接口最大的问题是:使用方容易用错,而究其根源,主要在于接口的说明文档,实现逻辑,测试用例,使用方理解等之间存在一致性问题,具体来说,在于以下几点:

  1. 接口设计越来越严重依赖某一个具体的产品需求,而不是基于普遍需求的抽象,导致越来越多的后期调整。接口设计及调整缺乏一致性保证,从而使得理解及使用成本上升,用错的概率增大
  2. 单个接口的功能及返回会随着时间的推移而发生变化,而这种变化信息无法及时的传递给以及在使用的调用方。比如增加传入参数,比如做一些性能优化,还有微调某些字段的含义(如曾经不返回正确的关注粉丝数,后来改为返回正确的数了)
  3. 测试人员对需求的理解与开发人员不一致,偶尔不全面,导致功能点漏测,自动化测试覆盖不足
  4. 使用方依赖的接口定义文档,SDK都出现与实现不一致,严重过时现象。文档与代码无法保持完全一致
  5. 使用方阅读文档描述文字,容易出现遗漏某些说明,从而因信息缺失导致不当甚至错误的使用
解决思路

因为 API 的设计,实现,使用都是程序员,或 IT 相关人士,在这个群体中,最通用的,且不容易发生理解错误的,不是自然语言,而是代码(为了避免编程语言的选择不同,这里我们使用类似 C 语言的“伪代码”模式进行描述),所以在 v3 版本中,主要的解决思路是,将 API 接口相关的所有信息,都以伪代码的形式进行描述,描述信息本身也以 API 的形式进行组织和公开,给所有相关方提供同等的,详细的,具体的信息,包括设计,实现,测试和使用方。

  1. 以一种程序可识别和处理的 DSL schema 方式定义 API,且 API schema 定义是公开的,类似 wsdl 文件。
  2. API schema 中包括以下约束信息:参数,返回字段,状态码(错误码),SLA保证,当前状态等
  3. 提供一套根据 API schema 进行 API 实现的规则说明,工具和最佳实践例子
  4. 提供一套根据 API schema 进行自动化测试的规则说明,工具和例子
  5. 提供一套根据 API schema 进行客户端编程使用的规则说明,工具和例子

具体的工作流程:

  1. 设计阶段
    • 需求收集阶段:平台产品与各端产品人员一起进行需求决策(必须要有平台产品的角色)
    • 设计阶段:平台产品与开发  阅读全文...

微博平台技术开放日:物联网与微博平台探索

九月 4th, 2013 评论关闭

9月4号,微博 #平台技术开放日# 第十一期,物联网与微博平台结合的探索,讲稿分享。

物联网与微博平台探索 from Tang Fulin 阅读全文...

技术经理的职责

八月 29th, 2013 评论关闭

技术经理与架构师是两个完全不一样的角色,遗憾的是,在很多公司或团队里,Boss 认为是一个角色,于是让一个人来承担。

架构师的职责很清晰,就是设计系统或项目的技术架构,达到“多”、“快”、“好”、“省”、“稳”等多个目标,至于目标优先级排序,就看具体的项目诉求了。但本质来说,架构师只需用负责解决“从机器视角看到的问题”,纯技术问题。顺便插一句,项目排期,资源,进度等,属于项目经理的职责范围,在这里不展开讨论。

技术经理的职责其实更广也更复杂,团队的成长体系,工作安排,KPI,重点方向选择,投入产出比,线上服务稳定,需求响应速度等等,都是需用考虑的范围。总结起来,大约三大块:

  1. 团队管理:氛围风格,老中青能力层次,每层的成员的成长方向,成长速度,招聘,绩效等等
  2. 方向把握:团队的工作内容选择,重点方向,什么是必须做好的,什么是次优先的,什么是可以做的,什么是不能做的。虽然很多时候技术经理没有绝对的决定权,但大多数时候,技术经理都是可以发挥自己的影响力的
  3. 执行力建设:在氛围风格已定的情况下,基础设施建设,生产工具链建设,运维工具体系建设三大件就成了决定因素

 

阅读全文...

转:如何设计一个优秀的API

七月 8th, 2013 评论关闭

到目前为止,已经负责API接近两年了,这两年中发现现有的API存在的问题越来越多,但很多API一旦发布后就不再能修改了,即时升级和维护是必须的。一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的。如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的打击就更大。如果API经常发生变化,用户就会失去对提供方失去信心,从而也会影响目前的业务。

但是我们为什么还要修改API呢?为了API看起来更加漂亮?为了提供更多功能?为了提供更好的性能?还是仅仅觉得到了改变了时候了?对于用户来说,他们更愿意使用一个稳定但是看起来不那么时髦的API,这并不意味着我们不再改进API了。当糟糕的API带来的维护成本越来越大时,我想就是我们去重构它的时候。

如果可以回头重新再做一遍,那么我心目中的优秀的API应该是怎么样的?

判断一个API是否优秀,并不是简单地根据第一个版本给出判断的,而是要看随着时间的推移,该API是否还能存在,是否仍旧保持得不错。槽糕的API接口各种各样,但是好的API接口对于用户来说必须满足以下几个点:

  • 易学习:有完善的文档及提供尽可能多的示例和可copy-paste的代码,像其他设计工作一样,你应该应用最小惊讶原则。
  • 易使用:没有复杂的程序、复杂的细节,易于学习;灵活的API允许按字段排序、可自定义分页、 排序和筛选等。一个完整的API意味着被期望的功能都包含在内。
  • 难误用:对详细的错误提示,有些经验的用户可以直接使用API而不需要阅读文档。

而对于开发人员来说,要求又是不一样的:

  • 易阅读:代码的编写只需要一次一次,但是当调试或者修改的时候都需要对代码进行阅读。
  • 易开发:个最小化的接口是使用尽可能少的类以及尽可能少的类成员。这样使得理解、记忆、调试以及改变API更容易。

如何做到以上几点,以下是一些总结:

1、 面向用例设计

如果一个API被广泛使用了,那么就不可能了解所有使用该API的用户。如果设计者希望能够设计出被广泛使用的API,那么必须站在用户的角度来理解如何设计API库,以及如何才能设计出这样的API库。

2、 采用良好的设计思路阅读全文...

无觅相关文章插件,快速提升流量