首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
184 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
32
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-08-31
为什么过早的优化是万恶之源?
为什么过早的优化是万恶之源?缘起Donald Knuth(高德纳) 是一位计算机科学界的著名学者和计算机程序设计的先驱之一。他被誉为 计算机科学的“圣经”《计算机程序设计艺术》的作者 ,提出了著名的“大O符号”来描述算法的时间复杂度和空间复杂度,开发了TeX系统用于排版科技文献,获得过图灵奖、冯·诺伊曼奖、美国国家科学奖章等多项荣誉。今天要说的就是他所提出的一条 软件设计重要原则 Premature optimization is the root of all evil 过早优化是万恶之源。 为什么说“过早优化是万恶之源”?我认为过早优化代码会让人陷入到错误的目标中去,从而忽视掉了最重要的目标。举个很简单的例子, 你需要快速构建一个产品来抢占用户,你当下最重要的目标是让这个产品快速上线 ,而不是把这个产品打造的好用(在中国互联网下,这样的事数不胜数), 如果你只关注到后者体验、性能问题而忽视了速度,在当下高度竞争的市场之下,你根本毫无机会。 当然上面这个例子是从感性的层面说的,对很多程序猿来说也可能涉及不到产品层面的内容。我们从软件设计的层面,理性的来说,过早优化可能会导致以下的一些问题:1. 增加代码的复杂性 :过度优化可能会导致代码的复杂性增加,从而降低代码的可读性和可维护性。如果代码过于复杂,可能会导致开发人员难以理解和维护代码,从而增加开发成本和时间。 2. 耗费开发时间和资源 :过度优化可能会导致开发人员花费大量时间和资源在代码的性能优化上,而忽略了其他重要的开发任务。这可能会导致项目进度延误和开发成本增加。 3. 降低代码的可移植性 :过度优化可能会导致代码的可移植性降低。如果代码过于依赖于特定的硬件或操作系统,可能会导致代码无法在其他环境中运行。 4. 降低代码的可扩展性 :过度优化可能会降低代码的可扩展性。如果代码过于依赖于特定的算法或数据结构,可能会导致代码无法适应未来的需求变化。过早优化的典型案例在软件工程史上由于过度关注软件性能导致项目最终失败的案例比比皆是,比如我下面要说的一些项目,在软件工程史上都是非常知名的项目(当然可能有些新生代程序员已经不知道了)。1. IBM OS/360操作系统 :在20世纪60年代,IBM公司开发了OS/360操作系统,这是当时最大的软件工程项目之一。在开发过程中,IBM公司过于关注代码的性能问题,导致代码的复杂性增加,开发时间延误,最终导致项目的失败。我知晓这个项目还是在我最近在阅读的一本软件工程经典书籍《人月神话》中,也推荐大家阅读下,这个项目虽然最终失败了,但也给整个软件工程领域留下了宝贵的经验。 2. Netscape Navigator浏览器 :在20世纪90年代,Netscape公司开发了Navigator浏览器,这是当时最流行的浏览器之一。在开发过程中,Netscape公司过于关注代码的性能问题,导致代码的复杂性增加,开发时间延误,最终导致浏览器市场份额严重下降。 3. Windows Vista操作系统 :在21世纪初,微软公司开发了Windows Vista操作系统,这是当时最大的软件工程项目之一。在开发过程中,微软公司过于关注代码的性能问题,导致代码的复杂性增加,开发时间延误,最终导致操作系统的用户体验不佳,市场反响不佳。话说这个操作系统我还用过呢,用户界面还是很漂亮的,很多UI设计也被沿用到了Window7中。如何识别过早优化在软件开发过程中,如何判断是否过早优化呢?这里有一些概括性的判断标准,可以简单参考下:1. 是否存在性能问题: 如果代码还没有性能问题,那么过早优化就是不必要的。因此,在进行优化之前,应该先测试代码的性能,确定是否存在性能问题。 2. 是否优化了未来可能发生的问题 :如果优化的是未来可能发生的问题,而不是当前存在的问题,那么就可能是过早优化。在进行优化之前,应该优先考虑当前存在的问题,而不是未来可能发生的问题。 3. 是否牺牲了代码的可读性和可维护性 :如果优化代码会导致代码的复杂性增加,降低代码的可读性和可维护性,那么就可能是过早优化。在进行优化之前,应该优先考虑代码的可读性、可维护性和可扩展性。 4. 是否浪费了大量的开发时间和资源 :如果优化代码会浪费大量的开发时间和资源,而不是提高代码的性能和效率,那么就可能是过早优化。在进行优化之前,应该评估优化的成本和收益,确定是否值得进行优化。判断是否过早优化需要根据具体情况进行评估。 在进行优化之前,应该先测试代码的性能,确定是否存在性能问题。同时,也应该优先考虑代码的可读性、可维护性和可扩展性,避免过度优化。总结作为一名在IT领域摸爬滚打多年的工程师,我深有体会地认识到过早优化是软件开发中的一大陷阱。在软件开发的初期,我们可能会过于关注代码的性能问题,而忽略了代码的可读性、可维护性和可扩展性。这种做法可能会导致代码的复杂性增加,降低代码的可读性和可维护性,甚至可能会浪费大量的开发时间和资源。在软件开发过程中,我们应该避免过早优化,而是优先考虑代码的可读性、可维护性和可扩展性。当需要进行性能优化时,应该在代码的基础上进行优化,通过分析性能瓶颈、优化算法和数据结构等方法来提高代码的性能和效率。同时,我们也应该意识到, 性能优化并不是软件开发的唯一目标,我们还应该注重代码的可读性、可维护性和可扩展性,以便保证代码的质量和可靠性。拓展代码优化的好处多多,但是这并不意味着所有的代码都需要进行优化,有时过度的优化反而适得其反——费时、费力、不讨好。“现代计算机科学的鼻祖”Donald Knuth曾说过“过早的优化是万恶之源”,因为:让正确的程序更快,要比让快速的程序正确容易得多。在项目开发中,总是有程序员浪费宝贵的时间去改进那些不需要改进的代码,而没有通过所做的改进增加价值。在对项目进行优化时,究竟哪些地方应该优化,应该如何优化,哪些不应该优化呢?你需要先来了解一下本文所说的这7件事。1. 究竟要优化什么?在优化工作开始的时候,你还尚未明确优化内容和目的,那么你很容易陷入误区。在一开始,你就应该清楚地了解你要达到的效果,以及其他优化相关的各种问题。这些目标需要明确指出(至少精通技术的项目经理可以理解和表达它),接下来,在整个优化过程中,你需要坚持这些目标。在实际的项目开发中,经常会存在各种各样的变数。可能一开始时要优化这一方面,随后你可能会发现需要优化另一方面。这种情况下,你需要清晰地了解这些变化,并确保团队中的每个人都明白目标已经发生了变化。2. 选择一个正确的优化指标选择正确的指标,是优化的一个重要组成部分,你需要按照这些指标来测量优化工作的进展情况。如果指标选择不恰当,或者完全错误,你所做的努力有可能白费了。即使指标正确,也必须有一些辨别。在某些情况下,将最多的努力投入到运行消耗时间最多的那部分代码中,这是实用的策略。但也要记住,Unix/Linux内核的大部分时间花费在了空循环上。需要注意的是,如果你轻易选择了一个很容易达到的指标,这作用不大,因为没有真正解决问题。你有必要选择一个更复杂的、更接近你的目标的指标。3. 优化在刀刃上这是有效优化的关键。找到项目中与你的目标(性能、资源或其他)相背的地方,并将你的努力和时间用在那里。举一个典型的例子,一个Web项目速度比较慢,开发者在优化时将大部分精力放在了数据库优化上,最终发现真正的问题是网络连接慢。另外,不要分心于容易实现的问题。这些问题尽管很容易解决,但可能不是必要的,或与你的目标不相符。容易优化并不意味着值得你花费工夫。4. 优化层次越高越好在一般情况下,优化的层次越高,就会越有效。根据这个标准,最好的优化是找到一个更有效的算法。举个例子,在一个软件开发项目中,有一个重要的应用程序性能较差,于是开发团队开始着手优化,但性能并没有提升太多,之后,项目人员交替,新的开发人员在检查代码时发现,性能问题的核心是由于在表中使用了冒泡排序算法,导致成千上万项的增加。尽管如此,高层次的优化也不是“银弹”。一些基本技术,如将所有东西移到循环语句外,也可以产生一些优化的效果。通常情况下,大量低层次的优化可以产生等同于一个高层次优化的效果。还需要注意的是,高层次优化,会减少一些代码块,那么你之前对这些代码块所做的优化就没有任何意义了,因此,刚开始就应该考虑高层次的优化。5. 不要过早优化在项目早期就进行优化,会导致你的代码难以阅读,或者会影响运行。另一方面,在项目后期,你可能会发现之前所做的优化没有起到任何作用,白白浪费了时间和精力。正确的方式是,你应该将项目开发和优化当作两个独立的步骤来做。6. 依赖性能分析,而不是直觉你往往会认为你已经知道哪里需要优化,这是不可取的,尤其是在复杂的软件系统中,性能分析数据应该是第一位的,最后才是直觉。优化的一个有效的策略是,你要根据所做工作对优化效果的影响来进行排序。在开始工作之前找到影响最大的“路障”,然后再处理小的“路障”。7. 优化不是万金油优化最重要的规则之一是,你无法优化一切,甚至无法同时优化两个问题。比如,优化了速度,可能会增加资源利用;优化了存储的利用率,可能会使其他地方放慢。你需要权衡一下,哪个更符合你的优化目标。
2023年08月31日
28 阅读
0 评论
0 点赞
2023-08-30
TCP的三次握手四次挥手
TCP的三次握手四次挥手
2023年08月30日
10 阅读
0 评论
0 点赞
2023-08-30
基础科普!大白话详解HTTPS
基础科普!大白话详解HTTPS
2023年08月30日
10 阅读
0 评论
0 点赞
2023-08-30
高可用的一些解决方案
高可用的一些解决方案后台服务可以划分为两类,有状态和无状态。高可用对于无状态的应用来说是比较简单的,无状态的应用,只需要通过F5或者任何代理的方式就可以很好的解决。后文描述的主要是针对有状态的服务进行分析。服务端进行状态维护主要是通过磁盘或内存进行保存,比如MySQL数据库,redis等内存数据库。除了这两种类型的维护方式,还有jvm的内存的状态维持,但jvm的状态生命周期通常很短。高可用的一些解决方案高可用,从发展来看,大致经过了这几个过程:冷备双机热备同城双活异地双活异地多活在聊异地多活的时候,还是先看一些其他的方案,这有利于我们理解很多设计的缘由。冷备冷备,通过停止数据库对外服务的能力,通过文件拷贝的方式将数据快速进行备份归档的操作方式。简而言之,冷备,就是复制粘贴,在linux上通过cp命令就可以很快完成。可以通过人为操作,或者定时脚本进行。有如下好处:简单快速备份(相对于其他备份方式)快速恢复。只需要将备份文件拷贝回工作目录即完成恢复过程(亦或者修改数据库的配置,直接将备份的目录修改为数据库工作目录)。更甚,通过两次mv命令就可瞬间完成恢复。可以按照时间点恢复。比如,几天前发生的拼多多优惠券漏洞被人刷掉很多钱,可以根据前一个时间点进行还原,“挽回损失”。以上的好处,对于以前的软件来说,是很好的方式。但是对于现如今的很多场景,已经不好用了,因为:服务需要停机。n个9肯定无法做到了。然后,以前我们的停机冷备是在凌晨没有人使用的时候进行,但是现在很多的互联网应用已经是面向全球了,所以,任何时候都是有人在使用的。数据丢失。如果不采取措施,那么在完成了数据恢复后,备份时间点到还原时间内的数据会丢失。传统的做法,是冷备还原以后,通过数据库日志手动恢复数据。比如通过redo日志,更甚者,我还曾经通过业务日志去手动回放请求恢复数据。恢复是极大的体力活,错误率高,恢复时间长。冷备是全量备份。全量备份会造成磁盘空间浪费,以及容量不足的问题,只能通过将备份拷贝到其他移动设备上解决。所以,整个备份过程的时间其实更长了。想象一下每天拷贝几个T的数据到移动硬盘上,需要多少移动硬盘和时间。并且,全量备份是无法定制化的,比如只备份某一些表,是无法做到的。如何权衡冷备的利弊,是每个业务需要考虑的。双机热备热备,和冷备比起来,主要的差别是不用停机,一边备份一边提供服务。但还原的时候还是需要停机的。由于我们讨论的是和存储相关的,所以不将共享磁盘的方式看作双机热备。Active/Standby模式相当于1主1从,主节点对外提供服务,从节点作为backup。通过一些手段将数据从主节点同步到从节点,当故障发生时,将从节点设置为工作节点。数据同步的方式可以是偏软件层面,也可以是偏硬件层面的。偏软件层面的,比如mysql的master/slave方式,通过同步binlog的方式;sqlserver的订阅复制方式。偏硬件层面,通过扇区和磁盘的拦截等镜像技术,将数据拷贝到另外的磁盘。偏硬件的方式,也被叫做数据级灾备;偏软件的,被叫做应用级灾备。后文谈得更多的是应用级灾备。双机互备本质上还是Active/Standby,只是互为主从而已。双机互备并不能工作于同一个业务,只是在服务器角度来看,更好的压榨了可用的资源。比如,两个业务分别有库A和B,通过两个机器P和Q进行部署。那么对于A业务,P主Q从,对于B业务,Q主P从。整体上看起来是两个机器互为主备。这种架构下,读写分离是很好的,单写多读,减少冲突又提高了效率。其他的高可用方案还可以参考各类数据库的多种部署模式,比如mysql的主从、双主多从、MHA;redis的主从,哨兵,cluster等等。同城双活前面讲到的几种方案,基本都是在一个局域网内进行的。业务发展到后面,有了同城多活的方案。和前面比起来,不信任的粒度从机器转为了机房。这种方案可以解决某个IDC机房整体挂掉的情况(停电,断网等)。同城双活其实和前文提到的双机热备没有本质的区别,只是“距离”更远了,基本上还是一样(同城专线网速还是很快的)。双机热备提供了灾备能力,双机互备避免了过多的资源浪费。在程序代码的辅助下,有的业务还可以做到真正的双活,即同一个业务,双主,同时提供读写,只要处理好冲突的问题即可。需要注意的是,并不是所有的业务都能做到。业界更多采用的是两地三中心的做法。远端的备份机房能更大的提供灾备能力,能更好的抵抗地震,恐袭等情况。双活的机器必须部署到同城,距离更远的城市作为灾备机房。灾备机房是不对外提供服务的,只作为备份使用,发生故障了才切流量到灾备机房;或者是只作为数据备份。原因主要在于:距离太远,网络延迟太大。如上图,用户流量通过负载均衡,将服务A的流量发送到IDC1,服务器集A;将服务B的流量发送到IDC2,服务器B;同时,服务器集a和b分别从A和B进行同城专线的数据同步,并且通过长距离的异地专线往IDC3进行同步。当任何一个IDC当机时,将所有流量切到同城的另一个IDC机房,完成了failover。当城市1发生大面积故障时,比如发生地震导致IDC1和2同时停止工作,则数据在IDC3得以保全。同时,如果负载均衡仍然有效,也可以将流量全部转发到IDC3中。不过,此时IDC3机房的距离非常远,网络延迟变得很严重,通常用户的体验的会受到严重影响的。上图是一种基于Master-Slave模式的两地三中心示意图。城市1中的两个机房作为1主1从,异地机房作为从。也可以采用同城双主+keepalived+vip的方式,或者MHA的方式进行failover。但城市2不能(最好不要)被选择为Master。异地双活同城双活可以应对大部分的灾备情况,但是碰到大面积停电,或者自然灾害的时候,服务依然会中断。对上面的两地三中心进行改造,在异地也部署前端入口节点和应用,在城市1停止服务后将流量切到城市2,可以在降低用户体验的情况下,进行降级。但用户的体验下降程度非常大。所以大多数的互联网公司采用了异地双活的方案。上图是一个简单的异地双活的示意图。流量经过LB后分发到两个城市的服务器集群中,服务器集群只连接本地的数据库集群,只有当本地的所有数据库集群均不能访问,才failover到异地的数据库集群中。在这种方式下,由于异地网络问题,双向同步需要花费更多的时间。更长的同步时间将会导致更加严重的吞吐量下降,或者出现数据冲突的情况。吞吐量和冲突是两个对立的问题,你需要在其中进行权衡。例如,为了解决冲突,引入分布式锁/分布式事务;为了解决达到更高的吞吐量,利用中间状态、错误重试等手段,达到最终一致性;降低冲突,将数据进行恰当的sharding,尽可能在一个节点中完成整个事务。对于一些无法接受最终一致性的业务,饿了么采用的是下图的方式:对于个别一致性要求很高的应用,我们提供了一种强一致的方案(Global Zone),Globa Zone是一种跨机房的读写分离机制,所有的写操作被定向到一个 Master 机房进行,以保证一致性,读操作可以在每个机房的 Slave库执行,也可以 bind 到 Master 机房进行,这一切都基于我们的数据库访问层(DAL)完成,业务基本无感知。也就是说,在这个区域是不能进行双活的。采用主从而不是双写,自然解决了冲突的问题。实际上,异地双活和异地多活已经很像了,双活的结构更为简单,所以在程序架构上不用做过多的考虑,只需要做传统的限流,failover等操作即可。但其实双活只是一个临时的步骤,最终的目的是切换到多活。因为双活除了有数据冲突上的问题意外,还无法进行横向扩展。异地多活根据异地双活的思路,我们可以画出异地多活的一种示意图。每个节点的出度和入度都是4,在这种情况下,任何节点下线都不会对业务有影响。但是,考虑到距离的问题,一次写操作将带来更大的时间开销。时间开销除了影响用户体验以外,还带来了更多的数据冲突。在严重的数据冲突下,使用分布式锁的代价也更大。这将导致系统的复杂度上升,吞吐量下降。所以上图的方案是无法使用的。回忆一下我们在解决网状网络拓扑的时候是怎么优化的?引入中间节点,将网状改为星状:改造为上图后,每个城市下线都不会对数据造成影响。对于原有请求城市的流量,会被重新LoadBalance到新的节点(最好是LB到最近的城市)。为了解决数据安全的问题,我们只需要针对中心节点进行处理即可。但是这样,对于中心城市的要求,比其他城市会更高。比如恢复速度,备份完整性等,这里暂时不展开。我们先假定中心是完全安全的。如果我们已经将异地多活的业务部署为上图的结构,很大程度解决了数据到处同步的问题,不过依然会存在大量的冲突,冲突的情况可以简单认为和双活差不多。那么还有没有更好的方式呢?回顾一下前文提到的饿了么的GlobalZone方案,总体思路就是“去分布式”,也就是说将写的业务放到一个节点的(同城)机器上。阿里是这么思考的:实际上我猜测很多业务也是按照上图去实现的,比如滴滴打车业务这种,所有的业务都是按城市划分开的。用户、车主、目的地,他们的经纬度通常都是在同一个城市的。单个数据中心并不需要和其他数据中心进行数据交互,只有在统计出报表的时候才需要,但报表是不太注重实时性的。那么,在这种情况下,全国的业务其实可以被很好的sharding的。但是对于电商这种复杂的场景和业务,按照前文说的方式进行sharding已经无法满足需求了。因为业务线非常复杂,数据依赖也非常复杂,每个数据中心相互进行数据同步的情况无可避免。淘宝的解决方式和我们切分微服务的方式有点类似:注意看图中的数据同步箭头。以交易单元为例,属于交易单元的业务数据,将与中心单元进行双向同步;不属于交易单元的业务数据,单向从中心单元同步。中心单元承担了最复杂的业务场景,业务单元承担了相对单一的场景。对于业务单元,可以进行弹性伸缩和容灾;对于中心单元,扩展能力较差,稳定性要求更高。可以遇见,大部分的故障都会出现在中心单元。按照业务进行单元切分,已经需要对代码和架构进行彻底的改造了(可能这也是为什么阿里要先从双活再切到多活,历时3年)。比如,业务拆分,依赖拆分,网状改星状,分布式事务,缓存失效等。除了对于编码的要求很高以外,对测试和运维也有非常大的挑战。如此复杂的情况,如何进行自动化覆盖,如何进行演练,如何改造流水线。这种级别的灾备,不是一般公司敢做的,投入产出也不成正比。不过还是可以把这种场景当作我们的“假想敌”,去思考我们自己的业务,未来会怎么发展,需要做到什么级别的灾备。相对而言,饿了么的多活方案可能更适合大多数的企业。本文只是通过画图的方式进行了简单的描述,其实异地多活是需要很多很强大的基础能力的。比如,数据传输,数据校验,数据操作层(简化客户端控制写和同步的过程)等。
2023年08月30日
9 阅读
0 评论
0 点赞
2023-08-30
PHP 微服务开发框架
PHP 微服务开发框架从近年来的业界架构演进来看,微服务已经逐渐成为趋势。伴随着微服务架构的这种快速发展节奏,各种开发语言各种类型的微服务开发框架相继出现,据各家使用微服务框架的情况,可以看到主要分为四种模式:无服务治理类:gRPC、brpc 为代表单语言带服务治理类:Dubbo、Spring Cloud 为代表,主要适用于 Java 语言多语言带服务治理类:TARSService Mesh:SideCar 模式,仍在发展成熟期目前PHP相关的微服务框架不多,基本上都是基于Swoole开发, 下面介绍几种网络上信息相对较多的几款PHP微服务开发框架。腾讯TarsTars是基于名字服务使用Tars协议的高性能RPC开发框架,同时配套一体化的服务治理平台,帮助个人或者企业快速的以微服务的方式构建自己稳定可靠的分布式应用。官网:https://tars.tencent.com/base/tars_index/cn/index.html项目地址:https://gitee.com/TarsCloud/TarsPHP产品介绍:https://www.oschina.net/news/108987/tars-php-the-roadPHP-msfPHP-msf是Camera360社区服务器端团队基于Swoole自主研发现代化的PHP协程服务框架,是Swoole的工程级企业应用框架,经受了Camera360自拍相机亿级用户高并发大流量的考验。产品说明:https://www.oschina.net/p/php-msf项目地址:https://github.com/pinguo/php-msf-docsSwoftSwoft是基于swoole协程2.x的高性能PHP微服务框架,内置http服务器。框架全协程实现,性能优于传统的php-fpm模式。官网:https://www.swoft.org/文档:https://www.swoft.org/docs项目地址:https://github.com/swoft-cloud/swoftHyperfHyperf是基于 Swoole 4.4+ 实现的高性能、高灵活性的PHP协程框架,内置协程服务器及大量常用的组件,性能较传统基于PHP-FPM的框架有质的提升。框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还提供了协程版的 Eloquent ORM、WebSocket 服务端及客户端、JSON RPC 服务端及客户端、GRPC 服务端及客户端、Zipkin/Jaeger (OpenTracing) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、Apollo 配置中心、阿里云 ACM 应用配置管理、ETCD 配置中心、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成、Swoole Tracker、Blade 和 Smarty 视图引擎、Snowflake 全局ID生成器 等组件,省去了自己实现对应协程版本的麻烦。官网:https://www.hyperf.io/文档:https://doc.hyperf.io项目地址:https://github.com/hyperf-cloud/hyperf其他语言 15 种微服务架构框架
2023年08月30日
16 阅读
0 评论
0 点赞
1
...
38
39
40
...
112