欢迎来到舟哥的博客,希望你开心点,因为我很开心。

  • 为了公益,为了狗狗,91xungou.com寻狗小程序上线了!

    不太更blog,因为有太多工作上的事情,尤其zhouzhou.net的备案搞了半天终于弄完善了,终于我能回来了。

    首先呢,我要推荐大家访问https://www.91xungou.com这是我最新制作的一个网站,其实它不仅仅是一个网站,起源自微信小程序“寻狗”(微信用户可以搜索“寻狗”两字就能找到我做的小程序)以及新浪微博账号“寻狗小程序”。

    一看名字就知道,这是一个帮助主人找回失踪狗狗的工具,利用小程序的特性可以快速的录入垂直字段,通过分享机制(生成朋友圈分享图片,分享好友和群,同步推送到网站以及微博)快速的帮助狗狗主人传播失踪狗狗的讯息,方便快速的发布寻狗启事。同时,将散落在各处割裂的信息源合并放一个页面,这样方便狗主人汇总线索!

    目前来看,工作效果非常好,用户数节节攀升,可以明显看到数据在提高。我会把产品,代码的心得不定时的分享出来,加深自己的体会。

  • 自己的docker基础镜像php-fpm+nginx+alpine+composer,专为symfony4优化。

    https://github.com/nickzhuo/phpallinone

    Nginx: 1.13.10
    PHP: 7.2.3
    Redis客户端: 4.0.0
    Composer: 最新版
    ALPINE: 3.7

    也可以直接使用build完毕的镜像

    daocloud.io/nickzhuo/phpallinone:latest

  • Hello world!

    Welcome to WordPress. This is your first post. Edit or delete it, then start writing!

  • 把证书从startssl换到了腾讯云免费的TrustAsia

    有点后知后觉,发现startssl的根证书即将被浏览器移除了,当然老的已颁发证书不受影响。ps:好像国内的证书,沃通也被禁了。

    SSL对网络非常重要,尤其做接口来说,例如你可以在你的客户端做ssl pinning,保证百分百的传送安全,当然SSL会加重服务器的消耗,但这又算得了什么呢。

    查了一下,腾讯云提供免费的DV证书,真的很不错,另外表扬下,腾讯云的产品感觉和性能感觉已经超过阿里云很多。

  • 时速云老是断,把网站搬到香港搬瓦工。

    最近一段时间每天都能收到监控宝关于时速云的大量警告,也不知道是为什么,到底是误报还是时速云的问题。正巧也需要一台服务器跑点程序,弄了台香港搬瓦工,感受感受,目前来看很棒,用docker管理服务真的很惬意。

  • 让我们给业务做减法,给代码做减法。

    最重要的写在开头:道术合一,知行合一

    现在是讯息爆炸的时代,搜索引擎降低了学习的门槛,凡是都能从百度谷歌了解个一二。正因为这随手就来的一二,带来了想要的“结果”,让大家只掌握了术,但忽视了道。我认为“道术合一,知行合一”,术是千变万化的,但是道确实永远的,做减法就是我自己的代码之道。

    可怕的观点:执行效率是第一

    我经常听到一种观点,代码需要的是更快的执行效率。以及由这个观点产生的衍生观点,例如:设计模式并不重要等等,因为我们可以绕过框架或者现有的方法,用更“原生”的方式实现一样的结果,这样会运行的“更快”。这是一个可怕的观点,可怕就可怕在看上去没错。软件行业发展到现在已相当成熟,我们绝不能用单一指标衡量代码,如同我们不能用百公里加速来衡量一个车,如果这样想,无疑要选比亚迪,实际情况真的是这样么?

    代码是一种业务的体现:全方位的评估才合理

    代码是一种业务能力的体现,举个例子:小轿车是个人出行业务的体现,全方位评估软件工程带来的结果才更合理。尤其在国内,人天的成本大幅度的提高,技术团队每天的开支相比其他传统行业近乎天文数字,我们对于迭代周期要求非常的高,单个sprint产出的价值太重要,甚至于正版软件相较于人力成本也已经变得是一个合理的支出范围。所有,我更倾向于,在初期掌握一支小型化技术团队,把握住业务的核心,最大程度整合资源,打通外部内部数据,且团队要能不停的适应业务的变化。而且不光是技术团队,所有业务团队其实都应该如此。

    业务好等于代码好:好业务是不停迭代出来的

    很多人都告诉我,自己的代码写的多么多么的好,一次写完永久运行。但这样好么,我可以负责的说,这样的代码不值钱。互联网业务是不停的试错出来的,业务好不好对公司来说就是赚钱不赚钱,也就常常带来一个问题,需求肯定不停的变化。我以为业务的打磨是好事,因为没有人能一下找到赚钱的模式,再牛X的业务都是不停的迭代变化出来的。所以,要做到能快速的迭代,我们必须让代码能够快速的变化。可能有些负责通知或者工具类的运维小脚本,写完之后可以静静的躺着运行若干年,但不代表这个代码是好的,只是代表业务是死的。但唯有赚钱的业务才需要不停的修改不停的改变,所以我的观点就是代码是不停的在迭代改变的,同样的我很悲观,盖房子的还能看到楼房屹立100年,作为软件从业者,你的作品可能只能在世界上存活3个月,这是一个非常残酷的事实。

    代码变化的本质:反应业务的变化

    业务随着时间的推移,往往公司从一开始一个人管全部到后来的运营分工精细化,这背后涉及的是人员和部门的变化。所以当设计系统的时候必然会参考业务部分的划分,使用者划分,和场景的划分等来做设计。如果能在动手写代码之前闭上眼睛看到使用者工作的状态,线下业务转线上的整个过程,思考出每个节点,那就是一种正确的模式,因为你看到了业务,看到了代码的真正价值体现!

    语言的进化:都是为了业务

    面向过程编程之所以进化到了面向对象,是因为我们发现所有的业务都是存在现实世界中事物对照的,以及他们的关系。有了面向对象,抽象让我们可以更好概括真实世界,多态让代码中事物拥有同时对应多个现实世界事物的能力,继承让我们能够复用大量的代码。进化到了面向切面,我们发现业务不停的在做微调,所谓的微调无非是一些业务逻辑在场景中顺序的改变,有了AOP这样棒的工具,代码的组织变得更合理,当然阅读性会差点。所有的代码特性进化其实本质都是为了更好的表达业务,包括可以用trait来实现一些非通用的多继承,用生成器让函数的返回变得“动态”起来。

    最后

    业务是一组代码的集成,如同你开了一个面馆,没有必要非自己磨出面粉做出的面条才是最好的。站在一个更高的格局看系统,你需要的是有限的资源下,包装面馆,整合所有。把握最核心,例如浇头做核心,抓大放小。夸张的说,即使只开了一个小店,但是想着一个跨国企业规模。还是那句话,尽可能的在年轻的学习阶段过度设计自己的系统,然后不停的做减法,就能真正的感悟系统,最后你会特别理解罗斯科的作品,真的不用太复杂。

    最最后

    谨以此文,把自己的小小感悟献给刘锦,一个任劳任怨,每天认真工作学习的安庆少年,未来的安庆马克·罗斯科。

  • 最近互联网周边的体验

    今天订阅号直奔主题,简单的说说一些周边体验,可能有些与实际已经不符,而且也仅仅是一家之言,如有冒犯请见谅。

    开头题外话多说一句,为什么要用周边,我觉得艺术圈给我带来最大的理解之一就是艺术品的市场价值和艺术价值是不挂钩的,同理也适用在软件行业,代码的商业价值和技术价值是不挂钩的。切莫局限在技术的片面表现中,越走越细,举个例子,当你把关系型数据库看成一个服务的时候,不仅仅是简单的提供sql运行能力,还要有分布式,要有冷备份热备份,还有高可用,要有健康程度监控,要有审计,等等,当你完成了这整个服务方案的时候你发现你的业务还没开始。再举个例子,如果没有七牛这样的周边,可能一些图片APP团队还在自建分布式文件系统中,沉没在fastdfs的泥潭中。我们要最快的整合周边,把商业价值放大,这样才有闲置资源放大技术价值。

    再中间插一句,很多很多小伙伴和好朋友问我现在去了哪里,借订阅号宝地说一句。老夫已经把天赋带到了空艺术,一个艺术平台。贯穿艺术领域各垂直和横向、国内和国际产业链,整合线上和线下资源,打破艺术领域与资本和非专业化消费受众壁垒间迅速发挥领军作用。(妈蛋,这个介绍是复制的,不是我写的。)

    容器和持续集成篇

    Daocloud:国内容器团队,他提供了一套容器管理面板和完整的CI功能,可以完成代码上传后的自动触发构建,测试,部署,监控。生产环境容器必须部署在自己的云上,本身提供的主机称为胶囊主机,只是作为调试用。他提供的SaaS服务包含数据库和缓存也只能用在测试环节,如果你已经有自己的托管主机或者有自己的IaaS供应商可以考虑使用它。但Daocloud有一个致命问题,不支持集群,它的集群是一个“假”集群,只是随机把服务放到某一台机器上而已。CI部分,Dao的优点在于他有国外主机用来build镜像,速度非常的快,因为我们的代码包大量依赖第三方源。可惜的是,对于junit的输出xml格式兼容性有点问题,嵌套多个testcase输出的结果无法兼容,可能要手工输出成dao需要的格式,或者等他们升级。Daocloud的服务很棒,上班时间客服反映迅速,我个人强烈推荐容器爱好者注册一个Dao,只要有一台自己的PC机,简单装上他们的agent,就能开启你的第一次容器之旅。对了,Daovoice也是一个很棒的功能,可以为你提供一个在线客服聊天,当然很简单很初级。最新他们也出了DCE可以部署在私有云上的管理套件,但还是那个问题,没有解决集群的话,他对企业的帮助不大。

    数人云:他提供了一套开源的可以私有化部署的基于SwarmKit的管理面板,但我真想说这个公司就是完全来搞笑的,代码的完成度非常的低,开源并不是可以为质量不负责做借口的依据,使用过程中充满BUG,用了之后我整个人都不好了。

    灵雀云:很干脆,基本就是一个镜像仓库加速和容器面板,没有数据库缓存之类的周边,这个是致命伤,CI做的也很一般,和Daocloud不能比。最讨厌的是客服也不友好,当你表达出没有付费意愿之后,就把你切成了免费账号,只有一个镜像功能,有点大牌哦。

    网易蜂巢:迅速的成长中,每次登陆都可以发现大网易版本迭代很快的,而且投了百度的关键字竞价。但就从Build环节老失败说起,没有国外节点,很容易buld不过去。没有提供测试环节,所以就是镜像构建加部署等等,用起来的感觉很稚嫩,不过界面配色我挺喜欢的。

    时速云:放在最后必然要重点介绍,如果你是一个创业公司刚起步,那么我觉得时速云是最棒的体验,他提供了创业团队需要的一切,我指的是一切。在保证自己代码团队已经完全容器化之后,你无须购买任何主机,只要push代码就能完成CI/CD,部署,监控等一条龙服务。他是基于k8s的架构,所以自然而然的天生能力强者,他提供的主机完全可以用在生产环境,关键是一个容器的最便宜收费才28.8人民刀一个月,简直太便宜了不是。他的团队也提供了分布式的Mysql和分布式Redis给你使用,当然Mongodb以及大数据的周边还没,但是对于创业公司来说这已足够,关键足够的便宜!缺点也有,没有外国的Build主机,我有超过1G的镜像会很容易build失败,界面追求炫酷,有些控件不实用,例如查看构建日志就容易把浏览器弄崩溃。还有一个很神奇的地方在于,帮助文档没有搜索,这挺诡异的。但我还是强烈推荐时速云,我觉得是国内目前容器提供商中最有潜力最有前途的一个。

    IaaS篇

    青云QingCloud:着重介绍下青云,目前我公司的业务都跑在上面。青云的最大优势在于技术上非常先进,尤其刚开的上海区,网络完全基于SDN/NFV,我一直认为光主机虚拟化是不解决任何问题的,网络必须虚拟化。这点青云目前国内做的最好,不像阿里云的经典网络被很多人吐槽,没办法,技术肯定是越新越好的。青云的后台及其的友好,产品经理应该是下了大工夫的。尤其是大数据部分,做的真的很全,Elasticsearch,Spark,Storm青云是目前最好的选择,有点爱不释手,我简单计算了下计算能力,同等计算能力下,费用是阿里云的8折。青云还有一个独门秘籍,因为支持SDN,所以可以让Docker直接用SDN代替Docker Overlay,简单到只要装一个他们的插件即可。推荐青云+Daocloud的组合,可以满足中大型互联网公司的基本95%的需求。

    Ucloud:和青云的对决中已经处于下风,本来也是一个很新的IaaS,周边不全,可能聚焦的不是大数据的业务,听说服务游戏商比较多。

    阿里云:有点老了,但是阿里云有自己的优势,ECS可以选择的机房多,例如我公司的SS服务器就放在阿里云香港节点,但时间跨度太久了,他真的老了,而且价格体系非常混乱,同配置的服务器测下来总感觉慢一点。如果你有机房地区的特殊要求,可以选择阿里云,但不推荐。

    Azure:试用的流程有点繁琐,爱买不买的样子,放弃。

    代码库

    Github:私有库要收费,其他没缺点啊!

    Coding.net:因为自己团队代码在上,体验比较深刻。有很多bug,例如:项目在团队和个人之见转移可能会出权限问题,感觉还不能商业化,最诡异的地方在于当你希望成为付费用户的时候,你会发现收费是基于项目而不是团队,对你来说收费的好处仅仅是可以让一个项目的开发者超过50个人,天哪,真有单项目那么庞大的开发团队吗,恩。除此之外,界面很丑,交互操作的感觉很糟糕。

    测试

    Swathub:简直让我大呼哇塞的一款产品,简单说就是SaaS化的selenium,非常非常有前途,使用难度非常低,通过向导式的表单可以很轻松的建立一个testcase,并且保存在云端供整个测试团队学习使用,说的通俗点他真的就是一段可以控制浏览器的代码,让你的测试团队不再是按键精灵,节约了很多鼠标。通过api触发配置在CI环节简直神器!能大大幅度的提高测试过程的效率!但是特殊的控件,例如:bootstrap的组件,由于DOM的多层嵌套或者布局的缘故需要自己手写对应的选择器。如果我有钱我会考虑收购这家公司,非常有前途。:D

  • 想要成为PHP高手的十个建议

    勇哥对我说,我写的都是道,但是大部分人需要的是术。我恍然大悟,想想这有道理,道理虽然是根本,但是术还是要有的。特别推出一针灵系列,顺手弄个耸动标题吸点粉,请轻喷。

    PHP使用简单,上手特别的快,这导致使用者水平参差不齐。而且因为诞生时间太久,有很多冗余的东西,缺点堆堆的,这里不展开。有太多技巧可以提高水平,今天先说十个,有些可能非常颠覆你的想法,但请听听我的看法。

    1。熟练使用SPL,这是基础

    PHP本身是一门工具,SPL是工具中的工具。SPL的使用会大大简化你的设计,我发现N多程序员无法回答和SPL相关的问题,这是致命的。例如:SplSubject接口可以轻松帮助你做出一个观察者设计模式,SPL系列迭代器满足99%的使用场景,虽然你可能不写自动加载,但是spl_autoload干嘛的总要知道吧。

    2。参数需要注入,不要和环境发生依赖关系

    你写的代码承载的是你的业务,业务是可以工作在CGI或者CLI下的。看到太多的Sample中控制器会直接使用$_GET,$_POST之类的环境变量,这是致命的。如果你的模型层也有直接获得GPC,恭喜你,重构已经提上议事日程,因为你的业务根本无法再CLI下执行,请把环境变量和业务参数的绑定设计成注入的关系。

    3。不用写任何一行注释,熟练运用PHPDoc

    代码本身是不用注释的,难道你会在一个user变量中保存一个order讯息么?当然不会,因为他叫user呀,代码本身应该如同说话一般流畅,在写代码的同时最好打开一个词霸。而PHPDoc是你的备注,强化代码对使用者的帮助,让所有的“人”(例如:IDE)明白你的意思,静态代码检测是一切效率的基础。

    4。任何模板引擎都是垃圾

    这是我的个人观点,为什么要使用另外一种DSL去描述模板呢?除非你能将模板工作交给一个专门团队做,而且用的引擎应该是跨语言的。实际生产环境中,只要有静态页面,和JS的模板引擎足够了,除非你要为SEO做服务。额外说一下,大量的模板引擎把模板和缓存有绑定在一起,灾难加灾难等于毁灭。SO,我从不会面试提问任何Smarty的问题,因为那就是一坨屎。

    5。使用PHP编写路由而不是依赖HTTP容器

    这个问题和参数注入类似,很多代码中包含的.htaccess其实是很无厘头的,路由也是业务的一部分(除了锁定入口)。我只想问一句话,你的代码难道不想运行在nginx,IIS,lighthttpd上了么?还有很多http容器呢!如果你想把自己的代码商品化,切记把路由放在代码中。而且我想说.htaccess简单的语法,是无法和高级路由器相比的。

    6。显示声明变量并且初始化

    任何变量使用之前请初始化,如果你是一个合格的程序员。虽然PHP本身会很无厘头的包容你的这些做法,但是这很不职业,尤其extract函数配合GPC使用,导致的后果是致命的,可能覆盖任何关键变量。如果要我配置php.ini,第一个就把extract给disable掉。

    7。优秀的代码必须使用Composer

    代码是一种服务的载体,所以必须灵活部署,他需要有自己的包依赖管理和autoload管理。千万别在自己写autoload了,我相信你可以,Composer的出现解放了太多PHP程序员。而且请记得千万在本地部署一套本地Composer(Docker做很容易),因为你的CI(持续集成)用得到他。

    8。只有视图才会用到Array

    这一点很难做到,因为PHP的Array太变态好用。在我的理解中Array只是一具尸体(无法控制读写,无法控制公开程度,没有方法),在业务中所有的值必须以对象的形式传递,这样才能在每一层中做对应的约束等等。只有在视图中才会用到Array,当然前面说了如果没有SEO,也就没有PHP视图,那么其实你的代码中可能就没有Array了。好吧,我的言行有点过激了。

    9。不要在代码中随意退出

    我想举个例子,你去别人家做客,从大门走进去,走的时候为什么要从窗户跳出去呢?MVC中单一入口进入,其实还有后半句话,要从单一出口退出。如果代码不是你一个人写的,任何程序员无权在自己的辖区内中断代码,因为你根本不知道Runtime时候上下文关系,可能导致OB失效,导致HOOK失效,等等。如果你说这样节约性能,我只想建议别用百度。

    10。优秀的PHP程序员必须关注死亡皇后岛订阅号

    好吧,这才是这篇文章的目的,只有关注了死亡皇后岛,才能第一时间获得舟哥手写各种语言的心得。谢谢大家,关注之余不要忘记随手转发,万分感谢。

  • 编程感悟系列:本地方法和远程方法与可见性问题

        数据库一不小心说了四节,自己觉得有点枯燥,那就开一个新系列讲关于编程感悟吧(多一个一级菜单真是一个不错的选择啊)。
    
        我总是建议年轻的程序员(虽然我也很年轻)应该把项目复杂化,尝试各种手段让自己的项目充满过度设计的感觉。然后静下心来做‍减法,当你会用减法并且理解其中奥秘的时候,才能学到编程的精髓,才能学会用编程的方式思考问题!
    
        而且你会惊讶的发现,解决问题的过程实在是令人着迷,倘若你的工作只是完成需求,那么根据契约精神你只能收获的是工资。罗伯特清崎在《穷爸爸和富爸爸》里写到,“老板发你的工资是保证你不会离职的下限”。我的理解是,在工作中不应该只获得工资,更多的是学习知识!
    
        说到减法,举一个不恰当的例子,暴雪的最新游戏《守望先锋》就是一个做减法的典型,当国内游戏从业者一个劲的往产品叠加功能,例如:每日签到模块,抽奖模块等。《守望先锋》却大幅度精简系统,没有一丝的肉。是他没有能力做类似签到模块么?显然不是,是因为他的终极诉求是为了带来愉快,所以玩守望的每一分钟都没有被浪费的感觉。
    
        为什么这次的题目是《本地方法和远程方法与可见性问题》呢?我发现问题都是连环相扣的,我要用代码可见性问题做引子,推出我的观点,代码本身就是最最好的注释。本地方法就是本地文件夹定义的function,通过本地引用方式调用定义的方法,缺点是调用者和实现者必须相同语言,你无法用java调取ruby写的方法。本篇中我把跨语言的调用都称呼为远程方法,当然可能他不是真的在“远程”,同语言也可能是远程方式调用。
    
        为了进一步说明代码本身是最好的注释,我创造了三个名词,代码可见,文档可见和定义可见来帮助大家阅读。对每个人来说,本地方法使用起来非常便捷,常常得到一个软件包放到项目内就能跑起来,这其实就是代码可见。当你无法理解上下文的时候,只要进入代码里看一眼便能明白有什么问题。代码可见简单直观,只要你有源代码,你就明白他是干啥用的。
    
        远程方法使用起来很是麻烦,我们需要去找实现者写的定义文档,可能是一个json,可能是一个wiki,也可能是一个Markdown文档,里面的描述尽可能的详细,总之按照里面说的定义方法使用肯定没问题。但是糟糕的是,万一远程方法返回了“不该发生的东西”,这怎么办?这往往是因为文档的更新总是落后于代码造成的,也许我们在条件充足的情况下,会精心的制作文档。一旦hotfix来临,谁还会想起在深夜2,3点更新自己的文档呢?常常以来,文档成了第一行代码者的专利。
    
        文档可见看着很美丽,真正用起来,但也别着急否定它。我认为这是一个好东西,因为代码不光面对是的研发人员还有测试人员等。不要有了点缺点就否定它,我们要帮助它变好,只是需要大量的周边去维护,手工维护文档是不科学的!
    
        Github上充斥着大量的RPC框架,基本都是基于某个协议层,支持多语言的服务客户端实现等云云,最最关键的一点是会告诉你,一旦用了它速度提高N个级别等等。毫无疑问,这些性能指标肯定是真实存在的,但衡量服务调用难道就用一个性能指标就够了吗?到底我们需要什么样的框架呢?
    
        定义可见浮上水面,用SOAP举例子。经常听N多人说SOAP好慢呀,没有自己写的简单框架来得快,我永远不参与类似讨论,虽然我不是SOAP支持者,性能太过低下,但我们要理解为什么这样做。SOAP支持WSDL,这就是定义可见,我支持定义可见。支持WSDL的IDE,例如:Eclipse,只要基于WSDL实例化客户端,代码的使用如同本地方法!
    
        WSDL给了我们什么启示?原来定义可见多么的重要,我们的工作方式也会随之改变。先定义我们要的方法,基于定义产生文档,也基于定义实现客户端和服务端。这一切不就是TDD(Test-Driven Development)么?通过现代化的工具(例如:Swagger)帮助你完成“无脑”工作岂不是更好,所有围绕这个方法工作的人们,都能协作无偿提高效率,这就是定义之美。
    
        可见性就是为了让“人”更懂方法,这个人可能是真的人也有可能是电脑(IDE),也可能是以前的你和未来的你,一切的定义都必须显示,他真的能让效率提高。看到这里,你想说你的代码里没有那么多远程调用,但我想说的是,即便很多本地代码也定义含糊不清,静态代码分析在你的代码面前失了效,没有代码提示怎么让你的代码被传播,多利用注解Annotation等等技巧(请关注新的一针灵系列)让你的代码更容易被更多的人读懂吧。        
    
        当你调用远程方法和调用本地方法已经完全一样之后,那更抽象的理解方法到底是什么呢?方法是提供某个业务的能力,他需要分层,每一层既是调用者也是实现者更是定义者,到底该怎么分层?怎么描述结果,请支持关注本公众号,死亡皇后岛,老夫会为你做进一步解释。随手转发,关爱优质订阅号!
    
  • 关系型数据库使用中的误区系列:不要把业务放进数据库

        任何东西都不是多多益善,帕累托法则在生活中处处体现,关系型数据库就是一个典型的例子,你会发现80%的业务跑在20%的功能之上。显然,我和帕累托一样,不相信均匀分布在真实生活中体现。
    
        以下摘录自Andy Warfield的《The 80/20 rule… for storage systems.》,“80/20 法则通常被认为是源于意大利经济学家维尔弗雷多·帕累托。帕累托出生于1848年,他是(至少被认为是)占领运动的早期成员之一。他发现意大利国家财富的80%是掌握在几乎少于20%的人口手中的。由此发散开来看,80/20法则在其他方面的应用同样值得注意,也是很有趣的:因为帕累托观察发现他的园子里的80%的豌豆产自于20%的作物上(他似乎更喜欢数豌豆而不是其他豆子)。"
    
      很多程序员在做到某个阶段的时候都会来问我,要不要用触发器?要不要用存储过程?等等一系列类似的问题,你也会发现从搜索引擎可以找到很多文章在围绕这个话题展开分析,介绍各种各样的技术等等,但我想申明我的观点,在OLTP的系统设计中,请不要把你的业务逻辑以触发器和存储过程形式放到数据库中!OLTP只能保存关系,也许有些feature一时帮了你的忙,但是后患无穷。就好像你能在任何饭店轻易点到一块巧克力蛋糕,但味道永远不能和专门蛋糕店比。
    
       回顾一下历史,还记得10-15年前,B/S主流结构还是ASP。PHP的用户不对,这时候大C还没把cdb改成Discuz,VBB里的附件居然是存放在数据库的二进制里,Perl还很热,leobbs如日中天,每个空间商都会标注支持cgi-bin这样的可执行目录,表明这个空间不是静态的。也就在这个时代,关系库真的开始进化,程序员从文本库中解放了出来。
    
       有了新的工具大家自然要研究透彻,但是工具不是说要把他用足用透才是好的,每个工具都是有他最适合的场景的。DVBBS动网是ASP时代的一个经典产品,记得当时会把高级和普通版本划分成存储过程和非存储过程版本,这导致很多人眼里存储过程是一种高大上的东西,所有不是自己技能栈的东西就高大上,但真的是这样吗?同样的,去一家饭店非要吃遍所有菜才是好的么,我想如果你是帕累托,只会点其中的20%吧。
    
        我对软件工程的理解之一,业务描述语言必须单一化,面向结果!代码究竟是什么?代码本质是为了提供服务,如果存储过程被引入进来,你的代码中是否包含数据库DDL部分就是一个问题。CVS中推上去的TAG到底包含了DDL语句么?
    
        当然这对百度型人才来说也不是什么问题,你可以投机取巧一点把DDL放在代码目录下类似script目录,利用hook来实现和代码同步上线,但这合理么?今天不想说怎么自动化上线和我的方案,进一步说,当一个newbie程序员来到你的团队,在review现有代码的时候,是无法用大脑做静态代码分析(Code Static Analysis)的,他会百思不得其解上下文和结果,因为你的代码不连贯,更不语义化,因为SQL是面向过程的。
    
        触发器也提供了类似效果的诡异陷阱,程序员一遍遍的review代码,但无法找到发生DML的地方,原来一切都是触发器默默的在背后干着坏事。对于外键的使用我也持保留的态度,任何业务关系必须在代码中显式描述,物理数据库利用外键保持数据一致性我认为不合理,例如:物理级别的分表怎么办呢?
    
        对于数据库的认知是对编程认知的一小部分,看到这里你应该理解了我想表达的观点,业务关系请放在业务代码中描述清楚。不管你认可与否我的观点,这也越来越逼近我们探讨的本质,未来的代码中该怎么描述业务?怎么设计我的架构?设计模式怎么用?
    
        symfony book中有一句话我很喜欢,build app not build tools,我极其排斥重复造轮子,但是你要知道轮子是怎么造出来的,才能知道以后的轮子长什么样子。请持续关注本订阅号,您的转发是我的动力!
    
  • 关系型数据库使用中的误区系列:业务字段展示字段傻傻分不清楚

        松本行弘在《代码的未来》中领悟道,这世界上没有java编程,没有ruby编程,更没有php编程,其实这世界上只有编程这两个字呀!
    
        好喜欢这句话,我觉得数据库编程也是一样的道理,虽然我们在谈数据库,更多的探讨是如何拥有编程的思维去处理这些问题。当碰到跨语言,跨平台的编程时,我们会称之为架构,但其实本质还不是在编程么?最后你会看到,人的架构永远大于软件架构,编程技巧只是人类处理真实世界问题在代码中的体现!这是我的感悟。
    
        作为系列的第三篇,我们谈谈关系型数据库常见的问题,也是初创型公司不能高速发展乃至转型的羁绊,业务字段展示字段傻傻分不清楚!
    
        先从一个简单的例子开始说起,我们总会设计各种各样的管理系统,例如酒店管理系统,里面管理着所有的业务实体,酒店实体自然是酒店业务在代码中的映射。我们常常会接到一个类似的需求,需要为菜单中包含宫保鸡丁的酒店标识为上海味道,前台可以基于这个标识筛选出符合期望的酒店。
    
        很糟糕,这是一个标准的死亡陷阱,程序员先做了第一件事情,为酒店增加了一个属性叫做上海味道,对应的关系表也多一个字段。第二件事,必然的会修改所有可以触发该字段变更的地方加入新逻辑,若这是一个复杂的系统,必然痛苦不已。
        
        所有初创公司的研发团队都消耗在了一些无用的事情之上,很快产生边际效应,他们已经无法应付真正的新品类拓展,光是打补丁便已经停不下来。那么到底是哪里错了呢?
    
      我要否定的就是这两件事,它们是不对的,首先第一点,我想先解释一个问题,什么是业务?我个人理解业务其实是一套流程,可以用UML工具绘制出来,业务绝对不是一套炫酷后台系统原型,更极端的说,是把真实生活中流程映射到计算机系统层面,他的每个环节对应了不同的部门,对应的产生了一系列的指标,有了指标自然也要有正确方式去使用工具驱动完成这些指标。在我的例子中,上海味道这个字段不是业务流程中驱动业务前进的字段,他的本质只是一个展示字段帮助提高用户格式化数据获得体验。
    
        这就牵出来第二个问题,业务字段和展示字段是同一个东西?他们都存放在关系型数据库中么?我的回答是否,初创型公司给C端用户体验的网站以及客户端往往都会从直接从数据库中读取数据,虽然很多公司表面上做成了微服务(多端发展导致不得不实施的结果),但他的数据源还是一个问题!试问一下,我能把含有酒店总经理联系方式的酒店实体表供前台网站读取么?即使前台程序员能控制用户的展示,那么前台的程序员真的需要知道这个字段么?万一被黑客攻破了网站难道你的数据就赤裸裸的暴露出来了么?
    
        终于,我们发现前台展示层最需要的持久层应该是一个文档化的,全文搜索的系统,关系对他只是可选的。他只是存放了业务字段的投影,也可以基于业务字段存放一些自己的复合字段。你根本不用增加一个表字段叫上海味道,也不用在菜单编辑保存的时候更新这个字段,他只是在重建前台index的时候被更新,至于前文的第二件事情,怎么更新呢?我们需要一篇新的文章,基于项目内和项目外的实时异步通讯,在这个文章之前我们还要探讨下本地代码方法和远程RPC到底有什么不同。
    
        这个问题和《关系型数据库使用中的误区系列:数据的价值》中导致犯错的原因有点类似,需求方的原始需求被错误的分层,业务字段和展示字段傻傻分不清楚!该前台程序员做的事情被扔到了后台来,你甚至可以很简单的理解,后台不用排序筛选的字段都不是业务字段,但具体的应用还要看公司业务的需要!
    
        后记,这个原则,是在到喜啦团队中反复强调遵守的原则,他真的可以帮你避免了很多无用的工时开销,更好的理解业务!安利时间又到了,在我们首席科学家botao带领下,我们选择solr为前台千万级的PV提供个位数毫秒的数据响应能力,恩。
  • 关系型数据库使用中的误区系列:数据的价值

        数据库这东西说起来真是一发不可收拾,其实本来只想写一篇文章总结,未曾想到写完第一节就超长了,也好,直接上一个系列吧!
    
        正如前文所说ANSI SQL真是一种功能性极强的DSL,如同打架必备的折椅,睡觉需要的床,踢球要的足球一样,我认为他是当下最适合通过描述过程筛选数据的语言,但注意我说的是过程!例如:我要筛选库存红色的苹果,筛选价格从高到低的订单且只要100条,诸如此类。
    
        但我们也常在反思对于过程的精确描述究竟是为了什么?这个查询的背后初衷是什么?我的观点是,我们描述了那么多的过程不就是为了得到预期的结果吗?我们为什么不能直接描述结果,让把其他的事情交给计算机来做呢?
    
       每个小伙子在追GF的过程中包含了吃饭,看电影,打LOL等等过程,所有的这些,都是为了让对方成为你的女朋友这一结果,而且常常为了达到结果你会动态调整你的过程,痛并快乐着。万幸的是,在计算机的世界里不用大费周章,你没有痛,只要你能将结果准确的描述出来,那么程序便会为你实现结果。
    
        试想一下,描述一句“我需要一个吃素菜的便宜的,而且我邀请朋友都喜欢的饭店”,计算机呈现的结果便会是你需要的那样,那岂不是更好。真心希望各位读者读到此处,从DSL角度,过程描述和结果描述角度,能带来你一点对于编程思想的畅想,我们频繁的使用SQL编程到底是为了什么?有没有可以让计算机学习之后,告诉我结果的技术呢?请带着想法关注本系列,关注budaoxing这个订阅号。
    
        《关系型数据库使用中的误区系列:最大误区》中我想表达的是在于后台业务代码和ETL之间的分层没做好,简单来说就是业务和报表分离。说到报表,最大的误区在于数据的价值!大部分的报表到底是为了什么制作出来的呢?吾以为,报表只是工具,帮助实施业务策略,提高单项指标以及整体指标。于是乎,对于报表的处理根本不在于你是否能写出这样的查询,几百行的SQL根本不是什么麻烦事,而在于和需求方沟通之后找到对方需要的关键性维度以及基于这些维度的预警和预警后所采取的策略。
       
        例如:CEO可能需要一张客服销售业绩报表,我相信只要有条件描述,SQL总能写出来,但是若能增进一步,你会否思考为什么总是这个SALES排名前列,她有什么独特的技巧和方法可以帮助提升整个团队的业务能力?又有时候需要SEM的相关报表,这些投放报表的意义是什么呢?我想不外乎是降低营销成本吧,那么怎么降低呢?光从API取得的数据足够么?是不是要结合内部的数据,尝试通过组合复合维度,环比同比CPC,CPS等来发现和预警问题,通过分时数据提高系统的敏感性,及时充分的持续微调让系统策略不失真!
    
        你真的对数据敏感么?每一张的报表都需要花费心思的精心设计,让数据的价值发挥出来,而不是告诉你做就做,它应该是值得你骄傲的作品!中途安利一下,到喜啦的BI系统中有200多张供业务部门查询的报表,运行在4个集群上百个节点上,而这些都是技术团队的工作结晶,所有的一切都是有价值的,保证领先于整个O2O行业。因为我相信,任何的决策都不应该是感性的,是应该基于数据做出理性的判断!
    
        突然发现,本来写的不是数据价值,老夫只能含泪改副标题了,请原谅我的啰嗦。本篇可能和关系型数据库关系不大,但是我还是放在了这个系列中,因为数据本质都一样,在这个数据库系列中,要多谈谈自己的想法和实践经验。
    
        最后,程序员在施展的过程中请不要以完成需求而做出一个个慢一拍的东西出来。全栈全业务,思考业务本身,相信自己的能力!在数据的海洋中遨游,终结所有问题!请持续关注本订阅号budaoxing,请帮忙顺手转发!马上回来关系型数据库哦!
  • 关系型数据库使用中的误区系列:最大误区

        开了订阅号,看到序言的PV数往上跳过了自己的期望值,尤其看到订阅者中男女比例已经达到二比一时,小小的脸红之余有了一点小小的膨胀。SO笔耕不能停!虚心接受大家意见,调整了下段落布局,希望大家喜欢。
    
        这次,我们来简单说说关系型数据库,我喜欢使用大量的引用和比喻来阐述观点,文章会很碎同时也会比较发散,希望能为以后和之前的文章承上启下。最后我也深信一点,能够百度到的“知识”不是“知识",所以我不是百度的搬运工。
    
        写SQL肯定是一种编程,准确的说是DSL(领域特定语言)编程,ruby之父松本行弘在《代码的未来》一书中用了大量的文字描述这个话题,非常引起我的共鸣,因为我常反思未来是否在业务描述中会有一种DSL可以描述特定业务,那会有多动态,有多抽象,或者这是唯一正确的道路?我想在本文埋下一个伏笔,让大家牵挂着这个问题!这里我最想说的是,主流IT媒体有这样一种观点,“21世纪人人都要学会编程”,我很赞同,但我要补充的说,“21世纪人人都要学会领域特定语言编程”,而不是人人都在写JAVA。
    
        关系型数据库RDBMS的使用往往陷入“误区”,我仔细分析了下,最大的误区在于场景选择!!你需要的是OLTP还是OLAP,这个误区在当下弥漫,99%的中国互联网企业做的架构有问题,那原因是什么呢?
    
        首先我们说说OLTP,就是传统的联机事务,你可以理解为存放线上订单的数据,后台编辑的酒店宴会厅关系数据等。OLAP则指的是联机分析,可能基于某些维度绘制出各种变化的表报,例如:酒店销售周汇总,BD人员出勤季报等。而最最要命的是往往这里的OLAP指的是ROLAP也就是带关系联机分析,所以头痛的是,程序员接到需求就一股脑儿的把这些AP的需求放到了生产环境中的TP服务器里。
    
        这时候一股脑儿的“优化技术”就来了,什么主从分离,方便从库出报表不拖慢主库之类文章百度一搜一大把,试问一下,一个slave能满足报表需求么?生产环境的数据库里的TP表真的能满足你么?外部的三方数据怎么办?SEM的数据难道也扔到宝贵的生产环境里去?你开始有点茅塞顿开,这根本是两种技能栈呀,分属两个部门!TP就应该放在MySQL这样的通常意义上的关系型数据库里,程序员DBA管,而OLTP是应该放在ETL(数据仓库)里由数据仓库管理员处理,你要用SQLServer或者MySQL做数据变形,简直要命!ETL的一些问题,我们将在以后大数据的文章中详细描述。
    
        那么问题的根本原因是什么呢?第一,需求方只知道需求,大部分产品经理无法区分这样的需求到底是由哪个部门完成,第二,有些公司根本没有数据仓库,这就有点无奈,第三,厂商的胡乱宣传让大家总期待在某一个版本会有一个allinone的东西出现!
    
        我的建议是,如果是报表类需求请交给ETL来处理,程序员可能只参与到ETL分层中的ODL(原始数据层)那层,区分是否是报表有一个原则很简单,需求中的报表肯定不是实时的!如果实时的报表,那么我认为他其实不是报表,已经是业务的一部分!是一种聚合后的决策用工具,如果这样的需求,必须在你的关系库里完成,当然额外的我想提醒你,如果在这样的查询中出现了select嵌套或者group having之类的聚合后筛选,我可以基本断定你的代码有问题,你缺少一张真正的物化表!不是物化视图,是一张真的表!
    
        如果你对ETL还有关系型数据库持续感兴趣请关注本公众号budaoxing,因为我接下来就是介绍关系型数据库的第二大误区。
  • 写在订阅号开篇

        还有半个月,入职到喜啦就满3年,到喜啦让我学习到很多,为做一个纪念,老夫决定开个订阅号把自己工作中的感悟分享下,主要涉及代码设计模式,大数据处理,业务设计,软件工程,运维测试自动化,带团队笔记。把已分享的和还未分享的碎片整理下,系统的写出来,顺便给自己一个时间的总结。
    
        如同每次做培训之前说的一样,我的文字是我的思想,是我的感悟,请亲手试过觉得好再转变成自己的想法!张鸣先生的《重读中国近代史读》的序中有这样一段,大意是A和B介绍A的思想,B并不认同,但在某些场合,B却会用A的思想去反驳C,因为B没有自己的思想,这是最要不得的!现在的IT行业有一个怪现象,喜欢聚众,好似人多力量大,一会一个座谈会,一会一个分享课,嘉宾各个抬头多多,浮躁的气氛仿佛看到了民间科学爱好者只凭胡思乱想和刷脸来处理问题,严肃的仪式化的东西只是外在,我们需要的是探究本质,请务必不要拿来主义,和碎片化学习!
    
        首先,我认为这世界所有东西都是相通的,软件工程亦是如此,我时常举一个例子给想进入互联网的传统老板来解释为什么现在单个软件项目的造价是如此昂贵,而非想象中一个网站找个大学生几千块就能搞定。我用美食做例子,作为一个饕餮爱好者,中国的美食博大精深,好比我爱的全聚德,那好味道我不想再描述,但其本质是很难复制的,你无法在一夜之间开一百家全聚德,因为掌握烤鸭技术的厨师无法短时间内陪训出来。但反观麦当劳,标准的流程化作业,任何一个人在短时间培训都能成为操作工,全球的麦当劳味道几乎一致,这样的公司才能成为世界五百强。现代软件工程提供的也是这般效果,我们将代码切片分层,根据场景组装,为能预见的复杂性业务设计出复杂的解决方案,试问你作为老板会不会为一个“可以复制的成功”埋单?我想我是会的,佛瑞德·布鲁克斯在《没有银弹:软件工程的本质性与附属性工作》中阐述了一个观点, 没有任何一项技术或方法可使软件工程的生产力在十年内提高十倍。在实践中,我很同意,充斥炫酷的IT专业名词没有带来什么变化,软件行业能力高低依然是设计能力的体现,我想把我的思想最重要的一个环节,“优秀的代码是最精确描述业务结果"带给大家。
    
        作为开篇最后我想说,本想早点开始动手写的,但我是一个拖沓的处女座,请大家原谅我的手慢。我的文字肯定没有张公子的好,但如果喜欢,请随手转发,更欢迎大家加入到喜啦技术团队,这是一个年轻的喜欢学习的团队,颜值高技术强!我会以1-2天的频率更新本订阅号,绝无保留。
  • 重新启程

    好多年没有写blog,感觉内心都不够平静,装了一个ghost,很方便,可以用Markdown语法写,好吧重新启程。