刚才百度了一下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 微服务框架的更多相关文章

  1. 协程,greenlet原生协程库, gevent库

    协程简介 协程(coroutine),又称为微线程,纤程,是一种用户级的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来时,恢复之前保存的上下文 ...

  2. Python3的原生协程(Async/Await)和Tornado异步非阻塞

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_113 我们知道在程序在执行 IO 密集型任务的时候,程序会因为等待 IO 而阻塞,而协程作为一种用户态的轻量级线程,可以帮我们解决 ...

  3. Python 原生协程------asyncio

    协程 在python3.5以前,写成的实现都是通过生成器的yield from原理实现的, 这样实现的缺点是代码看起来会很乱,于是3.5版本之后python实现了原生的协程,并且引入了async和aw ...

  4. 小议Python3的原生协程机制

    此文已由作者张耕源授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 在最近发布的 Python 3.5 版本中,官方正式引入了 async/await关键字.在 asyncio ...

  5. 运筹帷幄决胜千里,Python3.10原生协程asyncio工业级真实协程异步消费任务调度实践

    我们一直都相信这样一种说法:协程是比多线程更高效的一种并发工作方式,它完全由程序本身所控制,也就是在用户态执行,协程避免了像线程切换那样产生的上下文切换,在性能方面得到了很大的提升.毫无疑问,这是颠扑 ...

  6. Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现

    普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态.而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在Python3.10中,原生协程的实现手 ...

  7. 基于netty轻量的高性能分布式RPC服务框架forest<下篇>

    基于netty轻量的高性能分布式RPC服务框架forest<上篇> 文章已经简单介绍了forest的快速入门,本文旨在介绍forest用户指南. 基本介绍 Forest是一套基于java开 ...

  8. 基于netty轻量的高性能分布式RPC服务框架forest<上篇>

    工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...

  9. 基于thrift的微服务框架

    前一阵开源过一个基于spring-boot的rest微服务框架,今天再来一篇基于thrift的微服务加框,thrift是啥就不多了,大家自行百度或参考我之前介绍thrift的文章, thrift不仅支 ...

  10. 基于Spring Cloud和Netflix OSS构建微服务,Part 2

    在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...

随机推荐

  1. 戴尔n4110在win7下无法使用virtualbox的解决方法(应该对win7都有用)

    正文 因为已经学了一段时间的汇编了嘛,想着就拿单独一台机器出来学汇编好了,刚好趁着天气降温回学校拿被子的机会把笔记本也拿出来了,然后我装上了virtual box,把编译好的文件写到虚拟盘中,打开就直 ...

  2. python学习:窗口程序

    https://www.cnblogs.com/zyg123/p/10385456.html # 导入tkinter模块 import tkinter # 创建画布需要的库 from matplotl ...

  3. Excel比较两列是否相等

    通常的方式: 先将两列排序 通过判定如 =A1=B1 或者ctrl + \ (mac 是 command) 可以定位到差异的那行

  4. 所谓的安装phpmyadmin

    所谓的安装phpmyadmin, 或者 安装drush, 都是下载一个文件, 然后URL访问或者命令行访问这个文件, 进入到某个页面或者获得某个结果.刚开始觉得很神秘哦, 为什么?--安装软件分两种1 ...

  5. nacos 1.4.2 建立集群,公司启动linux服务器常用命令

    2022-7-29 编写micro自动处理脚本,并加入了守护精灵进程 先启动prop1 服务器(xx.1xx.165.186) 再启动prop2服务器 (xx.1xx.174.173) ####### ...

  6. [*]Quadratic Residual Networks: A New Class of Neural Networks for Solving Forward and Inverse Problems in Physics Involving PDEs

    Accepted by SIAM International Conference on Data Mining (SDM21) 本文提出了二次残差网络,通过在应用激活函数之前,添加二次残差项到输入的 ...

  7. entity framework “XXXXX”的“XXXXX”属性不能设置为“null”值

    "T_LICENSE"的"LICENSEFIRSTDATE"属性不能设置为"null"值.必须将该属性设置为类型为"System. ...

  8. 关于pytorch一些基础知识的备份

    压缩conda环境用于备份目的实际上没有意义,因为还有其他方法可以做到这一点,这可能更合适,并使用专为此而设计的内置功能. 您可以创建一个环境.txt版本conda,详细说明其中的每个模块和版本,然后 ...

  9. msyql查询各部门性别人数,如果某个部门没有男生或女生则用0代替

    根据部门或者班级查询男女各多少人,可以直接使用: select org_code as orgCode, sex, count(*) as totalCount from blade_student ...

  10. 自定义jar包供ERP使用

    功能要求:需要在ERP中调用其他web服务或者自身web服务(比如跨账套过账等) 1.编写java程序,并将程序打包成jar包 import org.apache.http.HttpEntity; i ...