微服务架构这几年很火。趁着最近的时间,摆弄微服务是什么感觉。微服务架构microservice的概念由MartinFowler于2014年3月提出:微服务架构是一种架构模式,提倡将单个应用程序划分为一组小的服务,服务之间相互协调配合,为用户服务。提供最终价值。每个服务都运行在自己独立的进程中,服务之间使用轻量级的通信机制进行通信。每个服务都围绕特定的业务构建,可以独立部署到生产环境、类生产环境等。另外,要尽量避免统一集中的服务管理机制。对于具体的服务,要根据业务上下文选择合适的语言和工具来构建。下图是一个电商系统的微服务架构图:与单体应用相比,微服务架构有以下优势:每个服务相对简单,只专注于一个业务功能;微服务架构是松耦合的,每个服务都可以独立测试、部署、升级、发布;每个微服务都可以由不同的团队独立开发,各自可以选择最好最适合的不同编程语言和工具;每个服务都可以根据需要进行横向扩展,提高系统并发度。没有灵丹妙药。微服务架构在带来诸多优势的同时,也存在以下不足:微服务架构增加了系统的复杂度,增加了运维开销和成本。比如单个应用可能只需要部署到一个小的应用服务集群,而微服务架构可能变成几十个独立的服务需要构建/测试/部署/运行,还可能需要支持多种语言和环境;作为分布式系统,微服务架构引入了其他几个问题,如消息序列化、网络延迟、异步机制、容错处理、服务雪崩等;服务管理的复杂性,如服务注册、发现、降级、熔断等;服务之间存在相互调用,给排查系统故障带来了极大的挑战。可以说,传统应用架构的系统越来越臃肿,难以维护和扩展。同时,容器化技术(Docker)的蓬勃发展和DevOps思想的成熟催生了一种新的架构设计风格——微服务架构的出现。RPC框架微服务架构中的各个服务通常不在同一台机器上,甚至不在同一个网络环境中,因此微服务之间如何调用是一个亟待解决的问题。我们通常使用RPC协议来解决:RPC(RemoteProcedureCall),即远程过程调用,是一种计算机通信协议。该协议允许在一台计算机上运行的程序调用另一台计算机上的子程序,而无需程序员为此交互额外编程。——Wikipedia实现了RPC协议的框架,让服务端和调用者屏蔽各种底层细节,让调用者像调用本地函数一样调用远程函数(服务)。RPC框架一般为服务端和客户端提供序列化、反序列化、连接池管理、负载均衡、故障转移、队列管理、超时管理、异步管理等功能。我在网上找了一张图来说明RPC框架的工作原理:目前按照数据序列化所采用的技术,可以分为JSON-RPC和gRPC两种:JSON-RPC是一种轻量级的RPC基于JSON格式的协议标准可以基于HTTP协议传输,也可以直接基于TCP协议传输。JSON-RPC的优点是易于使用和阅读。gRPC是一个高性能、通用的开源RPC框架,由Google设计,主要用于移动应用程序开发,基于HTTP/2协议标准。它基于ProtoBuf(ProtocolBuffers)序列化协议开发,支持多种开发语言。gRPC具有低延迟、高效率、高扩展性、分布式支持等优点。既然Consul有了RPC框架,我们就可以只考虑服务间的业务调用,而无需考虑底层的传输细节。此时,如果服务A要调用服务B,我们可以在服务A中配置服务B的IP地址和端口,剩下的传输细节交给RPC框架。这在小型微服务的情况下很好,但当服务规模很大并且每个服务部署了多个实例时,这将成为一个巨大的挑战。例如,服务B部署了三个实例。此时服务A要调用服务B,应该请求哪个实例的IP呢?如果服务B部署的三个实例中有两个宕机,服务A可能还会请求宕机的实例,服务将不可用。将IP地址和端口写成配置文件不灵活,微服务架构往往需要保证高可用和动态伸缩。因此,我们需要一个服务注册和服务发现的工具,可以动态改变服务信息,找到可用服务的IP地址和端口。市面上服务发现的工具有很多,比如Consul、ZooKeeper、Etcd、Doozerd等,本文主要以Consul软件为例。Consul是一款支持多数据中心、分布式、高可用的服务发现和配置共享的服务软件。它由HashiCorp用Go语言开发,基于MozillaPublicLicense2.0协议开源。Consul支持健康检查,允许HTTP、gRPC和DNS协议调用API存储键值对。下面是引入服务注册和服务发现工具后的架构图:在这个架构中:首先,S-B实例启动后,自身的服务信息(主要是服务所在的IP地址和端口号)是在领事注册。Consul将对所有已注册的服务执行健康检查,以确定哪些服务实例可用,哪些不可用。S-A启动后,可以访问Consul获取所有健康的S-B实例的IP和端口,并将这些信息放入自己的内存中,S-A可以利用这些信息调用S-B。S-A可以通过监听Consul来更新存储在内存中的S-B的服务信息。比如S-B-1挂了,健康检查机制会将其标记为不可用。这样的信息变化会被S-A监测到,S-A会在自己的内存中更新S-B-1的服务信息。可以看出,Consul软件除了服务注册和服务发现的功能外,还提供了健康检查和状态变化通知的功能。对于Java开发者来说,Hyperf有相当成熟的Dubbo和SpringCloud微服务框架可以选择。作为一个PHPer,用Google查了一下“PHP+微服务”,发现有用的相关内容寥寥无几,没有实质性的参考价值,无限惆怅。..好在已经有高手实现了基于Swoole扩展的高性能、高灵活性的PHP协程框架Hyperf,并提供了微服务架构的相关组件。Hyperf是一个基于Swoole4.3+的高性能、高灵活性的PHP协程框架。它内置协程服务器和大量常用组件,也保持了极其灵活的可扩展性,标准组件基于PSR标准实现,基于强大的依赖注入设计,保证了大部分组件或类的可替换和可重用。于是,在学习了微服务架构的基础知识后,我使用Hyperf框架搭建了一个基于PHP的微服务集群。这是项目源码地址:https://github.com/Jochen-z/p...。该项目使用Dokcer搭建,docker-compose.yml代码如下:version:"3"services:consul-server-leader:image:consul:latestcontainer_name:consul-server-leadercommand:"agent-server-bootstrap-ui-node=consul-server-leader-client=0.0.0.0"环境:-CONSUL_BIND_INTERFACE=eth0端口:-"8500:8500"网络:-microservicemicroservice-1:build:context:。container_name:“microservice-1”命令:“phpbin/hyperf.phpstart”depends_on:-“consul-server-leader”volumes:-./www/microservice-1:/var/wwwnetworks:-microservicetty:true微服务2:构建:上下文:。container_name:“microservice-2”命令:“phpbin/hyperf.phpstart”depends_on:-“consul-server-leader”volumes:-./www/microservice-2:/var/wwwnetworks:-microservicetty:true应用程序:构建:上下文:。container_name:"app"命令:"phpbin/hyperf.phpstart"depends_on:-"microservice-1"volumes:-./www/web:/var/wwwports:-"9501:9501"networks:-microservicetty:truenetworks:microservice:driver:bridgevolumes:microservice:driver:local从这里开始Consul容器consul-server-leader用作服务注册和服务发现的组件。容器microservice-1和microservice-2分别作为服务调用者提供加法和除法操作的服务容器app。Consul-server-leader配置容器的URL,通过访问consul-server-leader获取microservice-1和microservice-2服务的IP地址和端口,然后app调用加分服务通过RPC协议获取结果返回给用户。应用容器是部署Hyperf项目并对外提供HTTP服务的Web应用。比如App\Controller\IndexController控制器中有一个add方法:publicfunctionadd(AdditionService$addition){$a=(int)$this->request->input('a',1);#接受前端用户参数$b=(int)$this->request->input('b',2);return['a'=>$a,'b'=>$b,'add'=>$addition->add($a,$b)#RPC调用];}App\JsonRpc\AdditionService中add的实现:classAdditionServiceextendsAbstractServiceClient{/***定义对应服务提供者的服务名称*@varstring*/protected$serviceName='AdditionService';/***定义对应服务提供者的服务协议*@varstring*/protected$protocol='jsonrpc-http';publicfunctionadd(int$a,int$b):int{return$this->__request(__FUNCTION__,compact('a','b'));}}继承AbstractServiceClient创建一个微服务客户端请求类,Hyperf帮助我们在底层与Consul和服务提供者进行交互,具体的我们只要通过其中的add方法就可以远程调用microservice-1和microservice-2提供的服务添加服务类。至此,PHP微服务集群搭建完成!参考文章:微服务架构密不可分的微服务架构详解,密不可分的RPC详解使用Consul进行服务注册和服务发现Hyperf文档-微服务
