alinode 与 Node 应用性能管理——朴灵

alinode 与 Node 应用性能管理——朴灵
下载链接见文章结尾
====================================================================
alinode Node apm by @
/ Node.js @
Node.js alinode
Joyent Node.js (TSC)
ES6
ECMAScript 6
ECMAScript 2015
LTS
npm
~21 ~4500 npm, Inc.
hold
CPU gc
Node.js GC
APM APM new relic
“bug fix fix
a + linode ali + node
alinode Bug
CPU GC http
async_active_handles and more.
TODO
CPU Profiling GC
CPU npm.taobao.org
QPS ~200
cnpm npm
html minify
250 -> 150% N * 1 CPU CPU 63 /
alinode
heapdump/CPU profiling/GC trace
APM
wormhole
UC Web etc.
CNPM cnodejs.org teambition
node core contributor Node
process.exit(0);
====================================================================
链接: https://pan.baidu.com/s/1pLRjkc7 密码: 2cqh

用 Node.js 构建海量页面渲染服务——不四

用 Node.js 构建海量页面渲染服务——不四
下载链接见文章结尾
====================================================================
用 Node.js 构建海量页面渲染服务
不四 @ tmall,Node.js 开发工程师 dead-horse @ github,koa / cnpm 维护者
我是谁?
海量?
从两年前说起...
天猫的大量页面基于 php 渲染 数据模板打包后推送 CDN 每次请求都渲染页面
大量文件在网络情况不一的 CDN 节点同步非常困难 每次请求渲染导致大量的机器资源浪费
php 太灵活,多业务共享难以升级,性能
系统要重构,契机出现了
Why Node.js
“Any application that can be written in JavaScript, will eventually be written in JavaScript.”
–Jeff Atwood
模板渲染层 js 的独特优势:前后端模板共享 阿里内部 Node.js 环境十分完善 轻量级、高性能
回归渲染的本质
回归渲染的本质 前端开发编写维护的 模板
回归渲染的本质
前端开发编写维护的 模板 运营维护或者后端系统产出的 数据
回归渲染的本质
前端开发编写维护的 模板 运营维护或者后端系统产出的 数据 通过一个渲染容器进行合并产出 页面
// index.xtpl
{{#each ($data.items) }}

{{this.name}}

{{/each}} // items.json [{ "link": "//detail.tmall.com/item.htm?id=10126492964", "name": "item one" }, { "link": "//detail.tmall.com/item.htm?id=10126492964", "name": "item tow" }] // index.xtpl {{#each ($data.items) }}

{{this.name}}

{{/each}} // items.json [{ "link": "//detail.tmall.com/item.htm?id=10126492964", "name": "item one" }, { "link": "//detail.tmall.com/item.htm?id=10126492964", "name": "item tow" }] // result

item one

item tow

扩展上下文 系统时间、系统环境 http 请求上下文 通用工具方法,安全处理包 {{#if ($system.now.before('2015-11-11 00:00:00'))}}

Comming soon...

{{else}} {{#each ($data.items) }}

{{this.name}}

{{/each}}

{{/if}}
{{/if}}
{{#if (!$http.detector.app.is)}}
{{include ("downloadPage")}}
模板中的静态资源管理
前后端统一的资源加载器 基于统一的 seed 控制依赖以及版本 输出 combo url 到页面 依赖自动去重,css / js 头尾加载
// 模板

{{placeholder('css')}}

{{require('mui/mod/a.js', 'mui/mod/b.js')}}
{{require('mui/mod/a.css', 'mui/mod/b.css')}}

{{placeholder('js')}} // 渲染出的 html

Contents

模块化 {{!多 共享的头尾}} {{extend("solution://base/")}} {{#block(“body”)}} {{!引 模块}} {{use ("mui://zebra-act-flashy/", $data.items)}} {{use ("mui://zebra-act-shop/", $data.shops)}} {{/block}} 模块化 {{ require ("mui/zebra-act-flashy/index.css") }} {{ require ("mui/zebra-act-flashy/index.js") }}
// 模块 mui/zebra-act-flashy {{! load css and js }}

资源位
资源位
楼层
导航
// 引 跨 共享的通 头尾 {{extend("solution://base/")}}
{{#block(“body")}}
// 模块化构建
{{use ("mui://headbanner/", $data.modules[1])}} {{use ("mui://banner/", $data.modules[2])}}
{{use ("mui://multi-banner/", $data.modules[3])}} {{use ("mui://floor/", $data.modules[4])}}
{{use ("mui://nav/", $data.modules[5])}}
{{/block}}
模块化 ->
模块化 -> 规模化
模块化 -> 规模化 跨业务共享模块
模块化 -> 规模化
跨业务共享模块
面向运营的可视化页面搭建平台
模块化 -> 规模化
跨业务共享模块 面向运营的可视化页面搭建平台 Native 页面搭建
渲染服务
服务基于 koa 框架
扩展 xtemplate 模板
阿里云 oss 提供模板和数据的存储支持 阿里 CDN 提供缓存支持
koa, 不仅仅是 generator
Middlewares are Decorators
Middlewares are Decorators
Express:中间件顺序执行
Middlewares are Decorators
Express:中间件顺序执行 Koa:包裹在后面所有中间件的装饰器
function caculate(times) { let i = 0;
while (i < times) i++; }
function caculate(times) { let i = 0;
while (i < times) i++; }
// decorator
function log(fn) {
return function (...args) {
const start = Date.now();
fn(...args);
const used = Date.now() - start;
console.log(call ${fn.name}(${args}) used ${used}ms);
} }
function caculate(times) { let i = 0;
while (i < times) i++; }
// decorator
function log(fn) {
return function (...args) {
const start = Date.now();
fn(...args);
const used = Date.now() - start;
console.log(call ${fn.name}(${args}) used ${used}ms);
} }
caculate = log(caculate);
caculate(100000); // call caculate(100000) used 0ms caculate(10000000); // call caculate(10000000) used 6ms
// 设置响应时间 header
function* responseTime(next) {
// 所有的后续中间件之前执
const start = Date.now();
yield next;
// 所有的后续中间件之后执
const used = Date.now() - used; this.set('X-Response-Time', ${used}ms);
}
// 错误处理
function* errorHandler(next) {
try {
yield next;
} catch (err) { logger.error(err); this.status = 500; this.body = err.message;
} }
Abstract Context
Abstract Context
express
无法对已经发送的 body 修改
不能在设置 body 后设置响应头
Abstract Context
express
无法对已经发送的 body 修改
不能在设置 body 后设置响应头
koa 在所有中间件执行完成之后再发送响应
中间件执行过程中可以对 body 和 header 任意修改
app.use(render); // 渲染
function* render() {
const renderResult = yield _render(this.req.path) this.charset = renderResult.charset;
this.body = renderResult.body;
}
app.use(gbk); // 对渲染的结果做编码转换 app.use(render); // 渲染
function* render() {
const renderResult = yield _render(this.req.path) this.charset = renderResult.charset;
this.body = renderResult.body;
}
function* gbk(next) {
yield next;
if (this.charset !== 'gbk') return; this.body = iconv.encode(this.body, 'gbk');
}
app.use(gzip); // 对输出的 html 做压缩 app.use(gbk); // 对渲染的结果做编码转换
app.use(render); // 渲染
function* render() {
const renderResult = yield _render(this.req.path) this.charset = renderResult.charset;
this.body = renderResult.body;
}
function* gbk(next) {
yield next;
if (this.charset !== 'gbk') return; this.body = iconv.encode(this.body, 'gbk');
}
function* gzip(next) {
yield next;
if (this.acceptsEncodings('gzip') !== gzip) return; this.body = yield _gzip(this.body);
}
const koa = require('koa'); const app = koa();
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(render); // 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(renderLog); // 记录渲染 志 app.use(render); // 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(backup); app.use(renderLog);
app.use(render);
// 备份容灾
// 记录渲染 志
// 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(detector); app.use(backup); app.use(renderLog);
app.use(render);
// 判断终端类型 // 备份容灾
// 记录渲染 志
// 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(cacheControl); app.use(detector);
app.use(backup); app.use(renderLog);
app.use(render);
// 设置 CDN 缓存头 // 判断终端类型
// 备份容灾
// 记录渲染 志
// 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(meta); app.use(cacheControl);
app.use(detector); app.use(backup); app.use(renderLog);
app.use(render);
// 记录时间等信息 // 设置 CDN 缓存头
// 判断终端类型 // 备份容灾
// 记录渲染 志
// 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(trace); app.use(meta);
app.use(cacheControl); app.use(detector);
app.use(backup); app.use(renderLog);
app.use(render);
// 打印 trace log // 记录时间等信息
// 设置 CDN 缓存头 // 判断终端类型
// 备份容灾
// 记录渲染 志
// 渲染
app.on('error', err => logger.error(err));
app.listen(port);
const koa = require('koa'); const app = koa();
app.use(onerror); app.use(trace);
app.use(meta); app.use(cacheControl);
app.use(detector); app.use(backup); app.use(renderLog);
app.use(render);
// 异常处理
// 打印 trace log
// 记录时间等信息 // 设置 CDN 缓存头
// 判断终端类型 // 备份容灾
// 记录渲染 志
// 渲染
app.on('error', err => logger.error(err));
app.listen(port);
稳定性
首先,你要有单元测试
app.use(onerror); app.use(trace); app.use(meta); app.use(detector); app.use(cacheControl); app.use(backup); app.use(render);
// 异常处理
// 打印 trace log // 记录时间等信息 // 判断终端类型
// 设置 CDN 缓存头 // 备份容灾
// 渲染
编写可测试的代码
测试覆盖率与持续集成
让测试覆盖率告诉你哪里可能存在 bug
持续集成察觉每次代码变更引入的潜在风险
Cluster
Master 只做进程管理
worker 异常退出后自动重启 (cfork) http 服务优雅退出 (graceful)
监控关键指标,对异常告警
所有的请求都有 accesslog 追踪 所有的异常统一记录,并分类输出 依赖系统调用 tracelog,记录请求和响应情况
日志
系统状态:CPU / 内存 / Load / 磁盘空间 / ... 服务状态:响应时间 / QPS / ... 依赖服务状态
监控
系统 / 服务状态异常:RT 增高 / Load 增高 / ... 依赖异常:调用失败 / 调用超时 / ... 服务异常:异常日志
告警
快速感知(告警)
快速感知(告警)
快速定位(监控、日志)
快速感知(告警)
快速定位(监控、日志)
目的是快速恢复
双十一 === DDos
绝大部分的页面不需要每次请求都重新渲染
解决双十一流量高峰的高并发问题
大大节省机器成本
合理利用 CDN
合理利用 CDN
基于 CDN 的 URL 统一
不同终端请求相同 url CDN 识别设备类型 渲染服务返回不同页面
基于 CDN 的 URL 统一
不同终端请求相同 url CDN 识别设备类型 渲染服务返回不同页面
容灾与预案
Impossible is nothing
依赖服务宕机
机房断电、断网
光缆被挖断
消灭单点、弱化依赖
异地双机房部署
OSS 双节点主备容灾 数据、模板磁盘文件容灾
预案自动化
CDN 回源健康检查,异常自动切换 OSS 健康检查,异常自动切换 系统 Load 过高自动切换静态备份 渲染异常自动切换静态备份
====================================================================

链接: https://pan.baidu.com/s/1i55aAI5 密码: 15i1

Blend,完美地混合 Web App 与 Native App ——雷志兴

Blend,完美地混合 Web app 与 Native App ——雷志兴

====================================================================
雷志兴(berg)百度资深工程师2007~前端基础技术技术开源(tangram/fis/clouda)w3wmember 微博@berg 微信订阅号devlife(行云出由)outlineweb 开发者在无限种的困局blend:融合与界限释放 web 天然的灵活性系统架构与实践在产品中天衣无缝地应用多少 nativeapp 可以用 web 技术实现,html5 37%,phonegap 49%,appcelerator 63%,性能46%,与 nativ 交互29%,apis 37%,元素固定位置,图片或 tab slider,弹出层,加载更多,无限下拉,转场、动画问题87.5%,调研百度移动站点,滑图浏览,可滑动的容器,元素固定,弹出层,最终,分享,软键盘。多级菜单,下拉刷新,刮奖,400+androidApp,国图,非游戏,工具
能力:离线能力,输入调起键盘,设备状态,系统控制,多媒体处理,文件系统,跨应用调用。
容器:可滑动的容器,可滑动的 tab,卡头效果,下拉刷新,无限滚屏,
组件:分享,弹出层,划图浏览,IM,多级菜单,刮奖,摇一摇。
400+Android App
Blend:融合与界限
Native:性能高,开销可控,动画流畅,系统 API。
web:开发速度快,推广成本低,发版优势,定制性高,开放。
instagram、evernte、apple app store、ibooks、twitter
手机百度、手机淘宝、微信、58同城
The Verge放弃 app
微软开发跨端的 web 编程套件
basecamp
decision based on computing speeds quickly decay
native shell + netive navigation - david
creator of ruby on rails,partner at 37signals
phonegap、appcelerator、native
Native:运行容器、基础 API、系统核心能力,复杂或重要交互
web:内容呈现、时效性功能、需快速迭代部分、开放给第三方、
blend:灵活、低耦的组件库、api 及运行环境
融合 webapp 与 native app
释放 web 天然的灵活性 every element can be a webview
容器的多样性
常用或核心组件 native 化
native 代码针对关键问题,代码规模小,可控
转场、动画、重点组件由native 完成
释放 web 的灵活性到 native 中,单个 webview 变小,局部性能可控,webapi,events
系统架构与实践,打包平台/api,本地资源 web 资源,插件动态更新,多 webview,运行容器 technique overview
关键概念:background page,启动 app 时自动启动 webview,做事件传输和插件加载的中枢
webview 通讯,blend.ui.fire('open', 'top',{},callbackFn),blend.ui.on('open', function(event){})
layer 对应 webview(android view)
layergroup 对应 webview(android viewpager)
component 对应页面上的 native 组件(独立 apk)
可以被动态加载,分成固定和非固定两种
加速手段 dom 加大缩减 dom 体积,复用 webview 减少重绘
javascript 避免大量 dom event 监听
动画 androidview 代替 css3
网络资源离线:webview 预加载、预渲染
复杂控件:嵌入 native 控件
内核 T5浏览器
实践
如同对待 dom 一样对待 webview(谨慎创建,即使销毁)
通讯或其他密集操作,几种到 rootwebview 处理
善用本地能力,调用网络检查能力,在低速网络中做图片压缩,
webapp 优化同样适用:少用 js 动画,减少阴影、透明、圆角、做点击延迟、适时采用 cssflex 布局,减少 dom 重绘
采用适当的编译套件自动生成 webview 和 hybrid 两份代码
native 限制 webview 数量,动态加载插件做重试
性能首要目标原生动画与空间,缩减 dom,可离线,t5内核
灵活性,带来无限可能,随时更新,动态扩展,低耦合,无限定制
能力,设备 api,系统能力封装,webview 控制力,云能力
web 一份代码,随处运行,web for all
天衣无缝的使用快速开发 mvp 最消息可执行产品,于都 lite 版,醉了于都,开发两周,轻应用 store 升级,开发一周
大中型 app,释放 web 灵活性,随时更新又保证体验,clouda.com
android/ios sdk,多 webview 支持,插件动态加载,native 组件打包平台
blend 用 web 封装轻量的 native 运行环境,多 webview 技术释放了 web 灵活性,动画,调度,资源挂历由 native 保证性能和稳定性插件动态加载进一步扩展系统的自由度
blend 也是一种开发理念,释放 web 的灵活性到 app 中,做到快读的迭代速度,也能足够流畅。
====================================================================

链接: https://pan.baidu.com/s/1sldFVlV 密码: 7j7v

手机QQHybridApp优化新思路——陈桂鸿

手机qqHybridapp优化新思路——陈桂鸿
2014-10-10
下载链接见文章结尾
====================================================================
AK (AlloyKit)手机 QQ Hybrid App 优化新思路腾讯 AlloyTeam 高级工程师 - 陈桂鸿2014-10-10 个人简介 About Me个人信息鸿 腾讯 AlloyTeam2010腾讯WebQQQ+ QQ间联 发http://www.alloyteam.com/author/rehorn/  陈工作方向Web + Client HybridWebAppH5 Alloyteam动团队 发构 发项腾讯优QQ 主要内容  Web / Client 选型  移动时代 Hybrid Web 困境  问题到此为止,AK(AlloyKit) 产生与架构  WebViewURL态资线  动态 cgi优  Web 规UI Kit Pro  WebJS Api  AK 其他模块  多端融合思考 更快的迭代更高开发效率WebClient更好的性能更高级的 api 能力 Hybrid硬件性能提升渲染性能加载性能Web 迭代能力客户端高级能力 移动时代 Hybrid Web 困境  打开慢、打不开动 络 稳载时间⻓长  一直在菊花、到处是菊花cgi载时性能差、卡动图体验差,有些功能 Web 做不了统级 api  调试不方便pc 调试组选图AK 关于 AKAKAlloy+Kit多端Mobile开发套件合金WebviewWebClient体验AlloyTeamServer解决方案高性能 Hybrid Web 开发框架 AK 用户与数据5 BG9 D100+ JSApi200+ App19+亿/天10+亿/天 AK 架构体系 打开慢、打不开、菊花?耗时分析WebviewWeb 资  动态 cgi 载载时时时 缩短白屏,消灭菊花  Webview 内核初始化提速  pc 180ms ios 50ms  android 4s手Q android 4.7.2 缩短白屏,消灭菊花  Web 前端加载耗时?优  还  缓  H5线办进击 Hybrid App缓 AK 的离线机制  前端透明  特征  zip offlineURL  多种离线更新方式户  传输优化zip 压缩传输试换选择 线  机制灵活可控  废  安全校验  md5过篡 AK 的离线机制完善的离线包更新机制资户  Web App 启动Q 录 & 启动  实时 push员资时  更优的资源下载策略  检查http cgi -> sso socket98.5% -> 99.94%载优续传块 载试逻辑  更优的资源更新策略 - 增量更新压缩Webapp-v3_1 覆盖MD5 比对bsdiff Chromium Courgette进bsdiffWebapp-v3_1bspatch  影响 bsdiff 效果的因素  zip压缩  zip标时间压缩仅顺额  zip  js 进uglify 压缩变变增量包大小减少 80%+  离线文件安全  verify.json (md5  verify.signature)MD5 + 非对称加密### 更优的资源调度 - 控制中心 AK CCenter  过  预 载续传试逻辑 离线化的价值手Q吃喝玩乐首页数据来源:habo.oa.com 离线包机制手Q群成员列表页面 动态数据拉取优化方案  静态资源 100ms ~ 1s  动态数据,cgi 数据,定位信息等, 4s ~ 6s  AJAX & 直出?& 户 环线 动态数据拉取优化方案  模拟客户端弱网络、无网络下体验  localStoage & 手Q JS Api (20M)  数据缓存层解决方案  优localStorage命名空间、有效期、版本、容错、默认数据、重要性、重写 Clear 动态数据拉取优化方案  提升缓存命中率  cgi url + param key/value  default data应 问题 +储30-40 命中率? 提升数据缓存命中率优化前:只有重复打开的页面才能命中缓存,首次打开详情页本地无缓存优化后:首次打开详情页也能命中缓存,一般有 30% 的用户会进入详情页思路:命中率、允许数据冗余、数据一致性命中率:90%+ 动态数据优化价值手Q群成员列表页面 动态数据拉取优化方案  基于 SSO Request 的数据协议优化  ajax http 恶  ip频 脏词 ⻉贝  验证码Q讯  开发支持稳SSOsocket 回顾打开慢、打不开、菊花?AK  内核启动优化  Webview 热启动  静态资源线  动态数据localStorage 缓SSO Request& 性能差、卡  性能优化最佳实践  Web 交互模型抽象  UIKit - Pro UI 库 体验差 - JS Api 增  补⻬齐系统能力  获张图红  h5 api 兼容android视频  更高效原生组件 & ios lua 客户端插件  图 查选择选择  Webview 能力扩展  data 20M localStorage  Webview event postMessage  Webview 导  SSO Request... 开发调试  模拟调试  远程调试  webkit / werein / jsconsole / livereload / browersync  调试工具  mobug AK 其他辅助模块限校验录态动动续录态  JS Api  DNS 管理  ip  尝试检验ip 访问  数据上报键动报 api报 多端融合多端团队跨端技术堆栈团队协作版本化思维 THANKS使用技术改变世界,成为业界卓越团队—— AlloyTeam@ QCon 上海 2014
====================================================================

链接: https://pan.baidu.com/s/1dFf0pmp 密码: cqh1

从零开始做运营读后总结

该书第一章节主要讲述了运营的职业发展道路,一个互联网产品不管上线于否都需要运营,能做出好产品的不一定能做运营,而能做好运营的人职业发展道路开阔,也则可以向产品方向发展。二者岗位息息相关,很难离开其中一方。

第二章节主要讲述了运营的定义和职能,运营就是要获取足够多的有价值的用户流量,将其转化。也就是一切能够进行产品推广、促进用户使用、提高用户认知的手段。

第三章重点讲述了内容运营的消费者和内容的生产者,以及重点以知乎为例的ugc(用户生成内容)类型的社区模式。和如何甄别优质内容和展现

第四章讲述了微信公众平台的内容发布时间和内容原创的重要性,从数据看,最多的是在晚上,但是那样竞争性太大,可以选择中午发布,这样可以尽可能的避开峰潮得到展现,还能在晚点得到第二波峰潮。内容的原创性在微信有一定的激励机制,以及微信内容发布的频率。总结:内容原创且符合定位的用户,加发布频率高的,用户阅读数据可以呈现稳步上升状态。

第五章讲述了如何让用户自发的成为内容的生产者,第一种以Gmail(谷歌电子邮箱)为例的“邀请机制”可以让用户感觉到稀缺性,体会到高贵感,但是如果用户预期控制不当/内容生成者/运营者的能力不足/网站技术问题,很容易导致用户期望值降低,无法带来留存和活跃。第二种“护城河机制”就是认为的确立一个较高的入场门槛。好处是避免小号等灌水内容,确保用户发言或者发帖时已经学习过规章制度减少垃圾内容。坏处是考验了用户耐心极有可能流失部分用户。营造氛围,规定社区运营的的规章、建立标准化内容,也可制造冲突,让用户自发战队,最好可以利用当下最被关注的热点,可以减少制造冲突带来的风险。

该书比较适合刚入门或者入门不久的人读,看完还是有一点收货的。