微服务的概念由 Martin Fowler 于2014年3月提出:php
微服务架构是一种架构模式,它提倡将单一应用程序划分红一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每一个服务运行在其独立的进程中,服务和服务之间采用轻量级的通讯机制相互沟通。每一个服务都围绕着具体的业务进行构建,而且可以被独立的部署到生产环境、类生产环境等。另外,应尽可能避免统一的、集中的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。
下图是一个电商系统的微服务架构图:前端
微服务架构与单体应用相比,具备如下优势:java
没有银弹,微服务架构在带来诸多优势的同时,也会有以下缺点:node
能够说,正是传统应用架构的系统变得日益臃肿,面临难以维护、扩展的问题,同时容器化技术(Docker)的蓬勃发展和 DevOps 思想的日渐成熟,催生了新的架构设计风格 – 微服务架构的出现。git
微服务架构中的各个服务一般不在同一个机器上,甚至不会在同一个网络环境里,所以微服务之间如何调用是一个亟待解决的问题,咱们一般使用 RPC 协议来解决:程序员
RPC(Remote Procedure Call),即远程过程调用,是一个计算机通讯协议。该协议容许运行于一台计算机的程序调用另外一台计算机的子程序,而程序员无需额外地为这个交互做用编程。——维基百科
实现了 RPC 协议的框架,可让服务方和调用方屏蔽各类底层细节,让调用方像调用本地函数同样调用远端的函数(服务)。RPC 框架通常为服务端和客户端提供了序列化、反序列化、链接池管理、负载均衡、故障转移、队列管理、超时管理、异步管理等职能。在网上找到一个说明 RPC 框架工做原理图:github
目前,根据序列化数据时采用的技术的不一样,可分为 JSON-RPC
和 gRPC
两种:web
JSON-RPC
优势是易于使用和阅读。gRPC
具备低延迟、高效率、高扩展性、支持分布式等优势。如今有了 RPC 框架,咱们就能够只考虑服务与服务之间的业务调用而不用考虑底层传输细节。此时,若是服务 A 想调用服务 B 时,咱们能够在服务 A 中配置服务 B 的 IP 地址和端口,而后剩下的传输细节就交给 RPC 框架。这在微服务规模很小的状况下是没有问题的,可是在服务规模很大、并且每一个服务不止部署一个实例的状况下会面临巨大挑战。好比,服务 B 部署了三个实例,这时候服务 A 想调用服务 B 该请求哪一个实例的 IP ?假如服务 B 部署的三个实例有两个都挂掉了,服务 A 可能会依旧去请求挂掉的实例,服务将不可用。将 IP 地址和端口写成配置文件显得很不灵活,微服务架构每每要保证高可用及动态伸缩。spring
所以,咱们须要一个服务注册与服务发现的工具,可以动态地变动服务信息,而且找到可用的服务的 IP 地址和端口。目前市面上服务发现的工具备不少,如 Consul、ZooKeeper 、Etcd、Doozerd 等,本文主要以 Consul 软件为例。docker
Consul 是一个支持多数据中心、分布式高可用的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License 2.0 的协议进行开源。 Consul 支持健康检查,并容许 HTTP 、gRPC 和 DNS 协议调用 API 存储键值对。
下面是引入服务注册与服务发现工具后的架构图:
在这个架构中:
可见, Consul 软件除了服务注册和服务发现的功能以外,还提供了健康检查和状态变动通知的功能。
对于 Java 开发者来讲,有技术至关成熟的 Dubbo 和 Spring Cloud 微服务框架可供选择。做为一名 PHPer,我用 Google 查了一下「PHP + 微服务」,发现有用的相关内容少之又少 ,没有什么实质性的参考价值,无限惆怅。。。幸亏,有大神在基于 Swoole 扩展的基础上,实现了高性能、高灵活性的 PHP 协程框架 Hyperf ,并提供了微服务架构的相关组件。
Hyperf 是基于Swoole 4.3+
实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量经常使用的组件,性能较传统基于PHP-FPM
的框架有质的提高,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是可替换
与可复用
的。
因而,我在学习了微服务架构相关的基础知识以后,使用 Hyperf 框架构建了一个基于 PHP 的微服务集群,这是项目源码地址:github.com/Jochen-z/p.…。该项目使用 Dokcer 搭建,docker-compose.yml
代码以下:
version: "3"
services:
consul-server-leader:
image: consul:latest
container_name: consul-server-leader
command: "agent -server -bootstrap -ui -node=consul-server-leader -client=0.0.0.0"
environment:
- CONSUL_BIND_INTERFACE=eth0
ports:
- "8500:8500"
networks:
- microservice
microservice-1:
build:
context: .
container_name: "microservice-1"
command: "php bin/hyperf.php start"
depends_on:
- "consul-server-leader"
volumes:
- ./www/microservice-1:/var/www
networks:
- microservice
tty: true
microservice-2:
build:
context: .
container_name: "microservice-2"
command: "php bin/hyperf.php start"
depends_on:
- "consul-server-leader"
volumes:
- ./www/microservice-2:/var/www
networks:
- microservice
tty: true
app:
build:
context: .
container_name: "app"
command: "php bin/hyperf.php start"
depends_on:
- "microservice-1"
volumes:
- ./www/web:/var/www
ports:
- "9501:9501"
networks:
- microservice
tty: true
networks:
microservice:
driver: bridge
volumes:
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 协议调用加法运算和除法运算的服务获取结果并返回给用户。
app
容器为 Web 应用,部署了一个 Hyperf 项目并对外提供 HTTP 服务。例如,在 App\Controller\IndexController
控制器里有 add
方法:
public function add(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
的实现:
class AdditionService extends AbstractServiceClient
{
/**
* 定义对应服务提供者的服务名称
* @var string
*/
protected $serviceName = 'AdditionService';
/**
* 定义对应服务提供者的服务协议
* @var string
*/
protected $protocol = 'jsonrpc-http';
public function add(int $a, int $b): int
{
return $this->__request(__FUNCTION__, compact('a', 'b'));
}
}复制代码
继承了 AbstractServiceClient
便可建立一个微服务客户端请求类,Hyperf 在底层帮咱们实现了与 Consul 和服务提供者交互的细节,咱们只要 AdditionService
类里的 add
方法便可远程调用 microservice-1
和 microservice-2
提供的服务。
至此,PHP 微服务集群搭建就完成了!
欢迎你们关注个人公众号【java小瓜哥的分享平台】,文章都会在里面更新,整理的资料也会放在里面