微服务概述

什么是微服务

微服务的概念和用法类似于Laravel框架的服务提供者,维基上对其定义为:一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。

为什么要微服务

在开发大型应用时,我们往往会把某一类的常用函数创建一个服务或者模型来处理相关的逻辑,便于我们在控制器内随时引用。但问题是,这些模型或者服务更像是把辅助函数进行归类堆砌,无法处理更复杂的业务逻辑,也不具备独立运行的条件,更不能提高业务逻辑的复用性。即便是通过composer安装的完整业务逻辑依赖包,很多时候也不得不开发对应的配置功能来结合才能使用。
尤其在开发多拓展应用的软件时,我们常常因为某些功能相近的代码块的维护和迭代感到力不从心,也常常因为反复造轮子而感到疲倦。这些问题在云市场上的一些应用表现得特别明显,往往客户只需要一只蚊子腿,却不得不为了烹饪蚊子而架设炉子甚至建厨房,每个独立的应用最终都变成了全家桶,几乎每个不同品类、不同用途的软件里面,相重合的功能高达60%以上。因此而来的巨额成本只能由客户来承担,而开发者同样为了开发和维护这些功能而浪费了很大的精力。
为了解决这些问题,微服务应运而生。

何时需要微服务

任何的业务逻辑,都可以作为一个微服务来向不同应用模块、其它微服务、甚至是框架提供服务。每个微服务都自成体系,有自己的框架和规范,只需要提供统一的接入标准来告知开发者如何引用即可。
和传统的服务或者模型不同,微服务更偏向于业务型的逻辑服务,通常会将某些在应用开发者必不可少,但又和软件主要业务逻辑关联不大的功能块作为微服务来运行,便于向多个不同的应用和软件提供对应的服务,例如用户服务、支付服务、权限服务、消息推送服务等等。

微服务能带来什么

  1. 提高软件功能块的复用性、耦合性、灵活性,降低软件主体底层功能的维护成本;
  2. 提高软件可拓展性,和主体功能的高可用性;
  3. 使用者接入轻如云市场,可低成本快速对接海量优质云服务;
  4. 即装即用,符合前沿的优秀程序设计逻辑;
  5. 开发者更专注于业务逻辑本身,大幅度降低开发周期和开发成本;
  6. 开发者避免重复造轮子,还可以减轻多个软件同一个轮子的迭代压力;
  7. 开发者可将自身的开发积累快速发布为微服务,技术积累同时变现增收;
  8. 解决市场上开发能力过剩,而需求方却始终找不到满意产品和服务的问题;
  9. 需求方可以在鱼龙混杂的开发者市场中低成本快速定制符合需求的服务,也可以让开发者快速将现有服务应用到产品中;
  10. 微服务市场诞生后,大家会看到许多有意思的微服务。

    合理运用微服务

    微服务的概念由来已久,也已经广泛的运用到各大开发体系中,但是一些做法可能会使微服务模式的作用和优点没有得到发挥,甚至引发负面作用。以下整理一些微服务模式的共识,希望有助于您合理的运用微服务:
    不要轻易构建微服务
    更准确地说,不要从微服务开始。一旦应用程序变得太大和笨拙而无法轻松更新和维护,微服务就是一种管理复杂性的方法。仅当您感到整体的痛苦和复杂性开始蔓延时,才值得考虑如何将应用程序重构为较小的服务。直到您感到痛苦之前,您甚至还没有真正需要重构的整体。简而言之就是:不到真的很必要做成微服务的时候,就没必要以微服务的方式来构建应用。
    不要通过使它们变得太小来制造太多的微服务
    如果您对微服务中的“微”概念走得太远,那么您很容易发现自己的开销和复杂性超过了微服务体系结构的整体收益。最好倾向于大型服务,然后仅在它们开始发展微服务需要解决的特征时才将它们分开—即,部署变更变得越来越困难,通用数据模型变得过于复杂,或者其中的不同部分服务具有不同的负载/规模要求。
    不要将微服务转变为SOA
    由于微服务和面向服务的体系结构(SOA)在最基本的层次上都对构建可被其他应用程序使用的可重用的单个组件感兴趣,因此它们经常相互融合。微服务与SOA之间的区别在于,微服务项目通常涉及重构应用程序,因此更易于管理,而SOA则关注于改变IT服务在企业范围内的工作方式。演变为SOA项目的微服务项目可能会在自身的负担下崩溃。
    不要在没有DevOps或云服务的情况下进行微服务
    构建微服务意味着构建分布式系统,并且分布式系统很难(如果您做出选择,使它们变得更加困难,它们就特别困难)。尝试在没有a)适当的部署和监控自动化或b)托管的云服务来支持您现在庞大的异构基础架构的情况下进行微服务正在引起很多不必要的麻烦。为自己省去麻烦,以便您可以花时间担心状态。

微服务架构

生命周期

概述 - 图1
微服务生命周期

负载均衡

轻如框架默认支持负载均衡方式的部署,微服务的负载均衡需要借助框架来实现。
其它框架请参阅相关文档。

数据库负载均衡

数据库的负载均衡主要通过读写分离来实现。
总体思路:
搭建主数据库服务器用于写入操作,同时配置数据库自动同步到多个从服务器用于读取操作,以减轻数据库耦合压力、高连接压力,同时可以很大程度降低风险。
配置方法:
/config/database.php 文件中配置数据库的读写服务器的主机名即可,具体请参考详细说明文档
概述 - 图2

应用负载均衡

优化好数据库的负载均衡后,应用服务器也可以通过配置多个从服务器实现负载均衡的效果。
要实现该方法需要借助Nginx的负载监听,并将所有请求均匀分配到每台应用服务器上。
概述 - 图3
整体思路:

  • 轮循(默认):Nginx根据请求次数,将每个请求均匀分配到每台服务器上。
  • 最少连接:将请求分配给连接数最少的服务器。Nginx会统计哪些服务器的连接数最少。
  • IP Hash:绑定处理请求的服务器。第一次请求时,根据该客户端的IP算出一个HASH值,将请求分配到集群中的某一台服务器上。后面该客户端的所有请求,都将通过HASH算法,找到之前处理这台客户端请求的服务器,然后将请求交给它来处理。

概述 - 图4
配置方法:

  1. upstream server1 {
  2. server 192.168.72.100:80 weight=3 max_fails=3 fail_timeout=15 max_conns=1000;
  3. server 192.168.72.101:80 weight=2 max_fails=3 fail_timeout=15;
  4. server 192.168.72.102:80 weight=1 max_fails=3 fail_timeout=15 ;
  5. server 192.168.72.103:80 backup;
  6. server 192.168.72.104:80 down;
  7. }
  8. server {
  9. listen 80;
  10. server_name www.xxx.com;
  11. #charset koi8-r;
  12. access_log logs/host.access.log main;
  13. location / {
  14. proxy_pass http://server1;
  15. index index.html index.htm index.php;
  16. }
  17. }

概述 - 图5
概述 - 图6

事件广播

微服务的事件广播用于在多个微服务之间的通讯,是一种被动触发的事件响应机制。
微服务在完成某些关键操作时,可以将结果或数据向整个系统进行广播,当应用开发需要监听该方法时,只需要按规范定义对应的监听器即可接收到该服务广播的数据。

事件广播

事件的广播只需要执行 Event() 方法,该方法可以在模型文件的内置方法或者继承了模型文件的控制内调用。执行后系统内所有监听 listener 事件的监听器都会被执行并传输对应数据。
该方法的说明请参考:https://www.yuque.com/shenwa/qingru/kh3of6#z6bb8

$this->Event("listener", $data);

事件响应

微服务需要在manifest.json文件指定该服务需要监听的所有事件,同时在微服务的模型文件中定义处理事件的方法。
该方法的详细说明请参考:https://www.yuque.com/shenwa/qingru/kh3of6#x0n0d

{
  "application":{
    "name": "用户服务"
    ......
  }
  ......
  "events": ["storage.remove"],    #监听的事件列表
......
}
public function Processor($listener, $data=array()){
  switch ($listener){
      case "storage.remove" : {
          //检测用户头像是否被删除
          $uid = .....;
          if ($uid){
              //如果被删除则替换为默认头像
              $this->UpdateInfo($uid, array('avatar'=>$this->defaultAvatar));
          }
          break;
      }
      default :
  }
  return true;
}

熔断机制

该部分说明会在晚些时候补充。

队列机制

微服务的队列机制需要依赖框架的队列机制,该部分说明会在晚些时候补充。

快速接入微服务

轻如框架

轻如框架默认自带微服务支持模型,激活后即可使用。

DiscuzX

安装微服务插件:

微擎2.X

安装微服务模块:https://shenwa.coding.net/public/qingrucloud/swa_microserver/git/files
安装后,在模块内使用超级管理员账号管理微服务,然后在需要使用微服务的地方直接引用。

//定义微服务目录
const MICRO_SERVER = IA_ROOT . "/addons/swa_microserver/";
//引用辅助函数
require_once MICRO_SERVER . "helper.php";
//直接调用服务
serv("identity")->foo();    //其中 identity 为服务标识

更多框架

接下来我们会推出更多主流框架和常见系统的接入支持,也欢迎有实力的开发者把微服务框架和市场接口接入到自研软件和系统中去,更希望广大开发者把已有技术成果萃取为微服务发布到市场中来。