文档章节

使用12-factor的理念快速创建高可维护性的应用—叶峰 (1213开发者实践日)

七牛云
 七牛云
发布于 2014/12/17 09:19
字数 3439
阅读 209
收藏 18
点赞 1
评论 0
【叶峰】:今天的这个分享,这个标题是使用 12 个理念去快速创建高可维护性的应用。如果大家能很好的应用 12 条法则的话,我们可以更加的对抗   software  erosion 。这个 12 条比则是 Adam  Winggins 提出来的 12 条理念。

 

 

但是现在很多团队在自己的摸索中,已经发现了这12条其中的一部分。然后我也跟很多朋友聊过这个话题,如果是来自大公司的话,他们很多会认为这12条应该是日常应该做的事情。如果来自创业公司或者小团队来说,这12条理念会让开发速度变慢。但其实这12条理念其实可以非常好的对抗software  erosion

 

 

它的本意是随着时间的流逝被消磨或者腐蚀掉了。前面几个星期前写的代码,现在已经看不太懂,或者说公司有一个系统,你现在有一个新的需求,你要满足这个需求,就是要满足这12条例子最快地实现这个需求。如果现在运行得很好的一个产品,可能一两年之后操作系统更新了,底层的依赖已经变了,这时你重启系统,发现已经不能运动了,不知道怎么回事。这样的版本因为系统资源不够了,必须要进行清理。我们讲一下Heroku这个公司,有很厉害的iOS开锁的作者。这家公司并不是非常成功的,因为它在10年被收购的时候,我看了一下它线上只有大概一万个运用,他们的现金流应该是比较有限的。但是他们有非常强大的工程能力,他们还是在10年的时候被两亿美金收购掉了。大家可能都回用git去管理代码,平时部署会很麻烦,但是你只要用git  push就可以完成代码的版本了。

 

 

我只要fork一下就可以了,如果我的生活环境有什么变化,我可以直接fork一份。我们为什么不直接用Heroku去开发呢?因为Heroku比所有的EPS都要贵一点,还有一个最大的问题,实际上是很强的问题,部分AT是被墙掉的,所以没有办法。其实Heroku有很多的开源可以去用,但是我们发现这些克隆的版本都有很多的限制,我们并不是一定要造一个Heroku出来,去做我们的开发。我只需要在Heroku这个创始人他们在创建Heroku的这个过程中,学习会了这套理念,把这套理念用到我们的开发中就可以了。这边是具体的12条,根据我们的实践下来,就是这12条。

 

 

我们并不需要全部都去应用出来。但是其中的部分,其实还是挺有价值的。第一条实际上它的原文讲的是每一个代码都要用独立的代码仓库去管理,到现在就是microservices的架构。我们知道Twitter每次公共的API调用都产生超过100次的内部API调用。

 

 

有利于开发团队进行协作、降低部署成本,异常快速回滚。这个就是我们用到的内部的一些私有的仓库,遵守这条发作的话会有一些好处,比如说一份代码我只要修改一下定制就可以了。如果说一个系统没有办法用一份代码存储的话,说明它必须切分成多个代码仓库。这边我们用到三个比较基础的东西,这个模型层,实际上是私有的Ruby的代码库。

 

 

它封装了一些对数据库的操作,它是独立成一个代码仓库,我们可以通过环境变量注入只读的数据库,这样可以确保它是很干净的。还有一个只写的对外提供APT的接口。在这里把它分成不同的子系统,我们可以用X-Rate-Limit。这样的好处在于不管是客户端的问题还是内部的其他子系统的问题,或者说是来自外界的恶意攻击,我们都可以有办法把攻击降到最低。第二点跟刚刚一开始提到的,如果你需要系统迁移或者系统升级,这种情况下怎么样保证系统很容易的进行迁移。需要对依赖做声明。这边的话是Gemfile的示例,这个文件会具体的申明用到哪一个库的数据。你可以保证用到的都是一模一样的版本。这样还是有点抽象,这里举个例子,Sidekg和系统默认的版本不一致,如果我用Bundle  exec,将来万一他们是不兼容的,或者代码迁移到其他系统,这个系统默认的库就是不兼容的。

 

当然目前特别流行的docker是可以很容易地满足这个需求,今天就不讲这个事情。还有第三点的话,我们提倡把配置放到Unix的环境变量中。一开始是放在代码常量里面,但是代码常量有个不好的地方,你要修改的话要来回地改动代码。这样会影响你在代码仓库的一个情况。如果你在比如说上线前的版本和上线后的版本配置不一样的话,你要在代码仓库维持两个分支,肯定这样是不合理的。还是举个例子,如果是ruby的话他有一个比较推崇的.ENB

 

 

第四点和第三点关系很大的,我们对外部系统的依赖,比如说我们要访问七牛的API,我们建议放在稳定变量,包括其他的子系统。刚刚我们提到了就是我们的模型层,我们会有对外暴露的两个接口,这两个接口会注入进来。这边有个简单的测试,你永远不应该把不应该提交的代码仓库提交出去。这边是个简单的示例,这个脚本是很简单的执行环境命令。如果我们用dot  enb的话,不管用什么语音都是很容易实现的。但是它对整个系统的稳定性的帮助是非常大的。

 

 

第五点的话其实对于我们实践下来,其实感觉并不是特别的重要,大家看一下就好。

 

 

第六是这样的,就是应用应该作为没有状态的进程去运行。除了和持久化相关的服务,其他服务都是应该无状态的。这么做有什么不好的地方?你没有办法确保同一个客户一样的进程保存在里面,而且下一次这个客户的请求也会到其他的机器上。

 

 

我们刚刚提到了可以通过环境变量的注入依赖,我们提倡把每一个独立的应用绑定,就是内嵌HTTP的库。他们直接对外绑定端口,对外提供服务,而不是依赖外部的服务容器运行。这个绑定的端口它未必以HTTP的协议进行运行。

 

 

并且我们刚刚提到以这样的方式去申明的话,这些服务就可以作为其他的服务的依赖。高层次的API就可以基于低层次的API执行了。以这样的一种方式去做的话,接下去有非常好的应用,就是说我们在最前端可以用layer  awore  tcp  proxy进行。如果它get某一个路径的话,我们可以转化到对应的m  point上面。还有类似的做法,以类似的这种TCP的代理方式,我们可以很简单地复制一份流量。我如果要进行系统的性能测试,我肯定不能在正常环境下测,但是我如果部署两份一模一样的流量,这样子一是可以做性能的压力测试,另外在线如果线上有什么bug的话,新系统如果要上线,我一样可以用这样的方式测试。相同的流量下来,它会有什么样的反应。这种方式在GitHub的应用,它不可能允许DNS的这种方式随机给你指定某一个机器去响应你的请求。因为每个推的,每个往上面push的代码都是跟个人相关的。但是以这种方式去做的话,就可以捕捉到Git协议里面的一段,然后我们可以抓出你的用户名,可以定向到对应的机器上去。这样可以做到很容易的扩容。

 

第八点,扩容的方式我们提倡是以多进程的模型进行扩容。

 

 

虽然是以多进程的模式扩容的话,并不代表每个进程是单进程的。因为我们刚刚提到了,我们提倡服务都是无状态的。每个服务都是无状态,扩容就很容易。可以把同样的进程部署到不同的服务器上。后面两点实际上讲述多进程的模式,我们提供的服务就不应该把自己变成系统的daemon。常见的把一个程序绑在后台的一种方式,但这几种方式其实都不太好的。第二个是把代码放在阿帕奇的容器里面运行,这样两份代码互相会有冲突,你使用阿帕奇这样的容器。另外的话像rubyunicon,这样子也是不够好的。都会遇到很多奇怪的问题,如果进程挂掉了怎么办?进程异常退出,会飘到其他的PID上面。如果我们没有做好好的环境隔离的话,会有不纯净的环境,额外的环境变量会对系统造成异常的影响。这边还是以Ruby为例子,我们以procfile示例,对外提供FTTP的服务,这两个脚本随时会因为各种原因退出,如果以这样的方式导出到upstyle

 

第九点是快速启动,优雅关闭。

 

 

第十点的话,我们还是希望开发、测试、部署的环境要尽量接近。

 

 

很多公司因为分工很明确,代码是开发写的,生产环境和运行是运维的事情。作为负责开发,要从需求的正确性到往后,整个代码的正确性都是应该负责的。第二条机器太慢的情况已经比较少见了,所以我们尽量保证开发的环境和运行的环境是一样的。持续集成很重要,其实很多人,特别是小团队可能会觉得持续集成,搞测试是一件很烦的事情。其实不是的,你要很简易的搭一个不断地跑测试的服务器是很重要的。它会往这个服务发一个HTTP的包,不管成功、失败会发出来一份文件。整个环境的搭载是很容易的,大概一两个小时就可以搭起来了。我一直是写Ruby的,对于创业公司来说这样可能会有点过了,因为很多时候你们不知道会做成什么样子。这种情况回归测试是很重要的,遇到一个bug,写一个测试能够重现它。下一次这个测试会直接告诉你怎样做的,这样也是回到刚刚的一个主题,将来这个代码不可维护了。任何的改动破坏到原来的东西,测试都会跑不过。第十点,我觉得是特别重要的一点。如果每个系统都往文件里面写的话,每一个日志都会分摊在不同的地方,一旦出了问题,你都不知道该去看哪里的日志了。

 

据我个人得经验,服务器满了,都是日志把磁盘写满了。理想的情况下,应该是把所有的日志直接标准输出,再从印象到服务器上,这是理想的状况。

 

 

所有的日志统一分析和处理。我一个朋友他跟我讲说这12点其实对他们公司来说都是很正常的做法,但是小团队的话如果搭这样一套环境比较困难,我们现在目前还没有搭自己的日志服务,现在用的是一个国外的paper  trail的服务。

 

 

这样做的另外的好处就在于我可以做日志报警,如果出现这样的一个情况的话,我必须收到一封邮件。不管里面多少个子系统,任何一个子系统出现问题,我都可以收到一封邮件。好的,谢谢大家,今天的分享就到这里。

 

PS:开发者最佳实践日·第8期-互联网产品从设计到上线 北京站

报名地址:http://qiniu-8.eventdove.com

© 著作权归作者所有

共有 人打赏支持
七牛云
粉丝 39
博文 60
码字总数 109690
作品 0
浦东
RT-Thread 3.0 发布之际,创始人首谈其设计理念

1. 源自“简单、唯美”的设计理念 诞生于2006年的RT-Thread,最初源于对当时小型RTOS现状的诸多不满。最令人印象深刻的是彼时不同RTOS混乱的命名风格——如果那个时候有一份类似Linux/Unix风...

Andy-RTT ⋅ 2017/09/13 ⋅ 20

阿里百川与极客邦科技达成战略合作 Weex宣布开源

4月21日,由InfoQ主办的QCon全球软件大会在 北京举行。超过150名国内外技术专家将为大家带来一场技术盛宴。在大会的开幕式上,极客邦科技与InfoQ中国创始人霍泰稳,和阿里巴巴资深总监,淘宝...

阿里百川 ⋅ 2016/04/22 ⋅ 0

SaaS微服务十二要素应用宣言(The Twelve-Factor App)

Heroku是业内知名的云应用平台,从对外提供服务以来,他们已经有上百万应用的托管和运营经验。前不久,创始人Adam Wiggins根据这些经验,发布了一个“十二要素应用宣言(The Twelve-Factor A...

yown ⋅ 2017/08/27 ⋅ 0

云原生架构概述

云原生架构概述 Harries Blog™2017-12-251 阅读 SpringcatAPIDockerCassandra 1. 什么是 云 原生 1.1 CNCF 组织 在讲云原生之前,我们先了解一下CNCF,即云原生计算 基金 会, 2015 年由 谷...

Harries Blog™ ⋅ 2017/12/25 ⋅ 0

Facebook 新开源项目使创建 React 项目变得容易

Facebook的 React 项目是一个开源库,它允许开发人员快速构建应用程序以及在JavaScript中构建它们的用户界面。但是,这有点过于轻描淡写了,因为除了JavaScript,你还必须学习很多的工具,才...

oschina ⋅ 2016/07/24 ⋅ 9

Google 如何控制 Android 平台?

下面的图片是因为Oracle和Google的官司暴露出来的Google的一份文件。 大致意思是(=====线之间): =====================================================================================...

红薯 ⋅ 2011/09/14 ⋅ 0

OSC 第 135 期高手问答 — 深入实践 Spring Boot

OSCHINA 本期高手问答(2016 年 11 月 28 日 — 12 月 4 日)我们请来了@快意开发(陈韶健)为大家解答关于使用 Spring Boot 开发框架相关的问题。 陈韶健(Chen Shaojian),华阳通信技术总...

局长 ⋅ 2016/11/28 ⋅ 61

实践课堂|2016成都站|报名开始啦!

Hi,QingCloud 的小伙伴们,欢迎参加史上最有营养的云知识讲堂。 QingCloud 实践课堂系列开始于 2014 年末,在深圳、上海、广州、成都、杭州、北京六个城市,QingCloud 的研发工程师们同近千...

cathyli ⋅ 2016/05/04 ⋅ 0

如何基于 Kubernetes 开发高可靠服务?

Kubernetes 是当前主流的容器编排服务,它主要解决「集群环境」下「容器化应用」的「管理问题」,主要包括如下几方面: 容器集群管理: 编排 调度 访问 基础设施管理: 计算资源 网络资源 存...

Docker ⋅ 05/01 ⋅ 0

360°透视:云原生架构及设计原则

本文由 网易云 发布 云原生(Cloud Native)的概念,由来自Pivotal的MattStine于2013年首次提出,被一直延续使用至今。这个概念是Matt Stine根据其多年的架构和咨询经验总结出来的一个思想集...

wangyiyungw ⋅ 05/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

C++内存映射文件居然是这样?!

内存映射文件大家都时不时听过,但它到底是个什么?赶紧来看看吧 内存映射文件到底是干嘛的呢?让我们先来思考下面几个问题: 如果您想读的内容大于系统分配的内存块怎么办?如果您想搜索的字...

柳猫 ⋅ 24分钟前 ⋅ 0

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 今天 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 今天 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部