从0到1搭建后端架构的演进(MVC,服务拆分,微服务,领域驱动)

目录
  • 一、MVC
  • 二、服务拆分
  • 三、微服务架构
  • 四、领域驱动设计

产品是一款服务于人力资源的SaaS在线服务,面向HR有Web Android/iOS 小程序多个客户端

后端采用RESTful风格API来提供服务。主要使用Python语言,方便快速迭代。

架构的演进经历了4个大的阶段:

一、MVC

项目刚开始的时候,后端同事不超过5个,这个阶段主要的工作是实现产品的原型,没有太多的考虑架构

使用Django来快速实现功能,DB的表结构设计好之后,抽象出功能View

由于产品设计也很不完善,后端需要很多的预留设计,避免产品逻辑的变更带来整个表结构的变动

在这个阶段代码上最重要的是确定适合团队的代码规范,代码检查规则。

整体上架构如上图

  • Nginx负责负载均衡,分发流量到多个Django服务
  • Django处理逻辑
  • 异步任务就交给Celery
  • 数据量比较大的地方使用Redis做缓存
  • 同时还有实时消息通知的需要使用了Nginx Push Module

问题与优化方式:

  • Django并发性能差
  • 使用uWSGI Master+Worker 配合 gevent 携程支持高并发Redis连接数过多
  • 使用redis-py自带的连接池来实现连接复用MySQL连接数过多
  • 使用djorm-ext-pool(https://github.com/djangonauts/djorm-ext-pool)连接池复用连接Celery配置gevent支持并发任务

随着开发的功能越来越多,Django下的app也越来越多,这就带了发布上的不方便,每次发布版本都需要重启所有的Django服务,如果发布遇到问题,只能加班解决了。而且单个Django工程下的代码量也越来越多,不好维护。

二、服务拆分

随着后端团队的壮大,分给每个同事的需求也越来越细

如果继续在一个工程里面开发所有的代码,维护起来的代价太高

而我们的上一个架构中在Django里面已经按模块划分了一个个app

app内高类聚,app之间低耦合,这就为服务的拆分带来了便利。

拆分的过程没有遇到太大的问题,初期的拆分只是代码的分离

把公用的代码抽离出来实现一个公用的Python库,数据库,Redis还是共用,随着负载的增加,数据库也做了多实例。

如上图,服务之间尽量避免相互调用,需要交互的地方采用http请求的方式,内网的调用使用hosts指向内网地址。

问题与优化方式:

  • Nginx Push Module由于长时间没有维护,长连接最大数量不够,
  • 使用Tornado + ZeroMQ实现了tormq(https://github.com/zhu327/tormq)服务来支撑消息通知
  • 服务之间的调用采用http的方式,并且要求有依赖的服务主机配置hosts指向被调用的地址,这样带来的维护上的不方便。
  • 以及在调用链的过程中没有重试,错误处理,限流等等的策略,导致服务可用性差。
  • 随着业务拆分,继续使用Nginx维护配置非常麻烦,经常因为修改Nginx的配置引发调用错误。
  • 每一个服务都有一个完整的认证过程,认证又依赖于用户中心的数据库,修改认证时需要重新发布多个服务。

三、微服务架构

  • 首先是在接入层引入了基于OpenResty的Kong API Gateway,定制实现了认证,限流等插件。
  • 在接入层承接并剥离了应用层公共的认证,限流等功能。
  • 在发布新的服务时,发布脚本中调用Kong admin api注册服务地址到Kong,并加载api需要使用插件。

为了解决相互调用的问题,维护了一个基于gevent+msgpack的RPC服务框架doge,借助于etcd做服务治理,并在rpc客户端实现了限流,高可用,负载均衡这些功能。

  • 在这个阶段最难的技术选型,开源的API网关大多用Golang与OpenResty(lua)实现,为了应对我们业务的需要还要做定制。
  • 前期花了1个月时间学习OpenResty与Golang,并使用OpenResty实现了一个短网址服务shorturl用在业务中。
  • 最终选择Kong是基于Lua发布的便利性,Kong的开箱即用以及插件开发比较容易。
  • 性能的考量倒不是最重要的,为了支撑更多的并发,还使用了云平台提供的LB服务分发流量到2台Kong服务器组成的集群。
  • 集群之间自动同步配置。

饿了么维护一个纯Python实现的thrift协议框架thriftpy,并提供很多配套的工具, 如果团队足够大,这一套RPC方案其实是合适的,但是我们的团队人手不足,水平参差不齐,很难推广这一整套学习成本高昂的方案。

最终我们开发了类Duboo的RPC框架doge,代码主要参考了weibo开源的motan。

四、领域驱动设计

  • 在这一架构中我们尝试从应用服务中抽离出数据服务层
  • 每一个数据服务包含一个或多个界限上下文,界限上下文类只有一个聚合根来暴露出RPC调用的方法。
  • 数据服务不依赖于应用服务,应用服务可以依赖多个数据服务。
  • 有了数据服务层,应用就解耦了相互之间的依赖,高层服务只依赖于底层服务。

在我离职时领域驱动设计还在学习设计阶段,还没有落地,但是我相信前公司的后端架构一定会往这个方向继续演进。

Service Mesh这种新一代的微服务架构正在成为主流,虽然现在的工作与微服务无关了,但是也还会继续关注学习。

架构的设计,技术的选型,不能完全按照流行的技术走,最终还是服务于产品,服务于客户的需求。设计过程中由于团队,人员的结构问题,有很多的妥协之处,如何在妥协中找到最优解才是最大的挑战,更多相关问题的讨论,请大家持续关注我们!

(0)

相关推荐

  • 详解Java 微服务架构

    一.传统的整体式架构 传统的整体式架构都是模块化的设计逻辑,如展示(Views).应用程序逻辑(Controller).业务逻辑(Service)和数据访问对象(Dao),程序在编写完成后被打包部署为一个具体的应用.如图所示: 系统的水平扩展 如果要对系统进行水平扩展,通常情况下,只需要增加服务器的数量,并将打包好的应用拷贝到不同的服务器,然后通过负载均衡器(Nginx)就可以轻松实现应用的水平扩展. 整体式架构的缺点 应用复杂度增加,更新.维护困难. 易造成系统资源浪费. 影响开发效率. 应用

  • 解读Serverless架构的前世今生

    一.Serverless简介 Serverless架构的出现,带来了跨越式的变革.Serverless下主机管理.操作系统管理.基础软件的部署运维.资源分配和扩缩容能力全部由云厂商提供,把计算能力做成像水电煤一样的公共服务,这就意味着基于Serverless服务构建应用,开发者只需要专注在产品代码上,而无需管理和操作云端服务运行环境,计算资源从过去购买"服务器"转向购买对应的"服务". Serverless = Faas (Function as a service

  • 适合后台管理系统开发的12个前端框架(小结)

    1.D2admin 开源地址:https://github.com/d2-projects/d2-admin 文档地址:https://d2.pub/zh/doc/d2-admin/ 效果预览:https://d2.pub/d2-admin/preview/#/index 开源协议:MIT 2.vue-element-admin 开源地址:https://github.com/PanJiaChen/vue-element-admin 文档地址:https://panjiachen.github.

  • SSM框架前后端信息交互实现流程详解

    一.从前端向后端传送数据 常见的3种方式 1.form表单的action:此方法可以提交form表单内的输入数据,也可同时提交某些隐藏但设置有默认值的<input>,如修改问题时,我们除了提交问题的相关信息,还需要将用户的编号提交给后端,此时就可以设置一个默认值为用户编号的<input>,并将其隐藏 2.<a>标签的href属性:此方法一般用来提交一些较少的数据,比如对象编号 1 <a href="<%=path%>/Question/Dis

  • 浅谈SpringCloud实现简单的微服务架构

    Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均衡.断路器.数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署.Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟.经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂.易部署和易维护的分布式系统开发工具包. 接下

  • 从0到1搭建后端架构的演进(MVC,服务拆分,微服务,领域驱动)

    目录 一.MVC 二.服务拆分 三.微服务架构 四.领域驱动设计 产品是一款服务于人力资源的SaaS在线服务,面向HR有Web Android/iOS 小程序多个客户端 后端采用RESTful风格API来提供服务.主要使用Python语言,方便快速迭代. 架构的演进经历了4个大的阶段: 一.MVC 项目刚开始的时候,后端同事不超过5个,这个阶段主要的工作是实现产品的原型,没有太多的考虑架构 使用Django来快速实现功能,DB的表结构设计好之后,抽象出功能View 由于产品设计也很不完善,后端需

  • SpringCloud微服务架构升级汇总

    一.背景 1.1 应用系统的架构历史 1.2 什么是微服务? 起源:微服务的概念源于 2014 年 3 月 Martin Fowler 所写的一篇文章"Microservices".文中内容提到:微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值. 通信方式:每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API). 微服务的常规定义:微服务是一种架构风格,一

  • SpringCloud微服务架构实战之微服务治理功能的实现

    微服务治理 Spring Cloud 工具套件为微服务治理提供了全面的技术支持.这些治理工具主要包括服务的注册与发现.负载均衡管理.动态路由.服务降级和故障转移.链路跟踪.服务监控等.微服务治理的主要功能组件如下: 注册管理服务组件Eureka,提供服务注册和发现的功能. 负载均衡服务组件Ribbon,提供负载均衡调度管理的功能. 边缘代理服务组件Zuul,提供网关服务和动态路由的功能. 断路器组件Hystrix,提供容错机制.服务降级.故障转移等功能. 聚合服务事件流组件Turbine,可用来

  • 详解多云架构下的JAVA微服务技术解析

    微服务生态 微服务生态本质上是一种微服务架构模式的实现,包括微服务开发SDK,以及微服务基础设施. 目前比较成熟的 JAVA 微服务生态包括 servicecomb(华为), spring-cloud (Pivotal), dubbo(阿里), tsf(腾讯)等.gRPC.Thrift 等也用于内部服务之间的通信,但是微服务基础设施比较欠缺. 核心的微服务基础设施包括:注册中心.配置中心.应用网关.此外,分布式事物管理.计划任务.调用链跟踪系统等也是微服务基础设施的组成部分.完整的微服务基础实施

  • 浅谈Java开发架构之领域驱动设计DDD落地

    目录 一.前言 二.开发目标 三.服务架构 3.1.应用层{application} 3.2.领域层{domain} 3.3.基础层{infrastructrue} 3.4.接口层{interfaces} 四.开发环境 五.代码示例 六.综上总结 一.前言 整个过程大概是这样的,开发团队和领域专家一起通过 通用语言(Ubiquitous Language)去理解和消化领域知识,从领域知识中提取和划分为一个一个的子领域(核心子域,通用子域,支撑子域),并在子领域上建立模型,再重复以上步骤,这样周而

  • 微服务全景架构全面瓦解

    目录 1 微服务优势与挑战 1.1 微服务的优势 1.1.1 单一职责 1.1.2 轻量级通信 1.1.3 独立性 1.1.4 进程隔离 1.1.5 混合技术栈和混合部署方式 1.1.6 简化治理 1.1.7 安全可靠,可维护. 1.2 面临的挑战 1.2.1 分布式固有复杂性 1.2.2 服务的依赖管理和测试 1.2.3 有效的配置版本管理 1.2.4 自动化的部署流程 1.2.5 对于DevOps更高的要求 1.2.6 运维成本 2 微服务全景架构 3 微服务核心组件 3.1 服务注册与发现

  • 详解Rainbond内置ServiceMesh微服务架构

    目录 ServiceMesh 微服务架构对比 为何使用ServiceMesh ServiceMesh相对其他微服务架构优势 最大层度透明 学习成本低 架构灵活 ServiceMesh架构性能 ServiceMesh只对网络进行治理么? Rainbond与ServiceMesh ServiceMesh 一般的字面解释是“服务网格”,作为时下最流行的分布式系统架构微服务的动态链接器,处于服务到服务的通信的专用基础设施层,该层独立于应用程序为服务之间的通信提供轻量级的可靠传递. 如果简单的描述的话,可

  • Springcloud微服务架构基础知识解析

    一 前言 学习微服务要从基础的架构学起,首先你要有个微服务的概念才能学习对吧!!如果你都不知道啥是微服务,就一头扎进去学习,你自己也觉得自己也学不会对吧.本篇文章主要让大家快速了解基础的架构分格,以便于微服务入门. 二 单体架构 单体架构是传统架构,其发展了几十年,我们今天任然还在用单体架构开发,存在即合理:单体架构也就是通常的表现层跟UI界面交互,业务层写业务逻辑,数据DAO层访问数据库.其部署方式也很简单,直接将项目打包成war包放进web服务器(如tomcat,jetty)中运行: 其优点

  • 详解微服务架构及其演进史

    目录 1 传统单体系统介绍 1.1 单体系统的问题 1.2 单体系统的优点 1.3 单体服务到微服务的发展过程 2 关于微服务 2.1 单一职责 2.2 轻量级通信 2.3 独立性 2.4 进程隔离 2.5 混合技术栈和混合部署方式 2.6 简化治理 2.7 安全可靠,可维护. 3 微服务演进史 3.1 第一阶:简单服务通信模块 3.2 第二阶:原始通信时代 3.3 第三阶:TCP时代 3.4 第四阶:第一代微服务(Spring Cloud/RPC) 3.5 第五阶:第二代微服务 3.6 第六阶

  • 使用webpack5从0到1搭建一个react项目的实现步骤

    前言 在这之前,每开始一个新项目我都是使用现有的脚手架,这非常便于快速地启动一个新项目,而且通用的脚手架通常考虑地更加全面,也有利于项目的稳定开发:不过对于一个小项目,根据需求自己搭建可能会更好,一方面小项目不需要脚手架那么丰富的功能,另一方面可以提高对项目的掌控度以方便后期的扩展. 这篇文章是在实践中总结的,具有实操性,读者可跟着一步步进行搭建,中间我会穿插一些原理,当然因为笔者的能力有限,不会特别深入. 预备知识 熟悉Javascript && HTML && CSS

随机推荐