云烟计算-你是云儿我是烟
RSS 图标 Email 图标 首页图标
  • 一种包依赖引发的通宵发布与回滚

    发表于 2010年04月16日 yejun 没有评论

    引用来自架构组姚明同学的邮件:

    Intl-biz/wsproduct里面的代码修改如下:

    public void setIndByAll(Integer indByAll) public void setIndByAll(Integer indByAll, Object… objects)

    对应于intl-biz/wholesalesearch里面的代码:

    WsProductDO.setIndByAll

    由于intl-biz/wholesalesearch是依赖于intl-biz/wsproduct,但是无论Intl-biz/wsproduct里面的代码是否修改,都是能编译通过的。

    那么问题出在哪里呢?问题出在方法签名不一样。

    这里,我们的编译脚本有一个致命问题:

    我们的编译脚本是先编译了intl-biz/wholesearch,这时候对应的方法签名是:WsProductDO.setIndByAll(Ljava/lang/Integer;)

    接着才编译了intl-biz/wsproduct,这时候这个方法签名发生了变化,变成了WsProductDO.setIndByAll(Ljava/lang/Integer;[Ljava/lang/Object;)

    所以到线上的时候,intl-biz/wholesearch需要的是前者,但是intl-biz/wsproduct提供的却是后者,所以出现了大家看到的异常。

    我的看法:

    1. 减少不必要的包依赖;可以走远程服务的走远程服务;
    2. 底层有变动接口签名,一定要通知相关方,当我们改的人不知道相关方有哪些团队时,一定要在发布群里说一下,并找架构组同学REVIEW;架构组同学的信息会比较全面一些;
    3. 发布时的编译顺序很关键,这个编译顺序列表要随时维护;
  • 全球速卖通的模式

    发表于 2010年03月5日 yejun 2 条评论

     

     

     

    系统改进的空间还很大,物流,交易,风控,发布产品,搜索 产品,推广产品。

  • 架构那点事儿

    发表于 2010年02月26日 yejun 2 条评论

    系统越来越复杂,连发布都成了问题。

    A项目说,我是战略级的,这几天我要独占发布,别的项目都要等;

    B项目说,我也是战略级的,我可以让A先发,但A发完我就要发;我发的时候,别人也不能发;

    C项目说,我只是独立一个小需求,我不和你们有代码相关性,我自已不成吗?配置管理说,我们就这几个人,需要先支持A和B,你的C先等等;

    D项目说,我只是一个模板,让我先自已走UED发布流程行不行?A项目说,那不行,我们上的预发布上不能体现你的模板改动。到时候你还得再作一次发布;

    E项目说,我有个二方库要更新,发一下行不?大家都说,你千万别发,你一发我们全要回归测试;

    架构作到这种程度是比较常见的。一个作了十年的公司,系统错综复杂,这些现象很常见:内部包依赖由层次结构变成部份网状+部分层次;同一系统由不同团队维护;同一模块被多个不同系统调用;同一业务功能有多个模块实现;

    于是公司组织上成立架构部门,负责对共同依赖的二方库和配置文修的进行统一管理,所有修改由架构组专人负责。基础服务逐渐作成远程服务(RMI,REST,HTTP SIMPLE XML API, HESSION,ICE,COBRA等)。基础开发框架也由架构人员统一,大家用同样的配置管理工具和开发工具,开发框架。这正好比社区里的物业,所有基础的水电道路服务由物业提供和协调。

    在架构的支持下,发布时的问题还是无法彻底解决。于是深入服务化,代码模块独立成为一个更有效的解决之道。我推荐在公司内部也学习FACEBOOK这样的系统架构,FB里面每个应用由不同的公司团队研发和维护,这些应用只依赖FB最基础的远程服务。公司内的应用也可以作成这种型式,配置一个个独立的研发团队,减少编译时的包依赖。

    在阿里软件的时候,老板给了个机会让我负责PaaS平台。基于前人的成果,我负责的团队实施了阿里软件用户中心的服务化改造。改造过程是痛苦的,改造的结果我个人是满意的,这个用户中心没有在后续发挥作用是可惜的。这个架构中大量应用了REST OVER HTTP的远程接口,承担了1000TPS以上的高并发调用请求。

    alisoft-udb-arch1

  • 从IE中导出证书私钥,导入FIREFOX中

    发表于 2010年02月9日 yejun 2 条评论

    1:下载证书工具:

    个人数字证书导出来的软件http://www.isecpartners.com/jailbreak.html下载后运行如下图标导出私钥

    导出的时候,在右侧证书上右键,所有任务,导出。

    选 择导出私钥。私钥用于签名和加密我发出的信息。

    输入密码。这个密码在证书导入FIREFOX或OPERA等其它地方需要用到。

    2:在FIREFOX中查看证书:

    3:导入”您的证书”

    4:直接可以访问需要证书的站点了。不需要重启FIREFOX.

  • 程峰同学整理的RSYNC算法资料

    发表于 2010年02月4日 yejun 没有评论

    【rsync算法】

        rsync是一个开源工具,提供快速地文件增量传输,其核心是”rsync算法”。该算法解释如下:

        现有两台机器a与b。a上有文件A,b上有文件B,且文件A与B非常相似(可能来自同一份源文件,只各自做了少量修改)。则rsync算法由如下若干步骤组成:

    1. b以s个字节为单位,将文件B分割成不重叠的若干块(例如B是1024字节,s是512字节,则B被分割成不重叠的2块)。最后一块可能不到s个字节。
    2. b对每个s字节块都计算两种校验和:32位的弱”滚动”校验和、128位的强MD4校验和。
    3. B将这些校验和发给a。
    4. a逐一搜索A中每个s字节块(因为A中出现不同内容的长度可能是非s整数倍的字节,所以A中每个s字节块的步进偏移量是1),找到与B中某s字节块有同样弱校验和与强校验和的字节块。(a如何找到文件A中与文件B中相同的字节块,这里就不详述了。该步骤是个计算密集的过程。为了提高性能,弱校验和的算法应该仔细设计,以到达单向、快速、计算量小。)
    5. a向b发送一串指令。b根据这些指令同步B文件。这些指令要么是到B某个字节块的引用,要么是数据内容。这些数据内容均是A中与B不同的字节块。

        b通过以上步骤,最终同步B文件。

     

    【弱滚动校验和】

        “rsync算法”的第4步中,a要对以1为步进值的所有s字节块频繁地计算弱”滚动”校验和。这就要求该校验和的算法应该尽可能的计算量小。下面是具体的算法:


    s(k,l)是字节块Xk…Xl的滚动校验和,该算法的优势如下:


    可见当已知字节块X1…Xn的滚动校验和以及X1、Xn+1的值时,使用该算法可以很方便地计算出X2…Xn+1的滚动校验和。

    以上只是一个简要的介绍,具体内容因篇幅有限,就不写出来了。这个算弱”滚动”校验和的算法挺巧妙的,所以就多写了些。其实这个算法是脱胎于Adler-32校验和算法的,有兴趣的童鞋可以再去看看。

     

    【校验和查找】

    “rsync算法” 的第4步中,关于机器a如何查找相同校验和的字节块的过程如下。

    当机器a接收到机器b计算出的文件B的校验和列表后,会搜索文件A中任一偏移量的s字节块,以找出相同内容的字节块。该搜索过程的基本策略是a顺序计算每个s字节块(偏移量的步进值为1)的32位滚动校验和,然后用该校验和在b发送的校验和列表中寻找匹配值。Rsync的算法通过一个简单的3层查询机制来实现该过程。

    第一层查询中,机器a首先为b传过来的校验和列表中每个32位弱滚动校验和,计算一个对应的16位哈希值,并据此对b传过来的校验和列表进行排序。同时机器a创建一个容量为2的16次方的哈希表。在该哈希表中,每条记录均指向排序后的校验和列表中第一个与该16位哈希值相等的元素。如果排序后的校验和列表中没有与该16位哈希值相等的元素,则该条记录指向null。

    机器a对文件A中每个偏移量的s字节块,都计算出32位滚动校验和与16位哈希值。如果容量为2的16次方的哈希表中,对应该16位哈希值的记录指向不是null,则进入第二层查询。

    在第二层查询中,机器a会从哈希表中对应记录指向的位置,开始扫描排序后的校验和列表。该过程一直扫描到某个32位滚动校验和的16位哈希值,与哈希表中对应哈希值不同时结束。如果发现有相同滚动校验和,则进入第三层查询。

    在第三层查询中,要比较该s字节块的MD4强校验和与对应校验和列表元素的MD4强校验和是否相等。如果相等,则我们假设找到了相同的字节块。其实存在这种可能性:弱滚动校验和与强MD4校验和均相同的两个字节块,其内容有可能不同。不过这种可能性非常小,所以rsync算法忽略不计这种情况。

    当发现相同字节块后,机器a会发送当前偏移量到上次相同字节块偏移量+s之间的这段数据给机器b,然后是相同字节块在文件B中的索引。这些数据会在匹配成功后立即发送,这样机器a的校验和查询过程与机器b的文件同步过程可以并行进行。

    在第二层查询中,如果最终没有发现相同滚动校验和,则机器a会步进到下一个s字节块进行滚动校验和计算(这一次的步进值是1),并重新执行上面的第一层查询。如果机器a最终找到相同校验和的字节块,则从该字节块后面重新开始新的搜索过程(这一次的步进值是s)。这个小技巧在A与B两个文件十分相似时,可以减少大量不必要的计算(查找字符串的子串时,这个技巧也经常使用)。

    下面是3张图示,大家将就着看吧 -_-|||…


     


     


    说明一下,我没有看rsynce算法的源码。所以这三张图只是个示意,可能存在出入。

     

    【总结一下】

    Rsync算法是Andrew Tridgell与Paul Mackerras在1998年的论文中介绍的。该算法主要针对当时网络情况的不稳定、窄带宽、高延时做出的。rsync算法很适合对一些小尺寸、相似度高的文件进行同步,但不适合大尺寸、路径结构深、文件数量庞大的文件群进行同步。原因从rsync算法可以看出,它需要对所有文件的全部弱”滚动”校验和与强MD4校验和进行计算、传递、比较,不管文件是否修改过。

    那如果我们能够标示出已经改变的文件,并只对这些文件做rsync同步,效率应该会大大提高。关于如何标示出修改过的文件,网上其实已经有许多解决办法,我就不当祥林嫂了。引用比较多的是:把某个需要同步的文件夹做成一个hash tree,使用修改时间作为hash值。因为linux下文件的修改,只会反映到该文件所在目录的修改时间,而不会反映到更上层的目录中,所以需要使用inotify接口自己写一个更新以上目录修改时间的同步程序(这个inotify我从没有用过,只是人云亦云罢了)。

  • How to enable runkit PHP extension with lampp

    发表于 2009年09月18日 yejun 1 条评论

    Lampp的php extension目录如下:

    [root@www no-debug-non-zts-20060613]# pwd

    /opt/lampp/lib/php/extensions/no-debug-non-zts-20060613

    [root@www no-debug-non-zts-20060613]# ll

    total 2144

    -rwxr-xr-x 1 root root 52784 Sep 24 2008 dbx.so

    -rwxr-xr-x 1 root root 137256 Sep 24 2008 eaccelerator.so

    -rwxr-xr-x 1 root root 28021 Jun 11 09:57 facedetect.so

    -rwxr-xr-x 1 root root 979070 Feb 27 2009 http.so

    -rwxr-xr-x 1 root root 81600 Sep 24 2008 interbase.so

    -rwxr-xr-x 1 root root 147440 Sep 24 2008 ming.so

    -rwxr-xr-x 1 root root 116440 Sep 24 2008 oci8.so

    -rw-r–r– 1 1000 1000 14354 Jun 7 2006 package2.xml

    -rw-r–r– 1 1000 1000 9820 Jun 7 2006 package.xml

    -rwxr-xr-x 1 root root 110444 Sep 24 2008 pgsql.so

    -rwxr-xr-x 1 root root 35408 Sep 24 2008 radius.so

    drwxr-xr-x 8 root root 4096 Sep 18 14:57 runkit-0.9

    -rw-r–r– 1 root root 49807 Sep 18 14:47 runkit-0.9.tgz

    -rwxr-xr-x 1 root root 177751 Sep 18 14:57 runkit.so

    -rwxr-xr-x 1 root root 59828 Sep 24 2008 sqlite.so

    -rwxr-xr-x 1 root root 56864 Sep 24 2008 zip.so

    新加载了这个runkit.so到php.ini里。

    runkit

    runkit support

    enabled

    version

    0.9

    Custom Superglobal support

    enabled

    Sandbox Support

    disable or unavailable

    Runtime Manipulation

    enabled

     

    过程如下:

    • 下载runkit

        在extension目录下,使用pear download runkit 成功下载runkit-0.9.tgz

    Fix is as follows

    Edit the file /usr/local/src/runkit-0.9/runkit_import.c and change the following line

    zend_unmangle_property_name(key, &cname, &pname);

    To:

    zend_unmangle_property_name(key, key_len, &cname, &pname);


    Again continue with the installation steps.

    #cd /usr/local/src/runkit-0.9
    #make
    #make install


    Edit the loaded PHP configuration file ( here /usr/local/lib/php.ini ) and add the following line.

    extension=runkit.so


    You can verify the runkit extension by

    root@host[/usr/local/src/runkit-0.9]# php -i | grep -i runkit
    runkit
    runkit support => enabled

    PHP
  • 一个接口服务器配置引起性能问题经验[3]

    发表于 2009年08月21日 yejun 没有评论

    一次发布,我们的前端接口API服务器有18台,这18台全部连到后面的一个内网VIP上,这个VIP配置的域名指向6台机器,这6台机器各有三个进程,相当于18台服务器,由于3个进程一台机器能充分发挥物理机的性能,所以没有用虚拟机。

    发布第二天早上发现,18台机器的系统响应非常慢,但LOAD上升,连接数很大,并且大显的TIME_WAIT。后排查发现,NETSTAT的结果中,大量连接指向一台机器。这台机器竟然是预发布的机器,也就是说,原因18台服务器的请求由一台机器在承担,系统负责太高。

    经验:发布时要检查系统之间的内部调用IP,是否配置在生产环境的VIP上。

  • 一次阿里旺旺SNS应用接口问题解决的经验[2]

    发表于 2009年08月21日 yejun 1 条评论

    想到上回发布阿里旺旺上的一个SNS应用接口,这个应用就是传说中的阳光农场。应用需要调用阿里旺旺的用户资料,比如头像,昵称等属性。调用方式是HTTP接口,登录的时候应用会对当前用户所有好友调接口,获取头像URL。

    在用户量达到70万左右时,系统开始出现问题(每个人会有50个游戏好友,相当于早上登录每分钟5000人的话,会有250000HTTP请求),甚至影响了其它子网站的登录。基于一周的排查,验证,确认问题出在头像接口对头像HTTP服务器压力过大引起,并且由于头像URL大多不同,CACHE的命中不高。

    将头像改成一个固定的相同的URL后,问题解决,因为这个URL头像有缓存,并且命中率100%。

    之后用户量再上升,发现又出现问题。系统登录出现问题。后经排查发现,头像接口服务器LOAD很低,没超过1,连接数很大,全部TIME_WAIT。原来头像接口是通过HTTP调用内网另一台服务器B获取到URL,虽然URL已经成为固定值了,但是内网调用还是存在,并且这个内网调用没有走内部VIP的域名,走了公网的普通域名。而B服务器的VIP对公网HTTP请求有访问速率的控制,内网VIP走相对控制较少。系统改成内网VIP后这个问题缓冲。当然最后是去掉了这个内网的调用。

    经验就是:内网高频高并发调用HTTP最好走内网域名和IP,并要注意内网设备的一些限制。

  • 昨晚发布阿云的用户中心经验[1]

    发表于 2009年08月21日 yejun 没有评论

    MEMCACHE三个月没重起了,这次连上后,用户密码从MC中验证后发现,登录失败。。。经验是:以后发布计划上,要密上MC的重启检查。

  • 云计算的电力问题

    发表于 2009年08月1日 yejun 没有评论

    一台普通服务器一年耗电约在1000元。

    阿里巴巴这样的网站,如果服务器数据在5W台这个级别,那么一年的电费将是5000w。而沃尔玛、GOOGLE这样的企业服务器在几十万台,一年的电费开销是相当可观的个数字。

    云计算肯定是大规模的计算,涉及的机器数量一定是具大的,同时云计算一定是经济的。正是因为企业发展需要越来越多的服务器,让这些服务器集中在一起,可以提高计算资源的利用率,让单台服务器更加高效的工作,节省出大量的的电能。节省电能就意味着减少CO2的排放。所以,云计算是一个可能的终局。