[TOC]

调研

1、术语

  • 1 毫秒(ms)=0.001 秒
  • 响应时间的 2-5-8 原理
    • 用户感觉:2 秒以内很快,2-5 秒还可以,5-8 秒忍受的边缘,8 秒以上难以忍受。
  • PV(Page View):页面访问量,即页面浏览量或点击量,用户每次刷新即被计算一次。可以统计服务一天的访问日志得到。
  • QPS Queries Per Second 是每秒查询率 ,是一台服务器每秒能够相应的查询次数。下面特指只具有查询的业务,这些可以通过缓存来提高性能。
  • TPS Transactions Per Second 也就是事务数/秒。下面特指具有写入的功能的业务,可以通过 Kafka 之类的提高性能。
  • 并发数:指系统同时能处理的请求数量,同样反应了系统的负载能力。这个数值可以分析机器 1s 内的访问日志数量来得到
  • 字节换算
    • 1Byte=8bit也就 1B=8b,注意运营商为了营销常用 b,一般磁盘存储大小 B。
    • 1KB=1024B1MB=1024KB 1GB=1024MB1TB=1024GB
    • 运营商的网络传输单位: Mbps,请注意 1M 大小的文件,在 1Mbps宽带下,要传 8 秒。
  • 一些价格概念
    • 阿里云 5Mbps 固定带宽每月 125 元
    • 阿里云 6Mbps 按照数量带宽 0.25 元/小时,是否是可以只买白天 5 点到下午 5 点,共 12 小时的带宽,这样每天 3 元,一个月 90 元
    • 阿里云按照使用量 1GB 带宽,0.8 元/GB
  • 文中涉及到招聘信息是从 boss 直聘中筛选,公司规模 200 人以上
    • 地点北京
    • 价格中位数

2、业务目标

2.1 业务目标

  • 系统每年有几个月运行的高峰期,在高峰期时要求高可用性及时响应
  • 与系统交互的有人与物联网设备。集中在白天 8 小时运行,晚上基本上没有啥访问量。
分类当前并发高峰3 年后并发高峰主要操作内容
6 万/秒27 万/秒高峰期 90%是查询,查询设备状态
不到 10%是写入操作。
设备3 万/秒9 万/秒95%的操作是上传数据
业务数据每秒中上传一次,以文字为主,大小 128 字节以内
3 分钟间隔上传图片,图片在 100KB 以内

2.2 系统指标

下面目标是在作业高峰期间,集中在某几个月的白天。其他月份使用频率低,可以用做数据备份与清洗、系统升级与优化。

  • 高可用性 99.9 % 。 由于系统的高峰期是白天,所以要细化到系统可用时长,以及从故障到恢复的时间。
  • 高并发
    • 物联网:QPS >=6 万
    • 业务网:QPS >=10 万
  • 正常业务响应时间(非大型报表与大数据统计业务)
    • 物联网:延迟小于 500ms
    • 业务网:延迟小于 1500ms

高可用性的策略

  • 多云架构、异地多活、异地备份
  • 主备切换,如 redis 缓存、mysql 数据库,主备节点会实时数据同步、备份。如果主节点不可用,自动切换到备用节点
  • 微服务,无状态化架构,业务集群化部署,有心跳检测,能最短时间检测到不可用的服务。
  • 通过熔断、限流,解决流量过载问题,提供过载保护
  • 重视 web 安全,解决攻击和 XSS 问题

高性能的策略

影响系统的性能因素:

  • 用户网络环境(网络工程师测试以下线路的质量与丢包情况)
  • 请求/响应的数据包大小(压缩包)
  • 业务系统 CPU、内存、磁盘等性能
  • 业务链路的长度
  • 下游系统的性能
  • 算法实现是否高效

针对常见性能问题的应对策略,系统 80%以上是查询。

  • 使用 redis 作为缓存
  • 数据库读写分离
  • 使用 kafka

高并发的策略

  • 使用 SpringCloud 或者 Apache ApiSix 来解决水平扩展与负载均衡。

  • 使用 Mqtt 服务器解决物联网传输的高并发

2.3 成本目标

保证系统功能的前提下,降低成本是唯一目标。可能的成本包括在

成本分类支出内容成本比率缓解措施备注
软件研发成本_ 人员支出
_ 购买第三方基础组件成本
100%_ 有效的管理
_ 好用的工具,例如代码生成器、自由的基础代码库
_ 适当人员外包,降低招聘与开发任务结束后,裁员的成本。
_ 购买一些成熟的软件,比自己开发会降低成本
网络与硬件成本_ 带宽成本
_ 服务器租赁成本
研发成本的 40%以下
云 3 年-5 年购买的总和
* 货比三家
网络与硬件运维成本* 服务器日常监控运维服务器购买成本的 10%-15%* 运维适当外包,但是自己知道如何管理运维
软件运维成本* 修改 Bug、组件升级研发成本 10%-15%_ 软件研发时的单元测试脚本与自动脚本很重要
_ 设计文档很重要

软硬件的成本比例是按照经验值来计算的,不适合所有情况,按照行业内的估算,购买网络与硬件的成本比率在逐年下降,软件研发的成本在逐年升高。

3、系统架构

  • 当前业务并发 5 万,就算业务发展到最高,也就是 50 万以内,业务功能比较单一,想寻找一个轻量级的 k8s 的横向扩展解决方案。主要是为了降低成本。
  • 设计系统时,所有的第三方组件,要做到弱耦合,只要符合标准,今后可以很快替换。
  • 解决高并发高响应是通过缓存与异步处理解决的。

3.1 待确认问题

使用 k8s 是否有利于降低整体成本

当前系统规模,没有必要使用 k8s。这样反而会增加成本。

是否使用 docker?

在实际项目中,如果程序部署到物理机上比在 docker 上快,可以在物理机上多部署几个实例。docker 的作用是部署方便,可以随时部署。

综合考虑,还是用 docker 部署。今后真的有一天要上 k8s,也有基础。

是否使用 SpringCloud?

用一项技术,首先要解决自己实际问题中的问题,并且要计算投入产出比,如果投入研发成本过多,建议使用简单并且成本低的方法。

可以借鉴 SpringCloud 的方法

上这两个模块,具体实现了那些功能?

这两个模块,用了多少台机器? 每年的租赁费是多少钱?

是否可以用其他的方法,来替换这两个功能?

地理服务模块能不能把功能给抽象出来?

现在车辆的坐标点,是否记录的太密集了?

历史的车辆的坐标点信息,是否可以清理掉? 留在系统中有什么用? 计算的结果不是存储起来了吗?

能把关于地理服务的功能模块提供一个文档,然后封装成一个独立的模块?

现在是通过 postgis 来计算相关信息的吗? 还是通过其他的方法?

Kafka 可以被 rabbitmq 来替换吗?

现在 kafka 用了多少台机器?

Kafka:优点: 吞吐量⾮常⼤,性能⾮常好,集群⾼可⽤。 缺点:会丢数据,功能⽐较单⼀。 使⽤场景:⽇志分析、⼤数据采集。RabbitMQ:优点: 消息可靠性⾼,功能全⾯。 缺点:吞吐量⽐较低,消息积累会严重影响性能。erlang 语⾔不好定制。 使⽤场景:⼩规模场景。RocketMQ:优点:⾼吞吐、⾼性能、⾼可⽤,功能⾮常全⾯。 缺点:开源版功能不如云上商业版。官⽅⽂档和周边⽣态还不够成熟。客户端只⽀持 java。 使⽤场景:⼏乎是全场景。

特性ActiveMqRabbitMqRocketMQKafka
成熟度成熟成熟比较成熟成熟的日志领域
时效性微秒级毫秒级毫秒级
社区活跃度
单机吞吐量万级,吞吐量比 RocketMQ 和 Kafka 要低了一个数量级万级,吞吐量比 RocketMQ 和 Kafka 要低了一个数量级10 万级,RocketMQ 也是可以支撑高吞吐的一种 MQ10 万级别,这是 kafka 最大的优点,就是吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响topic 可以达到几百,几千个的级别,吞吐量会有较小幅度的下降这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十个到几百个的时候,吞吐量会大幅度下降所以在同等机器下,kafka 尽量保证 topic 数量不要过多。如果要支撑大规模 topic,需要增加更多的机器资源
可用性高,基于主从架构实现高可用性高,基于主从架构实现高可用性非常高,分布式架构非常高,kafka 是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据经过参数优化配置,可以做到 0 丢失经过参数优化配置,消息可以做到 0 丢失
功能支持MQ 领域的功能极其完备基于 erlang 开发,所以并发能力很强,性能极其好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准
优劣势总结非常成熟,功能强大,在业内大量的公司以及项目中都有应用偶尔会有较低概率丢失消息而且现在社区以及国内应用都越来越少,官方社区现维护越来越少,几个月才发布一个版本而且确实主要是基于解耦和异步来用的,较少在大规模吞吐的场景中使用rlang 语言开发,性能极其好,延时很低;吞吐量到万级,MQ 功能比较完备而且开源提供的管理界面非常棒,用起来很好用社区相对比较活跃,几乎每个月都发布几个版本分在国内一些互联网公司近几年用 rabbitmq 也比较多一些但是问题也是显而易见的,RabbitMQ 确实吞吐量会低一些,这是因为他做的实现机制比较重。而且 erlang 开发,国内有几个公司有实力做 erlang 源码级别的研究和定制?如果说你没这个实力的话,确实偶尔会有一些问题,你很难去看懂源码,你公司对这个东西的掌控很弱,基本职能依赖于开源社区的快速维护和修复 bug。而且 rabbitmq 集群动态扩展会很麻烦,不过这个我觉得还好。其实主要是 erlang 语言本身带来的问题。很难读源码,很难定制和掌控。接口简单易用,而且毕竟在阿里大规模应用过,有阿里品牌保障日处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,社区维护还可以,可靠性和可用性都是 ok 的,还可以支撑大规模的 topic 数量,支持复杂 MQ 业务场景而且一个很大的优势在于,阿里出品都是 java 系的,我们可以自己阅读源码,定制自己公司的 MQ,可以掌控社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用 RocketMQ 挺好的kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量而且 kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集

1、ActiveMQ 已经不推荐使用了,因为社区活跃度很低,没什么人再去维护了。一旦使用过程中出现了问题,比较难以找到解决办法;

2、RabbitMQ 现在是使用的比较多的,吞吐量也达到了万级,而且延时低,最好的一个优点就是它提供了一个后台管理系统,对于中小型公司来说很有用的;同时目前来看,社区活跃度也比较高。缺点就是开发语言使用的是 erlang 语言,对于 Java 开发者来说,erlang 语言比较难以看懂,不能去深入的研究,只能简单的使用。

3、RocketMQ 的阿里开源的,现在社区也比较活跃,并且是用 Java 语言开发的,支持分布式集群。但是有被弃用的风险,一旦阿里什么时候不维护了,那么就有可能被废弃掉。如果是有能力大公司还好,可以自己去钻研源码,自己维护,如果是小公司的话,那么就被坑了。

4、Kafka 主要用在大数据领域。它的主要优点就是吞吐量大,同时也是分布式的。

RocketMQ 还是 RabbitMq?

以前是 RabbitMq 的用户,因为 RabbitMq 在国外先流行起来,但是现在想选 RocketMQ 了,主要原因是?

  • 阿里出的,中文的。
  • 加入了 Apache,项目更长久一些。
  • 用 Java 开发的,开发个插件可能会更好点
  • 带有 Mqtt
  • 性能比 RabbitMq 好
  • 缺点呢? 还要有实际项目经验的人说说。
基本概念
  • 经纪人(Broker):是为促成他人交易,充当订约居间人,为委托方提供订约的信息、机会和条件的主体。

  • Broker 是一个独立主体,但没有自主决策能力,只负责订约过程。

  • 代理人(Agent):是行使被代理者的权力,完成相关的使命或者任务主体。

    • Agent 是一个独立主体,负责完成任务但不负责执行任务,Agent 具有一定的自主决策能力,如对服务请求的选择。
  • 代理(Proxy)是指行为代理,不是一个主体

    • Proxy 是完全的传递者,如请求和响应的转发,操作控制的传递。

Brokers: 消息中间件

Agent: Kubelet

Proxy: Kube-Porxy

一些案例
应用场景

异步化提升系统性能

现在假设有两个系统 A 和 B,其中 A 系统处理业务大概 20 毫秒,B 系统处理业务大概 180 毫秒,然后 A 系统调用 B 系统这一过程一共是花了 200 毫秒。

如果这里使用了消息中间件的话,则是 A 系统处理业务 20 毫秒,发送消息到 MQ 中 2 毫秒然后就直接返回给用户了,B 系统什么时候去 MQ 中取消息 A 系统此时是不管的,所以对于用户来说 22 毫秒就得到了返回,即使用 MQ 直接提升了我们系统的性能。

系统间解耦

如上 A B 系统所示,即使 B 系统出现了故障,于 A 系统来说是不关心的,即用户也就是无感知的,B 系统恢复了就会自动再去取消息来处理业务。所以,消息中间件能使系统间解耦,且使系统间不互相直接影响

大流量削峰

现在假设我们在做双十二活动促销的时候,在线系统 A 面临过万的 QPS,而另一个后端数据系统 B 只能处理每秒 5000 左右的并发,这个时候如果我们将并发全部打到 B 系统的话,很可能就会挂掉了,即促销活动就会失败。而我们现在引入消息队列 MQ,将 1 万+的并发先打到 MQ 中,然后 B 系统就可以按照他自己的 5000 并发的处理能力来从 MQ 中获取消息,这样就完成了我们业务中大流量削峰的作用。

MQTT 选择那个好

MQTT broker 选择那个好?

身份认证服务选那个好?

自己用 spring 的开发一个? 还是用开源的 cas? 或者购买一个云服务?

现在购买阿里云单台服务器的配置?

4、身份认证服务

这是一个核心系统,可以解耦所有的系统。 这个系统是独立运行的,可重用性比较高。

主要的功能

  • 支持OAuth 2.1协议中的所有功能
  • 高可用性,高并发。可以负载均衡
  • 微信登陆
  • 短信认证

待选方案

方案说明开源成本备注
SpringAuthorizationServer_ Spring 官方出品,已经正式发布
_ 只是底层的函数库,以下内容需要自己开发
** 登陆页面、微信登陆、微信认证
** 负载均衡等
完全开源1.5 个人月开发成本
keycloak_ keycloak 是 redhat 公司出品
_ 是一个完整的产品,包括了所有功能
* 学习成本与二次开发成本较高,里面使用 Jboss 的框架
完全开源1.5 个人月的学习成本
cas_ 美国大学里面用的身份认证框架
_ 使用了 SpringBoot 作为开发框架
_ 是一个完整的产品,包括了所有功能
_ 学习与二次开发成本较高
完全开源1.5 个人月的学习成本
Authing-云服务_ 云服务完全云端,
_ 1 万个活跃用户每年 1 万,如果 5 万活跃用户,可以砍价格
云服务20 天整合成本
  • 阿里云也有类似的云服务,但是感觉好长时间没有执行,这项业务感觉快黄了。
  • 自己研发或者使用开源软件,研发成本在 5 万以内。 购买云服务,每年在 3 万左右。这个需要去询价。

5、业务区域

5.1 前端交互服务

  • 后台办公系统网页端
  • 移动端
    • 尽量使用小程序与微信公众号开发。不是特殊应用,不要开发 APP。

AntDesign 的学习成本较高,新手有人带的话,大概需要 1 个月,学玩后开发的质量与效率会很高。

3-5 年经验的中高级前端工程师,工资在 15K-25K 之间,13 薪水。

5.2 API 网关-负载均衡服务

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。

  • Apache 开源的还是有保证,有中国社区贡献,不用担心找不到基础支撑
  • APISIX 支持 MQTT 协议,对于构建 IOT 应用非常友好。
  • 有管理界面
  • 找人学习 20 天,花费 2 万就搞定了,平时就维护进行,一般不用二次开发,要是二次开发,就去网上找个兼职的就行。

APISix VS Nginx,Zuul2,Spring Cloud Gateway, Kong

从易用性上来将,ApiSix 更容易上手

5.3 具体业务服务模块

这部分要自己写代码,但是在使用的过程中,要做到可以横向扩展

  • 某一类人操作的内容或业务内容,可以单独放在一个业务模块中
  • 前后台分离,这部分只提供 API,所以尽量不使用 Session
  • 可以使用 wukong 框架简化程序开发:注意数据库操作,去前台的传递的数据参数
  • 使用 SpringBoot3.0 以上,可以把 java 程序打包成 native 模式,这样速度更快,使用的内容更少。这部分程序部署到 docker 中。
  • 如果要操作一些图片,可以将图片配置到 docker 外的一个文件服务器路径上。

5.4 缓存服务

这里使用了 redis,redis 相当稳定与可靠。 如果缓存数据量不大,可以使用单机模式。 当然也可以使用哨兵模式。

  • 如果不是查询特别频繁的数据,可以不使用 redis。
  • 如果要把 redis 作为消息队列等特殊操作,那么要启用 redis 的本地化存储操作。

5.5 分布式数据库服务

Apache ShardingSphere

Apache ShardingSphere 是一款分布式的数据库生态系统,可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。

  • Apache 开源,由京东牵头贡献,中文文档丰富
  • 读写分离,数据切片,高可用,数据加密。程序员就像操作单个数据库一样,后面是读写分离的数据库。

Mysql VS Postgresql

  • Mysql 与 Postgresql 都是很优秀的数据库。Mysql 虽然啥功能都不行,但是是多年前就有主从功能,这正式互联网急需的,所以一下子在国内流行了起来。

  • Postgresql 的优化版本 PostGis,内置了 gis 的函数。在 gis 开发中 PostGis 是首选数据库

  • Mysql 在互联网企业用的比较广,速度较快,用户群体广泛。

  • 为了便于维护,公司尽量使用一种数据库,由于用到 gis,这里推荐 Postgresql

  • 为了便于维护,可以将保存地理坐标信息的数据库,分离出去,单独一个数据库与业务所在的数据分离。

5.6 地理信息服务

里面包含了一些路径与坐标。通过计算得到路径与区域。

  • 这部分内容,建议与其他业务系统独立。
  • 关于地理信息,数据存储的格式,以及计算的方法,需要专门有人抽象出文档,便于今后维护。

6、物联网区域

6.1 设备端

  • 服务器端提供开发用的 SDK,便于其他公司人员开发。
  • 今后可以采取信息通道的形式,收取服务费。
  • 阿里云提出农机设备联网方案
    • 销售 CIM 卡,还有一种是不需要 cim 卡的
    • 物联网平台。 与后面要做的类似
    • IoT 设备身份认证
    • IoT 安全运营中心

6.2 MQTT Broker 服务

  • Mqtt 是物联网首推的服务,单台服务器轻松支持 10 万连接
  • 如果支持 WebSocket 就更好了。
  • Mqtt 支持压缩传输的数据
  • 图片可以单独通过 Http 协议传输

常用的 Mqtt 服务器对比

各大互联公司都提供能,Mqtt 压力测试的服务,可以模拟上千万的并发。

MQTT Broker开源价格说明
Mosquitto完全开源,单机版,支持 10 万并发
EMQX部分开源
就是商业化产品
功能全
HiveMQ不开源,德国公司
阿里云 Mqtt 服务云服务
RabbitMq开源的消息组件、高可用、消息集群。可以作为 Mqtt Broker+Kafka 来看

说什么都没有实际好用,如果把系统搭建完毕,可以花 200 元,用阿里云的 Mqtt 测试服务,进行 5 万并发的测试。

6.3 Kafka Broker 服务

RabbitMq Vs Kafka

高数据量选择 Kafka,同时 Kafka 还可以作为数据备份。

  • Kafka 是每秒几十万条消息吞吐,而 RabbitMQ 的吞吐量是每秒几万条消息

    • 在一家公司内部,有必须用到 Kafka 那么大吞吐量的项目真的很少。大部分项目,像 RabbitMQ 那样每秒几万的消息吞吐,已经非常够了。
    • 因为 Kafka 为了更好的吞吐量,很大程度上增加了自己的复杂度。Kafka 的参数配置相对 RabbitMQ 是很复杂的。比如:磁盘管理相关参数,集群管理相关参数,ZooKeeper 交互相关参数,Topic 级别相关参数等,都需要一些思考和调优。
  • RabbitMQ 读取消息后就删除了, Kafka 呢,消息会被持久化一个专门的日志文件里。不会因为被消费了就被删除。

Kafka 配置与开发的成本还是比较高的。

Mqtt Connect to Kafka

  • 可以手工写,也可以使用一个现成的组件
  • MQTT Broker 的模式好点

Mqtt 是一种广泛使用的基于 ISO-IEC 标准(ISO / IEC PRF 20922)的基于发布-订阅的消息传递协议。 MQTT 具有许多实现,例如 Mosquitto 或 HiveMQ。 MQTT 主要用于物联网场景(如联网汽车或智能家居)。 但是由于它对 WebSockets 的支持,它也越来越多地在移动设备中使用。

但是,MQTT 并不是为实现高可伸缩性,更长的存储时间或易于与旧系统集成而构建的。 Apache Kafka 是一个高度可扩展的分布式流平台。 Kafka 从数以千计的 IoT 设备中摄取,存储,处理和转发大量数据。

因此,MQTT 和 Apache Kafka 是从边缘到数据中心(当然是双向)的端到端 IoT 集成的完美组合。

6.4 Kafka Consumer 服务

这部分需要自己写一些代码。具体做那些工作? 以什么样的逻辑与格式写入 Hadoop,需要现有的项目人员描述一下。

6.5 Hadoop 服务

  • 这部分具体用作什么功能?如果只是数据存储,那么用 kafka 就可以了。
  • 具体有那些计算的功能呢?

这个到底有啥用,主要计算的内容有那些呢?