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

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

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

扫描二维码登录本站

QQ登录

只需一步,快速开始

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

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

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

参加活动:0

组织活动:0

发表于 2018-9-1 16:52:06 | 显示全部楼层 |阅读模式 来自- 广东广州
本帖最后由 adminlily 于 2018-9-1 17:14 编辑
; {( x( x) c3 Z# z1 O" w' t
6 V0 q' t: `! w5 ?( L5 O

' |/ Z" u; Z2 G7 p+ T

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

/ O. \4 `& p- n5 v1 p3 v& a& F
! E, C: F! A" v' Z
先申明一下,因为我们公司规模较小,和在座各位朋友任职的一线互联网公司可能没有可比性。所以,我分享的一部分流程或方案,仅供参考。
" H3 J4 j9 A, k7 c1 k% m
/ W( \5 q8 \6 X. U* A' O7 G
背景
/ v6 ~' R1 ?- Y5 F- ~8 h9 G3 C
) n7 D1 h# n. {% w- |7 @* |1 z8 q

7 ^; h* c1 d& C0 V

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

8 H3 X: T4 l8 W6 M6 m# F
  T) C3 \  m. R  Q" H* P
Java项目改造
0 h) `2 p2 p8 z0 |3 h! i# ?

( }2 @- h8 _& p. X2 i
下面我们聊聊Java项目,我们把一个Git库中的2个项目(接口、后台管理)进行拆分:
% a" n& V4 B, |/ D
1 G* I6 s' n+ J  s( {
1、接口服务
3 c% J6 E$ i2 h" p. b/ b' h( j
. G! V  D. A$ R+ d# Y
2、后台服务7 }; Y& {& @; Q: V( f5 K; V# D

1 A  k) Y, {1 k, C# ~
3、html5包/ g8 J* K! r# |! v( _; ^, R; T3 t6 f
3 j' o, B4 }' |2 C

0 z0 c, {1 s- A4、公共包服务7 u, w8 T" a0 b! i; Z

: z5 y0 s7 A  ]) Y
% r1 l/ m0 K/ `" b: C8 d
我们主要做了前后端分离,代码Git库分支化管理(事实上大部分小公司都可以这么拆分)。
( g; l0 j' |% u$ W* Y: i7 c
. ]3 Q" Z' \( c' m7 }5 f+ X- ~
我们采用和其他公司不同的方式,定义公共版为主分支,为每个客户建立1个额外分支(事实上分为开发分支、集成分支),发现公版的bug,到主分支改,改完后合并到各个分支,这样就不必重复切换到每个客户项目中改bug。
2 q) D+ ]0 d( Z' a) `

2 D1 N1 L# C, f6 d* E9 b2 O
Jenkins
; `5 I2 Z7 j- d* Y1 B3 z0 e
7 i. F; X) b3 P' K) H3 `2 W9 b
使用Jenkins编译,包含我们Java项目、H5项目、安卓项目、iOS项目。
; p' ^3 g' `, `6 F6 f) s( e! t( R

; q4 N% q% F, o+ P" J2 l
开发人员只需要本地调试后,提交代码到Git库的某个项目分支上,由Jenkins自动编译。如果编译错误会通过邮件反馈到影响代码的开发人员邮箱中,另外测试人员一键部署后,测试出问题,也可以通过Jira提单给开发人员。开发人员收到后,继续提交代码,不再像我们之前,必须通知开发人员,开发人员本地打包。

3 d) T; y& ]- x: l- @% p% d
流程如下:

0 H; D% P% I% Z8 d7 ?
1.png
1 t: ~& k; D. n+ j
这里我们做了一点偷懒,我们版本号的维护也交给了Jenkins,通过脚本由Jenkins自动增加版本号。

% F1 f/ o) {7 I2 A9 J
: a% p6 X/ x( L" y1 R  Z6 V* z
我们还将所有项目中状态抽取出来,做成无状态项目(大部分公司都是这么做的,尤其之前听阿里分享,他们做到自动识别环境),这样,测试环境、生成环境的war包都是相同的。

4 x# F/ R6 Q$ ]2 Q
+ ~8 o" Y0 f% P9 |6 n/ @' e' k+ B
自动化部署
# m6 F9 M! @' S& E* w
! I3 l" p7 ^: j, L% \然后我们做了一个自动化部署的小平台,主要功能如下:
) u& [. u4 X$ V  t2 s7 i: G' Q
9 d# d0 ~2 S2 z7 l+ ^+ j1 {: p
1、升级、显示当前版本
# \, H8 Z5 n' K
7 D- r- u7 E  \6 |0 d( T

6 Z2 k8 `# z  B$ P* p: T/ e- i
2、对war包有效期,真实性校验) d4 Z; x5 @7 h# I% v+ J

& ^+ L1 S. h7 S4 h
; w+ D% Z1 X: ~1 ~: {! _

/ @6 G5 P) L5 F# }, a# E( E
3、开发人员将公共SQL放入公共.sql里
: ]2 D! O6 C7 |# _8 h9 l( _6 Q" s6 X9 [- u0 r  r2 F
" D' j% x# @+ q5 S
4、各个客户定制化需求的SQL放入各个客户.sql里
  `/ i9 T9 B  N' d( ~. u; v

( U8 }, W: `, `4 s2 y, b$ A, J) X  n' d7 H/ ^8 _/ q" O# A
项目经理升级时,自动提示未执行的SQL,点击执行即可。

9 v  R0 x9 B1 p3 j0 Q4 Q
5 W& s; u; @& n/ F: s" ?8 P1 U1 d, R; a

! u, l) c) }' z  ~" u3 W) o4 V! C6 E% R' }3 U( x3 `' E$ `
客户端
5 Z1 Z( ?, |( O; Y2 [8 ~8 I0 Y  E, I/ C$ O6 I
接下来,我们聊客户端:

& y$ y  A/ u6 w+ F  J; _8 Z
/ b/ m" y9 Z8 \+ o! D
客户端内容不多,我们有安卓、IOS客户端,也是经过一轮无状态抽取,然后抽取服务器地址,配置后,由Jenkins自动打包,同时打包测试环境包、生成环境包。
/ S0 B2 ]0 |3 t
1.png
/ Z  A4 ]$ E9 ]
3 G0 K! K: c! ~7 K0 |9 ]0 O* s. {
测试组
7 ?* u1 P' Z! q& i, H+ J1 Z, ~7 J- I* D0 c' M8 ?
测试人员从Jira提单后,开发人员解决后,会看到具体解决的版本号,然后进入OSS存储,安装Android程序,或者IOS程序,一键部署Java项目。

; v. w1 {5 m0 L7 D: g7 X" z7 x, ?
因为安卓和IOS均是同时发2个包,Java项目、H5项目无状态,所以生产环境和测试环境都可快速部署测试。
6 `+ E# \! Y0 w0 M/ _
1.png
  ]4 _1 Z6 t$ f6 v
" s% b) H# C- c! y9 D
运维组
& t2 P! ]4 y5 a6 B/ f. S6 U
! {9 s# j/ H+ Y
运维组重构先看看之前的图:

; X  \' T  M  a# n
1.png
1 |3 w1 G* j& x8 W
因为各个时期部署的系统版本以及服务器型号等都不通,所以线上环境比较混乱。
0 i3 ]  i% Y: ?- Y" o

* U( m& t% F) e' s
我们采用Docker容器统一方案解决此问题,使得每个客户机器环境均相同。我知道在座的各位都是Docker大神,我就不多讲了。

+ ~8 Q. e2 Z, I+ Y
! c( S6 c* V+ a: I, s9 p: s
看看我们现在的管理图:

/ |7 C; E7 B" q5 a% i
1.png

) `% [9 r3 h. f8 d  k. ^
我们用的是Portainer框架,简单二次开发了一点功能。

, D$ Z2 `( ~$ N
0 d- N4 h* w( W4 O( c
我们用了TLS认证,所以,管理者并不是通过Linux密码控制,而是通过配置平台,然后分配权限给各个项目经理所在的team中,然后,项目经理对team成员权限进行管理分配。

4 Z7 w; n* h$ B1 n8 y
! `) v, Q) ~6 b; u& n
该方案优点:
1 m8 @( y/ K- ]
$ h* P& i, A5 G2 U
  • 在Docker下,所有客户生产环境相同。
    ( |9 S0 w: V/ E, A* o# A: z* x. X
& a* f& L6 v! o0 |6 e

0 k3 ^0 Z9 S! c! e! R, c
  • 易于备份、迁移、恢复。

    : n$ {8 W. U3 ?$ m! n

+ J' O9 J: O$ F- l
: E" a+ h( s! F  S
  • 可建高可用环境,发包时采用灰度发包,蓝绿部署不中断服务。
    * d8 `7 n0 l4 P# d4 K
2 n% x2 B, ?8 J2 N" g
  • 可支持弹性伸缩设计,支持扩展。

    * Q, C8 B. M0 l3 u6 _

& b& [8 J$ x# S
  • 支持负载均衡,域名转发,意外切换容器等。
    ) p' ?  e  B  e- h( R/ G

3 g6 L( s1 x! m6 ~& u& V
. ]1 y: M* C) G( \# V/ @
  • 有利于转型微服务架构。

    5 ~0 t! O' F% a. Z* h

7 C0 I; d  g: g

" _  k4 b" t9 X, ]
快速搭建环境7 Q: q+ @# A5 C0 u

: e- c. r  F( H
而建立Docker集群需要我们自动化完成,这里我采用了Ansible工具来实施,我们可通过指令分发,指令获取所有机器某个包的版本,执行不同的代码。

7 N  B* U. t/ Y

) \5 X6 j* g8 |, o, |
这里我建立了各种仓库,方便Java开发,建立了一个私有仓库,一个Maven官方代理仓库,一个阿里云代理仓库;Docker上我为了方便开发打包其他环境,创建了Docker私有仓库;还有一些为了解决统一管理Linux服务器而创建npm仓库;以及安卓所要使用的Gradle私有仓库;未来,我们可能还会创建更多仓库,能支持的仓库列表都在下面:

! [& b  w+ |- l+ L
1.png
& `" |1 r: U& t3 M+ O  \
+ K8 }( }/ w) E; W5 S2 i, Z/ t

- m* P' z) ]5 m1 J大数据篇

# R& h% ]6 i( a: E/ l, Z
2 W8 B$ {2 |0 b% [1 j大数据一直以来是很多公司核心产品,对于小公司,如何低成本实施呢,我研究了一套强大的大数据框架Superset,并对其做了部分的二次开发。他能实现各种大数据图表展示,如下图:
" M0 `: A: {- s
1.png
5 F3 r, g" p* [" w8 a
我们采用iframe的形式将部分功能加入到我们管理后台。

6 f0 i9 T! _6 u

& s! O6 {, t) [: c# C
接口篇
4 F$ n' @0 E! S8 [6 q; r2 H
2 Z6 W5 x9 [: o, Z# g
我们采用了RESTful风格的API,也许很多人说RESTful不是很简单,10分钟上手,30分钟精通,事实上绝对比这要复杂的多。有很多的细节,很多的约束,经过几个月的协调开发后,都未必能避免出现不太和谐的接口。
  w6 f2 x6 Z  G4 g

  B6 Y  N$ h' D9 O& r5 r6 y- C5 J5 A
之前,我们项目,各种接口文档都存在,主要有一下:

2 T* R* ~' g# \2 l; z1 N

1 I) B2 L; P% ~: S, g( g8 ^
  • Swagger
    - [3 F* Q5 Z. ?! r& Q3 Z5 W
9 @" V( m( C! p7 V' F) U
  • 阿里的RAP
    1 D6 ?- ?- K, p7 O7 A' P8 e
4 m! m$ O5 a7 |  m9 O4 W
8 ]0 N+ W! K5 p9 A
  • Word文档
    4 L+ D8 G. N' g2 r
# U7 n3 s; ~0 H

  J5 O! Z" `' x& c6 T. \
  • 其它

    . h. F5 O  k( H% U6 \8 H: x

0 Y, r# D0 L6 x2 |2 n
对了,之前的接口是这样的:

2 k; b0 Q4 O* D+ x% ~) S& u& A
8 {$ d5 i. z! ^  o& t& Q- ~
  • …/A项目/模块1/getProducts ----接口

    % m, J) ^, F, H) Q1 N2 \7 E

. B" U9 \$ a8 u0 n1 P# o# J% l2 t( w

# l7 {" S5 L/ J4 k1 M0 X$ B
  • …/A项目/模块1/Products.html ----页面

    % l+ ?4 E) m  _% `; J

) S3 a' C+ n. u& n
: J; d$ F( O$ Q# c8 s, l& a4 U
  • …/A项目/模块1/Products.js ----静态资源

    , I" O1 L# R  {8 H
9 g% j" R+ D- F

! T' U# m4 v* c/ R3 D$ P( i

6 a+ Y0 L# T: N6 C" b
留下了很多的坑,这里不对RESTful再做详细介绍,有兴趣,大家可以自己了解下。我们统一了一个接口文档为postman,可能很多朋友会说postman怎么能作为接口文档,我只想说,他适合小公司,不仅有入参、出参示例(可以多个例子),还能在tests里写接口说明,也方便前端调试,调用服务器使用。

7 Z  a* e. M8 I0 |3 G& L. _
7 _# F4 c  }6 }3 h9 \) \. |: c
规范篇8 k$ I( R$ o" h6 o7 T6 X
( Y9 B& c% R2 U8 Z6 y- O( `
我们制定了一些规范和约束,比如,原来项目经理发现问题,会立马找开发,现在规定为先联系测试,由测试提单给开发。
5 A) C  x4 }: A8 V4 P3 @
; c/ j: r3 X3 t0 n
Q&A
' i: ~! f( P6 U9 d6 I5 C! g

1 L) x3 r& x3 r, v8 l# r
Q:请问Portainer仅用于测试环境还是在生产也用这一套?* l7 A) D* L4 Q
  c# Q+ I4 y: \' Z
  u/ I/ x: Y8 X* g2 t: g# _
A:因为Portainer是直接通过docker api执行的,并没有在服务器上装有什么客户端(也就是无侵入,这也是我们选用他的原因),我们只是在Docker里面配置了个http的TLS证书,加上我们对它做了一些改造,所以我们使用了Portainer应用生产环境。
% O- F3 o7 \1 W& |

0 ]7 ]* @* l2 W  S' a
Q:请问下测试的时候接口模拟您这边是如何处理的?

- T8 @4 g- A+ `* b$ \
/ P  T4 f4 b7 H* s. t1 l
A:Ostman默认录入了几个多种情况下的出参,其次,我们前端每个人都有一套独立环境,通过Web端管理部署(数据库和测试人员共用),不会受后台开发人员对接口修改而中断服务。其次我们有少量前端页面使用了mock.js。
$ j# A% u& d7 A/ Y' L: y

4 q0 Y* B3 x. l' [' g
Q:请问Docker里跑Java应用性能怎么调优,默认是共享资源池,对Java来说CPU切换很费性能,除了绑定CPU,但这样就没有弹性之说,麻烦说下?
. P* |. h' ^8 i7 \8 o
0 U6 r4 P! ~0 m: C. Y. Z
A:这个性能,我们对Java项目进行多次内存优化,通过ide的内存管理,线程查看等多重方法进行调优,单从war包体积上我们就缩小了60%,内存也下调很多。我们并不能自动伸缩,目前是通过Nginx配置多容器来实现负载均衡。

8 e  `8 E1 g1 P: P# f  T& n

! A$ a, U* N( a- W6 a3 c
Q:如何实现分布式事务?如何保证数据一致性?

- z, P: Q# [/ ?* z) e

6 r% r' ?& z+ |0 b
A:我们在Nginx层通过策略保证同一个机器请求只会分布到一台机器上,用最少代价解决这个问题,其次我们项目中,大部分都使用全局uuid操作和插库。
3 Q3 D- m: l8 B+ _8 R6 [+ a
& T5 w) r% p3 R. q; D
Q:贵司的业务模式跟我们很像,感觉很受用。想问下,多客户、多版本共存的情况下,版本升级这块儿是怎么做的?
4 r9 u2 I& F% F( b6 y

7 D- P/ j. k8 r
A:我们使用的是Git分支化管理,由Jenkins定义版本号,SQL分为公共和私有的部分,比如某个客户升级2.0.0版本,会自动检测上个版本到此时的SQL语句,提示项目经理点击,自动执行。(我们现在回滚项目版本,不支持SQL回滚,所以我们SQL一般只增不减、不改),我们可以随时查看某客户线上版本和SQL执行到什么地方。

; J+ a# A! O7 i. Y. S$ J
: c% F& v" ^" C# ^8 M0 M
Q:日志如何存储和分析?用什么工具?系统异常如何监控?
7 v* U% ~+ X" n  u
% W6 w( `' {# z/ |( K- P# T& E
A:先说说异常如何检测吧,我们做了一套http监控框架,以任务的形式添加,然后会对已配置的线上环境、多容器进行监控,比如任务为http://xx.com/..../messages?token={token},在配置任务执行时间及频率,然后配置项目列表,其中项目编辑的信息有host,可理解为http://xx.com/这块,还有变量列表,支持随意定义,比如token 11111111 用户token信息,这种k、v、说明文字,执行任务的时候,自动替换host和占位符。系统只记录变更,我们项目接口统一了出参,当状态码异常时显示,此方案可实现监控各种容器、各种测试、生产环境。
  h: f3 l0 ?5 n- G3 M% ^7 u0 _  s

9 T3 i8 i% k9 C" A
' i" v; [. k# @* X8 u
关于日志收集,目前我们并没有很多公司搞的很高大尚,因为这块,还在改造中。我们就是多容器映射了本地磁盘目录,然后对这些目录日志文件进行合并,对那种error级别的日志,筛选出来。
* P$ b$ U8 l  J1 h7 e

1 o* e8 z' l2 n* j3 J  e' h! T6 t* _  [
原创:邵磊

* b  f( o1 w& y, t1 p* S: F' }0 \  Y: g/ e+ E9 r/ b+ t

9 W: Q; O, n0 S% v0 s0 y

本版积分规则

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

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

Baidu

GMT+8, 2019-1-23 22:20 , Processed in 0.226315 second(s), 32 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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