架构 3年前

回忆人人车用户端架构演进

作者头像 刘宇帅
2739 0

最近入职了新的公司,新公司当前的技术架构和人人车当年的架构演进的过程很像,我尽量回忆了下当时在人人车的记忆,整理本文并在新公司内部做了分享。虽然离开人人车已经5年了,但是人人车技术团队对我不管是技术上还是作为程序员的基本素质上的影响都是终身受益的,感谢人人车公司、感谢当时的技术团队及每一位成员。

人人车介绍

1603500702208500_a640x364

人人车是二手车 C2C 模式首创者,于 2014 年 7 月上线,2017年月销数万台。

起步 — 能用就行

  1. LNMP一键安装(CI框架)
  2. Redis缓存
  3. Solr搜索

V0.1架构

image-20220611170708703

业务高速发展

  1. 线下团队爆炸性的增长,销售、评估师、客服人员等都增长不止一个量级
  2. 车辆数、订单量、客服量等也在飞速增长

技术架构负重前行

  1. 研发每天处理大量 bug
  2. 全员皆运维,都在敲命令
  3. 各种服务异常、全站异常
  4. 研发很辛苦,产量却很低
  5. 业务吐槽不靠谱

V0.2架构

image-20220611173522769

V0.2架构问题-运维与流程

  1. 服务器:2台服务器承担了所有服务,服务相互影响,资源竞争
  2. 发布:发布方式原始,svn checkout, scp 覆盖
  3. Rollback:回滚流程与工具缺失,回滚不方便、不完全
  4. 流程:上线流程不规范、无通报相关机制、无回滚预案、上线后回归验证不全面

V0.2架构问题-服务与架构

  1. 框架:无统一的框架,项目结构不统一,冗余,通用库、工具、类无法复用
  2. 服务拆分:服务分层不清晰,服务耦合严重,拆分不合理,业务调用不统一,跨层、跃层调用问题严重
  3. Cache:核心业务缺少缓存,系统响应慢
  4. DB层:DB 数据库耦合严重,未按业务独立拆分,部分字段设计不合理包含大 json、 长字段、慢查询
  5. 日志打印不规范、无统一的日志监控和可视化服务
  6. 服务监控缺失

V0.2架构优化方向

  1. 服务拆分
  2. 运维部署流程优化
  3. 服务监控
  4. DB 拆分
  5. 慢 SQL 优化
  6. 同步转异步
  7. 微服务架构探索

服务拆分原则

  1. 各模块 git 代码层面独立管理与维护
  2. 线上独立 SLB、独立部署、独立运维
  3. DB 层面数据隔离,独立从库
  4. 通用功能抽取到 api 层
  5. 核心业务逻辑增加 cache 层

DB慢查询优化

  1. 每天要求研发同学优化 top5 慢查询
  2. DB 读写分离
  3. 收敛数据库操作,提供API接口,可控
  4. 加强SQL审核
  5. DB schema 规范和review

DB schema规范

权限
1. 所有数据库的 DDL 操作全部收回,由 OP 统一管理
2. 收回 RD 的 delete 权限,所有数据不能做物理删除(逻辑上删除的需求可以通过 flag 标签的方式来处理) 

基础字段
1. 每张表三个必加字段,id (自动增长), create_time , update_time 用作存储主键, 记录创建时间,记录更新时间 , 这三个字段由 OP 维护,RD 无需处理
2. 有逻辑删除需求的表,可选增加 delete_flag 字段(int 类型,默认值为 0),用来 标识字段是否被逻辑删除

统一注释
1. 每张表/视图要有注释(comment),格式为 模块|用途|负责人|创建日期 ,例如: 贷款|记录贷款用户身份证号码|张三|2016-03-25
2. 每个字段要有注释(comment),格式为 用途|负责人|创建日期 , 例如:记录用 户性别@1:男@0:女@2:未知|李四|2016-03-25
3. 字段来源需要说明,来自哪张表的那个字段,例如:记录车辆 ID,#取自 cp_used_car.car_id|李四|2016-03-25
4. 如果字段为枚举类型,或普通数据类型当做枚举使用,需要列举枚举范围并说明每 个枚举值的含义,例如:记录用户性别,#系统根据用户身份证号码判断@1:男@0: 女@2:未知|李四|2016-03-25 ( | 用来分割不同项目 , # 用来标识数据来源 , @ 用来分割多个枚举 ,: 用来分割枚举名称和值 , 正常的描述中不要包含 | # @ :)

DB拆分优化

  1. 各实体分库分表设计
  2. DB 主从拆分
  3. 数据加密杜绝明文存储
  4. 表与 DB 设计:必须遵循人人车 DB 设计规范与 schema 设计规范
  5. 索引设计:合理使用索引,杜绝滥用索引

v1.0架构

image-20220612210952141

V1.0架构体感

业务拆分很清晰,开发体验很一般

V2.0 2017年“微服务架构”

监控系统:Openfalcon 报警与可视化(系统监控、应用监控)

功能性监控:healthcheck(服务本身及依赖资源检查)、无头浏览器监控与报警

日志系统:ELK(日志搜索与服务质量仪表盘)

接口框架:内网提供SDK(PHP compoer包,统一http调用实现和异常封装)、外网统一http结构和状态封装(全局异常捕获封装异常请求)

API网关:Kong(流控、黑名单、鉴权、日志、爬虫识别)

服务注册与发现:etcd+confd

配置中心:etcd+confd

自动化部署:Jenkins+gitlab

发布:小流量&&预发

自动化测试:单元测试、接口测试(Mock测试、行覆盖率和分支覆盖率)

服务跟踪:LOG_ID PLOG_ID

负载均衡:内网SLB + SDK

高可用架构:所有服务最少部署两份,多台ECS处于不同可用区

服务安全:服务调用统一授权(SDK封装实现)+ IP白名单

数据安全:Zeus(统一的数据加密服务)

框架:日志、Memcache、Redis、队列、接口Base SDK、统一异常等封装

API文档:Swagger

搜索服务架构

  1. search服务4台服务器,两个可用区
  2. solr集群(多可用区)
    1. 在售集群——C端
      1. 热备(预防在售solr集群出现不可恢复等故障)
    2. 已售集群——业务端
    3. spider集群——全量数据,SEO优化
  3. 降级(定时刷新核心筛选项到缓存服务,手动开启降级)
  4. 排序策略:公式算分+solr插件

image-20220612231022784

那些痛苦而美好的回忆

  1. 静态检查:代码风格严格检查,否则无法上线
  2. 测试:每次MR必须有新增的单元测试、接口测试,分支覆盖率、行覆盖率必须提升
  3. review:所有代码必须有comment才能合并
  4. Merge code:自己合自己代码报警
  5. 函数50行:所有函数不能超过50行
  6. push code:10点之后不能提代码(有效提高代码质量)
  7. 旧代码:所有在MR中被修改的文件必须满足静态检查、函数50行才能被合并

最后

PHP是世界上最好的语言

最后的最后

任何一门语言都可以是世界上最好的语言

作者头像

刘宇帅

非著名程序员,全栈开发工程师,长期专注系统开发与架构设计。

提示

功能待开通!


暂无评论~

相关文章

分布式架构之CAP理论/AP架构/CP架构

在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 一致性(Consistency) (等同于所有节点返回的数据都是一致的) 可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据) 分区容错性(Partition tolerance)(大部分分布式系统都不能在时限内达成数据一致性,就意味分布式系统一定会发生了分区的情况。这就是再分布式系统中 P 是一定该发生的,那么 A 和 C 我们只能选择一个。) Zoopk

全链路压测调研

什么是全链路压测 使用真实生产业务场景、在真实的生产系统环境下根据历史用户访问记录构造海量用户请求对整个业务链进行压力测试并生成报告,根据报告持续调优的过程。 为什么要全链路压测 我们针对单机器单系统的压测虽然可以掌握单个机器或服务的服务能力但是并不能依此来推测整个系统的服务能力,因为任何一个具体的业务系统都可能在系统容量、业务代码性能、物理机器、网络、中间件和各个系统之间调用或具体的业务流程中等等任何一点上存在瓶颈进而导致真个业务系统的服务能力下降,而这些众多的点我们没办法去确定具体那个点会成为瓶颈,我们只能通过全链路压测来测试服务能力找到瓶颈,因为我们要服务于用户而全链路压测的流量正是 m

网站架构之负载均衡方案

什么负载均衡 当我们单台的服务器无法支持用户请求的时候就需要把机器扩充到几台、几十台甚至几百台,而当用户请求到的时候我们合理的把用户请求分发到各个服务器,这就是负载均衡。负载均衡要理解最重要的一点,我这里用了“合理的分发”而不是平均分发,因为负载均衡并不是简简单单的均分流量,我们需要考虑到不同的服务器硬件配置、网络情况来合理的分配分配流量以达到各个服务器均不超载、合理利用集群资源达到最佳的服务质量。当然当我们用多台服务器做负载均衡时一般会选用相同规格的机器,但是不排除网络延迟、机器突发故障灯引起的单台服务器负载飙升处理能力下降等情况。 网站架构中负载均衡的应用 从图中可以看到网站中对负载均衡

20190117 负载均衡分享

什么是负载均衡 负载均衡就是用多台服务器对外提供单一服务,通常用于提高网站、应用、数据库或其他服务的性能和可用性,负载均衡是高可用网络架构的关键组件。 没有负载均衡的架构 有负载均衡的架构 为什么要负载均衡 配置再强的服务器都有服务上限,当单台的服务器无法支持所有用户请求的时候就扩充机器到到几台、几十台甚至更多来提供服务,这个时候需要我们合理的把用户请求分发到各个服务器,这就是负载均衡。 负载均衡要理解最重要的一点,我这里用了“合理的分发”而不是平均分发,因为负载均衡并不是简简单单的均分流量,我们需要考虑到不同的服务器硬件配置、网络情况来合理的分配分配流量以达到各个服务器均不超载、合理利用

搜索引擎调研

定义 搜索引擎(search engine)是一种信息检索系统,旨在协助搜索存储在计算机系统中的信息。搜索结果一般被称为“hits“,通常以表单的形式列出。网络搜索引擎是常见、公开的一种搜索引擎,其功能为搜索互联网上储存的信息。 工作方式 搜索引擎为一组项目提供一个接口,使用户可以指定关于感兴趣的项目的标准,并让引擎找到匹配的项目。搜索查询通常表示为识别一个或多个文档kennel包含的期望概念的一组单词。有多种样式的搜索查询语法在严格性上有差异。它也可以在以前的站点中搜索搜索引擎中的名称。而一些文本搜索引擎要求用户输入由白色空格分割的两个或三个字,其他搜索引擎可以使用户能够指定整个文档,图片,