Puma 的实现非常简单优雅。比我想象的简单很多,我应该会尝试下如何结合 Puma 和 LightIO 以取得更好的性能(也因为懒得为 LightIO 单独再写个服务器了)。
你为什么不告诉我 LightIO 然后我可以把我的 amber-kit 试着使用你的什么鬼 LIO 嘛,这样你可以专心写你的 LIO,我专心写 Amber-kit
不过,我可能更倾向于使用 system IO API,或者 Thread::Green
Docker / Vagrant 完全没问题,现在就在用,不过我更喜欢用 Vagrant,因为我主要在 macOS 上做开发。Windows 的话我也会用 Vagrant。
反正体验比较流畅,Windows 字体渲染也挺细腻的,有它特有的风味,share 一个文件夹作为 workspace 即可。
如果作为部署环境的话,Windows Server + IIS + Vagrant / Docker 也行。
Docker 在 Linux 作为云部署比较好,很多只要支持 Docker 镜像的主机平台都可以 docker image 直接搬。
我开发一般采用双平台:
Windows
Linux
macOS
在 Windows 下面,除了兴趣的 Win64 程序(包括桌面端、控制台)会用 Ruby Installer 之外,其它所有开发都用 Vagrant,作为主要开发环境。
在 Linux 下,rvm 就够了,Vagrant / Docker 作为测试和生产环境。
在 macOS 环境和 Linux 情况基本一致。
我不是来比较 Vagrant 和 Docker 的,不引战。
你不知道 lts 系列是有软件包升级吗?内核会有更新
你说的情况,我也是在 Darwin 碰到过。。。不过不是 IO API。而是 inet 部分的,这个很正常,Linux 内核本身就不是完美的,要不然 ubuntu 就不会有 LTS 长期维护保证持续 fix,macOS 其实升级也会更新 command line 还有 XNU。
遇到这种问题,每次都找 Core Team report。嘛,嘛,自己 fix 不太现实。
使用 lib 确实好解决平台问题,比如 boost::asio。自己写是遇见这种问题的。
我不管怎么封装,反正都一个目的,都是把事件异步的系统调用,what about iocp with Win64?
你在 Thread::Green 里看到的 select 也不是真正的 select,而是在 iom.h 里对 select epoll 和 kqueue 进行统一封装后的 API。
这是废话,GCD 的 libdispatch 也说自己是 kqueue 封装后的 API……
其实我很好奇的是,我看你们研究不同的 IO lib 跟玩玩具一样的。。。为什么不直接用系统 API?
我又不打算混在一起讨论~
其实我的回复只是告诉 #7 其实 rails 并没有被 IO 卡,puma 的异步处理还是很优秀的。
希望 mjit 能在 rails 这块庞大的 monolith 发挥作用,随着 SPA 开发模型、前端独立岗位的出现,还是亟需的。
等待数据库处理的时间是数据库本身的问题了,不属于 Ruby 管的范围,你们写 Rails 难不成:
class xxxController
def xxx
@data
Thread.new { // 数据库 -> @data }
end
end
你确定 View 能渲染出 @data 的内容,你确定渲染的时候 数据库已经读完了?
好,如果你 join 是吧,你可以让这次 puma task processor 的线程等待你执行完毕,但是,这就同步了呀
难不成在一次 html page request(Socket connection)中(也就是非 Ajax),你能告诉我怎么能先 write html content 给浏览器(就是 View)再等数据库异步回调再 write 数据的方式吗?
你误解了我的意思。。。我说的不是 Web 响应时间,我说的是网络通讯
为什么 Thin 在 Basic 的时候碾压其他 Server,因为它 I/O 异步了。为什么 View 和 DB 又变差了呢?因为读取模板和查询数据库是同步的。
你给出来的数据这很明显,Web 框架帮你找到路径之后调用你的业务逻辑肯定会有 View 渲染和 DB 调用,你看看 View 和 View + DB 的差异并不大,说明 DB IO 效率高了去了。
服务器做的事情,是把 数据 read,然后交给单个 task 线程去处理对应的路径反射你的 Controller 渲染你的 View(太长不写)。你看没有 View 效率多高,最差的情况拖了 6x。让一个性能很好的 Thin 拖得只剩下跟其它一样的水平。
异步不异步是另外的一个问题,服务器本身 schedule socket queue 是可以异步的。
但是你一个 Controller 作的事情比如你写了:
难不成你把 Controller 这三件事情分别异步成三个线程,甚至然后做完了再通知去让服务器 response 吗?像移动客户端有些 lib 设置了超时,等你异步做完这些事情,再 write 我客户端估计都已经 close 了。
先不讨论异步,Webrick 的 parse 是 Ruby 写的,比如 WEBrick::HTTPUtils::FormData
拿 Ruby 讨论 IO 就是耍流氓
如果你说用 Go / C++ 在流处理的时候碰到瓶颈,还是值得讨论的。
2018.3.29 更新:
但是只关注 I/O 会限制 Ruby 在 Web 服务器以外别的领域的发展
这一点是认可的,这是在开发通用编程语言,不是开发针对性的工具。
Ruby 就算没有 JIT,跑得比 C++ / Go 慢,也是值得用的,因为至少这样的工具好用而且编码也舒服,良好的 Ruby idiom 和 style 也是很好维护,无需编译,写起来也先行轻松。
首先,服务器都是开辟/派遣一个 thread 你的一次 action 的,要不就是 process,抢占任务都一个样,等待数据库那是远程调用的事,而且 MySQL 的组件是 C Extension。
如果不是 Ruby parse 数据包(无论 HTTP 还是 ws 还是别的)太慢你会换成 C 来 parse,Ruby parse 数据包带来的延迟的速度比跟客户端 IO 影响得还要高。
另外,服务器的 Ruby IO 的问题个人认为是 Ruby String 类 效率问题,你从流读取会把 buffer 读入里面,但是换做 C char 作 buffer cpy 处理,效率完全不一样。
读了一下 Thread::Green 的代码,其实 FD 通信,本身就是 blocking 的。。。比如 select 就是个阻塞调用,阻塞的地方在这个调用本身。
GCD 本质确实是 blocking 的没毛病
RPC 不要拿出来说,分布式就有一个 RPC 一粒粒组件之间调用带来的延时问题。
刚好相反,rails 太臃肿了,IO 开销实际上是很小的一部分,服务器真正做的部分只有通过调度、读 request、写 respose。
而你的 HTTP parsing、业务处理(rails 本身有大量的对象映射、抽象、创建和销毁等等)才是最大的问题。这些属于计算密集问题。
mjit 在类型明确一些的 block 是更容易被 jit 编译的,但像 AR(Active Record) 则不然,一层层的抽象几乎不尽相同的数据,动态的元编程动态嵌入方法和属性,阻碍了 old gen code 的形成。
话说这个实现也糙了一点。。。把 hot block 找出来然后 C 化然后 compile 而且还放在 /tmp。重点是,这样一来就依赖 gcc / clang 了。
我期待的好像不是这样的,有点失望。我期待它能本身提供编译的功能,就是 ruby file.rb 就已经能从 YARV -> 机器码,而不依赖外部工具。不过,实现到那样的 level,估计 Rubinius 会便利一些,后端天然的有 LLVM 垫背。
如果 MJIT 实现了即时 YARV -> Native Code 即时存储到内存空间预备即时调用,我觉得它干脆做成下一个 LLVM 了。
对客户端作用大一些吧,对于服务端做同步这种事情。。。你让服务器去做长时间等待异步同步,那是在消耗服务端资源。
我想表达的意思是。
关注点有问题,我刚才说的 绕开 GIL 实现并行,实际上是我用 Autumn 的 select 换成了 epoll 加入到 amber-kit 的实验途中,在对象创建关联上是有问题,经过多番调整,后来是通过了,但是,我发现 epoll 写的 iom 只是 IO 本身高效,但是,实际上你写一个 HTTP SV,或者 FTP SV,你都要 parse 协议的,Ruby parsing 效率很低,好,接着咱们换成 C 来实现了 parsing,这就是我上年回复姜叔叔说我把玩具的 协议 parsing 改成了 C extension 去 parse,当前我未释出的 amber-kit 版本达到了 10k+ req / s。
其实在我做那个试验时候,你的 em-midori 还没加 C HTTP parser 进去,后来我看到你加进去了。
虽然提高了效率,但是实际上问题还在后头,你有业务逻辑代码。
你写这些东西,终究是为了业务服务的,就像你写网站,终究是为了开网站,开网站有内容,有内容的话数据量会越来越大。
经过后面 bench,Ruby obj_a -- call -> obj_b -- call -> obj_c 还有 obj_a new obj_b new obj_c 所消耗的时间,远远比我上面说的写的东西耗时要多了去了。
更何况 Web develop 不像做 OJ 竞赛,没那么垂直和单纯与纯粹,你可以把算法优化到极限不管团队其他人能不能看懂。
GCD 是对于线程的封装没错,而对于 Thread::Green 这个新事物的观点我的评价是【听起来就像是】,这是我感兴趣、疑问的意思,我不太清楚 Ruby 这边发明这玩意来干嘛。
MJIT 解决的问题和 AutoFiber(Thread::Green) 解决的不是一个问题 那跟我说的也不是一回事。
我的观点是,Ruby 与其发明这些 IO 优化的玩意,不如解决计算上优化。
IO 是有瓶颈的,就算你解决了并发,非阻塞,实际上计算性能还是差得老远的情况下,你 Ruby 代码连磁盘 IO 都跑不赢,很可能你刷新一个网页,IO 就那么点东西,但是逻辑就已经够你处理半天了。
我想,Thread::Green 实现的是不用陷入内核态的轻量级调度,解决的是 类似于 Promise,RxJava 那种异步同步的问题吧。这样的话,跟 GCD 也没什么区别,GCD 很大一部分用例就是把线程异步回调同步起来。
另外,GCD - libdispatch 也是类似实现的,效率超高,不过,我輩认为,Ruby MJIT 还没上呢,而且 GIL 没彻底解决之前,没什么好兴奋的。
听起来就像是当初困扰我的【打算用 C 线程和 Ruby 对象关联,想绕开 GIL 实现并行,但是由于 GC leak 又串不到一起】的问题,有人出来解决了。
按照这么说,主流操作系统都是 blocking 的,每秒处理的指令集就那么多,而且核心都是数得出来的。
后续 non-block 都是抽象的,无论 批处理还是分时还是其它。
真正面对的问题是:找到问题对应最高效的解决方式。
那个是 ActiveSupport::Memoizable 的拆分版
其实占用内存还并不是最优解,也没有解决问题而是绕开了问题,以前有一个 256M 内存的机器,没挂 swap 的情况下 cpan 一下,在 extract 索引包的时候就炸了,OOM 错误。
真正要解决本质问题,我觉得要么就从 Ruby 更高效的调用方法去写,比如 for in / times 改成 while,还有对象避免 GC 对象复用。要么干脆 C 去用扩展来实现,至少可预算大 O 复杂度,虽然不如汇编能看出来跑了几个指令。
文章的思路算是 Go extension 了
但是你都这么来实现了,为什么项目一开始就不去用 Go 来写呢?
提一个题外话,用动态的系统(这里指比如 RubyVM)去写一些需要持久运行的东西(比如 server),一来行为不好确定(未来后天行为变了呢),二来出 bug 了要动态反查,如果要把 Perl / PHP 加入讨论,那更恶心了,我读了 Perl DBI / DBM 部分的源码,那真心是狗呕一样的一坨,self“内置”了很多东西,正如 PHP CI 框架 $this 隐晦了 class_loader,很多东西变得隐晦、不可预测,几乎只有写代码的那个人,自己才清楚这个模块结构是怎样的。
但是,动态虽绕开了“显”问题带来了“隐”问题,但总不可能让你把方案都完全确定了再写代码。如果用静态的系统去实现一些方案不确定的东西(姑且称为“隐”问题),有很多方案上需要细化动态处理的东西,你需要拿静态去模拟和抽象,静态的系统会被这些尚未探索明确的问题卡住,而且调整起来也很困难除非足够人手(带来的人力成本)。
我輩只是想说,这种事情其实是矛盾的,只能说各有千秋。
很多 Cpp 程序猿,可能后续会把 lua 学了以便自己在某些开发上能减轻负担。很多脚本程序猿,可能后续会把 C 学了写扩展,一个道理。Java 这种有商业公司养得白白胖胖的可以另外说(不过最近鉴于 Oracle 的事情,有点不好说了)。
光吃零食,肚子还是饿,可能还是会吃点正餐填一下肚子的。光吃正餐,嘴巴有点馋,可能还是会吃一点零食满足嘴馋。爱怎么吃怎么吃。
觉得 Ruby 薯片吃不饱,想把 Go 饭团搅进去充饥也是没问题的。
前不久买了英文版,啃得慢,上班忙,放一边了。中文版现在终于有了,求书
他们跟你说的是两码事,其实我在 OJ 的时候发现了这些问题,用 for in 跟 while 完全性能是两码事,原因具体看红放大镜书里面有解释,while 效率是比较高的。
他们用 times 的方式处理,a, b 是不会再在一个堆栈继续创建对象的,而你的 fib(n) 里面的 n 是继续创建对象的。在 Perl 入门经典那本书,就建议用 Memoize.pm 模块优化,消耗内存换性能,个人观点其实也就是预 malloc。Rubygems 里面也有 Memoize gem,可以搜搜看。
怎么说呢,这个其实不是脚本语言和编译型语言的区别的问题,但是如果不打算非常认知到底什么原因,然而这样理解暂时也不是问题,也没毛病。
这个应该是 C++ / Go 这种接近 Raw 处理的语言处理东西的方式的区别,Ruby 一个 for in 其实代入了一个 block 到 each,然后每个对象创建产生了大量的系统调用,本来 Ruby 创建对象就有大量的调用过程、还有方法调用也是耗时的事情,还有 GC 比起 Go 的内存管理差很远的,区别就在这里。
C++ 写一个算法,大概 O 几 基本上内心都有个数,但是 Ruby / Python 实际上掺和了 Object 的一些调用,一些语法也具有隐式处理。
所以本质上是没有可比性的,要说服的话,你应该找那种 Go / C++ 和 Ruby 在调用上用了几个指令接近的方式,但是我只能说,不太可能,我看了 Go 的源码,底层很多实现感觉几乎是拿着 Intel / AMD 处理器的文档对着优化过的。。。
详看它的运行时 https://github.com/golang/go/tree/master/src/runtime
赞同!!!一年前看过 tk 你的前端开发工作栈,然后就开始过一段时间 SPA 的修行,我把公司的系统做成了前端独立的全栈应用。其实也就是上文说的那种
实际上 SPA 根本没办法照顾 SEO,另外 React 也是因为考虑到整体化全栈方案其实很不靠谱所以更好的方案是 Components 组合而不是像 ExtJS 整块下来。
同构的方案不是小公司随便拿来玩的
Node.js - Express.js 中间层做首屏渲染很棒,实际上 checksum 一点都不好玩。而且,你得有一个很强大的微服务的后端,就是说,你公司得有 Hadoop 结构的团队(我的意思是你的项目已经很大了,Web 端已经支撑不住了,开始出现了微服务,然后 Hadoop 作为 Hibernate 支撑高 IO 数据),最好还要上 Apache Kafka。
然而,并不是每个公司都是 BAT 给时间成本随便玩弄这些东西的。
另外确定项目有这么大么?
推测 LZ 的团队模型是 Ruby + JS,吾辈认为,中间件同构适合的模型是 Java / C++ RPC + 消息中间件 + 消费者端(也就是 Express + React 渲染组合)。
据逼乎相关贴子了解,Amazon 用的就是 Java RPC + 消息中间件 + 消费者(RoR)的模式做某一块的业务。
首先如果用的是 Rails,下文就不用说了。。。Rails 就只是消费者端的一块,基本同一层的东西,JS 还搞一遍,不打架才怪。
另外,最近关注了 PHP / Rails 排行掉下来的一些评价,反正吾辈观点是几个巨头企业逐渐用 Micro Service 取代了 SOA,就是用 Java / C++ 来书写微服务,这样跑逻辑更快,然后输出给前端,Amazon 还在用 Ruby,只是 Ruby 请求微服务拿到了数据之后渲染网页,做快速开发。
大企业人力分配明确,独立岗位,如果还是拿 Rails REST 对比起 Node.js 同构,也就比如 Express.js request 微服务然后并且渲染首页优化 SEO,然后同时也提供 Components 的 Data 流,这才是同构比较适合的场景。
微服务的趋势,是所有前端、后端独立招聘岗位的企业都可能或应该做的事情。
以上纯属个人观点,有更好想法可以修正
能理解前辈内心一肚子气,实际上社会每个人都不服输的,没有人会示弱。
前端过度分离才是失控,但是如果就一个简单同构而已,学习成本也不算太高。
就像选择多门语言 Fusion 开发,其实两三门在一起沟通,都行。只要不是把 Erlang / Haskell / Ocaml / Clojure 甚至 BrainFuck 一起混到项目里,吾辈认为都是没关系的。
而且调用结构得自然,你选择了这个方案,那么,就意味着你得负责到底,跟同事之间讨论的时候就得好好沟通怎么对接。
对于项目交接的事情,我觉得,不是外包公司那种写一个代码公共模板,然后大家必须得按着这个步骤继续写,搞得跟军训一样,最后是机械劳动,都是不好维护的。
因为每个人多多少少都会有自己的代码风格,然后别人看了可能是没办法理解的。
你想要规范,可以,那你只能让开发者以固定代码风格、固定设计模式,甚至最好就是贴一个样板,全部复制粘贴这个来改。但是没人会愿意这样的。这个你在软件外包公司可以做量产的时候用,外包公司反正就是赚一笔钱,做体力活。但是一般开发者都是有情绪的人,他们不乐意的。
而且那样子也彻底贬低了开发者的智商,应该说直接无视了员工的智商。
一个工人不管他用什么锤子干活,只要他不是整天花式整墙极端分子,以至于其他工人没办法跟他的墙打通,他要是老老实实的抡起锤子工作,好好跟其他工人沟通,必要时打通通道,还是没问题的。
虽然我也在前端奋斗过一段时间,同不喜欢 node 一大波的东西在不同的 目录下放了一堆包。此时会想到 Monolith 的好处,但是事情并没有绝对,完全 Monolith 那就是 M$ 那种整套商业解决方案了。
我目前的情况跟前辈“应用总有一天会变复杂”刚好相反,领导是项目都没做,就直接“你总有一天生病,让你同事帮你改代码的”,然而我每次生病都是不敢请整天假,请个半天,几个小时,至今年假都没休过,更从来没有因为代码好不好维护。
前者过于开放,后者过于保守。
更贱的事情是,我领导不同意我用混合语言方案,结果我还是忍了一段时间,采用了 PHP,结果写 Laravel 的某个同事说两套 PHP curl 着不好对接,怪怪的,因为分成了两套项目,然后让我加进去跟他一起写 L,但是我压根不打算使用它。
然后,这次是重点,另一个同事跟他一起用 Laravel,然而那个人写的东西他也有看法,觉得是别人代码风格啦、模块不应该自己又写一遍啦啥的啦,用法啦。非得别人跟他同调
人就是这么犯贱的,别人的代码都是有问题的。
然而 ASP.NET 已经有了这种东西~
微软作为大厂一开始就有野心全栈化,其实微软哪里不打算全栈了,有数据库,又有办公全家桶,还有自己的语言、编译器,数不清啊……
话说是 05 年后,Ruby(Rails) 这种作为 Java 的挑战者挑战商业权威 Sun,然后那时候很多人鼓吹说喜欢用 Linux 啦(王垠),说 FVWM 多漂亮,在学校宿舍就他用着鄙视其他用 Windows 2000 的童鞋啦~
再后来就是开源鄙视闭源,鼓吹开源,然而,我最近在 mac 上买了几款软件,都是闭源付费的。因为开源的很多东西真的不如闭源的体验好,我宁可花钱 3000 买 Photoshop 也比 绘图压感不强、各种地方都没经过很多很多专业从事插画人员使用然后报告还有优化而纯粹一帮码农自认为观点上产出的 gimp 要好很多。
因为我现在需要的是画插画(需求),而不是看 GIMP 的源码去编写可持续使用的绘图软件,
Blender(开源)和 Maya(闭源)比较
Maya 是现行工业标准,什么叫「工业标准」,就是经过严格的生产环境考验,足够支持工业生产需求的标准化方案。Blender 是很酷,但不足以支持一整套工业生产流程。不是 Blender 做不到,而是开发者和用户基数不够大,开源社区的开发模式并不能保证其架构和 API 的稳定性。举个简单的例子,在硬件渲染上同时提供接口支持 HLSL/GLSL/Cg 的扩展支持,就足够耗费很多人的精力了(不知道现在 Blender 有没有支持 DirectX,貌似还没有),有没有就完全看社区的心情了。
摘自 https://www.zhihu.com/question/21975571/answer/144690708
一般人会认为,你总不能拿一个玩具放到公司里面给大量生产的美工用吧?但也不一定,如果你在为公司特有美术、业务情况维护和开发 Blender、GIMP 然后在公司内部用,倒是不错的主意!
小辈认为没有任何绝对的好处(完全都是好处?),也没啥绝对的坏处(一无是处?)。
工具是用来解决问题的,每个人按照自己的意愿,拿工具完成就好了,你跟别的工人在工地干活,整天喷人家的锤子多烂多垃圾,搞得人家今天没办法干活才是问题。道不同不相为谋,跟自己意愿更好的伙伴一起。
没错的,所以我老板的意见很大,真相是为了完成一个任务,自己过于发挥个性了
其实每个人都有自己的独立思考、实现方式,有些人喜欢 DIY,有些人不喜欢 DIY,然后有些人喜欢拼接 SQL 完成任务。
我前同事不喜欢 ORM、AR(ActiveRecord),把一件事情写成 SQL 的 swich / if 去条件拼接来完成。每次需要新的数据的时候,第一件事是手动创建表,然后再在逻辑中加入相关表查询的 SQL 代码。。。
但是别人看着很脑大,谁知道他拼接着起什么作用,干嘛来着。
前同事没学过 Ruby、Java 属于老的基本只接触 PHP 员工,ORM 都没用过也没了解过,甚至可能心态上也不愿意接受(之前跟他提过但是他一开始是不愿意接受,后来我把公司某一套系统跟他合作的时候一步步做完,引导他不要用 MySQL 存他 PHP 配置啥的都丢进去,引导他自己独立学会组织数据成结构成对象,适配配置和模型,而不是整天摆弄数组【由于 PHP 数组是 Array 和 Map / Hash 的组合体过于强大,让一些开发者感受到的是表面而没有深入】)。
硬是要区分 MVC 是没意义的,后端的 V 站在 API 的角度观点,那就是前端的数据源,那么就是前端的 M,思维是可以切过来的。
我曾经和前同事因为 ORM 的事情发生过争吵,他不让我碰他 PHP 的 M,只让我写 C 和 V,然后闹翻了,我干脆连 PHP 都不写了,把 ORM 全丢到 前端 去独立实现了。
最后任务还是完成了,是因为在过后领导批评让我好好如果把自己好的想法怎么让别人理解。然后那个同事在我多次把自己的设计稍微推动,然后也尽可能不排斥(尊重)别人站在别人观点哪怕不太正确的理解,毕竟实际实现的是人家不是你自己,不能太过分了。所以别人通过学习,还是把我的思维串起来了,事情做完了。
呵呵哒,前辈你得仔细观察一下,细微之处透露着小心思。
我是前端全栈拿 JS + Ruby 混合用,后端的只用 PHP,所以开发方案是 JS + Ruby <-> Laravel / CI。
然后由于 Ruby 不是 JS,没法同构,所以我才阐述了:
所以我带上自己的 amber-kit 之后模型是这样子的:
前端 Page(Input) + (View(Static) + Data(Input) -> Component)
其实是 SPA + Components 混合结构,然后由中间层路由。
扯那么多,其实该做的事情不过三件事情:M V C,我负责前端 + 中间层,把 M V C 都拿走了,而且还做成了首屏渲染,SEO 还有问题?那么其他人就只剩下 DAO 了,咿呀哈哈哈哈~
其实过后会发现那个 DAO 也变的多余了,没意义。
但也是有用的,因为其他人的 DAO 的数据是用在另一个网站的,我只是让它暴露几个接口,就像分几个资源过来我这边取数据,我可以不管数据库怎么实现。
这些都不是重点
你也可以认为要求全栈,说白了就是独立完成,但是独立完成的部分是按照【功能】划分的,比如它别的网站的东西,我管不着呀。。。
我没有偏要用一门语言去实现所谓同构的同构,只是为了达到这项目的,我用我喜爱的语言、工具做这项任务。
所以我建议说:
分工应该按照功能、模块分配给不同部门(大公司)或员工(小公司)执行,而不是按框架画饼甩出去然后你们一起做吧
作为老板、管理者,分布任务才是重要的,作为开发者,管你全不全栈,你把部分功能为了 SEO 丢到后端去写好,SPA 全静态也好,要是 Rails 全栈也好,屁大点事,因为完全是具体实现方案。
我意识到前后不可分离,其实本来就是一个客户端,一个客户端包括了界面、数据、存储,因为网络时代的原因,以前浏览器没办法达到独立客户端开发的素质,所以依赖于让“后端”把界面配置(HTML 发明的目的)和界面修饰(CSS 发明的目的)推送过来,然后前端也没办法存储加上数据分发问题,所以当初是集中存储,把这些合起来,就像是 后端语言 + Database -> HTML Output & CSS Output
不要开圣战,开了就没办法做了。
我从前辈的文章所看到的问题是,你们没有根据任务拆离,而是为了一两件破事把任务过度发散了。
谢谢理解,之前的帖子纯粹是卖萌的~
爱用啥用啥,每个人都自己的风格,就像相机那么多,买哪个品牌不好,过分强调个性不太好。
我的理解,以前的网站开发:
View render Data mixed
这个年代不区分前后端,页面都是动态或者静态的,就是有无脚本改动过的区别
后续演变:
View render + Data (Separated)
开始拆分模板和数据 ajax 异步,让页面先加载
后续演变(分支一):
前端 Page(Static) + Data(Input) -> SPA
后端 Data(Output)
这个是 SPA 的前端但页面客户端化的思想
后续演变(分支二):
前端 View(Input) + Data(Input) -> Component
后端 View(Output) + Data(Output)
SPA 太死板了,React 提出视图组件化(Component)
后续的演变 (Current):
前端 View(Input) + Data(Input) -> Component (与中间层 Sync & Checksum)
中间层 (前端占据) View(Output) + Data(Input & Output) -> Component (与前端 Sync & Checksum)
后端 Data(Output)
Current line 解决什么问题呢?就是解决不再让后端管制、约束前端开发者,前端开发者更自由、灵活自己去拿到数据后又自己去按照自己思维再二次分配,也更自由觉得像怎么做 View 自己管理,简单来说就是解决前端开发者不想用你的后端 Rails 来渲染它的 View。
其实我在我自己的工作环境就是这样的。。。我特别不喜欢 PHP 去捣鼓我的 View,但是项目前期我又没那么多时间搞中间层,就变成了上面的 SPA:
前端 Page(Static) + Data(Input) -> SPA
后端 Data(Output)
当初我发明 amber-kit,其实是我自己用的来做 中间层的。。。中间层对移动端也有好处,可以二次分发、整理数据,把不同的数据源聚合到自己前端(不论移动还是 Web 前端)组合的独立开来自由版本分发迭代的数据源。。
所以我带上自己的 amber-kit 之后模型是这样子的:
前端 Page(Input) + (View(Static) + Data(Input) -> Component)
中间层(前端占据)Page(Output) + Data(Input & Output)
后端 Data(Output)
其中,我负责前端 + 中间层的工作,但是老总特别不满,尤其我用的是 Ruby 来写,老总暴戾,说多么不好招人,因此经常在团队面前说我多另类啦,怪异啦,为了追寻某种风格啦。
这些设计,本质是为了让自己在自己的工作中有更多的主动权,自己的设计权。
想想看,如果前端只是为了写个 JS 控件,完全被动性地变成了配合后端输出成什么样的 HTML 再自己去把数据渲染。沟通上会有困难,因为前端开发不一定清楚后端渲染的规则、数据的规则,而且有点变成了后端的下属,人家给什么就怎么做,稍微麻烦了的话,就很容易引发矛盾了。如果是独立岗位的话,一定受不了的。
react 和 vue 同构,是为了 components 前后一致,一套代码多处执行,同构组合在一起,在同一个 proj,两端分别渲染出来的这个,下一步这个东西也是我自己预先定义的会反向跟后端按照预定的功能行为同步、校验。
吾辈认为,总想着一套代码多处执行,那肯定有问题。自己和自己分别在不同端的校验,该多麻烦。我认为以前 ASP 啥的也有一些自动生成脚本,反正生成的东西会跟服务端匹配,但是这个东西很依赖 IE,必须微软方案一套从头到尾下来。
我想说的就是这个,而没说 Rails 搞同构。只是觉得大方案都求全求同构,那是不现实的。
我已经听到有前端开发说不想碰 Node.js Server 了,他们想专注于处理交互(这也是前端职位的本意)
很正常,我觉得分工应该按照功能、模块分配给不同部门(大公司)或员工(小公司)执行,而不是按框架画饼甩出去然后你们一起做吧
过度抽象是不好的,但是我觉得设计出来的人,就得负责到底。
以前一个变量传递就能完成的事情,现在要写一个 API。需求没完成,没有人会是轻松的。
我想到的是不是前端把啥数据、自己能做的逻辑都丢给后端开发了,然后自己只是打算拿数据都不做点事情,然后后端逻辑过于变态,把后端累死了?
我觉得到最后,前端会嫌弃后端太不给力了,来来来,咱们自己连数据库算了,啊咧?这不是 Win32 MFC + ODBC 年代的 方式吗?
补充: 把前端框架放到后端渲染,开发难度指数上升,这难道不是 Rails 把 webpack 混进来的害处吗?吾辈当初不太认可 Rails 巨石思想,就是啥都包含进来,还一起构建,这样多管闲事,复杂度很高的。