任何微服务的容量都是有限的, 但是理想情况下一般的微服务应该只局限于服务器的数量(计算能力), 存储的容量和网络的带宽.
当用户的请求和用量增加时, 只要财务预算上没有问题, 理论上是可以接近无限地扩展的.
实际上, 这个假定往往并不成立, 更大的数据量, 更多的请求, 更高的并发量, 你的服务会撑不住.
你会想到加内存, 加存储, 加带宽, 加服务器, 然而事情没那么容易, 你的应用的服务能力必须能够随着资源的增加而线性增加
由于单机的内存, CPU 及带宽毕竟有限, 所以尽量把你的服务设计成由多个相对独立的, 无状态的自治节点组成, 这样你可以轻松地增加节点来应对不断增长的服务请求
从自给自足的小农社会到现代化的社会化大分工, 单个人掌握的技能变少了, 不同的人有不同的分工和专长, 社会的生产效率大幅度提高了
微服务就是要把服务做小,做精, 专注于一个相对独立的领域, 以利于分散风险, 和重用组合, 也有利于服务的扩展, 哪块是瓶颈, 就优化和扩展哪一块,而不是所有服务器都要一起升级.
例如我要做一个网络会议服务器,需要支持文字聊天,音频视频对话,桌面共享,文件分享,远程控制,会议录制等等,既有控制信令的处理,又有媒体的传输,编码解码和混音处理,如果都放在一起,可想而知,系统的复杂性大大增加不说,调优和扩展很难做,音视频的编码解码是极其耗费CPU 资源,允许丢包,而控制及文字聊天则不同,必须保证消息可靠传达,所以还是各自分开为不同的服务为好
状态总是存在的, 关键看你把它放在哪里, 内存里, 文件里, 数据表里, 还是缓存里?
假如我们把状态放在单个服务器的内存或文件系统中, 扩展起来就会非常麻烦, 高可靠性也有问题.
状态需要在不同的服务器之间同步, 才能做到避免单点失败, 每个服务器保持一致显然不可能应对海量请求和数据.
只有第三种,你的服务器才可以随意增加,线性扩展
根据地理位置, 用户组织或数据中心及服务区集群都可以进行数据分片, 假设你有多个客户, 这些客户分布在不同的地域, 不同的客户服务请求和数据大小也不同, 如何进行数据分片呢?
假设你提供的服务是在线教育平台, 域名是天天向上 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 状态, 不再接受新的服务, 等到所有服务在这台服务器已经结束了, 才能关机