Archive for 十二月, 2011

2011-12-31  开发中,积分系统;builder模式改造抽奖领奖流程

2011-12-31  待上线,修改代码,catch异常,即使tokyo崩溃,项目也可运行

2011-12-30  13:30人为操作导致tokyo server崩溃,数据丢失;15点左右,恢复一部分,使网页可运行;17点,全部恢复

安装

http://sourceforge.net/projects/clustershell/files/clustershell/1.5.1/ 下载源码安装。指定安装目录:

python setup.py install

新建配置文件:

mkdir /etc/clustershell

cp conf/* /etc/clustershell

新增配置文件groups:

[admin@v080049 apps]$ cat /etc/clustershell/groups
web: 192.168.80.49 192.168.80.105 192.168.80.106
db: 192.168.80.103 192.168.80.104
需要配置ssh的免密码登录。
使用

简单测试:clush -g web ‘ls’

部署代码:clush -g web “cd ~/prepare/happy_itry_v2/; echo ‘yes’ | ./taobao_push.sh “

双网卡,双IP配置,加静态路由

张映 发表于 2011-12-23

分类目录: 服务器相关

北网通,南电信的问题是很让人郁闷的一件,这也是河蟹社会的一种特色吧。为了解决这个问题,我考虑过三种方案:

1,双网卡,双IP;或者单网卡,双IP。

这种方案,成本低,但是维护挺麻烦,并且速度比后面二个要慢。

2,BGP双线机房。

BGP的费用要比第一种方案要高,但是全国真正是BGP机房的到底有多少,应当就那么几家。其他假的比较多。用这种方案就不用在搞双IP了,一个IP就OK。

3,CDN加速

CDN的价格是最高,买的是dell r410的服务器,拖管在机房,带宽160元/m/月,还是熟人才拿到这价格。我和chinacache的客户经理当面谈过,刚开始的价格是400元/m/月,后来我说是我朋友推荐的,直接降到200元/m/月,这价格降的真是离谱。我有一个linux运维的QQ群,在里面问chinacache的CDN多少钱一个月一M,有得说100多元/m/月,有的说900多元/m/月,卧槽,这差别太大。感觉不规范,所以没用,现在和朋友一起创业,能省就省,所以我选择了第一种方案。扯了这么多,进入正题。

一,服务器服务安排

服务器,我准备了三台dell r410的机器,

1,web服务器

2,mysql服务器

3,文件服务器

每台服务器有二个网卡,eth1走内网,eth0走外网,并且网通和电信都走eth0,这样的方式我个人觉得比一个网卡走网通,一个网卡走电信要快。在交换机上设置二个vlan一个走内网,一个走外网,交换机设置就不在这儿多说了。

二,网络配置

1,cd /etc/sysconfig/network-scripts

2,修改 ifcfg-eth1

  1. [root@localhost network-scripts]# cat ifcfg-eth1
  2. DEVICE=”eth1″
  3. NM_CONTROLLED=”yes”
  4. ONBOOT=”yes”
  5. TYPE=Ethernet
  6. BOOTPROTO=none
  7. IPADDR=192.168.1.2
  8. PREFIX=24
  9. DEFROUTE=yes
  10. IPV4_FAILURE_FATAL=yes
  11. IPV6INIT=no
  12. NAME=”System eth1″
  13. UUID=5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03
  14. HWADDR=78:2B:CB:57:28:E5

3,修改ifcfg-eth0

  1. [root@localhost network-scripts]# cat ifcfg-eth0
  2. DEVICE=”eth0″
  3. NM_CONTROLLED=”yes”
  4. ONBOOT=”yes”
  5. TYPE=Ethernet
  6. BOOTPROTO=none
  7. IPADDR=222.121.121.121
  8. PREFIX=24
  9. GATEWAY=222.121.121.1
  10. NETMASK=255.255.255.128
  11. DEFROUTE=yes
  12. IPV4_FAILURE_FATAL=yes
  13. IPV6INIT=no
  14. NAME=”System eth0″
  15. UUID=9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04
  16. HWADDR=78:2B:CB:57:28:E6

4,cp ifcfg-eth0 ifcfg-eth0:0

  1. [root@localhost network-scripts]# cat ifcfg-eth0:0
  2. DEVICE=”eth0:0″
  3. NM_CONTROLLED=”yes”
  4. ONBOOT=”yes”
  5. TYPE=Ethernet
  6. BOOTPROTO=none
  7. IPADDR=112.121.121.121
  8. PREFIX=24
  9. NETMASK=255.255.255.0
  10. DEFROUTE=yes
  11. IPV4_FAILURE_FATAL=yes
  12. IPV6INIT=no
  13. NAME=”System eth0″
  14. UUID=9c92fad9-6ecb-3e6c-eb4d-8a47c6f50c04
  15. HWADDR=78:2B:CB:57:28:E6

5,重起网络/etc/init.d/network restart

到这儿,双网卡,双IP基本上就配置好,但是网通和电信都是走的电信的网关,这样的话丢包会比较严重的。解决这个问题,有二个比较好的方法,一是加静态路由,一是加策略路由。我用的方法是加静态路由。

三,添加静态路由

route add -net 1.24.0.0 netmask 255.248.0.0 gw 60.12.105.145 dev eth0:0
route add -net 1.56.0.0 netmask 255.248.0.0 gw 60.12.105.145 dev eth0:0

上面是通过命令来加的,如果是双网卡的要加上dev的。因为静态路由有很多条,所以还是一起加比较好。

1,vim route.sh

2,把route add全部加到 route.sh里面

3,chmod +x route.sh

4,开机启动echo “sh /路径/route.sh” >> /etc/rc.local

下载网通路由,下载下来后,根据实际情况后修改

zz from:http://blog.51yip.com/server/1358.html

我们在淘宝开放平台上有一款店铺模块,顾名思义,其分为前台和后台模块两部分。前台模块展现在淘宝卖家的店铺页面里,比如店铺首页、列表页、宝贝详情页等。后台模块仅供购买了该APP的商家使用。

根据淘宝开放平台的规则,前台模块任何人可见,后台模块仅购买该APP的商家可见。这里的可见,即授权成功,由淘宝开放平台控制,仅当授权成功后,才会将控制权交到我们的APP上。

这里比较特殊的一点是,如果用子帐号,如“开心赚宝:开心分享”,登录淘宝,店铺后台模块是无法授权成功的。而同时,其访问店铺页面,又会以edit的模式来请求店铺后台模块!这样就导致了BUG:

父帐号未授权或应用不支持子帐号
 错误码:122

针对这个bug,个人认为目前开发者是没有办法的,只能依赖淘宝平台修复。

可能还是对前端理解不深入,总是觉得css、html是靠死记硬背,而非理解之后使用的。所以老记不住其中的一些东西。今天下决心要搞明白浮动和清理,以及浏览器兼容的各方面事情!

浮动

在w3c的文档里,如此描述浮动:

浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

这个导致的效果是,如果不清除浮动,则:

  • 若父元素里仅包含浮动的子元素,则父元素的宽、高会为0
  • 若子元素A为浮动,B不浮动,则B与A会重叠
  • 若子元素A、B都浮动,则顺序排列

一个div类型的块状元素,本来会占满100%的宽度,浮动后,就会自适应,仅占所需的区域了。

这样的代码:

<div>
       <div style="float:left">left</div>
       <div style="float:right">right</div>
       <div>non float</div>
</div>

产生的效果为:

可见第三个div占满了整个宽度,但是内容还是贴着左浮动的右边框了。

这时可以先清除浮动。

浮动的清理

<div>
    <div style="float:left">left</div>
    <div style="float:right">right</div>
    <div style="clear:both"></div>
    <div style="border:1px solid red;">non float</div>
</div>

产生的效果为:

浮动与块元素

所有被定义为浮动的元素都会被自动变为“块状元素”,也就是代表它可以定义宽度和高度了。

我遇到过的问题

1、多个浮动元素超出父元素宽度时,会折行显示,即超出部分会在下一行显示

2、最好在每组浮动结束后都清除掉浮动,否则会出现莫名其妙的问题。如果在firebug中看到某个父元素的height、width为0,就要注意了

———————————————

绝对定位的问题

子元素A一旦要做绝对定位,就需要将其父元素的postion显示指定,否则在不同浏览器下,会有不同的效果。

这时,需要注意父元素的overflow属性,这将决定着子元素若超出父元素的范围,是否可以显示。可以结合z-index一起使用。

该文章发布时间为2011年12月14日,支付宝的接口之后可能发生变化,本文仅供参考。

支付宝悬赏接口目前仅支持DSA签名方式。

测试阶段:

支付宝会提供4个key给开发者,即合作网站私钥、合作网站公钥、支付宝私钥、支付宝公钥,作为合作网站,我们真正使用的是合作网站私钥和支付宝公钥。在向支付宝发送请求时,使用合作网站私钥对url参数进行签名;在接收支付宝的返回时,使用支付宝公钥验证返回的内容。

php使用openssl_pkey_get_private将字符串形式的私钥转化为可用的resource。这里,由于dsa签名有多种,比如1026bit、是否encrypt之类,所以需要获悉支付宝在生成该私钥时使用的命令参数。经过网上搜索获悉:

1. 生成 DSA 参数
openssl dsaparam -out dsa_param.pem 1024
2. 生成 DSA 私钥
openssl gendsa -out dsa_private_key.pem dsa_param.pem
3. 生成 DSA 公钥
openssl dsa -in dsa_private_key.pem -pubout -out dsa_public_key.pem
4. 将 DSA 私钥转换成 PKCS8 格式
openssl pkcs8 -topk8 -inform PEM -in dsa_private_key.pem -outform PEM -nocrypt
生成的私钥文件如下:
—–BEGIN PRIVATE KEY—–
第一行64个字符
……
第七行64个字符
—–END PRIVATE KEY—–

支付宝提供的密钥若没有换行符,可自行进行换行,并添加头尾,以适合该格式。

支付宝文档里提供的DSA签名命令为:

openssl dgst  –dss1 -sign dsa_private_key.pem  -out dsasign.bin plaintext.tx

可见,其使用的签名算法是dss1,对应到php中就是OPENSSL_ALGO_DSS1,故签名步骤:

//除去待签名参数数组中的空值和签名参数

$querys = $this->paraFilter($querys);

// 排序

$querys = $this->argSort($querys);

$querys[‘sign’] = $this->sign($this->createLinkstring($querys), $this->private_key);

$querys[‘sign_type’] = ‘DSA';

function sign($data, $private_key) {

$res = openssl_pkey_get_private($private_key);

openssl_sign($data, $sign, $res, OPENSSL_ALGO_DSS1);

openssl_free_key($res);

//base64编码

$sign = base64_encode($sign);

return $sign;

}

在使用openssl族的函数进行开发时,可使用如下代码进行调试,查看openssl的出错信息:

          $res = openssl_pkey_get_private($private_key);

          // Show any errors that occurred here

          while (($e = openssl_error_string()) !== false) {

              echo $e . "\n";

          }

          var_dump($res);

开发阶段:

使用openssl函数或者命令,生成合作网站自己的私钥和公钥,将公钥提供给支付宝。并从支付宝处获取他们提供的支付宝公钥,即可。

我们的念头总是很多,以刚才的我为例。刚写完一个功能,于是起来走走。第一个念头是,燃一炷香。这个念头刚起,又想给妈妈打电话,继而又想起家里煤气有问题要给燃气公司打电话。一瞬间里,这3个只是粗的念头,微细念头更不知有多少!

如果随顺了自己的习气,那可能我刚才做的不是去燃一炷香,而是先打了某个电话。那第一个念头可能就被忘记了。这样的次数一多,就会觉得烦躁,因为做事的顺序不是依次而行的,而是东一下、西一下,毫无章法。

而如果能够专注的做事,察觉每个念头的升起,觉知这个念头是否与佛法相契合,若契合那么便全神贯注地做完,然后等待下一个念头的升起。我相信,这种生活会是精进和愉悦的。

设置-通用-网络-蜂窝数据网络-彩信
apn: cmwap    mmsc: http://mmsc.monternet.com   mms代理服務器: 10.0.0.172    mms最大信息大小:50000
配置成功后,“信息”左下角的照相机图片可点。相册的转发中包含“信息”选项。

最近学别人,搞了个流式布局的页面,使用了kissy框架。但是该框架要求提前知道img的height,否则若加载图片过慢,会造成图片重叠。

对于前端不熟悉,所以采取了提前获取图片真实高度的方法。

网上搜到了获取jpg图片信息的方法,基本原理是,图片的基本信息如宽、高、size等信息都是存储在文件的前几十个字节里的,所以不用获取全部文件,仅分析前面几十个字节并解析就可以获取这些信息了。

// 获取图片尺寸: 图片的信息都存储的前面几个字节里,获取并分析即可获取尺寸信息(但是我不懂的……)
function getjpegsize($img_loc) {/*{{{*/
        if (!$img_loc){
                return false;
        }
        $handle = fopen($img_loc, "rb");// or die("Invalid file stream.");//die == exit
        $new_block = "";
        if(!feof($handle)) {
                $new_block = fread($handle, 32);
                $i = 0;
                if($new_block[$i]=="\xFF" && $new_block[$i+1]=="\xD8" && $new_block[$i+2]=="\xFF" && $new_block[$i+3]=="\xE0") {
                        $i += 4;
                        if($new_block[$i+2]=="\x4A" && $new_block[$i+3]=="\x46" && $new_block[$i+4]=="\x49" && $new_block[$i+5]=="\x46" && $new_block[$i+6]=="\x00") {
                                // Read block size and skip ahead to begin cycling through blocks in search of SOF marker
                                $block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
                                $block_size = hexdec($block_size[1]);
                                while(!feof($handle)) {
                                        $i += $block_size;
                                        $new_block .= fread($handle, $block_size);
                                        if($new_block[$i]=="\xFF") {
                                                // New block detected, check for SOF marker
                                                $sof_marker = array("\xC0", "\xC1", "\xC2", "\xC3", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xCA", "\xCB", "\xCD", "\xCE", "\xCF");
                                                if(in_array($new_block[$i+1], $sof_marker)) {
                                                        // SOF marker detected. Width and height information is contained in bytes 4-7 after this byte.
                                                        $size_data = $new_block[$i+2] . $new_block[$i+3] . $new_block[$i+4] . $new_block[$i+5] . $new_block[$i+6] . $new_block[$i+7] . $new_block[$i+8];
                                                        $unpacked = unpack("H*", $size_data);
                                                        $unpacked = $unpacked[1];
                                                        $height = hexdec($unpacked[6] . $unpacked[7] . $unpacked[8] . $unpacked[9]);
                                                        $width = hexdec($unpacked[10] . $unpacked[11] . $unpacked[12] . $unpacked[13]);

                                                        $stream_meta_data = stream_get_meta_data($handle); //这里可以得到文件大小
                                                        //print_r($stream_meta_data);
                                                        $result['width']=$width;
                                                        $result['height']=$height;
                                                        foreach($stream_meta_data['wrapper_data'] as $va){
                                                                if(preg_match("/length/iU",$va)){
                                                                        $ts=explode(":",$va);

                                                                        $result['size']=trim(array_pop($ts));
                                                                }
                                                        }
                                                        $stream_meta_data = NULL;
                                                        $new_block=NULL;
                                                        fclose($handle);
                                                        return $result;
                                                } else {
                                                        // Skip block marker and read block size
                                                        $i += 2;
                                                        $block_size = unpack("H*", $new_block[$i] . $new_block[$i+1]);
                                                        $block_size = hexdec($block_size[1]);
                                                }
                                        } else {
                                                fclose($handle);
                                                return false;
                                        }//\xff
                                }//while
                        }//newblock
                }//$new_block[$i]
        }//feof
        fclose($handle);
        return false;
}/*}}}*/

当获取到这些信息之后,按照显示尺寸进行修改:$ret[‘height’] = intval($pic_info[‘height’] * 192.0 / $pic_info[‘width’]);

这样,显示时img代码如下:

<img src=”<?php echo $item[‘pic_url’];?>_250x250.jpg” width=”192″ <?php echo empty($item[‘height’])? ‘min-height=100′: ‘height=”‘.$item[‘height’].'”‘;?> >

今天在调用淘宝开放平台API的时候,某些情况下会报HTTP_RESPONSE_NOT_WELL_FORMED的错误,查看top的sdk,发现是json_decode的时候返回NULL。

获取原字符串,未看出什么不对的,只是有一些换行,replace之后,json_decode返回正确的objet值。

猜测是否是java的json_encode与php的有所区别?

修改top/TopClient.php的execute函数,在默认的情况下,置为false,因为不是所有的top接口都需要处理的。仅在需要的时候,设置为true即可。红色部分为我添加的。

    public function execute($request, $session = null, $need_replace=false/*cy add*/)
      {
          /* ....... */

          //解析TOP返回结果
          $respWellFormed = false;
          if ("json" == $this->format)
          {
              if ($need_replace){
                  $resp = preg_replace('/[\r\n]+/','', $resp); // cy add, 20111201, TraderatesSearchRequest need
              }

              $respObject = json_decode($resp);
              if (null !== $respObject)
              {
                  $respWellFormed = true;
                  foreach ($respObject as $propKey => $propValue)
                  {
                      $respObject = $propValue;
                  }
              }
          }

         /* ....... */
       }