微服务的基本架构

"记录常用的模型,账户系统、支付系统"

Posted by yueLng on 2017-03-28

“Yeah It’s on. ”

微服务代码结构

微服务是大的趋势。无论后台架构怎么改变,都不能脱离它是业务架构具体实现的本质。无论是前期发展而来的单体架构,遵循着严格的代码分层风格,还是现在大家认同的微服务。微服务是后端开发的绝对趋势,外部用户需求增强直接导致了应用复杂度增加,只有将应用分解再分解才能利用更小的成本干更多的事。微服务的另一种表现是后端“侵占”系统工程、运维部署、DBA的工作,在中型及以下的公司中更多地利用云资源,云主机,云数据库的租用模式降低了企业的成本,也使得后端开发是多面手,能够开发应用,能够部署发布系统,规划网络。整个趋势应该是效率更高成本更低的模式迈进。当然在产品创意时期,快速试错阶段,是否采用微服务结构,则完全取决于开发组长在微服务领域的积累,有的同学认为使用微服务会增加系统成本,但是这个“成本问题”还需要好好商榷。在产品期初阶段,我是不反对单体架构的,只要做好设计做好分层,对后面拆分服务也是方便的。毕竟微服务是高内聚低耦合设计的正交性 的正确实现。微服务在本质上是SOA面向服务架构的一种具体实现,过去的企业总线模式绑定了固定的技术,而微服务则更加注重轻量级,易于修改与部署。可以这么说单体架构是一张服务图,而微服务是一棵服务树。

该怎么合理设计微服务架构,服务在系统中应该表示为组件,可以提供某种作用例如汽车中的发动机,具体在代码系统中应该是能提供接口。所以规范好服务的边界,以及提供充分的周边服务就是设计的考虑点。我们可以从Chris Richardson 微服务系列的七篇文章得到一些灵感

  1. 微服务架构的优势与不足
  2. 使用 API 网关构建微服务
  3. 微服务架构中的进程间通信
  4. 服务发现的可行方案以及实践案例
  5. 微服务的事件驱动数据管理
  6. 选择微服务部署策略
  7. 将单体应用改造为微服务

除了第一篇的总起和最后一篇的具体实践,其余5篇都是指导我们在微服务中应该具体注意哪些话题。当然还包括其他应该关注的话题

  • 日志和审计,主要是日志的汇总,分类和查询
  • 监控和告警,主要是监控每个服务的状态,必要时产生告警
  • 认证与鉴权
  • 统一的服务测试(单元测试,整体测试)
  • 服务依赖关系管理(服务调用关系链跟踪)

很多团队在想自己公司是否需要引入微服务,他应该考虑应用系统是否能够拆分成体积小的微服务,以及各个服务之间的耦合情况,其次外部条件是否容许,是否能够独立开发与部署,能否采用轻量级的通信机制和架构。在我看来微服务还是另外一种单体应用,只是着重关注于本身的业务实现。一个完整的微服务同样也包括handler、service、dao,具体的代码组织架构则是设计模式那一层级所要考虑的事,例如是否需要在handler层与dao层加入service来实现具体的业务逻辑,这个就跟软件开发具体能力直接相关,也是能看出后端工程师是否能写好代码的重要表现。但是有一点要注意,过早的优化是万恶之源,在写代码中不断思考不断优化才是可持续发展之路。

BASE模型

  • Basically Available(基本可用):系统在出现不可预知的故障的时候,允许损失部分可用性,但不等于系统不可用
  • Soft State(软状态):允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性
  • Eventually Consistent(最终一致性):系统保证最终数据能够达到一致

在微服务架构中,每个微服务都有自己私有的数据集。不同微服务可能使用不同的SQL或者NoSQL数据库。尽管数据库架构有很强的优势,但是也面对数据分布式管理的挑战。第一个挑战就是如何在多服务之间维护业务交易一致性;第二个挑战是如何从多服务环境中获取一致性数据。最佳解决办法是采用事件驱动架构。其中碰到的一个挑战是如何原子性的更新状态和发布事件。有几种方法可以解决此问题,包括将数据库视为消息队列、交易日志挖掘和事件源。

Christian Posta认为微服务的价值在于自治,在于每一个系统都能够独立的变化,为了在实现自治的同时又保证业务需求,“事件机制”是非常好的选择。事件是不可变的数据结构,它会及时捕获与某个动作相关的信息,并被广播到其他节点,其他节点会监听它们感兴趣的事件,并根据事件的数据做出决策(存储数据、更新数据等)。

账户系统

基本所有面向用户的系统都会涉及账户系统,在学校做项目的时候,只会注意注册、登录、登出功能。在工作之后才发现账户系统是有套路可寻的。现在的账户系统都会涉及第三方登录,所以这部分会两个话题讲。使用手机或邮箱注册登录,最初的办法是将登录信息写入服务器端的session、客户端的cookie,在用户访问网页时才能记住这个用户。后面发现更加简单的方法–使用token,JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。OAuth技术同样也可以用在自建账户系统中,值得特别注意的是refresh_token的设计,很多认证系统虽然使用了jwt作为认证的技术,但是并没有建立完整的鉴权系统。另外保存access-token的策略,简单做法直接使用user_id作为key,使用jwt-token作为value,而使用OAuth标准的系统来说,则需要考虑存储完整信息,使用token做key,而将所有与用户鉴权信息作为value。

微信登录流程

  1. 用户点击微信登录,调用第三方接口,进入授权页面,与后台无交互
  2. 用户点击授权,回调后台,将code参数传入后台
  3. 后台根据code、AppID和AppSecret 换取access_token
  4. access_token的有效期是2小时,refresh_token的有效期是30天
  5. 通过access_token获取用户头像、昵称等信息

支付系统

一般支付流程

  1. 用户点击微信支付,应用发送pay请求到后台,sign签名
  2. 应用收到后台的sign签名,调起第三方支付页面
  3. 用户与第三方支付交互,支付失败或成功返回应用
  4. 调用query_order查询支付结果,后台与第三方交互
  5. 第三方回调notify,支付成功或失败

参考