一、介绍

根据不同的场景,apolloconfig部署的架构会有很多种,这里不讨论细节,仅从部署架构的宏观角度,来介绍各种部署的方案

1.1 flowchart

用flowchart来表达部署方式,这里先介绍一些基本的概念

1.1.1 依赖关系

依赖关系用

  1. graph LR
  2. 1 --> 2

表示1依赖2,也就是2必须存在,1才可以正常工作,例如

  1. flowchart LR
  2. 应用 --> MySQL

表示应用需要使用MySQL才可以正常工作

依赖关系可能会比较复杂,以及存在多层级的依赖,例如

  1. flowchart LR
  2. 服务A --> 注册中心
  3. 服务A --> 服务B --> MySQL
  4. 服务A --> Redis

服务A需要注册中心,服务B,Redis

并且服务B需要MySQL

1.1.2 包含关系

包含关系用

  1. graph
  2. subgraph a
  3. b
  4. end

表示a包含b,也就是b是a的一部分,包含关系可能会出现嵌套的情况,例如

  1. flowchart LR
  2. subgraph Linux-Server
  3. subgraph JVM1
  4. Thread1.1
  5. Thread1.2
  6. end
  7. subgraph JVM2
  8. Thread2.1
  9. end
  10. MySQL
  11. Redis
  12. end

表示在一台Linux服务器上,运行着MySQL,Redis,2个JVM,JVM里分别又存在Thread

二、单机

单机部署的场景通常是新手学习,或者公司内部对性能要求不高的测试环境,不适用于生产环境

2.1 单机,单环境 All In One

这是最简单,部署起来最方便的单机部署方式

需要:

  • 1台Linux服务器:有JRE
  • 2个database:1个PortalDB和ConfigDB

如下图,所有模块部署在同一台Linux机器上,总共有3个JVM进程

  1. flowchart LR
  2. m[Meta Server]
  3. e[Eureka]
  4. c[Config Service]
  5. a[Admin Service]
  6. p[Portal]
  7. configdb[(ConfigDB)]
  8. portaldb[(PortalDB)]
  9. subgraph Linux Server
  10. subgraph JVM8080
  11. m
  12. e
  13. c
  14. end
  15. subgraph JVM8090
  16. a
  17. end
  18. subgraph JVM8070
  19. p
  20. end
  21. end
  22. c --> configdb
  23. a --> configdb
  24. p --> portaldb

JVM8080:对外暴露的网络端口是8080,里面有Meta Server,Eureka,Config Service,其中Config Service又使用了ConfigDB

JVM8090:对外暴露的网络端口是8090,里面有Admin Service,并且Admin Service使用了ConfigDB

JVM8070:对外暴露的网络端口是8070,里面有Portal,并且Portal使用了PortalDB

如果加入模块之间的依赖,flowchart会变成

  1. flowchart LR
  2. m[Meta Server]
  3. e[Eureka]
  4. c[Config Service]
  5. a[Admin Service]
  6. p[Portal]
  7. configdb[(ConfigDB)]
  8. portaldb[(PortalDB)]
  9. subgraph Linux Server
  10. subgraph JVM8080
  11. m
  12. e
  13. c
  14. end
  15. subgraph JVM8090
  16. a
  17. end
  18. subgraph JVM8070
  19. p
  20. end
  21. end
  22. c --> configdb
  23. a --> configdb
  24. p --> portaldb
  25. m --> e
  26. c --> e
  27. a --> e
  28. p --> m
  29. p --> a

Config Service和Admin Service会把自己注册到Eureka上

Portal通过Meta Server服务发现Admin Service

为了flowchart看起来更加简洁,可以只表示进程之间的依赖关系

  1. flowchart LR
  2. m[Meta Server]
  3. e[Eureka]
  4. c[Config Service]
  5. a[Admin Service]
  6. p[Portal]
  7. configdb[(ConfigDB)]
  8. portaldb[(PortalDB)]
  9. subgraph Linux Server
  10. subgraph JVM8080
  11. m
  12. e
  13. c
  14. end
  15. subgraph JVM8090
  16. a
  17. end
  18. subgraph JVM8070
  19. p
  20. end
  21. end
  22. JVM8080 --> configdb
  23. JVM8090 --> configdb
  24. JVM8070 --> portaldb
  25. JVM8090 --> JVM8080
  26. JVM8070 --> JVM8090

进程JVM8070依赖进程JVM8090和PortalDB

进程JVM8090依赖进程JVM8080和ConfigDB

进程JVM8080依赖ConfigDB

2.2 单机,单环境 分开部署

2.2.1 单机,单环境 分开部署 3台Linux服务器

3个JVM进程也可以分散到3台Linux机器上

需要:

  • 3台Linux服务器:分别部署3个进程
  • 2个database
  1. flowchart LR
  2. m[Meta Server]
  3. e[Eureka]
  4. c[Config Service]
  5. a[Admin Service]
  6. p[Portal]
  7. configdb[(ConfigDB)]
  8. portaldb[(PortalDB)]
  9. subgraph Linux Server 1
  10. subgraph JVM8080
  11. m
  12. e
  13. c
  14. end
  15. end
  16. subgraph Linux Server 2
  17. subgraph JVM8090
  18. a
  19. end
  20. end
  21. subgraph Linux Server 3
  22. subgraph JVM8070
  23. p
  24. end
  25. end
  26. JVM8080 --> configdb
  27. JVM8090 --> configdb
  28. JVM8070 --> portaldb
  29. JVM8090 --> JVM8080
  30. JVM8070 --> JVM8090

2.2.2 单机,单环境 分开部署 2台Linux服务器

不过通常我们会把Config Service和Admin Service部署在一台Linux服务器上

需要:

  • 2台Linux服务器:1台部署Portal,另一台部署Config Service和Admin Service
  • 2个database
  1. flowchart LR
  2. m[Meta Server]
  3. e[Eureka]
  4. c[Config Service]
  5. a[Admin Service]
  6. p[Portal]
  7. configdb[(ConfigDB)]
  8. portaldb[(PortalDB)]
  9. subgraph Linux Server 1
  10. subgraph JVM8080
  11. m
  12. e
  13. c
  14. end
  15. subgraph JVM8090
  16. a
  17. end
  18. end
  19. subgraph Linux Server 2
  20. subgraph JVM8070
  21. p
  22. end
  23. end
  24. JVM8080 --> configdb
  25. JVM8090 --> configdb
  26. JVM8070 --> portaldb
  27. JVM8090 --> JVM8080
  28. JVM8070 --> JVM8090

后续为了flowchart更简洁,将JVM8080里的内容进行简化,只显示Config Service,里面的Meta Server和Config Service不再显示

  1. flowchart LR
  2. subgraph JVM8080
  3. m[Meta Server]
  4. e[Eureka]
  5. c[Config Service]
  6. end
  7. subgraph new-JVM8080[JVM8080]
  8. new-c[Config Service]
  9. end
  10. JVM8080 --> |simplify| new-JVM8080

所以部署架构可以简化表示成

  1. flowchart LR
  2. c[Config Service]
  3. a[Admin Service]
  4. p[Portal]
  5. configdb[(ConfigDB)]
  6. portaldb[(PortalDB)]
  7. subgraph Linux Server 1
  8. subgraph JVM8080
  9. c
  10. end
  11. subgraph JVM8090
  12. a
  13. end
  14. end
  15. subgraph Linux Server 2
  16. subgraph JVM8070
  17. p
  18. end
  19. end
  20. JVM8080 --> configdb
  21. JVM8090 --> configdb
  22. JVM8070 --> portaldb
  23. JVM8090 --> JVM8080
  24. JVM8070 --> JVM8090

2.3 单机,双环境

单个环境基本没法满足实际的应用场景,例如公司里有SIT测试环境和UAT测试环境,此时需要部署2个环境提供配置服务

很容易想到的部署架构如下,把单机,单环境的部署架构重复2次即可

需要:

  • 2台Linux服务器
  • 4个database
  1. flowchart LR
  2. subgraph SIT
  3. c1[SIT Config Service]
  4. a1[SIT Admin Service]
  5. p1[SIT Portal]
  6. configdb1[(SIT ConfigDB)]
  7. portaldb1[(SIT PortalDB)]
  8. subgraph SIT Linux Server
  9. subgraph sit-jvm-8080[SIT JVM8080]
  10. c1
  11. end
  12. subgraph sit-jvm-8090[SIT JVM8090]
  13. a1
  14. end
  15. subgraph sit-jvm-8070[SIT JVM8070]
  16. p1
  17. end
  18. end
  19. sit-jvm-8080 --> configdb1
  20. sit-jvm-8090 --> configdb1
  21. sit-jvm-8070 --> portaldb1
  22. sit-jvm-8090 --> sit-jvm-8080
  23. sit-jvm-8070 --> sit-jvm-8090
  24. end
  25. subgraph UAT
  26. c2[UAT Config Service]
  27. a2[UAT Admin Service]
  28. p2[UAT Portal]
  29. configdb2[(UAT ConfigDB)]
  30. portaldb2[(UAT PortalDB)]
  31. subgraph UAT Linux Server
  32. subgraph uat-jvm-8080[UAT JVM8080]
  33. c2
  34. end
  35. subgraph uat-jvm-8090[UAT JVM8090]
  36. a2
  37. end
  38. subgraph uat-jvm-8070[UAT JVM8070]
  39. p2
  40. end
  41. end
  42. uat-jvm-8080 --> configdb2
  43. uat-jvm-8090 --> configdb2
  44. uat-jvm-8070 --> portaldb2
  45. uat-jvm-8090 --> uat-jvm-8080
  46. uat-jvm-8070 --> uat-jvm-8090
  47. end

但是这种方案,会存在2个Portal界面,没法1个界面管理2个环境,使用体验不是很好,Portal实际上可以只部署1套,推荐的部署架构如下

  • 3台Linux服务器:
    • Portal Linux Server单独部署Portal
    • SIT Linux Server部署SIT的Config Service和Admin Service
    • UAT Linux Server部署UAT的Config Service和Admin Service
  • 3个database:1个PortalDB + 1个SIT的ConfigDB + 1个UAT的ConfigDB
  1. flowchart LR
  2. p[Portal]
  3. portaldb[PortalDB]
  4. p --> portaldb
  5. subgraph Portal Linux Server
  6. subgraph JVM8070
  7. p
  8. end
  9. end
  10. subgraph SIT
  11. c1[SIT Config Service]
  12. a1[SIT Admin Service]
  13. configdb1[(SIT ConfigDB)]
  14. subgraph SIT Linux Server
  15. subgraph sit-jvm-8080[SIT JVM8080]
  16. c1
  17. end
  18. subgraph sit-jvm-8090[SIT JVM8090]
  19. a1
  20. end
  21. end
  22. sit-jvm-8080 --> configdb1
  23. sit-jvm-8090 --> configdb1
  24. sit-jvm-8090 --> sit-jvm-8080
  25. end
  26. subgraph UAT
  27. c2[UAT Config Service]
  28. a2[UAT Admin Service]
  29. configdb2[(UAT ConfigDB)]
  30. subgraph UAT Linux Server
  31. subgraph uat-jvm-8080[UAT JVM8080]
  32. c2
  33. end
  34. subgraph uat-jvm-8090[UAT JVM8090]
  35. a2
  36. end
  37. end
  38. uat-jvm-8080 --> configdb2
  39. uat-jvm-8090 --> configdb2
  40. uat-jvm-8090 --> uat-jvm-8080
  41. end
  42. JVM8070 --> sit-jvm-8090
  43. JVM8070 --> uat-jvm-8090

2.4 单机,三个环境

假设现在需要满足SIT、UAT、PP这3个环境的使用场景,

在之前双环境的基础之上,再多加1台PP环境的Linux服务和ConfigDB即可,Portal通过修改配置的方式,来管理这3个环境

  1. flowchart LR
  2. p[Portal]
  3. portaldb[PortalDB]
  4. p --> portaldb
  5. subgraph Portal Linux Server
  6. subgraph JVM8070
  7. p
  8. end
  9. end
  10. subgraph SIT
  11. c1[SIT Config Service]
  12. a1[SIT Admin Service]
  13. configdb1[(SIT ConfigDB)]
  14. subgraph SIT Linux Server
  15. subgraph sit-jvm-8080[SIT JVM8080]
  16. c1
  17. end
  18. subgraph sit-jvm-8090[SIT JVM8090]
  19. a1
  20. end
  21. end
  22. sit-jvm-8080 --> configdb1
  23. sit-jvm-8090 --> configdb1
  24. sit-jvm-8090 --> sit-jvm-8080
  25. end
  26. subgraph UAT
  27. c2[UAT Config Service]
  28. a2[UAT Admin Service]
  29. configdb2[(UAT ConfigDB)]
  30. subgraph UAT Linux Server
  31. subgraph uat-jvm-8080[UAT JVM8080]
  32. c2
  33. end
  34. subgraph uat-jvm-8090[UAT JVM8090]
  35. a2
  36. end
  37. end
  38. uat-jvm-8080 --> configdb2
  39. uat-jvm-8090 --> configdb2
  40. uat-jvm-8090 --> uat-jvm-8080
  41. end
  42. subgraph PP
  43. c3[PP Config Service]
  44. a3[PP Admin Service]
  45. configdb3[(PP ConfigDB)]
  46. subgraph PP Linux Server
  47. subgraph pp-jvm-8080[PP JVM8080]
  48. c3
  49. end
  50. subgraph pp-jvm-8090[PP JVM8090]
  51. a3
  52. end
  53. end
  54. pp-jvm-8080 --> configdb3
  55. pp-jvm-8090 --> configdb3
  56. pp-jvm-8090 --> pp-jvm-8080
  57. end
  58. JVM8070 --> sit-jvm-8090
  59. JVM8070 --> uat-jvm-8090
  60. JVM8070 --> pp-jvm-8090

2.5 单机,多个环境

原理同上,每个环境1台Linux服务器+1个ConfigDB

然后Portal添加新环境的信息即可

三、高可用

1个环境只有1个Config Service进程,无法满足高可用,为了避免单点宕机后影响系统的可用性,需要多实例部署,也就是部署多个Java进程在不同的Linux服务器上

3.1 最简高可用,单环境

回到常见的非高可用部署方式,

  1. flowchart LR
  2. c[Config Service]
  3. a[Admin Service]
  4. p[Portal]
  5. configdb[(ConfigDB)]
  6. portaldb[(PortalDB)]
  7. subgraph Linux Server 1
  8. subgraph JVM8080
  9. c
  10. end
  11. subgraph JVM8090
  12. a
  13. end
  14. end
  15. subgraph Linux Server 2
  16. subgraph JVM8070
  17. p
  18. end
  19. end
  20. JVM8080 --> configdb
  21. JVM8090 --> configdb
  22. JVM8070 --> portaldb
  23. JVM8090 --> JVM8080
  24. JVM8070 --> JVM8090

当Linux Server 1宕机时,client就只能读取本地磁盘上的config-cache了,如果需要防止单台Linux宕机导致Config Service不可用,可以尝试再新增1台Linux机器

需要

  • 3台Linux服务器:1台部署Portal,另外2台分别部署Config Service和Admin Service
  • 2个database
  1. flowchart LR
  2. c-1[Config Service]
  3. c-2[Config Service]
  4. a-1[Admin Service]
  5. a-2[Admin Service]
  6. p[Portal]
  7. configdb[(ConfigDB)]
  8. portaldb[(PortalDB)]
  9. JVM8080-1[JVM8080]
  10. JVM8080-2[JVM8080]
  11. JVM8090-1[JVM8090]
  12. JVM8090-2[JVM8090]
  13. subgraph Linux Server 1.1
  14. subgraph JVM8080-1[JVM8080]
  15. c-1
  16. end
  17. subgraph JVM8090-1[JVM8090]
  18. a-1
  19. end
  20. end
  21. subgraph Linux Server 1.2
  22. subgraph JVM8080-2[JVM8080]
  23. c-2
  24. end
  25. subgraph JVM8090-2[JVM8090]
  26. a-2
  27. end
  28. end
  29. subgraph Linux Server 2
  30. subgraph JVM8070
  31. p
  32. end
  33. end
  34. JVM8080-1 --> configdb
  35. JVM8090-1 --> configdb
  36. JVM8080-2 --> configdb
  37. JVM8090-2 --> configdb
  38. JVM8070 --> portaldb
  39. JVM8090-1 --> JVM8080-1
  40. JVM8090-2 --> JVM8080-2
  41. JVM8070 --> JVM8090-1
  42. JVM8070 --> JVM8090-2

这种部署方式下,Linux Server 1.1 或者 Linux Server 1.2宕机,系统仍旧可用,

3.2 高可用,单环境

在上述的基础上,如果client的数量有很多(例如上万个Java进程),可以横向扩展Config Service,引入Linux Server 1.3, Linux Server 1.4, …

Admin Service由于只有Portal访问,在数量上可以比Config Service少很多

具体如何评定Config Service的数量,请参考 Apollo性能测试报告

3.3 高可用,双环境

2.3 单机,双环境种,如果想让SIT和UAT都变成高可用,只需要分别在环境中再添加机器即可,如下图,每个环境中各有2台Linux Server,如果有性能上需求,可以再在每个环境中,使用更多的机器来部署Config Service即可

  1. flowchart LR
  2. p[Portal]
  3. portaldb[(PortalDB)]
  4. p --> portaldb
  5. subgraph Portal Linux Server
  6. subgraph JVM8070
  7. p
  8. end
  9. end
  10. subgraph SIT
  11. sit-c1[SIT Config Service]
  12. sit-a1[SIT Admin Service]
  13. sit-c2[SIT Config Service]
  14. sit-a2[SIT Admin Service]
  15. sit-configdb[(SIT ConfigDB)]
  16. subgraph SIT Linux Server 2.1
  17. subgraph sit-c1-jvm-8080[SIT JVM8080]
  18. sit-c1
  19. end
  20. subgraph sit-c1-jvm-8090[SIT JVM8090]
  21. sit-a1
  22. end
  23. end
  24. subgraph SIT Linux Server 2.2
  25. subgraph sit-c2-jvm-8080[SIT JVM8080]
  26. sit-c2
  27. end
  28. subgraph sit-c2-jvm-8090[SIT JVM8090]
  29. sit-a2
  30. end
  31. end
  32. sit-c1-jvm-8080 --> sit-configdb
  33. sit-c1-jvm-8090 --> sit-configdb
  34. sit-c2-jvm-8080 --> sit-configdb
  35. sit-c2-jvm-8090 --> sit-configdb
  36. sit-c1-jvm-8090 --> sit-c1-jvm-8080
  37. sit-c2-jvm-8090 --> sit-c2-jvm-8080
  38. end
  39. subgraph UAT
  40. uat-c1[UAT Config Service]
  41. uat-a1[UAT Admin Service]
  42. uat-c2[UAT Config Service]
  43. uat-a2[UAT Admin Service]
  44. uat-configdb[(UAT ConfigDB)]
  45. subgraph UAT Linux Server 2.1
  46. subgraph uat-c1-jvm-8080[UAT JVM8080]
  47. uat-c1
  48. end
  49. subgraph uat-c1-jvm-8090[UAT JVM8090]
  50. uat-a1
  51. end
  52. end
  53. subgraph UAT Linux Server 2.2
  54. subgraph uat-c2-jvm-8080[UAT JVM8080]
  55. uat-c2
  56. end
  57. subgraph uat-c2-jvm-8090[UAT JVM8090]
  58. uat-a2
  59. end
  60. end
  61. uat-c1-jvm-8080 --> uat-configdb
  62. uat-c1-jvm-8090 --> uat-configdb
  63. uat-c2-jvm-8080 --> uat-configdb
  64. uat-c2-jvm-8090 --> uat-configdb
  65. uat-c1-jvm-8090 --> uat-c1-jvm-8080
  66. uat-c2-jvm-8090 --> uat-c2-jvm-8080
  67. end
  68. JVM8070 --> sit-c1-jvm-8090
  69. JVM8070 --> sit-c2-jvm-8090
  70. JVM8070 --> uat-c1-jvm-8090
  71. JVM8070 --> uat-c2-jvm-8090

3.4 高可用,多个环境

在上述的基础上,如果要添加一个环境,例如BETA环境,需要新增2台及以上的Linux服务器+1个ConfigDB

Portal添加新环境的信息,指向BETA环境的apollo.meta

3.5 高可用,单环境,单机房

实际生产环境中,很多公司和测试环境进行了隔离,所以生产环境属于单环境,只有一个PRO环境

在只有1个机房时,参考 3.2 高可用,单环境

3.6 高可用,单环境,双机房

如果有2个机房,通常机房之间存在网络隔离,如果是同城机房,idc1和idc2,可以采用如下的部署方式

  1. flowchart LR
  2. idc1-p[idc1 Portal]
  3. idc2-p[idc2 Portal]
  4. portaldb[(PortalDB)]
  5. idc1-p --> portaldb
  6. idc2-p --> portaldb
  7. configdb[(ConfigDB)]
  8. idc1-c1-jvm-8080 --> configdb
  9. idc1-c1-jvm-8090 --> configdb
  10. idc1-c2-jvm-8080 --> configdb
  11. idc1-c2-jvm-8090 --> configdb
  12. idc2-c1-jvm-8080 --> configdb
  13. idc2-c1-jvm-8090 --> configdb
  14. idc2-c2-jvm-8080 --> configdb
  15. idc2-c2-jvm-8090 --> configdb
  16. subgraph idc1
  17. subgraph idc1 Portal Linux Server
  18. subgraph idc1-JVM8070
  19. idc1-p
  20. end
  21. end
  22. idc1-c1[idc1 Config Service]
  23. idc1-a1[idc1 Admin Service]
  24. idc1-c2[idc1 Config Service]
  25. idc1-a2[idc1 Admin Service]
  26. subgraph idc1 Linux Server 2.1
  27. subgraph idc1-c1-jvm-8080[idc1 JVM8080]
  28. idc1-c1
  29. end
  30. subgraph idc1-c1-jvm-8090[idc1 JVM8090]
  31. idc1-a1
  32. end
  33. end
  34. subgraph idc1 Linux Server 2.2
  35. subgraph idc1-c2-jvm-8080[idc1 JVM8080]
  36. idc1-c2
  37. end
  38. subgraph idc1-c2-jvm-8090[idc1 JVM8090]
  39. idc1-a2
  40. end
  41. end
  42. idc1-c1-jvm-8090 --> idc1-c1-jvm-8080
  43. idc1-c2-jvm-8090 --> idc1-c2-jvm-8080
  44. end
  45. subgraph idc2
  46. subgraph idc2 Portal Linux Server
  47. subgraph idc2-JVM8070
  48. idc2-p
  49. end
  50. end
  51. idc2-c1[idc2 Config Service]
  52. idc2-a1[idc2 Admin Service]
  53. idc2-c2[idc2 Config Service]
  54. idc2-a2[idc2 Admin Service]
  55. subgraph idc2 Linux Server 2.1
  56. subgraph idc2-c1-jvm-8080[idc2 JVM8080]
  57. idc2-c1
  58. end
  59. subgraph idc2-c1-jvm-8090[idc2 JVM8090]
  60. idc2-a1
  61. end
  62. end
  63. subgraph idc2 Linux Server 2.2
  64. subgraph idc2-c2-jvm-8080[idc2 JVM8080]
  65. idc2-c2
  66. end
  67. subgraph idc2-c2-jvm-8090[idc2 JVM8090]
  68. idc2-a2
  69. end
  70. end
  71. idc2-c1-jvm-8090 --> idc2-c1-jvm-8080
  72. idc2-c2-jvm-8090 --> idc2-c2-jvm-8080
  73. end
  74. idc1-JVM8070 --> idc1-c1-jvm-8090
  75. idc1-JVM8070 --> idc1-c2-jvm-8090
  76. idc2-JVM8070 --> idc2-c1-jvm-8090
  77. idc2-JVM8070 --> idc2-c2-jvm-8090

每个机房有自己的一套Portal, Config Service, Admin Service

对于ConfigDB,在同城双机房下,连接的ConfigDB是同一个,不存在2个不同的ConfigDB,对于PortalDB也是如此,需要连接同一个

ConfigDB和PortalDB在图中没有放入idc1或者idc2,需要自行选用合适的MySQL架构以及部署方式

四、部署图

4.1 ctrip

以ctrip为例,我们的部署策略如下: Deployment

  • Portal部署在生产环境的机房,通过它来直接管理FAT、UAT、PRO等环境的配置
  • Meta Server、Config Service和Admin Service在每个环境都单独部署,使用独立的数据库
  • Meta Server、Config Service和Admin Service在生产环境部署在两个机房,实现双活
  • Meta Server和Config Service部署在同一个JVM进程内,Admin Service部署在同一台服务器的另一个JVM进程内

4.2 样例部署图

@lyliyongblue 贡献的样例部署图(建议右键新窗口打开看大图):

Deployment