php-php异步网络通信引擎-服务发现-消息队列 案例

版权声明:原创文章欢迎转载,不过要记得加出处哦 https://blog.csdn.net/wljk506/article/details/80515310

本文只做为php微服务案例,其他更多功能请自行添加。

项目介绍

某个项目中,根据上传EXCEL文件,读取其中的数据并生成订单(分为总订单和子订单),如商品编码,收货人等信息,进行各种条件验证,并返回验证结果。用户根据返回的结果选择支付方式进行付款操作。

  • Excel 中最多有10000行,多用户同时上传
  • 国外用户访问国内服务器
  • 创建订单时并减少库存
  • 发送待付款邮件
  • 待付款邮件中有当前总订单下所有子订单信息的PDF文件
  • 等等更多

了解这么多需求后,那么就可以设计一个基本需要的架构了。
微服务这是肯定需要了->swoole,服务发现和注册呢->consul,一次性处理那么多数据不现实,必然要拆分处理,处理一部分,返回一部分结果,那么这个需要用到数据持久化,消息队列可以解决这个问题->rabbitmq,在验证的过程中数据查询频繁可以用elasticsearch,日志收集分析等可以用elasticsearch全家桶(elasticsearch logstash kibana) 。。。。。。。

近期做了 docker 版案例,给大家提供一个思路吧

风.fox

消息队列 RabbitMQ

消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
更多请看
https://www.jianshu.com/p/79ca08116d57
https://blog.csdn.net/whoamiyang/article/details/54954780

服务管理(服务发现,注册,健康检查) consul

consul 是一个服务管理软件。
- 支持多数据中心下,分布式高可用的,服务发现和配置共享。
- consul支持健康检查,允许存储键值对。
- 一致性协议采用 Raft 算法,用来保证服务的高可用.
- 成员管理和消息广播 采用GOSSIP协议,支持ACL访问控制。
ACL技术在路由器中被广泛采用,它是一种基于包过滤的流控制技术。控制列表通过把源地址、目的地址及端口号作为数据包检查的基本元素,并可以规定符合条件的数据包是否允许通过。
gossip就是p2p协议。他主要要做的事情是,去中心化。
这个协议就是模拟人类中传播谣言的行为而来。首先要传播谣言就要有种子节点。种子节点每秒都会随机向其他节点发送自己所拥有的节点列表,以及需要传播的消息。任何新加入的节点,就在这种传播方式下很快地被全网所知道。
更多请看
https://blog.csdn.net/viewcode/article/details/45915179
https://www.jianshu.com/p/28c6bd590ca0

swoole-php异步网络通信引擎

Swoole:面向生产环境的 PHP 异步网络通信引擎
使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用 PHP + Swoole 作为网络通信框架,可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。
更多请看
https://www.swoole.com/
https://wiki.swoole.com/



下载docker 环境

https://github.com/foxiswho/docker-nginx-php-swoole-rabbitmq-consul

git clone https://github.com/foxiswho/docker-nginx-php-swoole-rabbitmq-consul.git

下载案例文件

进入上面下载的目录wwwroot

cd wwwroot

然后下载 案例文件

git clone https://github.com/foxiswho/php-swoole-rabbitmq-consul-demo.git "dpsrc"

启动docker compose

到根目录(有docker-compose.yml的那个目录),然后执行

docker-compose up 

如果你需要关闭或者删除docker-compose up建立的所有容器,请在docker-compose.yml的目录下,执行如下命令

docker-compose down 

启动成功后

docker compose 启动成功后,先在浏览器访问http://localhost/demo/service_demo_mq_client/index,有程序自动创建消息队列的交换机,队列,路由KEY等。
然后再启动如下2个DOCKER:

docker-nginx-php-swoole-rabbitmq-consul_phpmqsub_1
docker-nginx-php-swoole-rabbitmq-consul_phpmqsub002_1

为什么要其中这2个docker呢,因为在docker compose创建时,消息队列里面全部是空的,没有建立测试里面的测试用的交换机,队列,路由KEY。执行一次后,就会自动创建这些

直接访问浏览器网址 即可
http://localhost/demo/service_demo_client/index

http://localhost/demo/service_demo_mq_client/index

其他

注册中心访问

浏览器打开

http://localhost:8500/ui/

消息队列web 管理

http://localhost:15672/

默认用户及密码
guest
guest

说明

访问php微服务返回数据

在浏览器中打开如下网址

http://localhost/demo/service_demo_client/index

此处是到服务注册中心去获取php-demo微服务信息,会返回该微服务的ip端口等信息, swoole_client 根据返回的ip端口去访问微服务,微服务php-demo处理后返回数据,此处就是显示处理后的数据

源码如下

<?php

namespace app\demo\controller;

use app\module\consul;

//本demo处理 app\service\controller\Demo
class ServiceDemoClient
{
    /**
     * 获取指定服务,发送数据,服务端处理数据,并返回数据
     */
    public function index()
    {
        //获取指定服务
        $services = consul::getServicesOne('php-demo');
        if (isset($services) && $services) {
            trace($services);
            //                $ser->ID;
            //                $ser->Address;
            //                $ser->Service;
            //                $ser->Port;
            $client = new \swoole_client(SWOOLE_SOCK_TCP);
            //连接到服务器
            if (!$client->connect($services->Address, $services->Port, 0.5)) {
                throw new \Exception("swoole_client connect failed.");
            }
            //向服务器发送数据
            if (!$client->send("hello world")) {
                throw new \Exception("swoole_client send failed.");
            }
            //从服务器接收数据
            $data = $client->recv();
            if (!$data) {
                throw new \Exception("swoole_client recv failed.");
            }
            echo $data;
            //关闭连接
            $client->close();
        } else {
            throw new \Exception("Consul service not find.");
        }
    }

    /**
     * 获取指定服务
     */
    public function getService()
    {
        ......
    }
}

php微服务

代码位置

app\service\controller\Demo.php

启动该微服务,与app目录同级目录下执行

php public/index.php service/demo/start

源码

//默认action start
class Demo extends Server
{
    // 监听所有地址
    protected $host = '0.0.0.0';
    // 监听 9501 端口
    protected $port = 9501;
    // 指定运行模式为多进程
    protected $mode = SWOOLE_PROCESS;
    // 指定 socket 的类型为 ipv4 的 tcp socket
    protected $sockType = SWOOLE_SOCK_TCP;
    // 配置项
    protected $option = [
        /**
         *  设置启动的worker进程数
         *  业务代码是全异步非阻塞的,这里设置为CPU的1-4倍最合理
         *  业务代码为同步阻塞,需要根据请求响应时间和系统负载来调整
         */
        'worker_num' => 1,
        // 守护进程化
        'daemonize'  => false,
        // 监听队列的长度
        'backlog'    => 128
    ];

    /**
     * 收到信息时回调函数
     * @param \swoole_server $server swoole_server对象
     * @param $fd TCP客户端连接的文件描述符
     * @param $from_id TCP连接所在的Reactor线程ID
     * @param $data 收到的数据内容
     */
    public function onReceive(\swoole_server $server, $fd, $from_id, $data)
    {
        //返回数据
        $server->send($fd, 'onReceive: ' . $data);
    }
}

消息队列

都是大同小异,
略,请自行看案例
空了时候再添加更多案例说明

阅读更多

扫码向博主提问

风.foxwho

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • php
  • java
  • go
  • 架构
  • more
去开通我的Chat快问
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页