请选择 进入手机版 | 继续访问电脑版

IT运维管理,ITIL,ITSS,ITSM,ISO20000-ITIL先锋论坛

 找回密码
 微信、QQ、手机号一键注册

扫描二维码登录本站

QQ登录

只需一步,快速开始

艾拓先锋
搜索
查看: 328|回复: 0

小型公司DevOps落地实践案例详解

[复制链接]
来自- 广东广州

参加活动:0

组织活动:0

发表于 2018-9-1 16:52:06 | 显示全部楼层 |阅读模式 来自- 广东广州
本帖最后由 adminlily 于 2018-9-1 17:14 编辑
( I% U; i6 D6 ^7 d2 s7 e
: G+ A2 d+ Z6 C% ^6 |8 O8 ?9 v
% W: ?, i, J8 H* Y) F5 C2 t

/ j: S1 f4 o7 J
  最近几年DevOps的概念越来越火,各个企业也逐渐意识到DevOps对项目研发效率的重要性,也有不少第三方企业提供整套流程成熟的解决方案。而我们侥幸,在这些第三方平台尚未崛起时,制定了一套适合自己的DevOps流程。

0 k2 I1 `6 g6 p0 g
0 d5 f, s8 M& S3 B  T' G8 ^, H
先申明一下,因为我们公司规模较小,和在座各位朋友任职的一线互联网公司可能没有可比性。所以,我分享的一部分流程或方案,仅供参考。

) U5 k3 G% o2 @) }" Q5 d
# d, m9 q: M2 _" Q! {6 w4 b1 p
背景
% D9 U: B, f% r" g- z$ B& t6 G/ z$ Q# {$ O& R

" v$ O3 i: `. o( |7 [* D

: W( J1 X0 i8 G. g先说下背景,我们公司做的大概可以理解成SaaS服务,即从服务器硬件到系统环境到服务都归我们管。而且每家客户都有很多个性化的需求,在我接手重构前,我们平均半个月才能接入一家,经过我们几个月的改造,我们现在可以接入一家客户大概可以控制在1人天。之前,我们开发流程比较混乱,没有文档,没有各种开发流程,现在我们逐渐规范,形成稳定的流程和体系。

" w% V  e4 c5 X2 b" X
8 G0 y" `1 \% h  ~* M( P
Java项目改造
- G1 C3 i: j/ U* c

- j' T5 U- ]% [
下面我们聊聊Java项目,我们把一个Git库中的2个项目(接口、后台管理)进行拆分:
) l; `+ D5 d: s% f  K* t
! Y6 ~3 N. `& H+ @; a
1、接口服务
( [6 w  l0 l4 T1 O. b% a. [5 m! m( e. `. A: ~9 M" x- y( a
2、后台服务
, [* O5 @+ t  Y: [0 M' b! v7 Z, G+ ^9 ^$ I) N) H# h
3、html5包. W; c- j$ r# J4 @5 ~/ y

8 F% C4 x( Q7 S+ t# c; b" E0 v. h/ F
, L; I1 y( S  ^* Y4、公共包服务
  Z! ~; k/ ?* c) v" P+ L1 [4 ?8 C
% w/ D# p0 W. n7 {" t9 b5 O  L
- Z$ ?" z& s6 Q' A  D/ r6 e
我们主要做了前后端分离,代码Git库分支化管理(事实上大部分小公司都可以这么拆分)。

: e2 F# U4 O4 y' w  U( n. P# y

9 q0 D# D' ?( {, A/ z) a
我们采用和其他公司不同的方式,定义公共版为主分支,为每个客户建立1个额外分支(事实上分为开发分支、集成分支),发现公版的bug,到主分支改,改完后合并到各个分支,这样就不必重复切换到每个客户项目中改bug。

9 d1 U  H: V# D. e1 d% f

" q9 t6 R# s( R3 T5 S" D
Jenkins7 A! x& L) `3 ?

% H' L/ F, _7 O6 \7 P  g2 L
使用Jenkins编译,包含我们Java项目、H5项目、安卓项目、iOS项目。
! J! Y) x! T) g) \+ y; l

/ g( r* r, ^3 V$ M+ c
开发人员只需要本地调试后,提交代码到Git库的某个项目分支上,由Jenkins自动编译。如果编译错误会通过邮件反馈到影响代码的开发人员邮箱中,另外测试人员一键部署后,测试出问题,也可以通过Jira提单给开发人员。开发人员收到后,继续提交代码,不再像我们之前,必须通知开发人员,开发人员本地打包。

! c9 j# {1 q$ x7 d; F
流程如下:

: m& g2 p1 z, {. x* ~
1.png

( _0 Z+ b* g, H/ v/ ]! K  g
这里我们做了一点偷懒,我们版本号的维护也交给了Jenkins,通过脚本由Jenkins自动增加版本号。

" ~8 z6 l" d2 s

% H2 Z2 c1 e( G7 v2 s% ^% _
我们还将所有项目中状态抽取出来,做成无状态项目(大部分公司都是这么做的,尤其之前听阿里分享,他们做到自动识别环境),这样,测试环境、生成环境的war包都是相同的。

1 f1 y! s9 G4 Q! s

' H  t6 w! F0 h
自动化部署# M- m: L3 o/ f, [! P8 V

. N( k! l- P/ R0 Y- P. l( l! w5 t然后我们做了一个自动化部署的小平台,主要功能如下:

5 d) ]6 B' u2 [' e
5 X: U+ L' j8 C3 D( p
1、升级、显示当前版本1 _0 c1 x. K. _5 Q% d; ]2 R  ~
* I' d1 R( N- ^

4 s7 Y: Q. m! X6 o, V
2、对war包有效期,真实性校验
, W) Z1 v5 F: K1 }  z
9 Z4 |' K  O& k. J1 z5 t" c: e0 E

3 N" B( h2 n$ H
2 f9 O5 t( h  d- J: m5 |
3、开发人员将公共SQL放入公共.sql里- i3 A- v1 R3 u- d& t+ G( R! e2 y

! ?6 ]% \9 n) d) o
9 e6 Z4 t" p' l/ z4、各个客户定制化需求的SQL放入各个客户.sql里1 K0 _- D2 f  C
  F; Q; m0 W# U6 ~; \
7 Z8 r: v- ^' j! R
项目经理升级时,自动提示未执行的SQL,点击执行即可。

# M' }" O# L% E* s- u6 u2 S* b, N
( Y4 s9 V6 A3 D7 W5 L  f" p4 |* `

) u, [9 H# B6 q3 p* P% ^4 ], G) ~7 @1 W
客户端) X+ `9 ]5 U+ \1 [0 s7 Z

% g2 Y" I. G( ]
接下来,我们聊客户端:

/ ]* H* _9 A+ ~

$ ?6 o9 g9 x: N# m  q2 c- E
客户端内容不多,我们有安卓、IOS客户端,也是经过一轮无状态抽取,然后抽取服务器地址,配置后,由Jenkins自动打包,同时打包测试环境包、生成环境包。
, h) H3 \2 ^6 q- I* n6 p
1.png
! B2 r2 @7 H; H$ B0 k, W& B: A- p
$ w2 N6 l  v: i' Z
测试组
" f8 J  |  \* `, }; T& ]1 G: Q3 X% {2 x$ _# v/ @% d# X; M' R9 r
测试人员从Jira提单后,开发人员解决后,会看到具体解决的版本号,然后进入OSS存储,安装Android程序,或者IOS程序,一键部署Java项目。
6 b. S3 Q( M* S0 [# G, X; [
因为安卓和IOS均是同时发2个包,Java项目、H5项目无状态,所以生产环境和测试环境都可快速部署测试。
! T1 C2 Z" h6 i
1.png

0 K1 ^2 X; A0 L; C* C# W9 d( U$ w) H

& {, }* b# s2 f7 b9 ^& D  ?  \) w
运维组

& ^; D* h+ g2 t

7 {& o3 b/ ]. H+ H/ x( Y, ?8 v3 v9 _
运维组重构先看看之前的图:

0 s# P$ E4 y# ~& y+ H
1.png

: m: g/ I/ r6 W1 t$ i) j, |) ]
因为各个时期部署的系统版本以及服务器型号等都不通,所以线上环境比较混乱。
; v3 S  F2 B) E( M: s6 g
$ S; F+ S) u2 s0 ?! R5 ]) i
我们采用Docker容器统一方案解决此问题,使得每个客户机器环境均相同。我知道在座的各位都是Docker大神,我就不多讲了。

! s5 m& ?# V% x/ u) v
) g6 a9 G$ `( B! }+ W! _- l
看看我们现在的管理图:
1 k  g6 M  }' D! L% Y7 t* k. W
1.png
% P3 B6 g0 r, ?
我们用的是Portainer框架,简单二次开发了一点功能。
8 |2 h& i4 u, I# _

( I( s6 U# M6 N' M. u
我们用了TLS认证,所以,管理者并不是通过Linux密码控制,而是通过配置平台,然后分配权限给各个项目经理所在的team中,然后,项目经理对team成员权限进行管理分配。

3 \( \( L" {1 R" w  G8 @7 `$ ~

( t# U) t. w) M  B7 P
该方案优点:
( V$ i; v5 q3 F+ q! X
# W+ n. e+ X, w6 O0 z
  • 在Docker下,所有客户生产环境相同。

    6 n- W) a( b/ M

$ a& `* L& V- k+ p  ~0 V0 E
( s! c$ d+ H/ U# K) c" ]
  • 易于备份、迁移、恢复。

    2 V' k1 s( E' ?/ o  L

% I& C, Q' \( Y' l
  u5 E9 C) F# ~/ j5 ?
  • 可建高可用环境,发包时采用灰度发包,蓝绿部署不中断服务。
    2 E+ t9 `" x2 D' L7 I0 e! d, X
5 y$ l" G3 w+ |$ F) |- N
  • 可支持弹性伸缩设计,支持扩展。

    4 q3 L9 g' c2 s) h

5 g9 A7 V1 x6 W/ Y( _) y
  • 支持负载均衡,域名转发,意外切换容器等。

    9 Z2 P# C2 Z. y; n0 e0 y
' r; ]  Y) D3 }

# L* J9 T* P# R6 Q1 X* C
  • 有利于转型微服务架构。
    8 E% |+ A$ Y/ E* Z3 c! O: V" ~( V( W+ T
; t# H% X8 A) l( t5 t. L

8 I4 |2 K: M2 Y# N* D& _# P! G
快速搭建环境
% V2 K: J% \1 v3 ~2 A9 k8 F' M; ]9 _
! H% J! U4 L4 Q. I3 ^! t* w
而建立Docker集群需要我们自动化完成,这里我采用了Ansible工具来实施,我们可通过指令分发,指令获取所有机器某个包的版本,执行不同的代码。
5 ~4 g/ k+ }  g& O; G8 H7 R; j
( y5 D) g. E7 @& `6 O8 f  s" U
这里我建立了各种仓库,方便Java开发,建立了一个私有仓库,一个Maven官方代理仓库,一个阿里云代理仓库;Docker上我为了方便开发打包其他环境,创建了Docker私有仓库;还有一些为了解决统一管理Linux服务器而创建npm仓库;以及安卓所要使用的Gradle私有仓库;未来,我们可能还会创建更多仓库,能支持的仓库列表都在下面:
: E5 {2 H- ]: L! T4 q, B
1.png

9 |) H8 L& g) M- [" D' c$ c4 ^; C7 |

! w5 C: `3 p8 Y: r2 S
( L' u; I1 |& ]9 t. p% l
大数据篇
7 o8 d) [9 ~5 K  S# d& d

3 g8 y2 W0 _6 {# @! Y大数据一直以来是很多公司核心产品,对于小公司,如何低成本实施呢,我研究了一套强大的大数据框架Superset,并对其做了部分的二次开发。他能实现各种大数据图表展示,如下图:

5 C5 v  l! l' }" z5 {
1.png
* Q! n8 {  z7 H
我们采用iframe的形式将部分功能加入到我们管理后台。
: S; J$ G. Q. p+ R2 e+ `3 z/ t
0 p' _- p) i' N8 h. S. ?, _
接口篇
4 f$ M+ u# N4 V7 c& A
# l$ E$ }5 m2 ], x. E6 l
我们采用了RESTful风格的API,也许很多人说RESTful不是很简单,10分钟上手,30分钟精通,事实上绝对比这要复杂的多。有很多的细节,很多的约束,经过几个月的协调开发后,都未必能避免出现不太和谐的接口。

3 n& f9 K  ]" `" w9 t

( y4 W2 r( k/ I
之前,我们项目,各种接口文档都存在,主要有一下:

9 W9 t* |8 ]3 u
7 ?8 d8 p( Y$ M0 u- g; J
  • Swagger
    9 w  s! L) M, l: b3 @

) p2 s& q- G8 M8 g, f$ o
  • 阿里的RAP

    / R3 H; k% o7 ~" h# r. c
7 `2 ^+ c3 _, L; z9 Z% c

( v6 b* [$ Y% k
  • Word文档
    2 \7 W9 ~. H0 A, B/ |1 T9 b

" H& _' Y3 s  E& z9 L8 q4 D0 e
0 x6 P: l1 B* q% o$ A# K6 u2 e
  • 其它

    ! D' T) a/ W2 x) d+ C/ D) T

+ a+ w+ w$ j% n
对了,之前的接口是这样的:

) q! D& R7 r8 o* @  ?
3 p/ X- q: B. r8 f* ?1 s1 u
  • …/A项目/模块1/getProducts ----接口
    , }6 f- P& `; s4 w+ A2 G# s  E
/ {7 N$ q9 @+ \

' Y+ B/ j2 a; p# Q( k2 k8 B# K: \
  • …/A项目/模块1/Products.html ----页面
    0 K3 n0 w$ L& h" K
& D! q: v( Y3 A! J  ^8 J- y/ H

) |! G5 g5 h4 L0 [9 a$ H0 c  l. y
  • …/A项目/模块1/Products.js ----静态资源

    5 L5 }- I) W0 }2 N1 `9 W0 D

% o" g" G  M. d% T

2 m, H) b: e$ U% h, k* D# }- r

- S% T  f2 L6 Z! L. u
留下了很多的坑,这里不对RESTful再做详细介绍,有兴趣,大家可以自己了解下。我们统一了一个接口文档为postman,可能很多朋友会说postman怎么能作为接口文档,我只想说,他适合小公司,不仅有入参、出参示例(可以多个例子),还能在tests里写接口说明,也方便前端调试,调用服务器使用。
( Y# Q: G; |  O4 I

( G2 ]' L( S2 P1 Z
规范篇6 b5 X/ h& q$ V& z

$ q7 e- P9 N1 W6 \
我们制定了一些规范和约束,比如,原来项目经理发现问题,会立马找开发,现在规定为先联系测试,由测试提单给开发。
; H' i$ \- R! q3 f0 M9 O$ @

$ W# c, x, K- T8 G+ C2 |
Q&A
/ @/ y' O  P8 R; W5 T1 y+ h: y
  z/ Z! R0 Z% O) J/ l
Q:请问Portainer仅用于测试环境还是在生产也用这一套?# ?9 Q, F- k# a) U
7 Z, n; z* G; n' _" G) K$ I$ |

" M0 Z/ R9 Q9 K" f* p% dA:因为Portainer是直接通过docker api执行的,并没有在服务器上装有什么客户端(也就是无侵入,这也是我们选用他的原因),我们只是在Docker里面配置了个http的TLS证书,加上我们对它做了一些改造,所以我们使用了Portainer应用生产环境。

8 {( p% f+ {! t

- [! c% [# }6 v& u4 |, o- a: p( c
Q:请问下测试的时候接口模拟您这边是如何处理的?
$ R" |! J0 ^, J

1 i7 g! V& U3 f$ ?9 J+ d; H
A:Ostman默认录入了几个多种情况下的出参,其次,我们前端每个人都有一套独立环境,通过Web端管理部署(数据库和测试人员共用),不会受后台开发人员对接口修改而中断服务。其次我们有少量前端页面使用了mock.js。
2 }8 `% g% d, ?) K* c, {

2 l- b7 U0 f" o/ q/ T6 E. M
Q:请问Docker里跑Java应用性能怎么调优,默认是共享资源池,对Java来说CPU切换很费性能,除了绑定CPU,但这样就没有弹性之说,麻烦说下?

; s, m/ e" J7 Q! ]5 a3 r$ D
) A" d+ F* R5 D9 s3 ^
A:这个性能,我们对Java项目进行多次内存优化,通过ide的内存管理,线程查看等多重方法进行调优,单从war包体积上我们就缩小了60%,内存也下调很多。我们并不能自动伸缩,目前是通过Nginx配置多容器来实现负载均衡。

5 ^- A1 T6 x" H7 m0 F

( n9 v" ?$ ?' y/ m# w  _3 i  g
Q:如何实现分布式事务?如何保证数据一致性?

2 w  Z0 f9 S* Q/ Y$ O% Y# o0 M, h

% A. D+ M  W; C* d4 x( R
A:我们在Nginx层通过策略保证同一个机器请求只会分布到一台机器上,用最少代价解决这个问题,其次我们项目中,大部分都使用全局uuid操作和插库。

- A8 m% x; B+ X2 ^/ Q$ O/ f

2 I! d/ U! }+ i* E. ~+ j+ o2 Q
Q:贵司的业务模式跟我们很像,感觉很受用。想问下,多客户、多版本共存的情况下,版本升级这块儿是怎么做的?

9 }8 _0 v9 G4 S0 C

" O3 Z( `/ s0 }0 g3 p+ ^0 M, d
A:我们使用的是Git分支化管理,由Jenkins定义版本号,SQL分为公共和私有的部分,比如某个客户升级2.0.0版本,会自动检测上个版本到此时的SQL语句,提示项目经理点击,自动执行。(我们现在回滚项目版本,不支持SQL回滚,所以我们SQL一般只增不减、不改),我们可以随时查看某客户线上版本和SQL执行到什么地方。
- ^$ r1 i+ q# S: T/ i2 X

& ^" g6 o2 c6 z0 Q7 k) J' G
Q:日志如何存储和分析?用什么工具?系统异常如何监控?

/ s2 U/ s9 s: O' A5 ]" z

  N6 T2 m4 _, n& v& r- x
A:先说说异常如何检测吧,我们做了一套http监控框架,以任务的形式添加,然后会对已配置的线上环境、多容器进行监控,比如任务为http://xx.com/..../messages?token={token},在配置任务执行时间及频率,然后配置项目列表,其中项目编辑的信息有host,可理解为http://xx.com/这块,还有变量列表,支持随意定义,比如token 11111111 用户token信息,这种k、v、说明文字,执行任务的时候,自动替换host和占位符。系统只记录变更,我们项目接口统一了出参,当状态码异常时显示,此方案可实现监控各种容器、各种测试、生产环境。
2 A$ w) M# u6 S4 ^& z- R
1 K& M( j9 `1 ]+ Q

: b% k& F' p7 G" K! W
关于日志收集,目前我们并没有很多公司搞的很高大尚,因为这块,还在改造中。我们就是多容器映射了本地磁盘目录,然后对这些目录日志文件进行合并,对那种error级别的日志,筛选出来。
" x; Z$ r% S# N$ P$ Z1 b

8 f: g+ ?; G2 e9 Y
原创:邵磊

7 w0 V" c- a8 \0 R9 b+ Y/ ^7 s& p2 `6 C& h. \# H5 J
- `6 }/ j' X+ H( O3 z3 z

本版积分规则

选择云运维时代的王牌讲师-长河老师,助你轻松入门ITIL Foundation培训课程

QQ|小黑屋|手机版|Archiver|艾拓先锋网 ( 粤ICP备11099876号-1|网站地图

Baidu

GMT+8, 2019-5-24 13:36 , Processed in 0.239909 second(s), 30 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表