最后1KM 没想象的那么简单

写这篇文章,源于最近我个人的一次电商购物体验。在国内一家号称很棒的3C购物平台(后面简称某D)上下单买了件大家电,结果遭遇送货尬尴,导致整个购物体验很糟糕。事后向客服反馈,倒也是很有诚意的一直道歉,那又有什么用呢。因为我已不会再次选择某D做大家电的购物。

很多时候,我们可以用一条鱼腥了一锅汤来委婉的解释这个。其实我们可以想一下,无非是由于某D不擅长或能不可及业务,才会将大家物流外包出去。因为只有这样才不会制约自身的发展。而由于公司的出身、文化或利益的不同,往往导致外包出去的服务品质无法达到某D的标准或与其相当,最终就变成了上面例子这样。

做互联网的人喜欢那apple举例,我也来凑个热闹。试想,apple做iPhone,并没有那么多硬件生产线,怎么还能把iPhone的整体品质做到一个行业标杆呢。很重要的一点就是供应链,这不是一个简单的上下游供应商的问题。更像是一门工程科学,需要严谨的科学支撑。显然,这不是土生土长的天朝人民的做事方法,所以怎么样:虎头蛇尾,开头都很好,无法保证产品(服务)品质的一贯性往往成为了现在或者短期内大家看到的样子。

而互联网另外一个最大的特点就是无国界性,任何好的产品和服务都在潜移默化的淘汰着不合理、落后的商业形态。泡沫众生的时候,可能没人意识到这个,但是如今很多行业的寒冬都已经到来,产品(服务)的精细化和一致化如果再不被重视,那么可能春天的脚本真的不会那么快到来了。

落地一些,说说传统制造业。大量的用户去海外购买产品,特别最近的日本购物热潮,也凸显出来国货的竞争力瓶颈在精细化的和人性化方面还有很大潜力,换言之就是现在做的很差劲。而这种变革,需要那只看不见的手去操作,但现阶段的经济环境和全民的意识还没办法真正让那只手有效的操作起来。

俗话说,不合理及市场。但愿本文能够给与更多人一些启发吧…

阅读全文...

scribe 安装记录

scribe是facebook的一款日志收集系统,看到fb瞬间觉得高大上的产品,但是整个安装历程很是坎坷啊,所以才把他记录下来,省得以后再次踩坑。

1. 系统依赖

a、gcc和gcc-c++ (vision 4.1.2 pass)

b、ruby (vision 1.8.5 pass)

c、python (vision 2.4.3 pass) 含 python 和 python-devel

d、libevent (vision 1.4 pass) 含 libevent 和 libevent-devel

e、其他: openssl-devel, bison, autoconf(vision > 2.65), bzip2-devel, automake

可以使用这个来解决依赖

sudo yum install automake libtool flex bison pkgconfig gcc-c++ boost-devel libevent-devel zlib-devel python-devel ruby-devel openssl-devel

一定不要着急装后面的组件 先把这些确认好 否则可能会重新安装 折腾起来更麻烦

2. 安装前置组件

boost   1.5.4
thrift    0.9.0
fb303    thrift包中已包含

2.1 安装 boost

这是一个C++的标准库,用来后续编译c++代码使用

wget http://nchc.dl.sourceforge.net/project/boost/boost/1.45.0/boost_1_45_0.tar.bz2

tar jxvf boost_1_45_0.tar.bz2

cd boost_1_45_0

./bootstrap.sh

./b2 install

。。。此过程巨慢 需要等待

默认安装到了/usr/local/include/boost/下

2.2 安装 thrift & fb303

thrift同样是fb退出的一款框架,旨在打通多种语言程序之间的开发。

看到这里就知道了,其实fb的蓝图很大,为什么scribe不是一个单独的软件包了。安装了这些框架和编译库,你就有了fb的基础开发环境,当然fb之后的新东西也就0基础安装了。并且这也会传染其他开发者一起使用这套开发框架… 榜样作用嘛

A、trift安装

wget http://mirror.bjtu.edu.cn/apache/thrift/0.7.0/thrift-0.7.0.tar.gz

tar zxvf thrift-0.7.0.tar.gz

cd thrift-0.7.0.tar.gz

./configure CPPFLAGS="-DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H"

make

make install

*configure时CPPFLAGS参数不可少,否则make时会产生诸如“uint_32未定义”之类错误。另外,configure时如找不到boost库,则需使用--with-boost参数指定boost库位置。thrift安装后可以进行简单的测试以确认是否安装成功。

B、fb303安装

cd contrib/fb303/

./bootstrap.sh

./configure

make

make install

C、运行一下thrift的例子(可选 这个步骤可以验证之前的组件是否都工作正常)

cd tutorial

thrift -r --gen cpp tutorial.thrift

cd cpp

make

./CppServer 可以启动Server

./CppClient 可以启动Client

3. 安装scribe

下载安装包 https://github.com/facebookarchive/scribe 并且解压进入目录

./bootstrap.sh

./configure (如上一条命令出现报错 请参见下面的特殊参数)

make

make install

报错看这里 基本上这里不保存的可能性不大

  • 典型错误 1
configure时遇到
checking whether the Boost::System library is available… yes
checking whether the Boost::Filesystem library is available… yes
configure: error: Could not link against  !
则需在configure时加上参数
--with-boost-system=lboost_system
--with-boost-filesystem=lboost_filesystem
  • 典型错误2
make时遇到
undefined reference to 'boost::system::generic_category()'
undefined reference to 'boost::system::system_category()'
在确认boost::system库存在且路径正确后,检查GCC链接代码(根据make输出)
g++  -Wall -O3 -L/usr/local/lib/ -lboost_system -lboost_filesystem  -o scribed store.o store_queue.o conf.o file.o conn_pool.o scribe_server.o network_dynamic_config.o dynamic_bucket_updater.o  env_default.o  -L/usr/local/lib -L/usr/local/lib -L/usr/local/lib -lfb303 -lthrift -lthriftnb -levent -lpthread  libscribe.a libdynamicbucketupdater.a
此时需将-lboost_system -lboost_filesystem两个选项放在最后,并在src目录下手动执行链接即可完成编译。

我当时遇了上面的错误1,试验了好多种方法,终于得到了解决,最终我的configure参数是这样的

./configure --config-cache --prefix=/usr/local --with-boost=/usr/local/lib --with-boost-system=boost_system --with-boost-filesystem=boost_filesystem CPPFLAGS="-DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H -DBOOST_FILESYSTEM_VERSION=3"

4 参考资料

  1. http://www.2cto.com/os/201307/224832.html
  2. http://abentotoro.blog.sohu.com/190515962.html
  3. http://www.linuxidc.com/Linux/2012-12/76340.htm
  4. http://shiyanjun.cn/archives/107.html
阅读全文...

来自一个O2O产品的笑话

这里讲述一个O2O的真实案例,虽然我对O2O也深感兴趣,但理智最终总会占据上峰。

一个O2O家政类服务,名字就不提了,这里暂且成为AppX。第一次知道AppX的时候,是一次跟朋友聊O2O方面的一些事情了解的,感觉是对线下传统家政行业的一个颠覆,也是由此,我第一次使用了这个AppX。我的使用场景是叫一个小时工打扫卫生。

注册,登录,然后填写地址信息,系统给我推荐了几名小时工,我选择了一位评价比较好的,约上了。由于是非工作时段,订单下好后并没有提示什么,次日上午,接到电话,说是客服确认订单,跟我核对一遍订单信息后,说了关键的一句,如果预约的这名小时工时间不便,可否换成其他人,我也没多想,就同意了。

结果正应了这个电话,原来预约的小时工被替换了,订单信息发生变更,期初没觉得怎么不妥,无意当中点入到小时工的评价中,看到了好多负面评价。然后第一感觉是不靠谱,我先后2次电话客服,说明我的疑虑,并且我特意说道“我是第一次使用这个AppX,我想获得一个比较好的体验,以便以后可以再次使用”,但是最终迟到的客服回馈告诉我,要么用这个小时工,要么取消订单。我一下子无语了,因为我本身也做过O2O的项目,出现这种情景,应该是O2O所有团队都不愿看到的。但是,那么 意外,他就发生了。

最后把这个事情将给朋友,朋友笑喷了。反过来想想,的确有意思。你开了家店,热心的把握迎进来,然后说有各种好吃的食物,结果点什么都没有,最后还告诉我只省最难吃的XXX,好评很差,问我吃不吃?

说几点从我个人经历感觉到的问题:

1、你准备好了么?

其实这个问题不该问,因为现在的创业者都是先用各种言辞说服投资人,然后再做事情,更况且有些人做出来的的并不是之前想的。显然,AppX并没有准备好接待他的顾客,因为店里的好吃的都卖光了。

2、互联网产品出身的人天生不适合做O2O

可能有人会说我的话太偏激,但是至少我的阅历告诉我,互联网产品出生的人大多情况都在创造伪需求,教育用户。因为互联网本身是没有任何价值可言的,所以互联网产品出身的人,通常都在想尽一切办法把用户搞进来,然后再教给用户怎么玩。而O2O是利用互联网这个工具,将传统行业进行提速。其本质是传统行业的互联网渠道营销。主要就表现为:您将点一份好评率很低的食物,请问是否要吃?既然互联网是低成本,高效率的工具,我为什么要吃这个,我大可还一家嘛~

3、一切泡沫最终都将消失

虽然现在仍在有人打着各种投资商喜欢的旗号骗吃骗喝,但已然变成了少数。越是高效的工具,越会快速的淘汰逐末,只是最终总是要有人为这个买单,投资商么?是的,但是他们不差钱。其实损失最大的时用户群的再次使用可能。国人骗来骗去太多了,所以大众很快就得到了免疫,信用危机不是一时能够解决的,但是最终肯定是损害了这个行业的用户信心。

我不否认靠搞钱生存的行业和现状,该死的华尔街教给了大家这个,没办法。但是一切不从实际出发的,不踏实的,建立在伪需求之上的产品都应该快速的被淘汰。

阅读全文...

进程管理工具 Supervisord

用强大来形容他一点都不为过,该工具源起python。目前已经成为一款很成熟的进程管理工具。通过简单的安装配置,就可以将你的非daemon进程转成daemon进程。比如自己的写的各种小程序,都可以瞬间华丽变身。
这里科普一下,为啥要转成daemon?简单的说,就是把你的程序从应用层面提升到服务层面(不管你的程序是否具有服务的层次)
下面进入正题:

1.安装
一种推荐的方法a)是使用easy_install,一种python的安装工具,可以方便的下载,安装,更新Python packages。
如果已经安装easy_install 只要在shell中输入 easy_install supervisor
b)如果木有,也不想使用easy_install,那就去http://pypi.python.org/pypi/supervisor下载,然后解包python setup.py install吧
更多安装方法也可以参照 http://supervisord.org/installing.html

2.配置
以下命令请在shell运行

echo_supervisord_conf > /etc/supervisord.conf
mkdir /etc/supervisord.conf.d
cat << EOF >> /etc/supervisord.conf.d
[include]
files = /etc/supervisord.conf.d/*.conf
EOF

如果需要打开web监控,请将如下配置前的分号去掉
[inet_http_server] ; inet (TCP) server disabled by default
port=127.0.0.1:8080 ; (ip_address:port specifier, *:port for all iface)
username=user ; (default is no username (open server))
password=123 ; (default is no password (open server))

3.给进程建立配置文件
为了方便配置的维护,所有进程配置请保存在/etc/supervisord.conf.d/路径下,以*.conf形式

vi /etc/supervisord.conf.d/yourprogram.conf

配置例子如下
[program:yourprogram]
directory = /var/program
command = /var/program/yourprogram
autostart = true
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile = /var/log/supervisord/yourprogram.log

详细配置请参加官方文档 http://supervisord.org/configuration.html#program-x-section-settings

4.启动
以root身份 在shell中输入 supervisord 即可。

阅读全文...

WebSocket over Nginx

WebSocket让我们体验到了别样的http,最近小研究了一下。如何讲websocket app如何部署,从而开放给用户使用,是这篇文章将要主要描述的内容。本人对Nginx一直很钟情,所以下面将描述一下nginx上的websocket配置。

1.首先,检查你的nginx版本,nginx -v 如果是1.4以下,不好意思,快去update吧,否则是无法顺利支持websocket的。

2.基础配置其实很简单,下面是我的一个chat app的配置,首先配置一个upstream,然后在具体的server localtion中把代理配好就可以了。nginx的另外一个优势就是强大的proxy,websocket app一般都工作在非80端口,用上这个proxy就可以将应用和你的网站融为一体了。

upstream lab_chat {
server 127.0.0.1:8080; # your websocket app here
}

location ~ /wschat/ {
proxy_pass http://test_chat;#必须
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;#必须
proxy_set_header Upgrade $http_upgrade;#必须
proxy_set_header Connection "upgrade";#必须
proxy_send_timeout 1h;#send 超时时间 记得一定要按需配置这个 否则默认60s就断开了
proxy_read_timeout 1h;#read 超时时间
}

3.参考文献&更多高级配置
http://blog.martinfjordvald.com/2013/02/websockets-in-nginx/
http://siriux.net/2013/06/nginx-and-websockets/

阅读全文...

一点点关于angularjs,一点点关于framework

最近在使用angularjs,感受一下用它来制作后台的便捷,的确值得一试。这里分享一个angularjs最常用的指令ng-repeat(类似与php中的foreach,js中的for)使用细节上的小问题。

ng-repeat可以用于js的数组和对象,可以对其中的元素进行遍历,当我首次使用ng-repeat的时候,只想对一个简单数组进行遍历(数据结构决定了我会使用很多js简单对象来存储数据),但是刚刚开始就发现了问题。猛戳这里在线demo ,代码如下:
js部分

$scope.list = ['item1','item2','item3'];

 

html部分

 

在demo中,可以发现,input的显示是没有问题,但是编辑里面内容的时候,会发现任意修改之后,马上input就失去了焦点,无法正常编辑(后来研究了一下,貌似是因为angularjs底层的watch做的怪)。然后翻遍了angularjs的document和stackoverflow,竟然没有解决办法,stackoverflow唯一靠谱的替代方案把简单数组转成如下结构,该问题得到解决。

$scope.list = [
    { val: 'item1'},
    { val: 'item2'},
    { val: 'item3'}
]

 

但是这样改变了数据结构,很不爽。所以去angularjs的github里面提了suggest,得到一个汗颜的答案,angularjs的代码维护人员让我去使用angularjs的最新版本(官网的document竟然不是最新版的,被坑了)在最新版本中,angularjs发现了ng-repeat的这个遗漏,因此新加了一个track by的语法。猛戳这里查看修正后的demo

这里,除了想告诉大家ng-repeat的使用细节以外,也要告诉大家,由于angularjs目前仍处在旺盛的青春期(当然,如果你想使用一款成熟的framework请绕路),请一定要使用http://code.angularjs.org/ 中的最新版本文档,当前最新在这里 http://code.angularjs.org/1.1.5/docs/。还有,google的产品似乎很喜欢使用googlegroups的maillist做问题交流,也请同学留意习惯。

可能有些人会觉得我这篇文章比较无聊,一个这么小的问题,至于花费时间去研究么,找个替代方案多好啊。但是我觉得使用framework就是这样,因为他不同于toolkit,当你准备好接受人家给你提供的便捷时,也一定要接受随之而来的束缚,接受framework的思想模式。任何不尊重framework的行为(包含语言攻击或者不按照规范使用)都是应该受到鄙视的。因为每个人的思维模式都不同,所以framework中呈现出来的思维也是不同的,有本事自己写个framework不要用人家的,或者干脆去用toolkit。每种思维模式都应该得到尊重,因为他是在特定环境和个人成长中产生的,也正因为此,世界才如此缤纷多彩。

阅读全文...

python学习笔记-常用模块

python常用库(官网:http://docs.python.org/release/2.5.2/lib/lib.html)

import os // 与操作系统相关的函数:如目录,文件,系统操作system,fork,exec族等等
import sys // 一些系统参数和常见处理函数
import subprocess // 替换os的一些老的开发函数如管道
import multiprocessing // 进程间通信,如进程,消息队列,共享内存
import threading // 线程间通信,如线程,线程队列,线程锁
import thread // 线程间通信另一种创建方式库
import Queue // 消息队列
import time // 时间操作的函数
import signal // 信号处理函数,如signal
import socket // socket通信函数,如socket,accept,gethostname,connect,listen,connect等等
import urllib
import praselib
import smtplib
import xmllib
import telnetlib
...........................
.pyc   python编译成的二进制跨平台文件,低版本不能加载高版本的该文件,方法:import py_compile
                py_compile.compile("dirpath")或python -m py_compile *.py
存在一个compileall库
.pyo   python优化编译成的二进制跨平台文件,低版本不能加载高版本,方法:python -O -m py_compile *.py
.pyd  python的动态链接库
http://www.linuxdiyf.com/bbs/thread-195160-1-6.html
来源&相关:
http://blog.sina.com.cn/s/blog_8ba5fecc0100y8q9.html
http://blog.chinaunix.net/uid-20653538-id-3277663.html
阅读全文...