微服务开发实战

微服务实战之扩展性

2017-09-02  本文已影响297人  老瓦在霸都

任何微服务的容量都是有限的, 但是理想情况下一般的微服务应该只局限于服务器的数量(计算能力), 存储的容量和网络的带宽.

当用户的请求和用量增加时, 只要财务预算上没有问题, 理论上是可以接近无限地扩展的.

实际上, 这个假定往往并不成立, 更大的数据量, 更多的请求, 更高的并发量, 你的服务会撑不住.

你会想到加内存, 加存储, 加带宽, 加服务器, 然而事情没那么容易, 你的应用的服务能力必须能够随着资源的增加而线性增加

由于单机的内存, CPU 及带宽毕竟有限, 所以尽量把你的服务设计成由多个相对独立的, 无状态的自治节点组成, 这样你可以轻松地增加节点来应对不断增长的服务请求

术语

要点

服务分离 Separation of services

从自给自足的小农社会到现代化的社会化大分工, 单个人掌握的技能变少了, 不同的人有不同的分工和专长, 社会的生产效率大幅度提高了

微服务就是要把服务做小,做精, 专注于一个相对独立的领域, 以利于分散风险, 和重用组合, 也有利于服务的扩展, 哪块是瓶颈, 就优化和扩展哪一块,而不是所有服务器都要一起升级.

例如我要做一个网络会议服务器,需要支持文字聊天,音频视频对话,桌面共享,文件分享,远程控制,会议录制等等,既有控制信令的处理,又有媒体的传输,编码解码和混音处理,如果都放在一起,可想而知,系统的复杂性大大增加不说,调优和扩展很难做,音视频的编码解码是极其耗费CPU 资源,允许丢包,而控制及文字聊天则不同,必须保证消息可靠传达,所以还是各自分开为不同的服务为好

无状态 Stateless

状态总是存在的, 关键看你把它放在哪里, 内存里, 文件里, 数据表里, 还是缓存里?
假如我们把状态放在单个服务器的内存或文件系统中, 扩展起来就会非常麻烦, 高可靠性也有问题.

状态需要在不同的服务器之间同步, 才能做到避免单点失败, 每个服务器保持一致显然不可能应对海量请求和数据.

只有第三种,你的服务器才可以随意增加,线性扩展

数据分片 Data sharding

根据地理位置, 用户组织或数据中心及服务区集群都可以进行数据分片, 假设你有多个客户, 这些客户分布在不同的地域, 不同的客户服务请求和数据大小也不同, 如何进行数据分片呢?

假设你提供的服务是在线教育平台, 域名是天天向上 www.day-day-up.com, 客户是各个大大小小的补习班,以及一些在线的教育机构。

你可以根据为不同的客户(租户tenant )进行数据分片

于是, 我们有如下配置数据表, 放在一个中央数据库中, 并缓存在 Redis 中

tenant_id tenant_name expire_date
d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 东方补习学校 2018-12-31
c5ae1066-522b-4cf3-aba7-923f72f7f07d 西方补习学校 2018-12-31
org_id org_name tenant_id
b30bae13-75ca-4b3c-8998-2d46ba6f74ff 大中华区 d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3
c3cd2f82-dde6-481d-b441-d7e4e50e3eb6 东南亚区 d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3
b18dde72-de20-4952-b33c-73da44ebe95a 主校区 c5ae1066-522b-4cf3-aba7-923f72f7f07d
tenant_id org_id database_pool_id
d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 b30bae13-75ca-4b3c-8998-2d46ba6f74ff ajpc_a1
d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 c3cd2f82-dde6-481d-b441-d7e4e50e3eb6 us_a1
d423b7f7-aa2f-40ee-afe7-6b4e5a245ff3 b30bae13-75ca-4b3c-8998-2d46ba6f74ff ajpc_b1
db_pool_id primary_db_pool backup_db_pool
ajpc_a1 mysql://username:password@hosta1/mysqldb_name mysql://username:password@hosta2/mysqldb_name
ajpc_b1 mysql://username:password@hostb1/mysqldb_name mysql://username:password@hostb2/mysqldb_name
us_a1 mysql://username:password@hosta1_us/mysqldb_name mysql://username:password@hosta1_us/mysqldb_name

小贴士 -- 快速生成 UUID
python -c 'import uuid; print uuid.uuid4();'

如何自动扩展和收缩

基本要求:

下面这个传统结构显然不够

根据Monitor 和 Metrics 系统所得出的结果决定, 实时增加服务器, 注册到类似 Consul 的服务发现系统中, 利用它的服务发现和健康检查功能, 用 consul-template 来刷新更改 HAProxy, Nginx 这样的软件负载均衡系统的配置文件并重载 ( F5 , NetScalar 这样的硬件负载同理), 减少服务器也是一样的过程.

如图所示

当然, 你的服务器最好是无状态的, 否则就很麻烦, 增加服务器时可能要做状态同步, 关闭服务器时要先将服务器设为 suspend 状态, 不再接受新的服务, 等到所有服务在这台服务器已经结束了, 才能关机

参考资料

上一篇下一篇

猜你喜欢

热点阅读