The 12-Factor App

介绍 & 实践

Zhang Yuchen

不仅写代码也运维自己的产品

关心微服务

容器化

喜欢 DevOps 文化

未知的太多,努力学习

Programmer

  • 12-Factor App 是什么?
    • 为构建 SaaS 应用所总结出的方法论
  • 12-Factor App 关心什么?
    • 降低学习成本
    • 提高可移植性
    • 稳定
    • 面向云平台部署
    • 方便扩展
  • 12-Factor App 是由谁提出的?
    • 贡献者们通过数以百计的应用程序的开发和部署,总结出关于 SaaS 应用的经验和智慧所提出的理想实践标准
  • 所以……是理想实践标准,我们更需要实践

引子

方法论

适合部署在云平台上,方便节省系统管理资源

操作系统解耦,提供最大的可移植性

标准化且清晰的流程配置,降低新人的学习成本

降低环境差异,并且使用持续交付实施敏捷开发

不发生巨大改变的情况下,实现扩展

DevOps +

更频繁的发布

稳定

易维护、易运营

灵活、简单

学习成本低

消除人员隔阂

知识与沟通

DevOps 是精益准则的实现

DevOps 关心 IT 价值流

价值流驱动我们开发软件、提供服务

统一的价值流,让我们重新团结在一起

忘掉 Title,为产品服务

Codebase & Config

git: notification-publisher

git: notification-publisher-deploy

prod

staging

...

env

MY_ITEMS_HOST: https://api.host-to-dest.com
API_VERSION: v2
SERVER_USE_FORWARD_HEADERS: true

一个应用,一份代码

一份代码,多份部署

Backing Services & Port Binding I

后端服务作为附加资源

通过端口绑定服务,你也是资源

mysql://host/db

smtp://auth@host

s3://host/bucket

http://host.com

本地与远程环境没有明显区别

服务配置写在 Config 中

在开发中方便被替换使用

通过端口暴露服务

服务就是资源

app 1

app 2

Backing Services & Port Binding II

...

ADD Rakefile /commsetting/Rakefile
ADD live_version.yml /commsetting/live_version.yml

CMD /commsetting/script/start_server.sh

EXPOSE 80

LOG_USER_SERVICE=http://for/bar

RESPONSYS_IDENTITY_FILE=./file_path

S3_BUCKET_NAME=bucket name here

REDIS_SERVER=redis://iamredis:6379

PREFERENCE_SNS_TOPIC=arn:aws:sns:xxxxxxx

Processes

无状态

使用文件系统共享数据

使用 S3 保存文件

将状态保存在数据库

在 Redis 中存储 Session

不恰当在内存中保存

进程相互依赖

无共享

应用程序在处理中应该创建与消费短暂的状态,并且在 response 中返回所有数据

使用后端服务保存状态,没人希望数据库是无状态的。

共享数据的进程是脆弱的,并且危险的。进程创建、消亡,易于回收,方便扩展。

无共享进程是扩展的基础,可以避免串联式的错误

Build Release Run I

Code

--------

   -----------

Unit Test

Code Quality

Style Check

Integration

Package

.....

Product

Config

Release

V1
V2

...

Pick a release

What about rollback?

Build Release Run II

我们希望 Build 更加复杂,包含很多步骤,因为错误可以立刻展现,方便开发人员妥善处理。

Release 最重要的是配置与 Build 产物的绑定。因为三个月前的代码是不能和现在的配置一起工作的。

Run 却要简单,包含更少的模块,最好自动化,方便部署人员处理。同时,一旦出现问题,可以简单回退。

  • 直接修改运行状态的代码可取吗?
  • 如果我有集成测试,应该在哪里做?
  • Docker image 算作 release 吗?

Dev/prod Parity - I

  • 修改到上线:10分钟以内
  • Dev & QA 监控、管理、维护自己开发的环境
  • 使用 docker-compose、brew 等包管理维护本地环境
  • 大量的线上问题可以在本地重现

使用等价的环境,我们可以开发、管理十多个服务……

数周

几小时

不同的人

不同的环境

一群人

类似的环境

HOW TO ?

Dev/prod Parity - II

redis:
  extends:
    file: docker-compose-common.yml
    service: redis

setting_db:
  extends:
    file: docker-compose-common.yml
    service: postgres

comm_setting_api:
  extends:
    file: docker-compose-common.yml
    service: _base
  command: bash -c "script/start_server.sh"
  ports:
    - "8080:80"
  links:
    - setting_db
    - redis

Cache

DB

API

compose file

$(docker_compose_run) bundle exec rake prepush ⁉️

Log & Alarm & Diagnostic

  • App 不应该考虑存储自己的输出流
  • 日志是事件流,我们希望按照时间、机器、模块等排列
  • 我们希望可视化的看到趋势
  • 日志、性能监控、诊断信息都有类似的模式
  • 警报可以监听日志状态、甚至来自所有的关心的运营数据
  • 工具、更多的使用工具

Wrap Up

5 Dev, 1 QA, 1 Ops

  • 20 多个简单的代码库
  • 20 多个 CI 流水线
  • 11 个应用:服务、前端、数据处理、管理应用等
  • 存储:  RDS, postgres, MySQL, Redis, S3 ...
  • 消息: SQS, Kensis, SES, SNS ...
  • 管理工具: Log, APM, CloudWatch, 1Pager

改动上线?数分钟

在某应用的开发中,超过 190 次部署

More

Q & A

Thanks!

12-Factor App/CN

By Yuchen Zhang

12-Factor App/CN

  • 1,579