无来

不管你来还是不来
我都在这里,夜夜点亮
不是为了守候
只是为了做好我自己

0%

在电商网站中,单页Web是非常常见的一种形式,比如首页、频道页、广告页等都属于单页应用。而这种页面是由模板+数据组成。传统的构建方式一般通过静态化实现。而这种方式的灵活性并不是很好,比如页面模板部分变更了需要重新全部生成。因此最好能有一种实现方式是可以实时动态渲染,以支持模板的多变性。另外也要考虑好如下几个问题:

  • 1、动态化模板渲染支持; 2、数据和模板的多版本化:生产版本、灰度版本和预发布版本; 3、版本回滚问题,假设当前发布的生产版本出问题了如何快速的回滚到上一个版本; 4、异常问题,假设渲染模板时遇到了异常情况(比如获取Redis出问题了),如何处理; 5、灰度发布问题,比如切20%量给灰度版本; 6、预发布问题,目的是在正式环境测试数据和模板的正确性。
  • 整体架构

    静态化页面的方案如下图所示:
    [转]应用数据静态化架构高性能单页Web应用

    直接将生成的静态页推送到相关服务器即可。使用这种方式要考虑文件操作的原子化问题(即从老版本切换到新版本如何做到文件操作原子化)。

    而动态化方案的整体架构如下图所示,分为三大系统:CMS系统、控制系统和前端展示系统。
    [转]应用数据静态化架构高性能单页Web应用

    ###CMS系统
    1、在CMS系统可以配置页面的模板和数据;
    1.1、模板动态在CMS系统中维护,即模板不是一个静态文件,而是存储在CMS中的一条数据,最终发布到“发布数据存储Redis”中,前端展示系统从Redis中获取该模板进行渲染,从而前端展示系统更换了模板也不需要重启,纯动态维护模板数据;
    2、原始数据存储到“元数据存储Mysql”中即可,比如频道页一般需要:前端访问的URL、分类、轮播图、商品楼层数据等;这些数据按照相应的维度存储在CMS系统中;
    3、提供发布到“发布数据存储Redis”的控制,将CMS系统中的原始数据和模板数据组装成聚合数据(JSON存储)同步到“发布数据存储Redis”,以便前端展示系统获取进行展示;此处提供三个发布按钮:正式版本、灰度版本和预发布版本。

    目前存在如下几个问题:
    1、用户如访问http://channel.jd.com/fashion.html怎么定位到对应的聚合数据呢? 我们可以在CMS元数据中定义URL作为KEY,如果没有URL,则使用ID作为KEY,或者自动生成一个URL。
    2、多版本如何存储呢? 使用Redis的Hash结构存储即可,KEY为URL(比如http://channel.jd.com/fashion.html),字段按照维度存储:正式版本使用当前时间戳存储(这样前端系统可以根据时间戳排序然后获取最新的版本)、预发布版本使用“predeploy”作为字段,灰度版本使用“abVersion”作为字段即可,这样就区分开了多版本。
    3、灰度版本如何控制呢?这个通过控制系统的开关来控制如何灰度;
    4、如何访问预发布版本呢?比如在URL参数总带上predeploy=true,另外可以限定只有内网可以访问或者访问时带上访问密码,比如pwd=absdfedwqdqw。
    5、模板变更的历史数据校验问题?比如模板变更了,但是使用历史数据渲染该模板会出现问题,即模板要兼容历史数据的;此处的方案不存在这个问题,因为每次存储时是当时的模板快照,即数据快照和模板快照推送到“发布数据存储Redis”中。

    前端展示系统
    1、获取当前URL,使用URL作为KEY首先从本机“发布数据存储Redis”获取数据;
    2、如果没有数据或者异常则从主“发布数据存储Redis”获取;
    3、如果主“发布数据存储Redis”也发生了异常,那么会直接调用CMS系统暴露的API直接从元数据存储Mysql中获取数据进行处理。

    展示系统的伪代码

    Java代码  
    --1、加载Lua模块库  
    local template = require("resty.template")  
    template.load = function(s) return s end  
    
    --2、动态获取模板  
    local myTemplate = "<html>{* title *}</html>"  
    --3、动态获取数据  
    local data = {title = "iphone6s"}  
    
    --4、渲染模板  
    local func = template.compile(myTemplate)  
    local content = func(data)  
    
    --5、通过ngx API输出内容  
    ngx.say(content)  
    即模板和数据都是动态获取的,然后使用动态获取的模板和数据进行渲染。

    此处假设最新版本的模板或数据有问题怎么办?这个可以从流程上避免:1、首先进行预发布版本发布,测试人员验证没问题后;2、接着发布灰度版本,在灰度时自动去掉CDN功能(即不设置页面的缓存时间),发布验证OK;3、发布正式版本即可;正式版本发布的5分钟内是不设置页面缓存的,这样就可以防止发版时遇到问题,但是问题版本已经在CDN上给全部用户造成问题。当然这个流程很麻烦,可以按照自己的场景进行简化。

    控制系统
    控制系统用于版本降级和灰度发布的,当然可以把这个功能放在CMS系统中实现。
    版本降级:假设当前线上的版本遇到问题了,想要快速切换回上一个版本,可以使用控制系统实现,选中其中一个历史版本然后通知给前端展示系统即可,使用URL和当前版本的字段即可,这样前端展示系统就可以自动切换到选中的那个版本;当问题修复后,再删除该降级配置即切换回最新版本。
    灰度发布:在控制系统控制哪些URL需要灰度发布和灰度发布的比例,同版本降级类似将相关的数据推送到前端展示系统即可,当不想灰度发布时删除相关数据即可。

    数据和模板动态化

    我们将数据和模板都进行动态化存储,这样可以在CMS进行数据和模板的变更;实现了前端和后端开发人员的分离;前端开发人员进行CMS数据配置和模板开发,而后端开发人员只进行系统的维护。另外因为模板的动态化存储,每次发布新的模板不需要老重启前端展示系统,后端开发人员更好地得到了解放。

    模板和数据可以是一对多的关系,即一个模板可以被多个数据使用。假设模板发生变更后,我们可以批量推送模板关联的数据,首先进行预发布版本的发布,测试人员进行验证,验证没问题即可发布正式版本。

    多版本机制

    我们将数据和模板分为多版本后,可以实现:
    预发布版本:更容易让测试人员在实际环境进行验证;
    灰度版本:只需要简单的开关控制,就可以进行A/B测试;
    正式版本:存储多个历史正式版本,假设最新的正式版本出现问题,可以非常快速的切换回之前的版本。

    异常问题

    其中一个担心就是本机从“发布数据存储Redis”和主“发布数据存储Redis”都挂了,那么我们直接调用CMS系统暴露的HTTP服务直接从元数据存储Mysql获取数据。

    另外一个担心是数据和模板获取到了,但是渲染模板出错了,比如遇到500、503;解决方案是:使用上一个版本的数据进行渲染。

    另外还一种问题是数据和模板都没问题,但是因为一些疏忽,渲染出来的页面错乱了或者有些区域出现了空白;对于这种问题没有很好的解决方案;可以根据自己的场景定义异常扫描库,扫描当前版本有异常就发警告给相关人员,并自动降级到上一个版本。

    来源:开涛的博客

    mysql 5.5已经出来有一段时间,性能有明显提升,特别是对多核CPU的支持与TPS性能的提升。上周博主介绍了linux下编译安装mysql 5.5的步骤,安装不出意外基本没有问题。不过可能很多朋友和我一样一直用的是mysql 5.1,现在想把数据库升级成5.5了。博主根据实际操作,记录这次升级操作。

    mysql基础信息

    1、安装目录
    [root@vm-199~]# /usr/local/mysql
    2、配置文件
    [root@vm-199~]# /etc/my.cnf
    3、数据目录
    [root@vm-199~]# /data/mysql
    4、启动脚本
    [root@vm-199~]# /etc/init.d/mysql

    备份数据和安装、配置文件

    [root@vm-199~]# mysqldump -uroot -p –all-databases </root/zhangnq/mysql5.1/mysql_dbk_20140217.sql [root@vm-199~]# tar czvf mysql_5.1.60_full.tar.gz /usr/local/mysql [root@vm-199~]# tar czvf mysql_5.1.60_data_full.tar.gz /data/mysql [root@vm-199~]# cp /etc/my.cnf ./

    数据备份好后关闭mysql数据库,/etc/init.d/mysql stop,删除/usr/local/mysql文件。

    安装mysql 5.5

    具体可以参考这篇文章《Linux下编译安装Mysql-5.5的简单步骤》(http://www.sijitao.net/1563.html),安装目录、数据目录和5.1的一样,都是/usr/local/mysql

    更新配置文件

    [root@vm-199 mysql-5.5.35]# cp support-files/my-huge.cnf /etc/my.cnf

    在配置文件中添加数据目录,datadir = /data/mysql 。

    启动mysql 5.5,执行更新程序并重启mysql

    [root@vm-199 mysql-5.5.35]# /etc/init.d/mysql start [root@vm-199 mysql-5.5.35]# /usr/local/mysql/bin/mysql_upgrade Looking for 'mysql' as: /usr/local/mysql/bin/mysql Looking for 'mysqlcheck' as: /usr/local/mysql/bin/mysqlcheck Running 'mysqlcheck' with connection arguments: '--port=3306' '--socket=/tmp/mysqld.sock' Running 'mysqlcheck' with connection arguments: '--port=3306' '--socket=/tmp/mysqld.sock' mydb.t1 OK mydb.t2 OK mysql.columns_priv OK mysql.db OK mysql.event OK mysql.func OK mysql.general_log OK mysql.help_category OK mysql.help_keyword OK mysql.help_relation OK mysql.help_topic OK mysql.host OK mysql.ndb_binlog_index OK mysql.plugin OK mysql.proc OK mysql.procs_priv OK mysql.proxies_priv OK mysql.servers OK mysql.slow_log OK mysql.tables_priv OK mysql.time_zone OK mysql.time_zone_leap_second OK mysql.time_zone_name OK mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK Running 'mysql_fix_privilege_tables'... OK
    至此mysql已经更新好了。登陆mysql,检查数据是否和原来一样。

    这个mysql升级其实不复杂,其实就是重新安装一遍,然后把数据目录文件覆盖一下。不过数据库升级,主要还是得注意数据备份,防止数据和意外丢失。

    • 查找目录下的所有文件中是否含有某个字符串
      find .|xargs grep -ri "IBM"

    • 查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名
      find .|xargs grep -ri "IBM" -l

    • 仅查找文件
      find . -type f|xargs grep -ri "IBM" -l

    • 查找文件为0,包括空格处理
      find . -type f -size 0c -print0 |xargs -0 ls -l {}

    • 删除为0的文件
      find . -type f -size 0c -print0 |xargs -0 ls -l {}

    CentOS Linux Server 会将许多系统运行的状态发邮件给管理员root用户,系统邮件存放在 /var/spool/mail/root 目录中,可以通过使用 mail 命令来查看邮件,但是时间长了,也会造成邮件过多,如何使用 Shell 命令来批量删除或者全部删除呢?

      方法一:使用mail命令,然后在 & 提示符下使用 d 命令(Delete),批量删除邮件,例如删除1~53邮件:

      # mail
      & d 1-53

      方法二:删除全部系统邮件

      # > /var/spool/mail/root or cat /dev/null > /var/spool/mail/root

      或者

      # echo “d *” |mail -N

    有時候系統會提示收到郵件,通常是一些系統錯誤的通知,看完確認沒問題就可以刪了。

    通知長得像這樣:
    You have new mail in /var/spool/mail/root
    刪除的方法很簡單,用以下兩種指令擇一即可。

    cp /dev/null /var/spool/mail/root

    /var/spool/mail/root
    這樣就會清空root的mail。

    在配置Hadoop集群分布时,要使用SSH免密码登录,假设现在有两台机器hadoop@wang-PC(192.168.10.100),作为A机,hadoop@chen-PC(192.168.10.107),作为B机。现想hadoop@wang-PC通过ssh免密码登录到hadoop@chen-PC。

    1.在A机下生成公钥/私钥对。

    [hadoop@wang-PC ~]$ ssh-keygen -t rsa -P ''

    敲击回车键即可,
    它在/home/hadoop下生成.ssh目录,.ssh下有id_rsa和id_rsa.pub。

    2.把A机器下的id_rsa.pub复制到B机器下的.ssh/authorized_keys文件里。

    [hadoop@wang-PC ~]$ scp .ssh/id_rsa.pub hadoop@192.168.10.107:/home/hadoop/id_rsa.pub.hadoop_wang
    hadoop@192.168.10.107's password:

    由于还没有免密码登录的,所以要输入密码。

    3.B机把从A机复制的id_rsa.pub.hadoop_wang添加到.ssh/authorzied_keys文件里。

    [hadoop@chen-PC ~]$ cat id_rsa.pub.hadoop_wang >> .ssh/authorized_keys
      [hadoop@chen-PC ~]$ chmod 600 .ssh/authorized_keys

    authorized_keys的权限要是600。

    4.A机登录B机。
    [hadoop@wang-PC ~]$ ssh 192.168.10.107
    第一次登录是时要你输入yes。
    现在A机可以无密码登录B机了。

    小结:登录的机子可有私钥,被登录的机子要有登录机子的公钥。这个公钥/私钥对一般在私钥宿主机产生。上面是用rsa算法的公钥/私钥对,当然也可以用dsa(对应的文件是id_dsa,id_dsa.pub)
    想让A,B机无密码互登录,那B机以上面同样的方式配置即可,把B的公钥复制过去添加到authorized_keys的末尾就行了。
    至此完毕。

    补充
    配置本地ssh config文件。执行:
    vi ~/.ssh/config
    加入以下内容:
    Host cssor_server #别名,域名缩写
    HostName cssor.com #完整的域名
    User cssor #登录该域名使用的账号名
    PreferredAuthentications publickey #有些情况或许需要加入此句,优先验证类型ssh
    IdentityFile ~/.ssh/id_rsa #私钥文件的路径

    4 采用 ssh-copy-idß

    [hadoop@wang-PC ~]$  ssh-copy-id -i ~/.ssh/id_rsa.pub remote-host

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
            break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
            break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
            break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
            break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
            break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
            break;
        default:
            echo ' - Unknown error';
            break;
    }

    我碰到的错误

    echo mb_detect_encoding($passengers);
    $json = str_replace('&amp;quot;', '"', $passengers);

    不能够形成一个生态的商业模式都是危险的。可能就是庞氏骗局或者传销