垃圾回收原来是这么回事

摘要:John McCarthy身为Lisp之父和人工智能之父,同时,他也是GC之父。1960年,他在其论文中首次发布了GC算法(其实是委婉的提出😂)。而Java的前身Oak是在1990发布的,利用JVM实现了跨平台。GC因此一举成名。 最近想复习一下JVM的知识。然后发现网上不少文章在写JVM的垃圾回收算法时,都比较偏向于具体实现,而少有站在更高角度来看垃圾回收算法的文章。而我本人想对垃圾回收算法有个全景的认识,所以,就找到了这本《垃圾回收的算法与实现》(以下简称《垃圾回收》)。本篇博客就是尝试对“全景”的总结。 以下为方便讨论,垃圾回收缩写成GC。 为什么要有GC 我时而听到C++程序员说我们是被GC惯坏了的一代。的确是这样的,我本人在学习GC算法时,大脑里第一问题就是为什么需要GC这样的东西。说明我已经认为GC是理所当然了。😂 总的一句话:没有GC的世界,我们需要手动进行内存管理,而手动内存管理是纯技术活,又容易出错。 既然我们写的大多程序都是为了解决现实业务问题,那么,我们为什么不把这种纯技术活自动化呢?但是自动化,也是有代价的。 这是我的个人理解,不代表John McCarthy本人的理解。 “垃圾”的定义 首先,我们要给个“垃圾”的定义,才能进行回收吧。书中给出的定义: 把分配到堆中那些不能通过程序引用的对象称为非活动对象,也就是死掉的对象,我们称为“垃圾”。 GC的定义 因为我们期望让内存管理变得自动(只管用内存,不管内存的回收),我们就必须做两件事情: 找到内存空间里的垃圾 回收垃圾,让程序员能再次利用这部分空间 [1] 只要满足这两项功能的程序,就是GC,不论它是在JVM中,还是在Ruby的VM中。 但这只是两个需求,并没有说明GC应该何时找垃圾,何时回收垃圾等等更具体的问题,各类GC算法就是在这些更具体问题的处理方式上施展手脚。 GC的历史 John McCarthy身为Lisp之父和人工智能之父,同时,他也是GC之父。1960年,他在其论文中首次发布了GC算法(其实是委婉的提出😂)。 标记-清除算法 由John McCarthy在1960年提出 引用计数法 由George E. Collins在1960年提出 此算法会有循环引用问题,Harold McBeth 1963年指出。 复制算法 由Marvin L. Minsky在1963年提出 《垃圾回收》的作者认为: 从50年前GC算法首次发布以来,众多研究者对其进行了各种各样的研究,因此许多GC算法也得以发布。[2] 但事实上,这些算法只不过是把前文中提到的三种算法进行组合或应用。也可以这么说,1963年GC复制算法诞生时,GC的根本性内容就已经完成了。[3] 那我们常常听说的分代垃圾回收又是怎么回事?作者是这样说的: 人们从众多程序案例中总结出了一个经验:“大部分的对象在生成后马上就变成了垃圾,很少有对象能活得很久”。分代垃圾回收利用该经验,在对象中导入了“年龄”的概念,经历过一次GC后活下来的对象年龄为1岁。[4] 分代垃圾回收中把对象分类成几代,针对不同的代使用不同的GC算法,我们把刚生成的对象称为新生代对象,到达一定年龄的对象则称为老年代对象。[5] 好了,这下我总算知道为什么要分代了,我的总结是: 将对象根据存活概率进行分类,对存活时间长一些的对象,可以减少扫描“垃圾”的时间,以减少GC频率和时长。根本思路就是对对象进行分类,才能针对各个分类采用不同的垃圾回收算法,以对各算法进行扬长避短。 留一个问题给读者:我们知道分代垃圾回收所采用的堆结构是: 为什么新生代空间要分成“生成空间”和“幸存空间”,而幸存空间又分成两块大小相等的幸存空间1,幸存空间2? 这些GC算法共同解决的问题 上面我们说了,GC的定义只给出了需求,三种算法都为实现这个需求,那么它们总会遇到共同要解决的问题吧? 我尝试总结出: 如何分辨出什么是垃圾? 如何、何时搜索垃圾? 如何、何时清除垃圾? 这样,只要涉及到垃圾回收,我就可以从这2点需求,3个共同问题(两点三共)出发来讨论、学习。 如何评价GC算法? 如果没有评价标准,我们当然无法评估这些GC算法的性能。作者给出了4个标准: 吞吐量: 单位时间内的处理能力 最大暂停时间:GC执行过程中,应用暂停的时长。 较大的吞吐量和较短的最大暂停时间不可兼得 堆的使用效率:就是堆空间的利用率。 可用的堆越大,GC运行越快;相反,越想有效地利用有限的堆,GC花费的时间就越长。 访问的局部性:把具有引用关系的对象安排在堆中较近的位置,就能提高在缓存中读取到想利用的数据的概率。 好吧。两点三共,四标~ 小结 搞清楚为什么要GC,要实现GC都要解决什么问题,而各类算法又是怎么解决的,最后怎么评价这些算法。GC原来是这么回事。 但是这不是GC的全部。但是提供我一个思考GC的思考框架。 以上就是《垃圾回收的算法与实现》的读书笔记。如果想更深入,可以阅读《垃圾回收算法手册:自动内存管理的艺术》。 [1] 《垃圾回收的算法与实现》 P2 ...

2017-02-04 · 1 min · 80 words · 翟志军 Jack Zhai

这样搭建Spark学习环境效率似乎更高

像学习Spark这类大数据平台,搭建环境,是一件很费时费力的事情。特别是当你想使用多台机器模拟真实生产环境时。 为了更有效的学习Spark,我决定将自己的学习环境按生产环境的要求来搭建。但是真实生产环境的群集往往由多个集群组成:Hadoop/Hbase集群、Zookeeper集群、Spark集群。掐指一算,至少需要6台机器了。 我们真的需要买6台机器吗?当然不是,我们只需要在自己的电脑上虚拟化出6台就好了。而我的电脑只有16G,虚拟化6台太吃力了。最终,我决定搭建成以下结构: 以下是搭建过程: 环境的搭建 按以前学习像Spring这些类Web,开发环境的搭建非常简单,也就引入几个依赖,添加几项配置,就好了。 但是学习Spark,我敢肯定不少人在环境搭建这一环节踩坑。正因为这样,才会有此博客。 Spark不是一框架,而是一个分布式的计算平台。所以,你不能通过引入依赖,添加配置就完成搭建。需要先将Spark这个平台部署起来。Spark支持4种部署方式: 单机:同一台机器,同一进程,不同线程运行Master和Worker 伪分布式:同一台机器,不同进程分别运行Master和Worker Standalone方式:多台机器分别运行Master和Worker,自己解决资源调度 Yarn和Mesos方式:将资源调度这一职责外包出去 虽然Spark的单机部署方式很简单,但是没有人会在生产环境上使用单机部署方式。而伪分布式我见不少人搭建,以此为基础来学习Spark。但我不推荐。 因为在线上真正运行的是Standalone、Yarn、Mesos方式,也称为完全分布式的方式。只有一开始就使用完全分布式的方式来进行开发调试,你才会学习到生产环境会遇到什么问题。 机器准备 如果采取完全分布式的部署方式来学习,你必须准备很多台机器,就像上面所说的。 我想大多数人都会选择虚拟化方案来得到多台机器。我推荐Virtualbox。 我见不少人手工的创建一台机器,然后安装操作系统,接着想要多少台机器,就复制几台,甚至还要分别进入机器修改每台机器的IP。。。 这样的方式,效率低,又很难与你的同事分享你的环境(也就是统一一个团队的开发环境,以避免不同开发环境不同引起的问题)。 所以,我一开始就使用Vagrant。把机器的虚拟化这一动作进行自动化和版本化(提交到git仓库中)。使用了Vagrant,你只需要在Vagrantfile中定义机器数据、机器的系统镜像、CPU个数、内存,然后执行vagrant up,就可以得到你想要的机器了。要与同事统一这些机器,只需要他使用相同的Vagrantfile就好了。 同时,这样,还能实现:统一开发环境与生产环境使用同样或相近的机器环境。 以下是一个Vagrantfile样例: Vagrant.configure(2) do |config| VAGRANT_VM_PROVIDER = "virtualbox" machine_box = "boxcutter/ubuntu1604" -> 系统镜像 config.vm.define "offlinenode1" do |machine| machine.vm.box = machine_box machine.vm.hostname = "offlinenode1" machine.vm.network "private_network", ip: "192.168.11.151" -> 指定IP machine.vm.provider "virtualbox" do |node| node.name = "offlinenode1" node.memory = 4096 -> 指定内存 node.cpus = 2 -> 指定CPU个数 end end config.vm.define "offlinenode2" do |machine| machine.vm.box = machine_box machine.vm.hostname = "offlinenode2" machine.vm.network "private_network", ip: "192.168.11.152" machine.vm.provider "virtualbox" do |node| node.name = "offlinenode2" node.memory = 4096 node.cpus = 2 end end ....... 还可以定义很多这样的机器 end 搭建Spark集群 在准备好机器后,接下来做的就是搭建Spark集群。我会选择Ansible来实现自动化搭建,而不是一台台机器登上去,一条条命令的执行安装。 ...

2017-01-31 · 1 min · 142 words · 翟志军 Jack Zhai

关于“以结果为导向”的管理方式的碎碎语

先申明:我反驳“以结果为导向”的某些理由,并不代表我认为管理应该不制定目标,管理不应该有结果。 前些天与朋友聊天,聊到管理。虽然两人所处不同行业,他是保险业,我是软件开发,当聊到管理的“以结果为导向”。我的话匣就打开了。 后来,我总感觉自己思路还不够清晰,就总结此文。 首先,我们需要统一对“以结果为导向”这个概念的理解。要不,我们的讨论可能就不在同一个频道上。 我听过的最多的,对于“以结果为导向”的理解就是:我只管结果,不管你中间过程怎么做。 这个“我”,是当事人。这里的假设是,这个“我”是一个管理者。 但是,为什么呢?只管理结果,不管过程呢?我得到的理由是: 人多了,会管不过来 作为“领导”(很多人常常把领导和管理两个概念混淆),下属当然要完成领导指派的“结果”,否则,我要你做什么? 我们要鼓励员工的主人翁精神 微管理会束缚员工的创造性 我不知道, 上述的有没有统一大家的理解。但我还是要尝试接着逐一讨论。 人多了,会管不过来 对于“人多了,会管不过”这个观点,我听到的阐述是: 当你手下只有3个人的时候,你当然可以管得过来,你可以很容易知道他们上班时间里有没有干与工作不相关的事情,甚至知道他们什么时候去厕所了。 但是当你做到事业部经理时,管理4个部门,每个部门都有100个人的时候,你怎么管。 这些支言片语中,我粗鲁地认为这些言语包含以下几点假设: 管理中,“监督”工作占很大的比例 管理一个3人团队和管理4个100人部门使用的是同一套管理方式 管不过来,是因为人多 我的个人观点: 以上几点假设之间相关的,因为如果管理400人时和管理3人时的方法一样,管不过来,当然是因为人多。同时,人数不是决定管理方法的唯一因素,还有你的团队成员职能结构组成等等。 我是领导,我只管结果 我擅自将“作为领导,下属当然要完成领导指派的‘结果’,否则,我要你做什么?”这句长句抽象成:我是领导,我只管结果。这个“结果”的同义词是目标,也被称为KPI。 首先,我们得承认,某些“领导”有这个权利那样做。 接着,我从这个观点中看到以下几点假设: 下属足够做得好,怎么样都能完成我(领导)定好的“结果” 领导的工作就是“管结果” 领导定好的“KPI”就是正确的 我的观点: 定好KPI是一种能力。如果一个没有定好KPI能力的领导说他只管结果,下面的员工就只能呵呵了。 管理是有级别的,过程终究是要管理的,只不过,不同的级别,管理的过程不一样。一线项目经理手下可能有前端、后端,如果他只管结果,不管,前后端是如何协作的,他是怎么知道他们团队的工作效率的?如果连自己的团队的工作效率都评估不了,我要这个项目经理做什么?😜 所以,并不是每种“领导”都有权利说“只管结果” 我们要鼓励员工的主人翁精神 这句话的假设是: 管理过程了,就是不鼓励员工的主人翁精神 只管结果,员工才会有主人翁精神 微管理会束缚员工的创造性 这句话的假设是: 只管结果,不管过程就不是微管理了 管过程就是微管理,那么,又引申出来假设:管过程会束缚员工的创造性 微管理会束缚员工的创造性 思考这些理由背后的假设是否成立 反驳一个人的观点时,一个有效的方法就是找到他的观点背后的“假设”。所以,我尝试去找到那些理由背后的假设。因为如果假设不成立,他的理由当然也就不成立了。 以上的“假设”在不同的公司环境,结果可能不一样。比如管理中,“监督”工作占很大的比例,在软件行业,管理活动中,“监督”所占的比例当然没有劳动力密集型工厂里的管理所占比例大。不过,说回来,软件行业也有劳动力密集型的。 软件行业的过程管理 说到底,一线软件开发团队当然需要过程管理,要不,你没办法评估它的开发效率。 当然,有些人就会反驳,你制定一个目标,如果他完成了,那么不是说明效率可以吗? 我的回答是:你的假设是完成目标等于效率高,你仔细想想,这两者是等于关系吗? 但是管理到什么程度算“微”,我目前没有想到好的度量方法。不过,过去一年中,我发现使用“看板”来进行微管理,效果不错。既能管理结果(软件产品),也能管理过程(团队成员协作)。本文的目的不在讨论软件行业如何进行过程管理,所以,就不深入讨论了。 小结 倡导“以结果导向”的管理方式的人,本质上是在倡导宏观管理。其实,倡导宏观管理,就是在假设宏观管理和微观管理是两个矛盾的东西。但是,我不认为这个假设是正确的,因为我们的目标是管理好一家公司以实现盈利,总之就是要管理好,为了实现这个目标,需要进行宏观管理时,就进行宏观管理,需要进行微观管理时,就进行微观管理。我们不能因“宏观”和“微观”的概念之分而忘记管理的初心。 上述观点纯属个人理解,不一定正确。欢迎讨论。 扩展阅读:平庸的领导忙着无数小事,卓越的领导从来只管大事

2017-01-20 · 1 min · 55 words · 翟志军 Jack Zhai

一个热词推荐的简单实现

为什么想做这个东西 一直好奇像亚马逊这类网站的搜索是如何做到推荐的,最近刚好看到一篇文章:Redis 与搜索热词推荐,然而只写了思路。所以,就是想自己实现一个。 先上个效果图,再聊: P.S. 按四年前,要写这样的前端效果,对于我这个后台开发,还是挺困难的。而现在,简单的学了下Vue.js,再加上同事的小小指点,就搞定了。😂 热词推荐的本质 假如你预先就知道了用户输入:s、sz、shen、深这些字时,就是想搜“深圳”,那是不是说,我们只要提前将这些字放到一个Map结构中,将用户的输入想像出一个key,value就是“深圳”。 说到底,热词推荐的本质就是一个大大的Map。难点就在于如何更新这个Map,以至于让用户觉得“智能”,或觉得我们在给他们做“推荐”。 这个Map,常常被人称为“索引”。其实使用“索引” 这个名词也更准确一些。Map中的Key是不能重复的。但是我们数据结构是要求可重复的,为什么呢?因为,在系统中,s、sh、shen、深等等这些都是key,而它们对应的value,可能相同,又可能不同。举个例子: hotword:0>zrevrange s 0 10 1) 鼠蛟 2) 鼠场乡 3) 鳝鱼 4) 鳝溪校区 5) 鳝溪农场 6) 鳝溪 7) 骚子营社区 8) 骚子营 9) 驷马镇 10) 驷马桥街道 11) 驷马桥 hotword:0>zrevrange sh 0 10 1) 鼠蛟 2) 鼠场乡 3) 鳝鱼 4) 鳝溪校区 5) 鳝溪农场 6) 鳝溪 7) 首院胡同 8) 首阳镇 9) 首阳山镇 10) 首阳山 11) 首钢试验厂 仔细看到其中的不同了吗?同时,这里还有一个问题,那就是当用户输入s时,出现了10个value,我们如何给这些value如何排序呢? 为了与排序模型解耦,我们为每个value都给出一个分数score。score越大,越排前面。最终索引结构就变成了这样子: P.S. 这些score之所以都为0,是因为数据问题。 总的来说,关于热词推荐,我们需要解决以下问题: 如何存储索引的数据? ...

2016-12-31 · 2 min · 260 words · 翟志军 Jack Zhai

似乎百分之七十的人都理解错了KPI

关键绩效指标(英语:Key Performance Indicators,简称KPI),又称主要绩效指标、重要绩效指标、绩效评核指标等,是指衡量一个管理工作成效最重要的指标,是一项数据化管理的工具,必须是客观、可衡量的绩效指标。这个名词往往用于财政、一般行政事务的衡量。是将公司、员工、事务在某时期表现量化与质化的一种指标。可协助将优化组织表现,并规划愿景。 KPI是指衡量一个管理工作成效的最重要指标。注意,是管理工作成效。实现中,管理工作当然由管理者来做,也就是管理者是拿来KPI来管理自己的工作成效。同时,KPI也要选择最重要的指标,而不是什么都选 ,因为并不是每项KPI都能体现管理工作成效。 光看这个定义,似乎很多公司都把KPI理解成:“员工完成了管理者安排的工作” == “管理者的管理工作有成效”!而且,只止于此。 翻看历史你就理解我说的了:宋太宗“雄韬武略”遥控指挥军队差点全军覆没! 作为管理者宋太宗的管理工作成效应该是打赢仗,而不是军队有没有按照他的“阵图”来行军。(我又甩锅了。呵呵) 光看KPI是没有问题的,谁都想知道自己的工作成效如何,尤其作为管理者。 但,KPI的选择并没有那么简单。根据自己对KPI的理解,管理者为自己找KPI时必须做到: 管理者必须理解KPI的目标:衡量自己的管理工作成效。 管理者必须理解公司的业务目标是什么,避免为了KPI而KPI。 管理者必须知道业务指标是什么?比如500万的销售额 管理者必须知道执行哪些管理工作才能帮助实现业务指标,如果不知道,那么就需要做实验,再验证! 管理者必须知道自己有没有100%执行相应的管理工作 定义个KPI都这么难,所以,管理者不好当啊。你也看到了,我一句也没有提下属的KPI。因为下属的KPI是需要管理者与其下属共同制定的。下属对自己的管理成效本质上就是很多公司希望的“自我管理”。而自我管理的成效是没有办法量化的,作为管理者,也只能看下属的自我管理后的表象。 看到这里,相信还是有很多人疑惑,到底怎么做KPI啊。 首先申明,KPI不是制定出来的,而是找出来的。因为指标本来就存在了,问题只是你选择什么指标作为管理成效的KPI。它是一个名词,不是动词。(想起人们常常开的玩笑:你今天被KPI了吗?) 那如何找KPI呢?我的回答是:你清晰地知道你的业务目标,以及如何达到,你就自然而然地知道你的KPI有哪些了。 小结 KPI是一个名词,不是一个动词。管理者的管理成效不等于员工的100%执行。KPI本质上是自我管理,不是上级对下级的工作安排。工作如何安排,不在本文讨论范围。 抱怨KPI是没有用的,现实世界中,KPI在企业中会与企业的其它因素起化学反应,远没有本文说的那么简单。 最后,两个思考题: “如果新浪要求自己员工每天要发2条以上微博” 这条能成为新浪员工的KPI吗? “主导XXX系统(或模块)开发” 这条能成为你的KPI吗? 请停留思考,然后再看:SMART原则。

2016-12-21 · 1 min · 30 words · 翟志军 Jack Zhai

反馈机制在企业中的作用?

进入ThoughtWork后,每天都会有人向你提反馈。比如站会,你这样说会更好;你代码这样写也许会更好;你这段时间英语进步得非常快……这些反馈中,有对你优点反馈,也会对你的缺点进行反馈。 这个过程,我才发现自己以前很多没有发现的不足,某些固化的思维方式,我的视野也一下开了好多。 后来,离开了ThoughtWorks。我尝试将反馈机制带入到自己的团队。怎么尝试呢? 首先,你需要让团队成员达成共识:只有成长,我们的生活才更美好,而反馈就是在帮助对方成长。当然人们对于“美好”的理解不同,有些人觉得有钱就是美好,有些人觉得得真正学到东西就是美好。这些都无所谓。因为成长了,这些美好都会有。 接着,从自己做起。每天尝试给团队成员反馈。只要找到合适的时机及时给予反馈。举例子: 一个成员写代码时,不加思索的就上个大大的if-else,这种情况,最好马上指出,同时告诉他背后的原因。但是现实中,有时,我们需要考虑多一些,比如这个成员是不是超级要面子的,这个成员是不是团队受尊重的老员工。这时就要考虑沟通方式了。 团队中两个成员因为某件事情吵了起来。而这件事,也不是特别大的事情,也没有吵多久。这时,你就要看他们是不是还气在头。合适的时机是等他们的气消了后,再分别给他们反馈。 然后,争取每隔一段时间就每一位成员进行一次一对一沟通。沟通的内容包括生活和工作,主要是了解他们对当前工作的看法,生活上有什么需要帮忙,学习上有没有遇到困难,工作上有什么不顺心……这个过程其实是成员向你反馈: 工作安排得合理不合理? 与同事相处是否舒服? 有没有学习的焦虑? …… 《创业维艰》这本书专门有一节谈“一对一的沟通”,有兴趣的朋友可以看看。 最后,引导并指导团队成员相互之间进行反馈。 话说这里了。那反馈机制在企业中到底起到了什么作用?我不知道专业的管理行家如何回答。但是,我自己的理解是这样的: 马斯洛的需求理论,反馈能满足马斯洛的需求理论中的的安全需求(你可以和他一对一沟通)、归属需求(Leader是把他当一个团队成员来对待的)、尊重需求(尊重了他)。 人天生就是通过反馈来成长,就像小孩通过你他的反馈来调整自己的行为。而如果团队成员得到了成长,就刚好可以满足了他的“自我实现”需求。 需求得到了满足,在其中工作,当然就会快乐。 有人就会说了,员工在工作中能否找到快乐,那是员工的事。这个观点即对,也不对。快乐的确是每一个人的。但是员工毕竟是人,不是机器。 不快乐的工作,同样可以完成机械的活,像珠三角大批的工厂工人。而创造性的工作,如软件开发,做产品,不是机械完成就好了的,也不是能通过机械地堆人就能完成的。 同时,反馈带给员工的成长,会正反馈到工作中,员工工作效率高了(学习新的技术、知道更多的解决方案),我们软件开发速度及开发质量会不会提高呢? 小结 我个人认为,以上只是“反馈机制”给企业带来表面利益,它给企业的是更深层次的东西:企业相互学习、相互帮助的文化。不是说企业有了“反馈机制”就有了文化,而是说企业文化就是由这些道不清说不明的东西,通过时间一点点积累起来的。 以上是个人习得的,希望能和大家交流。

2016-12-10 · 1 min · 24 words · 翟志军 Jack Zhai

模仿京东使用Openresty+Redis做读服务

看了开涛的Nginx+Lua开发教程,很是感兴趣。所以,自己也把环境搭建起来玩。 跟开涛的不同,我使用Vagrant + Ansible来搭建(不要问我为什么不使用Docker)。这样,所有的人只要两条命令就可以搭建好了,而不需要手工一条命令一条命令打。 所谓使用Openresty来做读服务,是指Openresty直接从数据源读数据,然后渲染输出,而不经过应用服务器,比如Tomcat服务器。Openresty 是一个基于Nginx和LuaJIT的动态Web开发平台。我不知道京东是否是直接使用Openresty还是自己编译Nginx + Lua。反正,我直接使用Openresty。 本次文章就是根据开涛的教程,实现使用lua-resty-template 做模块引擎,使用Redis做数据源。我把Openresty和Redis都安装在同一台机器上,以方便做实验,当然,如果你想装在不同的服务器,只需要修改下配置就好了。以下是架构: 搭建的步骤: 安装Openresty及其相关的Openresty module: lua-resty-template、lua-resty-redis 安装Redis,启动Redis 配置Openresty,启动Openresty 写页面逻辑代码 整个步骤我都写成了Ansible自动化配置脚本。所以,你已经不需要自己搭建。所有的代码都托管在:http://git.oschina.net/zacker330/openresty-lab 。 启动方法 启动前,你必须安装Vagrant 和 Ansible 2.0+。 git clone https://git.oschina.net/zacker330/openresty-lab.git cd openresty-lab vagrant up ansible-playbook ./ansible/playbook.yml -i ./ansible/inventory -u vagrant -k >> 输入ssh密码 `vagrant` PS. ansible-playbook需要通过ssh登录上目标机器来执行我们的任务。 接下来,我们解释下代码。 Openresty的配置如下: ## 省去了一些不重要的nginx配置 http { default_type application/octet-stream; ## 省去了一些不重要的nginx配置 ## 初始化所需要对象 init_by_lua ' require "resty.core" redis = require "resty.redis" template = require "resty.template" template.caching(false); -- you may remove this on production '; server{ listen 80; server_name 192.168.8.10; charset utf-8; ## 指定 模块路径 set $template_root "/usr/local/openresty/nginx/html/templates"; location ~ \.lsp$ { default_type text/html; content_by_lua 'template.render(ngx.var.uri)'; ## 访问index.lsp,将使用index.lsp模板 } } } 页面逻辑代码 index.lsp: {% raw %} ...

2016-10-15 · 2 min · 271 words · 翟志军 Jack Zhai

商业模式与产品设计有什么关系?以媒体公司为例

大概一年前,我做了产品负责人——负责产品的所有。其中一项最重要的工作:产品设计。 产品设计是以前我从来没有做过的。怎么办呢?除了,在网上了解别人怎么做外,自己还找了一些书来看,比如《谷歌和亚马逊如何做产品》,《启示录——打造用户喜爱的产品》,张小龙的文章,张小龙推荐的《乌合之众》……从这些书中,的确学到一些产品设计上有用的东西,但始终都是隔靴挠痒,不得其法。 而后,想到公司终究是要赚钱的,我们做产品的意义大部分就是为赚钱。而看到的文章或书,鲜有谈论产品设计时,如何赚更多钱的问题。在现实中,我表达出这样的困惑,但是常常得到的答案就是,你先做好产品再想这个问题好吧;产品都没做好,就想着怎么赚钱…… 商业模式是什么? 我无力反驳,也没有人给我指导,自己又想不通(时间也不允许),就只能找书来看了。关于如何赚钱的书,抽象一些就是“商业模式”的问题,就找到了《商业模式全史》。 而这本书首先给我们讲了什么是商业: 把采购或生产出的价值提供给他人,以换取同等的价值 而商业模式: 这些要素的组合就是商业模式 我从中总结出: 产品设计的过程,始终需要想清楚,你的产品提供给用户什么价值?是通过采购的,还是生产出的? 我想到开源中国的友商,像开发者头条、掘金,属于通过生产(用户生产内容)为用户提供高质量的内容,像凤凰网这类综合传统媒体则是官方生产内容,都是生产出的。 采购的例子,可以是类似简书、CSDN的签约作者,从这些作者采购高质量的内容。 媒体公司到底怎么赚钱,广告还是付费内容? 可,还是老问题?我们怎么以换取同等价值——赚钱?我们为什么要免费为广大用户采购和生产高质量内容呢?想想以前人们想要高质量的内容都要自己掏钱买杂志的。 《商业模式全史》说到90年代发起的一个商业模式:广告模式,来自美国的哥伦比亚广播公司。免费播出节目,然后吸引广告主投放广告。是不是想起央视?还有早上地铁上免费但但满是小广告的报纸? 最近两年出了一种传统广告模式的变种:百度百家的广告分成稿酬模式。也就是百度的广告赚钱了会和作者分成。(思考题:知乎应该算是高质量的内容社区,为什么他们现在还没有大量投放广告?) 这下,我终于明白了。开源中国社区本质上和广播公司一样,也是一家媒体公司。 媒体公司除了靠广告赚钱,还可以像《男人装》、罗胖的得到APP那样做付费内容赚钱。 媒体公司的两种商业模式: 广告模式 付费内容 那你到底采用广告模式还是付费内容呢?要看你的用户群体和你的内容价值。我自己画了图,以方便大家理解。 而内容价值这个容易产生歧义,我解释下: 用户对内容的渴望度和稀缺度决定了内容的价值。用户对内容的渴望度和内容的稀缺度同时高,内容的价值才会高。 这里举个例子:1953年创办的《花花公子》杂志。2016年开始在找买家了。我猜其中一个原因是不是因为人们对其内容的渴望度降低,而是稀缺性变低了。不是么,路边摊随随便都可以买到满足欲望的片子。 说回正题,商业模式也会有创新,将来说不定又会出现第三种商业模式。 用户体验为王,就可以赚钱? 很多人说产品时,上来就说:用户体验为王,用户爽了,我们自然就会赚钱。 其实,不说商业模式,只说用户体验,就是耍流氓。去过中国政%府办事的人都会吐槽政%府办事效率低(用户体验差),但是你没有办法啊,吐槽后还是必须和他们打交道。政府有垄断性资源,人家根本不需要考虑用户体验。 内容为王 最最后,你会发现,所有的媒体公司的赚钱方式都是围绕内容,不论你使用哪种商业模式,亦或两者结合。互联网只不过是渠道。知乎不是也出Kindle格式的付费书吗? 那么,我们在做产品设计,甚至运营时,都应该从内容本身出发,比如你这套积分系统的设计是否有利于网站得到更多优质内容、你的运营策略是否有利于留住那些生产高质量内容的人等等。甚至,我们的设计师也可以根据这点来考虑button放在哪个位置更吸引人生产高质量内容。 好,现在我们总结出第二个关键点: 媒体产品都是围绕内容来做,不论什么商业模式。 问题是什么? 好了,最后,回到我们的问题:商业模式与产品设计有什么关系? 我的回答: 产品必须根据现有或将来的商业模式来设计,否则产品只是功能的堆砌。 我能想像到有人会反驳我:你看Facebook一开始时不也没有谈商业模式吗? 我想说,一开始时,你可能是凭自己的兴趣爱好来做产品,可能是为了解决自己的小问题。但是当你成立了一家公司时,你不得不考虑如何养活一家公司时,你不可能不考虑商业模式了——如何赚钱。 小结 这些都是自己个人的总结,不一定对,希望好心人斧正帮助我成长。谢谢。

2016-09-15 · 1 min · 43 words · 翟志军 Jack Zhai

如何在半小时搭建一个简单的日志分析平台?

人们常常说数据如金,可是,能被利用起的数据,才是“金”。而互联网的数据,常常以日志的媒介的形式存在,并需要从中提取其中的"数据"。 从这些数据中,我们可以做用户画像(每个用户都点了什么广告,对哪些开源技术感兴趣),安全审计,安全防护(如果1小时内登录请求数到达一定值就报警),业务数据统计(如开源中国每天的博客数是多少,可视化编辑格式和markdown格式各占比例是多少)等等。 之所以能做这些,是因为用户的所有的行为,都将被记录在nginx日志中或其它web服务器的日志中。日志分析要做的就是将这些日志进行结构化,方便我们的业务人员快速查询。日志分析平台要做的就是这些。 说完这些,你是不是觉得日志分析平台很难做,需要十人的团队加班几个月才能完成? 自从有了Elasticsearch、Logstash、Kibana,俗称ELK,小公司也可以很轻松地做日志分析了。说白了,1天几G的日志,ELK完全可以吃得消。就像标题说的,只需要1个人半小时就可以搭建好了。前提是你已经熟悉了Ansible。下文也假设你已经熟悉Anbile,如果不熟悉可以看看我的另一篇文章:Puppet,Chef,Ansible的共性 本文目的就是教你如何在搭建一个日志分析平台的雏形。有了这个雏形,你可以慢慢迭代出更强大,更适合你业务的日志分析平台。同时,提供可执行的源代码:OSC-AdCenter 简单日志分析架构图 我做了简化,架构图中的每个组件都可以分别放到不同的机器。这里简单介绍下这些你组件: your app:你的应用,我们的源码中,把这个给省略了 Openresty:基于Nginx的Web开发平台,你可以想像它基于Nginx做了很多扩展,类似淘宝的Tengine。为什么我们不直接使用Nginx呢?因为在Openresty上,我们可以做更多事情。 Logstash:日志收集,结构化数据后,push到Elasticsearch中,基于JRuby。可使用其它日志收集工具替代,比如Beats Elasticsearch:分布式搜索引擎,基于Lucene Kibana:用于可视化数据,基于NodeJs 日志分析平台开发所需要工具 Ansible 2.0+:简单的自动化配置工具,运维工具。关于自动化配置还有什么好说的呢? Vagrant:操作系统虚拟化工具,开发时使用。如果没有听过,Docker总听过吧。这家伙就和Docker完全类似的功能,也早于Docker出现。 一个简单的支持yml格式高亮的文本编辑器,比如Atom 自行下载JDK8:jdk-8u66-linux-x64.tar.gz放到项目路径:provision/roles/jdk8/files/jdk-8u66-linux-x64.tar.gz P.S. 抱歉这个的确需要你自己下。 什么?不用写代码吗?的确不用需要写。如果你要扩展这个雏形就会需要写一些脚本。 启动一台服务器 因为我们需要在本地开发好以后,再部署到生产环境,所以,我们需要一台服务器用来做实验。用Vagrant可以在你的开发机上虚拟化一台。clone 下 OSC-AdCenter后,进入项目目录执行:Vagrant up 文件Vagrantfile有描述这台机器的配置: Vagrant.configure(2) do |config| ANSIBLE_RAW_SSH_ARGS = [] machine_box = "trusty-server-cloudimg-amd64-vagrant-disk1" machine_box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" config.vm.define "oscadcenter" do |machine| machine.vm.box = machine_box machine.vm.box_url = machine_box_url machine.vm.hostname = "oscadcenter" machine.vm.network "private_network", ip: "192.168.4.10" ##指定这台机器的IP,只能宿主机能访问 machine.vm.provider "virtualbox" do |node| node.name = "oscadcenter" node.memory = 4048 node.cpus = 2 end end end 更多关于Vagrantfile:https://www.vagrantup.com/docs/vagrantfile/ Vagrant机器的默认账号密码都是: vagrant,所以你可以使用ssh [email protected]登录这台机器。也可以使用vagrant命令登录,在Vagrantfile所在目录下执行:vagrant ssh oscadcenter。 部署日志分析平台 在你的开发机上,安装好ansible: 服务器准备好了,我们只需要一条命令就可以部署OSC-AdCenter了: ansible-playbook ./provision/playbook.yml -i ./provision/inventory -u vagrant -k 然后输入ssh登录密码:vagrant。 简单说明: ansible-playbook是ansible的一个命令 ./provision/playbook.yml是描述你的服务器配置的文本,你可以想像成所有的部署脚本都写在这个文件中 ./provision/inventory是服务器在playbook在的host与ip的映射表,比如playbook中这么写: ...

2016-09-10 · 1 min · 179 words · 翟志军 Jack Zhai

关于自动化配置还有什么好说的呢?

最近我们团队正在将生产环境的配置进行自动化。简单地说就是使生产环境在任何地方都可以快速的搭建起来,比如程序员在自己的机器上,公司内部的机器上,还有云上。 本文就是想阐明为什么要自动化配置。 进行配置自动化的这个过程,我发现,问题不在于程序员懂不懂Ansible、Chef、Puppet这些自动化配置工具的使用。 问题在于对“配置”本身的理解。我甚至发现还有运维人员也不能理解为什么要将配置自动化。 配置是什么? 很多人都将搭建Tomcat、Nginx这类脚本理解成一个个“任务”。这类脚本还不能被称为“配置”。 而这类Tomcat、Nginx的安装脚本大概是这样: apt-get install build-essential apt-get install libtool cd /usr/local/src wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.37.tar.gz tar -zxvf pcre-8.37.tar.gz cd pcre-8.34 ./configure make make install ..... 脚本来自:http://www.nginx.cn/install 运行这类脚本时,大脑里的概念是:我要“安装”Tomcat、Nginx。这类脚本被当成“动词”存在。也就是说在面对一台机器时,我们的思维方式是:我要写一个if来判断Tomcat是不是已经安装,如果没有安装,就是执行apt-get install,blabla…… 但是,现实的自动化配置工具Ansible、Chef、Puppet告诉我们,自动化配置的脚本更应当充当机器环境的状态的描述文档。也就是面对机器时,我们应该使用“形容”词。什么意思呢?来几个配置体会下: Ansible: # ./ansible-nginx/tasks/install_nginx.yml # 使用这个7-0.el7版本的yum包 - name: NGINX | Installing NGINX repo rpm yum: name: http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm # 当前机器的nginx的状态应该是最新版本 - name: NGINX | Installing NGINX yum: name: nginx state: latest # 当前机器的nginx service的状态应该是已经启动的。至于如何确保nginx这个service是如何启动的,我们不需要关心。 - name: NGINX | Starting NGINX service: name: nginx state: started 配置来自:https://www.nginx.com/blog/installing-nginx-nginx-plus-ansible/ ...

2016-08-12 · 1 min · 119 words · 翟志军 Jack Zhai