基于 Swoft 协程框架的 PHP 微服务治理

内容来源:2018 年 05 月 27 日,Swoole开源项目创始人韩天峰在“【上海】OSC源创会第75期”进行《基于 Swoft 协程框架的 PHP 微服务治理》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:2928 | 8分钟阅读

摘要

本次演讲将介绍 Swoole 3.0 全新的 PHP 协程编程模式,以及 Swoft 协程框架的使用,基于 Swoft Cloud 提供的各类组件实现 PHP 微服务架构。

嘉宾演讲视频回放及PPT,扫一扫下方二维码,即可报名观看。

基于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进行一些处理。

这里关于微服务的介绍可能比较简要,其实是因为做服务治理更多的还是要用成熟的框架。PHP方面我们推荐使用Tars,这是腾讯开源的微服务治理框架,基于WUP结构定义文件,可以自动生成接口骨架代码,有着完整的服务治理方案,自带发布、运维、监控、弹性伸缩体系。

以上为今天的全部分享内容,谢谢大家!

推荐文章

  • 经历了研发困局、运维之痛,同程微服务从1到1w的旅程
  • 阿里巴巴微服务与配置中心技术实践之道
  • 微服务迁移前,来听听这6个思考和经验

原文发布于微信公众号 - IT大咖说(itdakashuo)

原文发表时间:2018-07-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

【线程池】线程池与工作队列

为什么要用线程池? 诸如 Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。请求以某种方式...

3498
来自专栏青玉伏案

Git版本控制Windows版快速上手

  说到版本控制,之前用过VSS,SVN,Git接触不久,感觉用着还行。写篇博文给大家分享一下使用Git的小经验,让大家对Git快速上手。   说白了Git就是...

1998
来自专栏前端架构与工程

webpack多页面开发与懒加载hash解决方案

本文内容只适用于webpack v1版本,webpack v2已经修复了hash计算规则。 之前讨论了webpack的hash与chunkhash的区别以及各...

2148
来自专栏程序猿DD

云原生应用的12要素

简介 如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或软件即服务(SaaS)。12-Factor 为构建如下的 SaaS 应用提供了方法论: 使用...

36710
来自专栏企鹅号快讯

做网站-推荐3种CSS,JS合并的方式

在Web项目的开发中,js,css文件会随着项目的开发变得越来越多,越来越大,这就给给性能方面带来一些问题,如,页面引入的的js,css越多的话,那么对就增加了...

60611
来自专栏岑玉海

Hbase 学习(一) hbase配置文件同步

最近在狂啃hadoop的书籍,这部《hbase:权威指南》就进入我的视野里面了,啃吧,因为是英文的书籍,有些个人理解不对的地方,欢迎各位拍砖。 HDFS和H...

4356
来自专栏微信公众号:Java团长

Maven那点事儿

毋庸置疑,Jason 也是一个秃顶。James Gosling、Rod Johnson、Gavin King,你们可以告诉我为什么吗?

1003
来自专栏玄魂工作室

Python源码学习笔记(一)编译与安装

--------------------------------------------------------------------------------...

1002
来自专栏FreeBuf

通过Password Vault的XSS漏洞获取用户密码测试

大家好!自我上次写作以来到现在已经有段时间了。今天,我想和大伙分享一些非常有意思的内容。为了存储及管理的方便,相信大家可能都会选择使用一些密码管理器来存储不同网...

983
来自专栏linux驱动个人学习

线程详解

以下内容摘自《程序员的自我修养》 什么是线程? 线程(Thread),有时被称为轻量级(Lightweight Process, LWP),是程序执行流程的最小...

3605

扫码关注云+社区