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

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

 找回密码
 点击获取邀请码 - 立即注册

扫描二维码登录本站

QQ登录

只需一步,快速开始

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

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

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

参加活动:0

组织活动:0

发表于 2018-9-1 16:52:06 | 显示全部楼层 |阅读模式 来自- 广东广州
本帖最后由 adminlily 于 2018-9-1 17:14 编辑 2 [8 w8 ?/ u6 e- O+ {2 [6 l6 n

3 Q: e1 P; Q# k! L3 [$ E

3 a  [& l1 y4 }+ m

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

7 s. Y3 R! Z1 K9 @0 x6 E# I
. P4 C: G6 T! K
先申明一下,因为我们公司规模较小,和在座各位朋友任职的一线互联网公司可能没有可比性。所以,我分享的一部分流程或方案,仅供参考。
" u1 e9 M; h/ Y' H! j% U* t& j( M% g

- i/ K2 ?- B. d+ n* E
背景4 |1 \4 @4 h0 ~9 `$ _

1 j) b# i1 W+ x) x0 {) M  ?6 Z

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

8 }2 M, p$ @! ?5 r/ e; b, V
9 m: b6 B# J- z% D, r& r
Java项目改造$ O4 V1 K- c/ h! t
# K: t9 t% a6 Q! [! {
下面我们聊聊Java项目,我们把一个Git库中的2个项目(接口、后台管理)进行拆分:

) Y' I+ v- I6 E" }
2 V  r+ ?# S7 ^/ n6 |& `
1、接口服务3 P5 |" z" E. s& B

) B, |0 S% s; Y( s5 _, n  ?/ H* }
2、后台服务
  P& D8 f' w4 l$ H- S# h( d9 O: T6 i
3、html5包
: {2 q' g* y2 ?' g$ l
- [( x  Q: X- w/ b
1 D. H8 _3 S* q* y4 V4 Q) G5 w3 s4、公共包服务
+ B' r; k% e; y. k* K. S

: U! @8 A! s$ R4 t5 T  F# g3 v
; g( K- g, ~3 @
我们主要做了前后端分离,代码Git库分支化管理(事实上大部分小公司都可以这么拆分)。
% a) R0 J7 P, T. W7 \6 p# l! V
- g: b, S, f4 u$ h5 F& h
我们采用和其他公司不同的方式,定义公共版为主分支,为每个客户建立1个额外分支(事实上分为开发分支、集成分支),发现公版的bug,到主分支改,改完后合并到各个分支,这样就不必重复切换到每个客户项目中改bug。
- E" l! ?9 a( |: I4 X2 y: r
: r: b, ]$ C9 w7 M
Jenkins
- e# v. e5 C, E$ h

6 r4 T8 {4 F6 P
使用Jenkins编译,包含我们Java项目、H5项目、安卓项目、iOS项目。
$ Q0 _; `0 f# {; }- R" W
5 I# {, R  T8 @" y! o
开发人员只需要本地调试后,提交代码到Git库的某个项目分支上,由Jenkins自动编译。如果编译错误会通过邮件反馈到影响代码的开发人员邮箱中,另外测试人员一键部署后,测试出问题,也可以通过Jira提单给开发人员。开发人员收到后,继续提交代码,不再像我们之前,必须通知开发人员,开发人员本地打包。
& D0 {; m5 a, O
流程如下:
3 h) P* z) N$ G/ c
! P( T0 z' B7 d3 N5 A. V
这里我们做了一点偷懒,我们版本号的维护也交给了Jenkins,通过脚本由Jenkins自动增加版本号。

. O# b' B& e: @6 _% F( [

  W, P3 k4 ?1 Z9 e0 Q
我们还将所有项目中状态抽取出来,做成无状态项目(大部分公司都是这么做的,尤其之前听阿里分享,他们做到自动识别环境),这样,测试环境、生成环境的war包都是相同的。

6 E9 ~- w2 D# V% L) o
$ ]: L  d( |0 Z3 K& @7 `5 h
自动化部署5 U6 r' E; U0 X7 Q* n7 ]- d

% H0 b4 u5 ^1 L# y: {( Y然后我们做了一个自动化部署的小平台,主要功能如下:
3 y  t+ H, B5 X  y* a

5 S4 i+ \! s3 r# M+ W6 r- N& x
1、升级、显示当前版本2 Q# t) J/ m, s; \, U& [, o/ B
/ [$ c! ^% Z+ m
4 q6 f2 a" C# N' o+ d% y$ w
2、对war包有效期,真实性校验; U! w1 F) M( q2 C
, Q& }: d) y5 f* R( h

0 k/ Z7 {7 I( r* a2 i, m4 e
) T8 L9 e% F& e. F' u* u* c
3、开发人员将公共SQL放入公共.sql里2 ^0 Z" M, X" z" E0 {- ]

2 Y3 g8 G( D9 k8 P1 {# k
  k+ e. N# X1 I4、各个客户定制化需求的SQL放入各个客户.sql里
* a" y/ R4 ]) w0 j+ F% P3 A

# {% h" ?8 Z9 Q# Z- S6 Q
6 `" ]/ G1 }5 R- T/ H
项目经理升级时,自动提示未执行的SQL,点击执行即可。

$ l6 g- `" C3 O: d
7 `5 I4 N, D) y8 J

/ m$ p! i& w' x4 e' \; i. x
1 ~* p) Z: w: C
客户端
7 I9 z+ r( a; ?7 o; B9 j3 l! I1 u. \6 D
接下来,我们聊客户端:

3 E1 o; @; M# d! F# F! c
8 j( [2 ~& k/ p' B
客户端内容不多,我们有安卓、IOS客户端,也是经过一轮无状态抽取,然后抽取服务器地址,配置后,由Jenkins自动打包,同时打包测试环境包、生成环境包。
$ z+ [$ r1 t! k8 ^

6 g. O+ g# [3 N% E
: A. {$ {9 r# a' C0 D
测试组8 W6 {1 N% _& Q5 A% u5 ?  l

5 s9 M6 E2 ~9 }
测试人员从Jira提单后,开发人员解决后,会看到具体解决的版本号,然后进入OSS存储,安装Android程序,或者IOS程序,一键部署Java项目。
, M4 e1 w6 o) T3 A
因为安卓和IOS均是同时发2个包,Java项目、H5项目无状态,所以生产环境和测试环境都可快速部署测试。

& e! w# _9 c: F" }
$ v8 F# X6 |9 j- ~
+ Z, R# E5 o3 T. ]1 j
运维组
% f' J# I! X' B( \7 r7 {
& L" ?' z5 Q6 N3 H
运维组重构先看看之前的图:

  p, T4 |$ A4 D; M+ S5 [7 b* m
$ J, }9 p0 R" d5 ~$ F
因为各个时期部署的系统版本以及服务器型号等都不通,所以线上环境比较混乱。
; }9 E* i; @7 ^6 D+ }
" o) ]" c& a/ c2 }) G
我们采用Docker容器统一方案解决此问题,使得每个客户机器环境均相同。我知道在座的各位都是Docker大神,我就不多讲了。
2 n( h9 u+ A5 d4 J

+ m- w" b9 v6 T. v4 I4 H8 i% S
看看我们现在的管理图:

  d: N" G- e4 v* k0 s& A
; J9 F& {) z) i- h+ ?* z4 B) P
我们用的是Portainer框架,简单二次开发了一点功能。

1 c' p! [+ n; e+ R; ]- F' r  B
% Z4 X  f# w9 F- @" y  X& z
我们用了TLS认证,所以,管理者并不是通过Linux密码控制,而是通过配置平台,然后分配权限给各个项目经理所在的team中,然后,项目经理对team成员权限进行管理分配。

/ Q( V0 @, f4 i8 M- _* H/ Q

) H) o7 [2 N2 Y# p
该方案优点:

; L( u1 }' S( `+ t

7 |6 W$ A9 U5 o, s# X* \6 E
  • 在Docker下,所有客户生产环境相同。

    9 v0 W; H5 u* w' V& u
* u- m2 w' I/ y/ y

  B3 g4 o0 z! w/ K) `
  • 易于备份、迁移、恢复。

    5 f+ R) v' C( c: P5 M0 u; d3 j
: k5 c  a1 b  I- Y. _0 @  K
9 i' K4 ~! Q4 h) |* }
  • 可建高可用环境,发包时采用灰度发包,蓝绿部署不中断服务。
    / N: U" Q6 B9 D3 u3 ]. h

5 J) A5 D6 ~9 o- B2 C" g3 a& k
  • 可支持弹性伸缩设计,支持扩展。
    / I, C. k: l; y( I7 N

; e) a1 V: B) C% I5 d# M! C
  • 支持负载均衡,域名转发,意外切换容器等。

    7 G+ r. z) o/ T$ k  U
- r. M- d! R$ Z  [! P

2 N- e) m  C/ M, s: B
  • 有利于转型微服务架构。
    7 v1 ]3 n& j- N# H
, D' S9 |6 R' @7 e+ ?5 Y9 t
' m$ G1 Z, W% j
快速搭建环境
9 G( a+ }0 y5 h  B+ [

2 E# B  w9 A! O
而建立Docker集群需要我们自动化完成,这里我采用了Ansible工具来实施,我们可通过指令分发,指令获取所有机器某个包的版本,执行不同的代码。

! y, s1 ~& T  d% g6 a4 V1 X
+ x1 t  K5 @  I, R3 v) R) d: Q
这里我建立了各种仓库,方便Java开发,建立了一个私有仓库,一个Maven官方代理仓库,一个阿里云代理仓库;Docker上我为了方便开发打包其他环境,创建了Docker私有仓库;还有一些为了解决统一管理Linux服务器而创建npm仓库;以及安卓所要使用的Gradle私有仓库;未来,我们可能还会创建更多仓库,能支持的仓库列表都在下面:
0 n0 O9 o6 S  {* ^; e! J

( G9 L' E' N, x- h3 J% @

  y: c! h% Y5 ]( g

* m) p8 Z9 P' o3 Z0 O  f大数据篇
. Q( @- E0 Z- A

$ ^  o. L: t" [4 K! L大数据一直以来是很多公司核心产品,对于小公司,如何低成本实施呢,我研究了一套强大的大数据框架Superset,并对其做了部分的二次开发。他能实现各种大数据图表展示,如下图:

- s% U5 D$ J$ l* _
7 `7 `3 K! V# \  {0 G) Q" c
我们采用iframe的形式将部分功能加入到我们管理后台。

( P9 N# E, e  s0 ~; H7 x0 _1 [- p
& s# u) j. }0 C
接口篇% U8 O# @1 s8 r3 U
9 k% K5 w( M$ l3 s
我们采用了RESTful风格的API,也许很多人说RESTful不是很简单,10分钟上手,30分钟精通,事实上绝对比这要复杂的多。有很多的细节,很多的约束,经过几个月的协调开发后,都未必能避免出现不太和谐的接口。

( T1 U2 v& t2 [: v. ~- l' [8 z  S& Y
4 G4 x( M0 z+ s4 V# U- H! G: L
之前,我们项目,各种接口文档都存在,主要有一下:

* P2 D. k( p' o  h
4 Z) T6 L1 m* P1 g: ^5 L
  • Swagger

    ' I! A; G# r" \' \& m6 F* s% ]

* ^7 @* G  N7 N7 ~, k. J) x& G
  • 阿里的RAP

      O3 L$ J1 O  I1 P) L' U

4 V3 |# \! I( H% `) s
& {/ A& t, q$ e2 U5 E' T/ _7 }' g/ U
  • Word文档
    9 {7 }4 S8 z  T( q) T$ T

- F: O3 {5 K2 _( x
& j0 Y1 g  Q0 o9 ?4 R( t0 S* J
  • 其它

    + `3 q: b' U+ B3 K! a

. x$ h% W$ e  d1 V( l  e
对了,之前的接口是这样的:

: U2 E4 _, X% }. O$ E( V

" z8 }- o2 H" Y" F
  • …/A项目/模块1/getProducts ----接口
    $ t! q" v! {& p3 v9 X8 q6 B
  b. A3 _# n0 k

/ O3 k, R8 ~" t  j" R
  • …/A项目/模块1/Products.html ----页面
    3 m6 w' @9 v0 X& L2 M- v2 l

4 ?; k" E  _9 s9 {. w
. ~2 e  Q1 z" c
  • …/A项目/模块1/Products.js ----静态资源

    ' S# z7 o1 \. x) E

. z+ h0 X  |# w2 n
( b9 }! c+ L( q* n

$ H) o+ {- i  l5 s* Y6 J
留下了很多的坑,这里不对RESTful再做详细介绍,有兴趣,大家可以自己了解下。我们统一了一个接口文档为postman,可能很多朋友会说postman怎么能作为接口文档,我只想说,他适合小公司,不仅有入参、出参示例(可以多个例子),还能在tests里写接口说明,也方便前端调试,调用服务器使用。

4 c# V1 K2 Z' n! ?
4 ]1 A4 V  v. O2 \$ {' P) j
规范篇
. g+ r' x3 a& C- C+ P% y# a/ @) o; V

. |# N) V' N. q& x
我们制定了一些规范和约束,比如,原来项目经理发现问题,会立马找开发,现在规定为先联系测试,由测试提单给开发。
2 p9 I/ t" n6 O6 r3 H. Q$ X

# f# S# r. G0 A$ ?) T# @! T
Q&A
# H+ t- x4 x7 g; A5 F: S: I
9 a8 n6 C. i- i' I7 g) X' k( C* {
Q:请问Portainer仅用于测试环境还是在生产也用这一套?
( b, x8 x9 O% _& K# E
& i: P4 l! o" x
) T1 N# T1 a% o
A:因为Portainer是直接通过docker api执行的,并没有在服务器上装有什么客户端(也就是无侵入,这也是我们选用他的原因),我们只是在Docker里面配置了个http的TLS证书,加上我们对它做了一些改造,所以我们使用了Portainer应用生产环境。
+ {! M8 j/ @2 ~7 r: f, q

. G. i$ }' o' u+ b8 F3 K) R
Q:请问下测试的时候接口模拟您这边是如何处理的?

6 A/ ^) ?5 Z# Y. x

$ ~$ y) r6 d% x# k# o9 s, l5 c
A:Ostman默认录入了几个多种情况下的出参,其次,我们前端每个人都有一套独立环境,通过Web端管理部署(数据库和测试人员共用),不会受后台开发人员对接口修改而中断服务。其次我们有少量前端页面使用了mock.js。
! v$ J* z; @- h4 v; r  n4 K$ E
% X, Z0 k. q8 W
Q:请问Docker里跑Java应用性能怎么调优,默认是共享资源池,对Java来说CPU切换很费性能,除了绑定CPU,但这样就没有弹性之说,麻烦说下?
! d( _6 q, v- d/ S2 u$ `+ J& {& o
; v; P/ l, R' @4 t
A:这个性能,我们对Java项目进行多次内存优化,通过ide的内存管理,线程查看等多重方法进行调优,单从war包体积上我们就缩小了60%,内存也下调很多。我们并不能自动伸缩,目前是通过Nginx配置多容器来实现负载均衡。

) a( w& F0 R: S7 Q* e" Q) D5 m

2 I7 k+ m' P- q. t; k# v" z
Q:如何实现分布式事务?如何保证数据一致性?

# k1 m# Y0 C% h0 ]8 u' i! ]
' O) j$ A5 k7 I: O+ E' R
A:我们在Nginx层通过策略保证同一个机器请求只会分布到一台机器上,用最少代价解决这个问题,其次我们项目中,大部分都使用全局uuid操作和插库。

, ?7 E, Q/ [& c; ~" C$ _; S
; y* D: Z6 Z* E" d! i8 N$ {
Q:贵司的业务模式跟我们很像,感觉很受用。想问下,多客户、多版本共存的情况下,版本升级这块儿是怎么做的?
+ w' S5 q5 c) H; F9 W3 E
) R! x/ i; n+ G
A:我们使用的是Git分支化管理,由Jenkins定义版本号,SQL分为公共和私有的部分,比如某个客户升级2.0.0版本,会自动检测上个版本到此时的SQL语句,提示项目经理点击,自动执行。(我们现在回滚项目版本,不支持SQL回滚,所以我们SQL一般只增不减、不改),我们可以随时查看某客户线上版本和SQL执行到什么地方。
0 a3 i( I! i0 D4 ]
! D  _' Q5 u3 j" \
Q:日志如何存储和分析?用什么工具?系统异常如何监控?
! C! O! z% f: k  v7 D8 s
" w% y( R8 Z" Y3 g. p2 t4 A& ?
A:先说说异常如何检测吧,我们做了一套http监控框架,以任务的形式添加,然后会对已配置的线上环境、多容器进行监控,比如任务为http://xx.com/..../messages?token={token},在配置任务执行时间及频率,然后配置项目列表,其中项目编辑的信息有host,可理解为http://xx.com/这块,还有变量列表,支持随意定义,比如token 11111111 用户token信息,这种k、v、说明文字,执行任务的时候,自动替换host和占位符。系统只记录变更,我们项目接口统一了出参,当状态码异常时显示,此方案可实现监控各种容器、各种测试、生产环境。
4 m4 m/ j+ Z1 d1 j1 O  k  z/ }2 E
0 d7 a. F$ Y# _# {( K* e4 l' m
$ ?7 q" {4 A5 ^6 U, l
关于日志收集,目前我们并没有很多公司搞的很高大尚,因为这块,还在改造中。我们就是多容器映射了本地磁盘目录,然后对这些目录日志文件进行合并,对那种error级别的日志,筛选出来。
5 p% A; G2 h3 O5 c

9 Y" d( ]* Y+ U5 v
原创:邵磊

5 C( F0 Y& g9 h& r- ]1 J& M4 s0 L5 Y# g1 h4 L' ]0 L- |
( o$ z8 W1 O/ J" H

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?点击获取邀请码 - 立即注册

x

本版积分规则

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

QQ|小黑屋|手机版|Archiver|ITIL先锋论坛五万运维人社区 ( 粤ICP备17056641号|网站地图

Baidu

GMT+8, 2018-9-21 00:56 , Processed in 0.276163 second(s), 36 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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