swoft-个基于 Swoole 原生协程的PHP 微服务框架
刚才百度了一下swoft框架,官网打不开了,仓库也暂停了。不由感慨。曾经和同事踩了许多坑使用此极其小众的框架完成微服务项目。使用它的唯一目的就是提高程序性能(底层使用了协程),为此大家都学习了很多新知识,解决很多百度都百度不到的问题,赶上了一波docker微服务的潮流。更有同事搭建了k8s集群作为测试环境(相当复杂)。虽然团队规模不大,但是这个项目做的可以说是相当规范了。值得欣慰的是项目性能达到了预期,堪称精美。随着疫情的冲击,项目的商业价值渐渐没落。在运行了两年之后下线了,但没有想到的是如今swoft看起来也是无法使用了。所以码农翻身的作者说的对,我们应该把80%时间用在不变的基础里。追求新技术可能是一种赌注。但不管怎么说,这个框架的设计初衷是非常理想化的,可能是使用的复杂性过高导致用户太少,失去了生命力。即使只是昙花一现,它也曾闪过光!相信它的设计理念里还是有很多有价值可供未来借鉴的部分。
以下内容是转载的,原文见:https://cloud.tencent.com/developer/article/1169328
基于swoole 4.0全新的PHP编程模式
上面是一段PHP代码,其中2个函数的执行时间都是1秒,整段代码执行完成需要2秒。要想将这种串行执行方式转换为并行执行,在PHP中可以通过创建多进程来执行每个函数,单个进程执行单个函数,这样在1秒钟能就能执行完上面的代码。虽然在Java中多线程应用很普遍,但是很可惜PHP并不支持多线程。
除开多线程和多进程,还有一种方式也能实现并行编程,那就是协程(Coroutine),这也是GO语言的重要特性。协程的并发量相对多线程和多进程要高出很多,同一个进程内可以创建几十万甚至上百万个协程,且只占用少量的内存空间。线程和进程由操作系统调度,是非常昂贵的系统资源,创建过多的话,在上下文保存和进行切换的开销上会很大。
这里将前面的代码以协程的形式进行了重写,执行的时候会创建两个协程,执行时间为1秒。虽然执行效果和多进程或多线程一样,但实现原理有所不同。协程中这两个函数的执行基于一种自动让出的机制,一旦执行函数遇到IO操作,就会自动让出当前执行栈交由下一个函数执行,在IO完成之后再恢复协程栈。
PHP由于自身的天然缺陷无法支持多线程,所以我们绕开了它直接在swoft 4.0中实现了协程。但由于针对CPU密集操作只能利用到一个核,所以在使用协程的时候还是会利用多进程的方式来复用CPU的多核操作。
协程最大的好处在于能够提供极大的并发,因为它仅占用内存,不存在进程/线程切换开销,单个进程就可开启50w个协程。
我们在swoft 1.0的时候采用的技术方案和node.js的异步回调一样,在2.0的时候开始尝试实现协程,但是存在一些缺陷——协程不能用在所有的函数上,只能用在一些已经预定好的函数上。这是由于PHP有一些动态的特性,比如将URL映射到一个类方法上,这种场景下执行2.0的协程程序就会崩溃。4.0的时候我们对此做了一些优化,基于微信开源的库重新实现了协程方案,这时的协程就达到了在Go语言中的效果。
上面展示的就是PHP中使用协程的三种方式。左上的代码通过循环的方式创建了10个协程,下面这段则是在协程中执行读文件的操作,且内部还嵌套了两个协程,它们之间是相互依赖的关系。右边的代码直接创建了3个协程,每个协程的执行逻辑都不一样。
有了协程之后,就会涉及到如何管理协程或数据通信的问题。在Java多线程中,线程之间的通信可能会使用锁或者数据结构的方式解决,在协程编程中一般使用的chan的方式管理。
协程是一个用户态的线程,同一时间执行的协程只有一个。这一点和多线程不同,创建出来的多个线程都会并行执行。
左边这段代码是协程编程,它会读取一个全局的数组,当协程1读取数组的时候,协程2其实没有运行,直到协程1遇到IO操作释放了控制权,协程2才会恢复再去读全局变量,这样就完全不用加锁了。
右边是线程编程,可以看到如果程序要读取全局临界资源就一定要加锁,要不断的lock、unlock。
Chan有点类似队列,不过它自带了协程调度能力。
多线程读取队列时,会有生产者和消费者。在队列内存占用过多无法再写入的情况下,生产者还是会持续写入,一般的解决方案是进行盲等,比如让生产者sleep一段时间然后再去写入。在队列无数据可返回的情况下,一种方案是让消费者盲等,CPU死循环去等待,不过这样会占满CPU。一般的方案是在发现无数据返回的时候sleep一段时间,之后再尝试读取。
协程编程中可以通过chan来完成协程调度。当生产者发现容量不足的时候会展示挂起当前协程,直到有消费者拿走一些数据之后才会唤醒这个协程。消费者的读取机制也是一样的,无可用数据时就挂起,一旦生产者push数据后再唤醒。
由于PHP的动态语言特性,所以可以向chan中push任意的PHP变量,无论是对象还是数组。Chan的底层基于引用计数管理,完全没有内存拷贝,除了标量类型是直接复制之外,包括数组、对象这些复杂的数据结构都是用的引用计数管理。像Go语言一样,我们也提供了chan::select用来对多个chan进行读写判读。
协程框架swoft的介绍
Swoft是基于协程实现的web开发框架。它借鉴了spring Cloud做了完全组件化的实现,里面很多功能都是一个小的组件,当然也可以用自定义的组件替换内置的组件。该框架也提供了依赖注入、容器、连接池、AOP,除了应用在web领域之外,还能够用在微服务上。
上面两行命令分别是用来创建swoft工程和引入相关组件。
目前swoft支持3种服务器,swoft-http-srever 、swoft-websocket-server swoft-rpc-server。 第一个用来做主流的web应用程序,第二个是长连接通信服务,最后是微服务领域的RPC服务。
通过命令行脚本能够直接启用以上3种服务,这里也提供了一些常用的脚本工具。
Swoft参考Java的Spring框架,用了很多注解编程的方式。对于Web开发中的URL映射,可以直接通过注解的方式写Route。能够自动将URL映射到当前Controller方法中,URL中的参数也会自动带入类方法中。
基于swoft协程框架进行PHP微服务治理
Swoft自带了一些微服务常用的组件,包括服务注册、熔断、降级、负载均衡、接口多版本等。
Swoft的服务注册与发现是基于Google开源的consul,要使用consul需要添加一些配置,定义服务提供方和接入方的key。然后在前面提到的命令行脚本调用RPC start就会自动将我们的服务器节点注册到consul服务器中。
Swoft的接口声明也是基于注解的方式,如上图所示通过注解定义了service指向的服务以及调用的接口,调用的时候会映射到对应的方法。
swoft的熔断机制中失败超过一定次数,服务就关闭,成功的话,服务重新连接。
这段代码是关于熔断器的调用,首先确定熔断器的名词,正常情况下调用handler,失败的话就调用fallback进行一些处理。
swoft-个基于 Swoole 原生协程的PHP 微服务框架的更多相关文章
- 协程,greenlet原生协程库, gevent库
协程简介 协程(coroutine),又称为微线程,纤程,是一种用户级的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来时,恢复之前保存的上下文 ...
- Python3的原生协程(Async/Await)和Tornado异步非阻塞
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_113 我们知道在程序在执行 IO 密集型任务的时候,程序会因为等待 IO 而阻塞,而协程作为一种用户态的轻量级线程,可以帮我们解决 ...
- Python 原生协程------asyncio
协程 在python3.5以前,写成的实现都是通过生成器的yield from原理实现的, 这样实现的缺点是代码看起来会很乱,于是3.5版本之后python实现了原生的协程,并且引入了async和aw ...
- 小议Python3的原生协程机制
此文已由作者张耕源授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 在最近发布的 Python 3.5 版本中,官方正式引入了 async/await关键字.在 asyncio ...
- 运筹帷幄决胜千里,Python3.10原生协程asyncio工业级真实协程异步消费任务调度实践
我们一直都相信这样一种说法:协程是比多线程更高效的一种并发工作方式,它完全由程序本身所控制,也就是在用户态执行,协程避免了像线程切换那样产生的上下文切换,在性能方面得到了很大的提升.毫无疑问,这是颠扑 ...
- Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现
普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态.而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在Python3.10中,原生协程的实现手 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<下篇>
基于netty轻量的高性能分布式RPC服务框架forest<上篇> 文章已经简单介绍了forest的快速入门,本文旨在介绍forest用户指南. 基本介绍 Forest是一套基于java开 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<上篇>
工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...
- 基于thrift的微服务框架
前一阵开源过一个基于spring-boot的rest微服务框架,今天再来一篇基于thrift的微服务加框,thrift是啥就不多了,大家自行百度或参考我之前介绍thrift的文章, thrift不仅支 ...
- 基于Spring Cloud和Netflix OSS构建微服务,Part 2
在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...
随机推荐
- zk-复制安装
Zookeeper系列一:Zookeeper介绍.Zookeeper安装配置.ZK Shell的使用 一.Zookeeper介绍 1. 介绍Zookeeper之前先来介绍一下分布式 1.1 分 ...
- OCR接口
OCR基础框 import pytesseract from PIL import Image img = Image.open('实际数据1.jpeg') #具体位置截图 image1 = Imag ...
- vue打包添加时间戳,实现更新项目自动清除缓存
本来vue打包会自动用chunkhash来解决缓存问题,但是部分浏览器不会自动更新,因此可以通过后面t=${ }的不同来实现自动重新加载文件,保持最新的界面 (1).webpack打包:修改build ...
- 攻防世界-fileclude
攻防世界的一道文件包含题目 include("文件名"):会将文件中的内容视为代码块接入include所在代码中,输出的只是执行后的结果,文件中的注释.定义等无法查看. 本题中可以 ...
- drush .. drupal console
"You can run both." They compliment each other, yet the final decision is yours. Especiall ...
- CAD坐标显示不全怎么办?CAD坐标常见问题解答!
今天小编来和大家聊一下浩辰CAD看图王中关于CAD坐标的那些事,比如:CAD坐标为何显示不全?CAD坐标显示结果和之前不一样?以及不能精准捕捉CAD坐标等情况,应该如何轻松解决?今天就和小编一起来了解 ...
- Respecting causality is all you need for training physics-informed neural networks
未发表 本篇工作时关于连续时间的PDE.也是从因果关系的角度入手,最近看过几篇该作者的工作.(简而言之就是从初始条件方向开始训练) 目前的PINN框架缺乏尊重物理系统演化所固有的时空因果结构.因此,作 ...
- 2021年RT-Thread开发者大会
Time:2021-12-18,地点:大中华6楼喜来登酒店 主办方: RT-Thread:寓意实时线程,瑞赛德 世界有成千上万个 RTOS(Real-time operating system,实时操 ...
- abap screen页签开发注意事项
问题描述:我比较懒,开发程序的时候所有的页签都是直接公用主程序的按钮功能,这就导致,当我按了按钮之后,SY-UCOMM里保存的是我自建按钮的code, 如果不进行页签跳转,或者按其他按钮的话,直接按下 ...
- 富文本编辑器转word
https://blog.csdn.net/qq_41532872/article/details/108644773