用swoole搭建分布式的websocket服务器

  • 背景
    websocket在长连接应用场景中用的越来越多,随着业务量和应用场景的增加单台服务器所能提供的连接数达不到需求,所以多台服务器分布运行是日渐趋势。

  • 实现思路
    本次使用swoole来提供websocket服务,所需要服务器两台,nginx一台,mqtt服务全部用docker实现。两个服务分别开的端口是9091和9092来,nginx负载均衡监听9093端口,将来自不同客服端的连接转发到不同的服务上。
    当使用点对点聊天的时候,发送消息内携带对方用户的fd和服务id。消息发送到连接的服务端,服务端解析目标服务id,并同过mqtt将消息发布到目标服务器对应的主题,当目标服务器订阅到该消息,并解析消息中目标fd。然后将消息发给对应的fd客户端。
    在这里插入图片描述

  • 1.nginx负载均衡
    关于nginx负载均衡相关配置的可以参考我另一篇文章 nginx配置负载均衡

  • 2.mqtt搭建
    同样适用docker搭建mqtt服务。

docker pull
docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 
5672:5672 -p 1883:1883 -p 15675:15675 daocloud.io/library/rabbitmq:3.7.4

docker exec <容器ID> rabbitmq-plugins enable rabbitmq_mqtt

执行三个命令后,基本mqtt服务就搞定了,然后测试一下发布与订阅。
在这里插入图片描述
首先设置连接,然后客户端一个发布,一个订阅 同一个主题
在这里插入图片描述
测试时没有问题的。

  • 3.websocket服务
    使用使用swoole开启端口分表为9091和9092的服务。服务id分别为serverid:1和serverId:2。具体代码如下
    在这里插入图片描述
    另外一个文件server_slave.php里的内容一样只是端口改成了9092。
    在docker容器里分别启动两个文件。在这里插入图片描述
    在这里插入图片描述
    然后使用工具测试连接,注意在nginx配置里面是使用9093端口对外,然后分别负载在9091和9092端口。
    在这里插入图片描述

测试连接。
在这里插入图片描述
可以看到两个客服端A和B分别连接到了serverId=1 (127.0.0.1:9051 的服务) 和serverId=2 (127.0.0.1:9052 的服务)
其实多连接几次两个客户端也有可能连上同一台服务。

  • 消息分发
    想要将消息从客服端A发到客服端B,首先在发消息的时候要确定给谁发,并且,知道B客服端连接在了哪台服务上。所以为了简单处理,每个客服端携带连接的fd和他所连接的服务id,这是在他连接上服务端的时候返回的。

  • 1.当客服端A将消息发送到服务端A的时候,服务端A解析消息要分发的对象的服务id,然后找到要发布消息的mqtt服务的主题(这个主题是提前配置好),将消息发布到该主题后。服务端B订阅该主题后,获取到消息中要发送消息的客服端fd,然后将消息发推给这个客服端,整个流程就完了。

  • 2.或者服务端A使用消息通知直接将消息推送给服务B,比如rpc,或者http请求都行。

在这里插入图片描述
这里消息接收后交给Message类里的shotSend()方法处理,并返回给客服端消息处理结果

在这里插入图片描述
如果使用http请求方式通知的话,服务端可以提供request方法接收请求,具体操作看下图。
在这里插入图片描述
这样就可以了。我们试一下
在这里插入图片描述
可以看到服务B (serverId=2)上的客服端fd=6收到了来自服务A(serverId=1)的客服端fd=2的用户的消息。

至此 多服务器实现websocket部署功能以及基本实现,这只是一个dome用来学习的示例,仅提供思路。在现实使用场景中依然会有更多的问题。dome和产品的差距还是很大的,大家加油。

SwooleDistributed 是swoole分布式系统的实现,他提供了一套基于swoole扩展的分布式通讯框架。结构图:SwooleDistributed 不仅提供了分布式搭建的必要设施,还提供了4大组件帮助你提高编写代码的效率,你既可以部署成单机模式也可以搭配dispatch模块构建集群系统。有别于传统的MVC架构,SwooleDistributed 主要应对的是rpc服务或者是通讯服务,也就是说MVC中的View模块是没有实际意义的,所以在SwooleDistributed 中仅存在Model和Controller,另外为了方便开发我们额外添加了2个组件分别是Task和Timer。Task组件主要是处理异步任务,由于Task的设计结构简单只适合用于辅助swoole的worker进程,处理简单并不复杂的异步操作,如果你将他作为复杂耗时并且频繁调用的组件那是不可取的。Timer是封装好的定时器,他和Task组件关系密切,你可以通过Timer进行定时任务。目前提供便利的还有异步的Redis连接池,你可以方便简单的使用redis异步服务而不用担心连接池的问题,我们已经优雅的解决了。但值得注意的是所有的异步服务都只允许在worker进程中调用,task进程只能调用同步服务。未来将要实现的:1.异步的mysql服务,建立管理mysql连接池。2.mysql语法构建器,帮助快速构建mysql语句。3.Job服务组件的开发,结合消息队列系统实现分布式的异步任务。安装须知:php 7.0  2.需要使用最新版的swoole,请通过github下载编译swoole,1.8.7在php7.0下存在bug不建议使用  3.需要redis支持,安装redis扩展  swoole编译时选择异步redis选项  4.需要composer支持,安装composer,运行composer install安装依赖  5.如需集群自行搭建LVS  运行:php start_swoole_server.php start    启动swoole server服务器  2.php start_swoole_dispatch.php start    启动swoole dispatch服务器  3.单独启动swoole server不具备分布式特性,一台物理机只允许启动一个swoole server  4.swoole dispatch服务器可以和swoole server放在一个物理机上,一台物理机只允许启动一个swoole dispatch  5.可以启动多台swoole server和多台swoole dispatch搭建分布式系统(至少1台LVS,2台swoole server,1台swoole dispatch,1个redis)  6.单独启动swoole server可作为单机服务器。  7.修改config目录下配置,改为你自己的配置。  8.swoole server与swoole dispatch 必须在同一个网段。swoole dispatch无需配置,swoole server会自动发现  9.swoole server与swoole dispatch 都支持动态弹性部署,随时热插拔。swoole dispatch上线后30秒内被swoole server发现并建立连接  10.内置controller,model,task 3大模块  11.swoole server与swoole dispatch都被设计成无状态服务器,所有的信息共享都通过redis  12.最新版采用了异步redis进行数据存储,通过开启一个新的redis连接池进程,利用addProcess和sendMessage技术进行结果分发,优雅解决异步问题。  13.注意taskproxy为单例,不要变成成员变量使用,用到时load 标签:通讯框架
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值