2014年1月31日星期五

Yupoo(又拍网)的系统架构

Yupoo!(又拍网) 是目前国内最大的图片服务提供商,整个网站构建于大量的开源软件之上。以下为其使用到的开源软件信息:

(信息来源:http://www.yupoo.com/info/about/)。

一、Yupoo的整体架构

http://www.linuxeden.com/upimg/allimg/130521/1143291607-0.jpg

二、程序语言的选择

Yupoo的服务器端开发语言主要是PHP和Python,其中PHP用于编写Web逻辑(通过HTTP和用户直接打交道), 而Python则主要用于开发内部服务和后台任务。在客户端则使用了大量基于MooTools框架的Javascript。 另外,Yupoo把图片处理过程从PHP进程里独立出来变成一个服务。这个服务基于nginx,作为nginx的一个模块开放REST API。

http://www.linuxeden.com/upimg/allimg/130521/1143293926-1.png

三、服务器的选用

选用Squid的原因是"目前暂时还没找到效率比 Squid 高的缓存系统,原来命中率的确很差,后来在 Squid 前又装了层 Lighttpd, 基于 url 做 hash, 同一个图片始终会到同一台 squid 去,所以命中率彻底提高了。"

http://www.linuxeden.com/upimg/allimg/130521/1143295123-2.png

同时Yupoo也使用Python开发了YPWS/YPFS:

  • YPWS�Yupoo Web Server 是用 Python开发的一个小型 Web 服务器,提供基本的 Web 服务外,可以增加针对用户、图片、外链网站显示的逻辑判断,可以安装于任何有空闲资源的服务器中,遇到性能瓶颈时方便横向扩展。
  • YPFS�Yupoo File System 与 YPWS 类似,也是基于这个 Web 服务器上开发的图片上传服务器。

有网友留言质疑 Python 的效率,Yupoo 老大刘平阳在 del.icio.us 上写到 "YPWS用Python自己写的,每台机器每秒可以处理294个请求, 现在压力几乎都在10%以下"

四、Yupoo的消息系统

由于PHP的单线程模型,Yupoo把耗时较久的运算和I/O操作从HTTP请求周期中分离出来, 交给由Python实现的任务进程来完成,以保证请求响应速度。这些任务主要包括:邮件发送、数据索引、数据聚合和好友动态推送等等。PHP通过消息队列 (Yupoo用的是RabbitMQ)来触发任务执行。这些任务的主要特点为:

  • 由用户或者定时触发的
  • 耗时比较长的
  • 需要异步执行的

整个任务系统主要分为以消息分发、进程管理和工作进程组成。

http://www.linuxeden.com/upimg/allimg/130521/1143291505-3.png

五、数据库的设计

数据库一向是网站架构中最具挑战性的,瓶颈通常出现在这里。又拍网的照片数据量很大,数据库也几度出现严重的压力问题。和很多使用MySQL的 2.0站点一样,又拍网的MySQL集群经历了从最初的一个主库一个从库、到一个主库多个从库、 然后到多个主库多个从库的一个发展过程。

http://www.linuxeden.com/upimg/allimg/130521/11432a3J-4.png

最初是由一台主库和一台从库组成,当时从库只用作备份和容灾,当主库出现故障时,从库就手动变成主库,一般情况下,从库 不作读写操作(同步除外)。随着压力的增加,加上了memcached,当时只用其缓存单行数据。 但是,单行数据的缓存并不能很好地解决压力问题,因为单行数据的查询通常很快。所以把一些实时性要求不高的Query放到从库去执行。后面又通过添加多个 从库来分流查询压力,不过随着数据量的增加,主库的写压力也越来越大。在参考了一些相关产品和其它网站的做法后,进了行数据库拆分。也就是将数据存放到不 同的数据库服务器中。

如何进行数据库拆分?

  • 垂直拆分:是指按功能模块拆分,比如可以将群组相关表和照片相关表存放在不同的数据库中,这种方式多个数据库之间的表结构不同。
  • 水平拆分:而水平拆分是将同一个表的数据进行分块保存到不同的数据库中,这些数据库中的表结构完全相同。

一般都会先进行垂直拆分,因为这种方式拆分方式实现起来比较简单,根据表名访问不同的数据库就可以了。但是垂直拆分方式并不能彻底解决所有压力问 题,另外,也要看应用类型是否合适这种拆分方式。如果合适的话,也能很好的起到分散数据库压力的作用。比如对于豆瓣我比较适合采用垂直拆分, 因为豆瓣的各核心业务/模块(书籍、电影、音乐)相对独立,数据的增加速度也比较平稳。不同的是,又拍网的核心业务对象是用户上传的照片,而照片数据的增 加速度随着用户量的增加越来越快。压力基本上都在照片表上,显然垂直拆分并不能从根本上解决我们的问题,所以,Yupoo采用水平拆分的方式。

水平拆分实现起来相对复杂,我们要先确定一个拆分规则,也就是按什么条件将数据进行切分。 一般2.0网站都以用户为中心,数据基本都跟随用户,比如用户的照片、朋友和评论等等。因此一个比较自然的选择是根据用户来切分。每个用户都对应一个数据 库,访问某个用户的数据时, 要先确定他/她所对应的数据库,然后连接到该数据库进行实际的数据读写。那么,怎么样对应用户和数据库呢?Yupoo有这些选择:

1、按算法对应

最简单的算法是按用户ID的奇偶性来对应,将奇数ID的用户对应到数据库A,而偶数ID的用户则对应到数据库B。这个方法的最大问题是,只能分成两 个库。另一个算法是按用户ID所在区间对应,比如ID在0-10000之间的用户对应到数据库A, ID在10000-20000这个范围的对应到数据库B,以此类推。按算法分实现起来比较方便,也比较高效,但是不能满足后续的伸缩性要求,如果需要增加 数据库节点,必需调整算法或移动很大的数据集, 比较难做到在不停止服务的前提下进行扩充数据库节点。

2、按索引/映射表对应

这种方法是指建立一个索引表,保存每个用户的ID和数据库ID的对应关系,每次读写用户数据时先从这个表获取对应数据库。新用户注册后,在所有可用 的数据库中随机挑选一个为其建立索引。这种方法比较灵活,有很好的伸缩性。一个缺点是增加了一次数据库访问,所以性能上没有按算法对应好。

比较之后,Yupoo采用的是索引表的方式,我们愿意为其灵活性损失一些性能,更何况我们还有memcached, 因为索引数据基本不会改变的缘故,缓存命中率非常高。所以能很大程度上减少了性能损失。

http://www.linuxeden.com/upimg/allimg/130521/11432aP3-5.png

索引表的方式能够比较方便地添加数据库节点,在增加节点时,只要将其添加到可用数据库列表里即可。 当然如果需要平衡各个节点的压力的话,还是需要进行数据的迁移,但是这个时候的迁移是少量的,可以逐步进行。要迁移用户A的数据,首先要将其状态置为迁移 数据中,这个状态的用户不能进行写操作,并在页面上进行提示。 然后将用户A的数据全部复制到新增加的节点上后,更新映射表,然后将用户A的状态置为正常,最后将原来对应的数据库上的数据删除。这个过程通常会在临晨进 行,所以,所以很少会有用户碰到迁移数据中的情况。当然,有些数据是不属于某个用户的,比如系统消息、配置等等,把这些数据保存在一个全局库中。

分库带来的问题如何解决?

分库会给在应用的开发和部署上都带来很多麻烦。

1、不能执行跨库的关联查询

如果我们需要查询的数据分布于不同的数据库,没办法通过JOIN的方式查询获得。比如要获得好友的最新照片,不能保证所 有好友的数据都在同一个数据库里。一个解决办法是通过多次查询,再进行聚合的方式。所以需要尽量避免类似的需求。有些需求可以通过保存多份数据来解决,比 如User-A和User-B的数据库分别是DB-1和DB-2, 当User-A评论了User-B的照片时,我们会同时在DB-1和DB-2中保存这条评论信息,我们首先在DB-2中的photo_comments表 中插入一条新的记录,然后在DB-1中的user_comments表中插入一条新的记录。这两个表的结构如下图所示。这样我们可以通过查询 photo_comments表得到User-B的某张照片的所有评论, 也可以通过查询user_comments表获得User-A的所有评论。另外可以考虑使用全文检索工具来解决某些需求, 使用Solr来提供全站标签检索和照片搜索服务。

http://www.linuxeden.com/upimg/allimg/130521/11432a130-6.png

2、不能保证数据的一致/完整性

跨库的数据没有外键约束,也没有事务保证。比如上面的评论照片的例子, 很可能出现成功插入photo_comments表,但是插入user_comments表时却出错了。一个办法是在两个库上都开启事务,然后先插入 photo_comments,再插入user_comments, 然后提交两个事务。这个办法也不能完全保证这个操作的原子性。

3、所有查询必须提供数据库线索

比如要查看一张照片,仅凭一个照片ID是不够的,还必须提供上传这张照片的用户的ID(也就是数据库线索),才能找到它 实际的存放位置。因此,必须重新设计很多URL地址,而有些老的地址我们又必须保证其仍然有效。Yupoo把照片地址改成/photos /{username}/{photo_id}/的形式,然后对于系统升级前上传的照片ID, 又增加一张映射表,保存photo_id和user_id的对应关系。当访问老的照片地址时,通过查询这张表获得用户信息, 然后再重定向到新的地址。

4、自增ID重复的问题

如果要在节点数据库上使用自增字段,那么我们就不能保证全局唯一。这倒不是很严重的问题,但是当节点之间的数据发生关系 时,就会使得问题变得比较麻烦。再来看看上面提到的评论的例子。如果photo_comments表中的comment_id的自增字段,当我们在DB- 2.photo_comments表插入新的评论时, 得到一个新的comment_id,假如值为101,而User-A的ID为1,那么我们还需要在DB-1.user_comments表中插入(1, 101 …)。 User-A是个很活跃的用户,他又评论了User-C的照片,而User-C的数据库是DB-3。 很巧的是这条新评论的ID也是101,这种情况很用可能发生。那么我们又在DB-1.user_comments表中插入一行像这样(1, 101 …)的数据。 那么我们要怎么设置user_comments表的主键呢(标识一行数据)?可以不设啊,不幸的是有的时候(框架、缓存等原因)必需设置。那么可以以 user_id、 comment_id和photo_id为组合主键,但是photo_id也有可能一样(的确很巧)。看来只能再加上photo_owner_id了, 但是这个结果又让我们实在有点无法接受,太复杂的组合键在写入时会带来一定的性能影响,这样的自然键看起来也很不自然。所以,Yupoo放弃了在节点上使 用自增字段,想办法让这些ID变成全局唯一。为此增加了一个专门用来生成ID的数据库,这个库中的表结构都很简单,只有一个自增字段id。 当我们要插入新的评论时,我们先在ID库的photo_comments表里插入一条空的记录,以获得一个唯一的评论ID。 当然这些逻辑都已经封装在我们的框架里了,对于开发人员是透明的。 为什么不用其它方案呢,比如一些支持incr操作的Key-Value数据库。Yupoo还是比较放心把数据放在MySQL里。 另外,Yupoo会定期清理ID库的数据,以保证获取新ID的效率。

数据库优化的实现

前面提到的一个数据库节点为Shard,一个Shard由两个台物理服务器组成, 可以理解为Node-A和Node-B,Node-A和Node-B之间是配置成Master-Master相互复制的。 虽然是Master-Master的部署方式,但是同一时间还是只使用其中一个,原因是复制的延迟问题, 当然在Web应用里,可以在用户会话里放置一个A或B来保证同一用户一次会话里只访问一个数据库, 这样可以避免一些延迟问题。但是Python任务是没有任何状态的,不能保证和PHP应用读写相同的数据库。那么为什么不配置成Master-Slave 呢?Yupoo觉得只用一台太浪费了,所以在每台服务器上都创建多个逻辑数据库。 如下图所示,在Node-A和Node-B上我们都建立了shard_001和shard_002两个逻辑数据库, Node-A上的shard_001和Node-B上的shard_001组成一个Shard,而同一时间只有一个逻辑数据库处于Active状态。 这个时候如果需要访问Shard-001的数据时,我们连接的是Node-A上的shard_001, 而访问Shard-002的数据则是连接Node-B上的shard_002。以这种交叉的方式将压力分散到每台物理服务器上。 以Master-Master方式部署的另一个好处是,可以不停止服务的情况下进行表结构升级, 升级前先停止复制,升级Inactive的库,然后升级应用,再将已经升级好的数据库切换成Active状态, 原来的Active数据库切换成Inactive状态,然后升级它的表结构,最后恢复复制。 当然这个步骤不一定适合所有升级过程,如果表结构的更改会导致数据复制失败,那么还是需要停止服务再升级的。

http://www.linuxeden.com/upimg/allimg/130521/1143294430-7.png

前面提到过添加服务器时,为了保证负载的平衡,需要迁移一部分数据到新的服务器上。为了避免短期内迁移的必要,在实际部 署的时候,每台机器上部署了8个逻辑数据库, 添加服务器后,只要将这些逻辑数据库迁移到新服务器就可以了。最好是每次添加一倍的服务器, 然后将每台的1/2逻辑数据迁移到一台新服务器上,这样能很好的平衡负载。当然,最后到了每台上只有一个逻辑库时,迁移就无法避免了,不过那应该是比较久 远的事情了。

Yupoo把分库逻辑都封装在我们的PHP框架里了,开发人员基本上不需要被这些繁琐的事情困扰。下面是使用框架进行照片数据的读写的一些例子:

     array('type' => 'long', 'primary' => true, 'global_auto_increment' => true),                     'user_id'     => array('type' => 'long'),                     'title'       => array('type' => 'string'),                     'posted_date' => array('type' => 'date'),                 ));         $photo = $Photos->new_object(array('user_id' => 1, 'title' => 'Workforme'));         $photo->insert();         // 加载ID为10001的照片,注意第一个参数为用户ID         $photo = $Photos->load(1, 10001);         // 更改照片属性         $photo->title = 'Database Sharding';         $photo->update();         // 删除照片         $photo->delete();         // 获取ID为1的用户在2010-06-01之后上传的照片         $photos = $Photos->fetch(array('user_id' => 1, 'posted_date__gt' => '2010-06-01'));     ?>

首先要定义一个ShardedDBTable对象,所有的API都是通过这个对象开放。第一个参数是对象类型名称, 如果这个名称已经存在,那么将返回之前定义的对象。你也可以通过get_table('Photos')这个函数来获取之前定义的Table对象。 第二个参数是对应的数据库表名,而第三个参数是数据库线索字段,你会发现在后面的所有API中全部需要指定这个字段的值。 第四个参数是字段定义,其中photo_id字段的global_auto_increment属性被置为true,这就是前面所说的全局自增ID, 只要指定了这个属性,框架会处理好ID的事情。

如果我们要访问全局库中的数据,我们需要定义一个DBTable对象。

     array('type' => 'long', 'primary' => true, 'auto_increment' => true),                     'username' => array('type' => 'string'),                 ));     ?>

DBTable是ShardedDBTable的父类,除了定义时参数有些不同(DBTable不需要指定数据库线索字段),它们提供一样的API。

六、缓存方案的选择

Yupoo使用的框架自带缓存功能,对开发人员是透明的。

load(1, 10001);     ?>

比如上面的方法调用,框架先尝试以Photos-1-10001为Key在缓存中查找,未找到的话再执行数据库查询并放入缓存。当更改照片属性或删除照片时,框架负责从缓存中删除该照片。这种单个对象的缓存实现起来比较简单。稍微麻烦的是像下面这样的列表查询结果的缓存。

fetch(array('user_id' => 1, 'posted_date__gt' => '2010-06-01'));     ?>

Yupoo把这个查询分成两步,第一步先查出符合条件的照片ID,然后再根据照片ID分别查找具体的照片信息。 这么做可以更好的利用缓存。第一个查询的缓存Key为Photos-list-{shard_key}-{md5(查询条件SQL语句)}, Value是照片ID列表(逗号间隔)。其中shard_key为user_id的值1。目前来看,列表缓存也不麻烦。 但是如果用户修改了某张照片的上传时间呢,这个时候缓存中的数据就不一定符合条件了。所以,需要一个机制来保证我们不会从缓存中得到过期的列表数据。我们 为每张表设置了一个revision,当该表的数据发生变化时(调用insert/update/delete方法), 我们就更新它的revision,所以我们把列表的缓存Key改为Photos-list-{shard_key}-{md5(查询条件SQL语 句)}-{revision}, 这样我们就不会再得到过期列表了。

revision信息也是存放在缓存里的,Key为Photos-revision。这样做看起来不错,但是好像列表缓 存的利用率不会太高。因为我们是以整个数据类型的revision为缓存Key的后缀,显然这个revision更新的非常频繁,任何一个用户修改或上传 了照片都会导致它的更新,哪怕那个用户根本不在我们要查询的Shard里。要隔离用户的动作对其他用户的影响,我们可以通过缩小revision的作用范 围来达到这个目的。 所以revision的缓存Key变成Photos-{shard_key}-revision,这样的话当ID为1的用户修改了他的照片信息时, 只会更新Photos-1-revision这个Key所对应的revision。

因为全局库没有shard_key,所以修改了全局库中的表的一行数据,还是会导致整个表的缓存失效。 但是大部分情况下,数据都是有区域范围的,比如帮助论坛的主题帖子, 帖子属于主题。修改了其中一个主题的一个帖子,没必要使所有主题的帖子缓存都失效。 所以在DBTable上增加了一个叫isolate_key的属性。

 array('type' => 'long', 'primary' => true),             'post_id'     => array('type' => 'long', 'primary' => true, 'auto_increment' => true),             'author_id'   => array('type' => 'long'),             'content'     => array('type' => 'string'),             'posted_at'   => array('type' => 'datetime'),             'modified_at' => array('type' => 'datetime'),             'modified_by' => array('type' => 'long'),         ), 'topic_id');     ?>

注意构造函数的最后一个参数topic_id就是指以字段topic_id作为isolate_key,它的作用和shard_key一样用于隔离revision的作用范围。

ShardedDBTable继承自DBTable,所以也可以指定isolate_key。 ShardedDBTable指定了isolate_key的话,能够更大幅度缩小revision的作用范围。 比如相册和照片的关联表yp_album_photos,当用户往他的其中一个相册里添加了新的照片时, 会导致其它相册的照片列表缓存也失效。如果指定这张表的isolate_key为album_id的话, 我们就把这种影响限制在了本相册内。

缓存分为两级,第一级只是一个PHP数组,有效范围是Request。而第二级是memcached。这么做的原因是, 很多数据在一个Request周期内需要加载多次,这样可以减少memcached的网络请求。另外Yupoo的框架也会尽可能的发送memcached 的gets命令来获取数据, 从而减少网络请求。

参考文章:http://www.infoq.com/cn/articles/yupoo-partition-database

来自:http://www.biaodianfu.com/yupoo-architecture.html

业内曝淘宝数据泄漏事件内幕


核心提示:倒卖用户信息背后的隐秘产业链:做电商就是做数据。
电商从业人员会选择一些付费的"情报工具",通过搜索引擎、数据库等技术,对淘宝店进行数据分析,比如你店铺的竞争对手做了哪些直通车广告,用了哪些关键词,效果如何,以及行业分析、店铺分析、宝贝分析、买家搜索等,软件都可以提供。而这,在一些人眼里,就是"商机"

支付宝昨天爆发了数据泄露丑闻,超过20g的支付数据资料被支付宝前员工从系统中窃取出去,并出售给第三方,后被媒体曝光。

"支付宝内鬼盗卖用户信息被抓凡客被指是最大买家"相关事件的前后动态:

1,据报道,阿里巴巴旗下支付宝的前技术员工李明,利用工作之便,在2010年分多次在公司后台下载了支付宝用户的资料,资料内容超20G。李明伙同两位同伙,随后将用户信息多次出售予电商公司、数据公司。

2,犯罪嫌疑人张建系李明团伙的第一个"客户",其以500元的代价,从李明处购得3万条支付宝用户信息。

3,据李明等供述,支付宝用户的最大买家系服装类电商公司凡客诚品,其花重金从李明团伙手中购得支付宝用户资料1000万条。但这个说法没有得到警方的证实。

4, 1月2日晚间,凡客诚品一位副总裁向经济观察报表示:"不太清楚这件事,没听说过。" 如果有需要公司会积极配合调查。

5,张建所购的支付宝用户资料中,包括公民个人的实名、手机、电子邮箱、家庭住址、消费记录等,从这些定位精准的用户信息中,张建掌握了目标消费群体的具体信息。

这已经不是支付宝第一次发生此类事件了,前期谷歌等搜索引擎在网上能搜索到数百万条支付宝用户信息的事情,在引发了一些关注后戛然而止,从此很少被提及,此次用户隐私数据丑闻在支付宝公关部的努力下,也很可能很快远离公众视野,消弭于无形。

支付宝的用户数据包含大量用户隐私,如电话、地址、身份证号、购物习惯、账户余额等。如果这些资料被不法分子掌握,理论上他们可以用来实施很多犯罪行为,威胁到用户个人财务安全。

倒卖用户信息背后的隐秘产业链:做电商就是做数据!

随着电商的发展,客户精准定位越发重要。大多数做电商的人,尤其是做到一定规模的人,都会购买数据。

这些电商从业人员会选择一些付费的"情报工具",通过搜索引擎、数据库等技术,对淘宝店进行数据分析,比如你店铺的竞争对手做了哪些直通车广告,用了哪些关键词,效果如何,以及行业分析、店铺分析、宝贝分析、买家搜索等,软件都可以提供。通过使用这类软件,电商从业人员可以获取竞争对手的数据,以作为调整营销策略和产品定位的参考依据。

举个例子,比如卖女性内衣的,如果手上有一个数据库,得知喜欢在网上买内衣的女性消费者,她们购物的频次如何,价格区间如何,消费规律如何,喜欢什么品牌等 等,如果知道了这些信息,我就可以提炼出更多的信息,以调整店铺战略。如果再知道了她们的手机号码、电子邮箱、家庭住址等,甚至还可以向她们定向群发短 信、邮件、直邮DM等,她们都是精细化营销的潜在消费者!

李明离职前从支付宝下载的数据多达20G以上,只要通过一些软件录入数据库再予以专业分析的话,基本上可以将所有支付宝、淘宝用户的消费习惯尽收眼底。"这些用户信息,都是可以带来钱的,可以变现的。"

你所不知道的更多内幕:

知名IT人士@Fenng 在知乎上对此次事件爆料:

事情的起因是在去年。年底冲无线 KPI ,外面搞了一家公司,做中间商,冲交易流量… 而后某个环节出问题,被捅出来了。然后查出来一堆人。不知道高一级的管理者要承担责任不。

然后怎么搞出来数据的事情就不得而知了。应该是囚徒困境,互相揭发吧。

数据的事情则是 2010 年就发生了,很巧的是,那段时间我的确听到有朋友跟我说外面有这个数据,但我分析了一下,觉得可能是在 EDM 环节出问题,人都走了,也就不关心这事了。那段时间还是团购网站的数据最热。

因为权限控制问题,销售部门那个时间几乎可以任意调取数据,内审还没上来。据说这个权限控制问题,在 2011 年逐步改进了,当然,到现在应该彻底杜绝掉了,毕竟各个环节的审计都上来了。

当事人其实在阿里年头不短,也算有钱的了。但人心都是贪的啊。哪有止境。

出问题的人不是工程师。

工程师团队还都是挺靠谱的,其实那时尽管有各种针对运维部门的审计工具,但要绕过去还是易如反掌的,只是没人动这个心思。

因为工作关系,我曾经一度能接触到所有数据,真的,所有数据。制度都是针对人的。如果人犯了糊涂,做点手脚,这个真的很难防范。

大公司里面,一定级别的人外面开个公司,然后把市场费用什么的洗走,应该很常见了吧。这种事情永远都不会杜绝。

知名互联网分析师葛甲在其微信公众号上对此表示:

这名前支付宝员工在3年前就开始窃取支付数据,这是孤立行为还是普遍行为,支付宝那些通过了多重安全鉴定的内部管控机制到底能否起作用?

本次数据泄露事件是否如支付宝轻描淡写的那样,仅是违规操作行为,不涉及敏感信息。如果真是这样的话,为什么要动用公安机关抓人。

支付宝在数据泄露事件中要承担什么责任?这么大一个公司,要对自己的行为负责,李某的职务身份是支付宝员工,履行的是公司职责,这个责任不能简单推给个人或是全社会就完事儿了。

被交易的用户数据既然有交易价值,为何支付宝还要死硬抵赖说不涉及用户的敏感信息?什么算敏感信息?那些电商网站买去那些没有人名,没有ip地址、信用卡、身份证的信息回去是要做什么?真的没有敏感信息吗?

既然支付宝已说这些用来交易的用户信息并没有被传到网上,必然是已经弄清了数据流动的一切来龙去脉,为何不公布这些事实真相,并积极检讨自身,而是要努力推卸责任,并东拉西扯把别的企业牵扯进来?

中国人为什么喜欢讲关系?



近日有学者表示:中国社会虽历来讲究人情关系,但当下社会讲关系的风气已登峰造极。不少网友对此观点表示赞同。是啊,在中国谁都知道"关系"的重要。没有 "关系"简直寸步难行。小孩入学要不要关系?审批项目、找工作、做生意、看病等哪一样大家不是在找关系?有人甚至还总结出一句话:"在中国,关系就是生产 力。"那么,为什么中国人最喜欢讲关系呢?
关系在中国究竟能有多大的作用?

最近有网站对大学生 就业进行了一项调查,结果将近50%的大学生回答说是"要靠关系"――就是如果谁有关系,谁有门道,谁就最有可能找到一份好工作。而选择"有能力"、"有 创新精神"、"敢开拓"等因素的最多也不超过18%。而细观网友的留言则发现,即使是"能力派"们也都认为"应当双管齐下",甚至悲观地认为"靠能力只是 一种理想"。可见大多数人都难以否认关系的重要性。

有网友曾感叹,在中国其实连扫街女工都要讲关系。街道环卫管辖内的那么多 地段,有的垃圾多,有的垃圾少;有的车辆多,有的车辆少;有的容易扫到人造成矛盾,有的比较清净。拥有分配哪个地段给你的权力的环卫站长、书记,你要不要和他搞好关系,送点礼,分到一块好点的地段,比较容易清扫,没那么危险。如果不懂,如果不去搞好关系,那么最差的地段就是你的了。付出更多的体力精神,吸 入更多滚滚灰尘,却还要给差评,扣工资扣奖金。

这也许就是中国关系社会最真实的一个缩影。人们评职称,需要找关系;孩子找工 作,需要找关系;看病,需要找关系;上学,需要找关系。人们处处为建立关系而投资。人们为失去关系而苦恼,人们也为有良好关系而兴奋。关系,让人性扭曲化,也让道德边缘化。除此之外,在中国一个人的社会关系网越大,其中有权有势的人越多,他在别人心目中的权力形象也就越大。《西游记》不就告诉了我们:凡 是有后台的妖怪都被接走了,凡是没后台的都被一棒子打死了吗!

中国人的"关系学"

中国人把人的 关系分成了三种。一种叫家人关系,这是最核心的一层,家人关系里对利益保护没有条件,而且不讲回报。家人关系不好的时候,当然会有愤怒和敌意,但更多的是 忍耐,因为家丑不可外扬。第二层关系是熟人关系,比如同学、邻居、同事和同村乡亲。熟人关系对人情的回报有一些期待,会通融但也有条件。第三层关系则是中 国文化中最少涉及的生人关系。公事公办是生人关系的特点。生人之间往往不给任何照顾,只讲利害,对回报要求最高。
这些关系牢 牢地构筑了一张庞大的、坚不可破的社会关系网。一张看似温情脉脉,实际上充满了冷漠与不信任的网。每个人都渴望拥有一张能令他人羡慕的关系网,每个人都在 苦心、细心经营着自己的关系网,每个人都期望能从自己的关系网中获得利益,而关系网的最大本质,就在于相互利用、相互依靠。

于是,人人都拼命拉关系、走后门。然而,关系"资源分配永远不会平等,因为并不是所有人都能结识并有财力买通"后门"的"把门人",所以,那些拼命拉关系的 人,或许因偶尔获益而沾沾自喜,更多的情况下是看到别人走后门,自己没有关系而倍感沮丧,但不少人沮丧之后又激发了寻找后门的更顽强的"斗志",就这样, 人们屡战屡败,屡败屡战,最终形成了一个更加不公正的社会环境――一个具有中国特色的"后门困境"。

中国人何时才能不讲关系?

讲关系的可怕,正是在于他已经占据了人的大脑,影响了人的思维和判断。让每一个中国人在做什么事情之前,都要想,我有什么关系可以在这件事情上用的,还要再 拉哪些关系?而那些手上掌握着公权力的人,也习惯性的把许多明明是职责上应该做的事,就是故意的不做,等着人上来拉关系,收好处。一个人这样做,危害还不 是很大,全国的人都这样做呢?那样的话,政府会变成什么样子?国家会变成什么样子?

在西方,如果你认识关键、重要的人物,也 会更有利于你的职业升迁或商业成功,但即便你没有什么"关系",你也能存活,甚至活得不是太差。但在中国,如果你没有任何"关系",那就可能意味着你活不 下去,或至少活得很差。西方的人际联系固然也重要,但它不能超越法律、道德和规则,从这个意义上说,西方社会基本上是一个"规则社会"。中国社会则是一个 靠"关系"来调节和维系的社会,中国虽然也有法律,有道德,有规则,但"关系"可以超越法律,腐蚀道德,破坏规则,"关系"甚至可以造就法外之"法"和潜 规则。

目前的中国社会,关系文化已弥漫一切领域,已深入很多人的骨髓。但关系的存在,意味着对游戏规则的破坏,意味着不公 平。关系,让政治不能政治;关系,也让经济不能经济;关系,也让文化不能文化。密密麻麻的关系,就像一张密密的大网,罩在国家的头上,让国家发展举步维 艰。可以说,不打破关系网,中国的民主政治、法治社会等就很难真正实现。

2014年1月25日星期六

互联网金融的中国“猫腻”

"Change or Die",今年59岁,说话喜欢不时插入几句英文的马明哲对着屏幕上的标语,叙述着平安集团的互联网金融规划。他和他的"五虎将"一起,正致力于从移动支付"壹钱包"的推广开始,把这家中国最大的综合金融集团,改造成互联网金融领域的新玩家。

"中国这几家互联网公司一定会给互联网金融,给世界做出一个重大的贡献",谈到潜在的对手马云和马化腾,马明哲谦虚的大加赞扬,强调平安和阿里巴巴及腾讯将是互补关系。

2014年,"中国特色"的互联网金融丝毫没有退潮的迹象。就在马明哲讲话的前一天,1月15日夜间,腾讯在超过5亿用户的社交软件微信上线了第一款理财产品:对接华夏财富宝货币基金的"理财通"。当天上午,已被阿里小微金服控股的天弘基金宣布,余额宝背后的货币基金"增利宝"规模突破2,500亿,一年前还籍籍无名的天弘基金超越华夏,成为中国最大的公募基金。

如果加上百度金融、网易理财、新浪和搜狐的金融计划,转型中苏宁的"零钱宝",各个机构在线销售的"类余额宝"产品,中国6.18亿网民中的绝大多数都已经被形形色色的互联网金融产品覆盖。另一边,微信支付和支付宝正激烈的争夺,投入巨资营销不断,甚至雇佣写手攻击对手。美国、日本和韩国同样有互联网金融,但是仅仅作为商业银行体系外有限的补充。互联网金融牢固地占据着数字时代的主流地位,中国商业环境又一次显得与众不同。

利率管制下的影子银行丛生,民间借贷汹涌,于是创造了套利空间,第三方支付的强大带来互联网属性,这二者结合产生了美国、日本和韩国所不具备的环境,让中国互联网金融拥有无穷的想象空间,甚至有了"撼动银行"愿景。企业家和创业者们正在努力和时间赛跑,希望在这个窗口期关闭前登上彼岸。

监管套利:踩着红线起舞

如果以好买财富、大家保这样的互联网第三方基金和保险销售为初始,那互联网金融"元年"将大大提前。但阿里和天弘的"余额宝"是真正改变了游戏规则的产品――"不是简单的网上卖基金,而是走进生活把理财融入生活,让客户原有的习惯延续,并在业务处理和技术上实现,与阿里摸索出了跨界合作方式。"在天弘基金年会上,副总周晓明如是总结这次"逆袭"的创新。

周晓明没有提到的,是和大互联网公司合作的另一个优势:与中国监管当局的博弈能力。支付宝刚刚推出余额宝,一位第三方基金销售机构负责人向记者指出,支付宝在2012年获得基金支付牌照,但没有获得基金销售牌照。"如果阿里这么做没有问题,那其他支付企业是不是也可以一起跟进?"

"余额宝"实际上绕开了基金代销程序,采用导入客户的嵌入式,既避免客户资源流向基金公司,又达到了推介产品的效果。"余额宝"的直销模式很快得到了官方认可。推出9天之后,中国证监会点名其"材料不全",但是对于第三方支付和基金的合作给予背书。当时支付宝公关总监陈亮就表示,很快就会补齐材料,不会停止销售。

百度的运气就没有那么好了――熟悉百度金融产品上线的人士复盘了整个过程:中国最大的搜索巨头和监管方经历了多个回合的拉锯,最终被压制在了一个颇为不利的位置。

2013年秋季余额宝成功后,百度金融中心迅速行动,负责的百度新晋副总裁李明远称,9月份开始产生想法,不到两个月推出了第一款产品――和华夏基金合作的,号称年收益8%的百度百发,金融业内人士纷纷不解,年化收益4%的华夏增利,百度怎么样给用户提供8%?

没有用户支付场景和强大账户体系的百度金融更加依赖营销,社交媒体上铺天盖地的宣传文案,强调百发远超存款的8%保本高收益,直接触及了证监会的底线:根据中国基金法,基金产品不得违法承诺收益率或者提前发布收益预测。百度10月21日的大规模宣传,换来两天后证监会的警示,要求百度递交合规有关材料。但前述人士透露,当时百度和华夏已经得到了默许,递交合规材料的同时,原定28日的产品上线不会受影响。

百度百发引来12万用户抢购,首日销售10亿元,并且缔造了一个互联网公司现金补贴抬高基金收益率的模式:通过百付宝返现,把投资者货币基金的收益率补齐到8%。之后网易,数米基金,东方财富网纷纷效法这种"补贴营销"。

这次没能逃过监管。2013年底,中国国务院的"影子银行基本法"正在酝酿,百度则再次推出理财产品"团购理财",明确表示会投资协议存款。然而中国银监会率先发难,知情人士透露,银监会要求证监会对百度理财产品采取更加严格的监管,直指百度把银行活期存款和理财收益作比较是"误导",宣传收益率违规,并误导投资者是百度在管理这款理财产品。

证监会随即行动,百度成了"有误导性"的坏孩子,被要求不得广告宣传其收益率高于存款,更禁止承诺收益。在中国监管当局看来,百度开创的先例引发了互联网公司激烈的竞争,伤害了传统银行。拥有代销牌照的数米基金和东方财富则直接遭遇了证监会的罚单,责令限期改正。

国务院107号文的威力正慢慢显现。过去半年,互联网金融的流行做法是用收益率和存款比较的宣传策略、补贴收益模式、引导流量客户的"直销",这些擦边球有些在默许下变成创新,有些则被叫停。但是监管真空期的几个月,已经让许多互联网金融企业收获了用户和高企的市盈率。李彦宏在分析师会议上将金融列为百度重要方向之一,而东方财富网享受了巨大的涨幅。

"互联网金融现在正处于监管套利型的超常发展阶段",中国央行研究局的雷曜博士认为互联网金融没有改变金融的本质,"新技术和新商业模式放大了传统金融和非传统金融之间的冲突"。

和美国不同,中国的电子支付取代了信用卡成为网上支付主渠道,伴随着移动支付兴起,已经让马明哲产生了"十年内信用卡消失"的危机感。雷曜指出,第三方支付机构是互联网金融"互联网属性"的核心。他们通过高流动性和货币替代性的电子货币,客观上具有了创造货币的能力,改变了金融市场的运行和传导机制。而监管电子货币有欧洲模式――纳入银行体系监管和美国模式――在银行体系外独立监管。将来要不要为支付机构设立特殊的监管框架,这决定了支付机构在汇兑、流动性上的监管要求。

资金套利:海量用户+货币基金模式好日子到何时?

"从散户那里把银行的活期存款收上来,再通过协议存款卖还给银行。"一位基金业老将这样形容被阿里、腾讯和百度普遍采用的"海量用户+货币基金"模式。天时地利人和都推动这个模式处于低风险的套利阶段。

据天弘基金披露的数据,超过2,500亿的余额宝超过80%是银行协议存款――协议存款收益较好,且可以提前支取,从流动性和收益角度,是互联网T+0式货币基金最好的投资标的。2011年2月,中国取消了货币基金投资协议存款不超过30%的规定,协议存款成为货币基金的主要资产,2012年银行又被禁止发行超短期理财产品,货币基金迎来了黄金年代:

中国宏观经济依旧处在转型阵痛之中,信贷不再松弛,存款利率没有市场化,于是资金会一直处于"紧平衡"状态――不宽松,但崩塌概率也很小,于是短端利率处于高位,其他资产回报也很低。货币基金能够以非常低的风险,在中国存款利率和同业利率之间游走,实现资金市场的期限套利。对银行,这意味着银行原有成本较低活期存款资金被高成本负债替换,息差会进一步缩小。

对比美国,70年代后半段到80年代初经历了和中国当下类似的阶段,瑞银证券统计,在1970-1990年二十年期间,货币基金持续扩张,1997年美国货币基金规模首次超过1万亿美元,1999年规模达到1.6万亿元,基金数达1,045只,从1990年到2011年,货币基金全部银行存款和储蓄存款的比率平均在40%和81%左右,截止2013年第三季度,中国货币基金占整体存款的比率仅0.6%,有着辽阔的加速发展空姐。

然而中国互联网金融的窗口期不会有这么长,在资金套利的世界里,他们已经来的很晚。利率市场化速度加快,中国银行首席经济学家曹远征认为,2015年有望取消存款利率的限制。在这短短几年间,国泰君安的分析报告预计,真正受到严重威胁的存款及理财资金不足5%:指向收入水平中下、尚未有太多财富积累的年轻客户群。

当货币基金不再享受低风险收益,互联网金融抓住的这些小额理财客户,有多少愿意转向较高风险资产?兴业全球基金的徐天舒很不乐观,"互联网的客户粘性一直不太强,要他们从'无风险产品'转换成高风险产品,很可能是一厢情愿,最后能在互联网热潮中赚到钱的只能是少数几家寡头,其他的就都是陪太子读书了。"

寡头之一的阿里金融已经开始了试水,支付宝方面告诉记者,余额宝肯定不是支付宝钱包的唯一理财产品。市场传言,支付宝正在和多家基金和保险公司接洽,考虑在支付宝中接入更多差异化理财产品。满足一部分客户牺牲流动性,换取更高的收益的需求。

互联网金融下一步:社交、供应链金融和P2P

处于中国特色状态的互联网金融不太可能一直持续下去。占得套利先机的互联网巨头,会怎么样将优势变现,以求得在真正的金融市场化浪潮中壮大?东方证券金麟认为,和所有与信息技术相关的产业类似,互联网金融市场可能会呈现赢家通吃,软硬件上的规模经济以及平台和大数据的自然垄断特征使得70:20:10定律再次发生作用。互联网巨头中,哪家会独大,哪家会成为稳固的追随者,剩下的份额如何瓜分?

・阿里小微金服

今年春天会正式挂牌的小微金服集团将会是中国最受期待的互联网金融企业。小微金服将会引入战略投资者。国有金融机构、红色资本和江浙的民营资本都是有潜在战略投资者,这会给予小微金服更强的政府关系和资金实力。小微金服也拥有最完善的金融业务。

――阿里小贷已经放贷累计超过1,500亿

――控股天弘基金拥有比银行更高的资本杠杆率和相对松弛的监管能够成为资管的出口

――余额宝的成功很快会带来基金、保险等合作机遇,可能走向中高端业务

――支付宝钱包正在移动支付领域试图和微信这个"超级APP"并驾齐驱,并向社交化迈进

――作为新浪微博的股东,已经推出微博支付

――阿里巴巴在数据、电商资源上均行业领先

・腾讯

腾讯在金融领域的布局更为暧昧。当民营银行热炒时,腾讯确实参与了民营银行的牌照申请,但是按照马化腾的说法,这只是为响应政府号召,作为小股东入股,腾讯诉求是服务银行,和银行合作而不是取代银行。但是12月10日的一次会议上,马化腾则表示腾讯会在前海投资百亿元设立互联金融和电子商务企业。财付通已经注册成立了小额贷款公司。接近广东银监会的消息人士指出,马化腾在前海私人参与投资了一家带有网络银行性质的金融机构。

――微信作为中国最受欢迎的社交应用,在移动支付和用户场景上具有显著的优势,微信支付已经拥有了2,000万用户,并以每天以万计数速度增加。

――包括微信在内的腾讯各个互联网平台也可以成为银行、券商的前端管理、客户关系维护工具。

――作为中国最大的社交网络拥有者,在社交金融领域有潜力。

――在游戏和Q币领域有潜在的增值空间

・百度

百度在PC端有最为稳固的流量优势,搜索占据垄断地位。在金融机构互联网化深入后后,百度在贷款、理财产品、信用卡等金融产品的聚合、比价和推介方面有一定优势。百度长期以来积累了企业客户和数据资源,在征信建设,小贷客户方面起点将很高。百度金融中心的发展则决定了百度如何在个人理财、百度钱包等领域突破。

――百度金融通过不断销售高收益理财产品,可能会获得一批有理财需求的客户,并引导他们进入即将推出的手机客户端,争夺社交金融和移动支付的战场。

――百度金融知心搜索可能通过收购等方式进一步扩张,加强线下金融机构的资源积累。

・新浪

金融背景出身的CEO曹国伟对新浪的金融业务有着很高的期待,公司已经将金融设定为基础业务之一。微博钱包、信用支付的信用宝、网络券商、基金和其他金融产品的销售,甚至最为激进的P2P人人贷业务都在新浪的规划中。

――能否通过信用宝在竞争激烈的支付领域获得独特的市场?

――新浪正和多家P2P贷款业务公司合作,商讨展开P2P业务。如果能够真正发挥微博的社交关系链的优势,并控制好风险,或许实现互联网金融的突破和创新。

2014年1月20日星期一

DigitalOcean使用小记

晚上看到微博上的@developerWorks同学推荐DigitalOcean, 赫然发现自己使用DigitalOcean大概也一年了(2013年2月28日开始),自从前段时间把52nlp搬牵过来之后,我在国外的vps就只有DigitalOcean了。所以在微博上简短回复了一下:

上半年就开始用DO了,52nlp前段时间也搬到DO了,用的是10美元每月的Plan, 彻底告别了linode。

自从08年底52nlp开张以来,依次用过便宜好用的虚拟主机host2ez, 朋友免费赞助的小空间,Godaddy上免费附赠的空间(但是带广告),国外的老鹰主机(Hawkhost),以及用信用卡注册免费使用一年的AWS(但是一直没用上),直到遇见口碑极高的Linode,花上20多美元/每月搞一个完全自主拥有root权限的VPS(Virtual Private Server)后,发现自己已经离不开VPS了,虽然没有了Cpanel之类的控制面板可用(貌似也可以自己安装),但是更享受这种完全自主的命令行控制和Root权限。之后接触并玩过的VPS还有目前使用的阿里云和DigitalOcean

Linode大概使用了有两年,期间几乎没有出过什么问题,感觉非常棒,不过印象去年也是微博上某个朋友推荐我用DigitalOcean,号称配置SSD VPS( SSD cloud server, SSD云主机),了解了一下它的配置,发现最低配5美元/每月的Plan(512MB内存,1核,20G SSD硬盘, 1TB流量)和我每月20多美元的Linode Plan的配置基本旗鼓相当(不过目前linode最低配已经升级为1G内存…,印象也是这一年期间逐步加量不加价的,有竞争就是好啊),不过国外便宜的VPS有很多,不能因为便宜就放弃Linode,所以在没有放弃Linode的前提下选了一个Digital Ocean中最便宜的5美元/月的Plan玩一下,在这个上面诞生了"我爱公开课","挖课"等网站,也跑了一个python flask网站,课程图谱的前身:CourseraReview,从2013年2月28号到目前为止,基本上还没有出现过什么问题,感觉还不错,也欢迎大家体验这几个网站。

2013年年底,终于决定告别用了2年多的Linode,不是因为Linode不好,而是性价比没有DigitalOcean好,刚好这篇对比DO和Linode的英文文章"Digital Ocean vs. Linode"也道出了我的心声,这哥们也使用了2年的Linode,但是最终决定告别Linode,投向DigitalOcean的怀抱。所以除了之前5美元的vps外,我又为52nlp选了一个DigitalOcean中最流行的10美元/月的Plan或者官方说法是"Droplets",下面是我的后台截图,2个DigitalOcean Droplets:

Digital Ocean Droplets

这是10美元/月 vps的配置情况,选的是NewYork 2机房,安装的是Ubuntu 12.04 64位服务器(这个注册购买Digital后可选很多Linux服务器):

DigitalOcean 1GB VPS

DigitalOcean的后台相对也很简洁,image下可以手动备份VPS镜像,自动备份需要付费(大约是你所用Plan价钱的1/5), 下图是一个自动备份记录:

DigitalOcean 备份

SSH Key菜单下是教你如何添加ssh key建立2台机器之间的互信,以后通过ssh登录VPS不需要再次输入ssh密码:

DO SSH Key

Billing是DigitalOcean计费的页面,包括当前使用情况以及历史记录,DigitalOcean貌似允许欠费,另外相对于Linode每月月初就收费的情况,DO是按照小时计费的,相对灵活很多。这是我的账单页面,是从13年2月28号开始使用的,用Paypal付款,另外直接用双币信用卡付款也行:

DigitalOcean Billing

Support页面是寻求DigitalOcean工作人员帮助的地方,这个很重要,即使是VPS,也不能保证不会出任何问题,万一遇到个啥问题挂了,如果联系不上客服就麻烦了。DO虽然是初创企业,不过这一块儿做得挺不错的。目前为止,我提过两个不是很紧急的问题,一个是咨询如何直接用信用卡付款的问题,另外一个比较有意思,就是在购买第二个10美元配置的vps时,我先通过google搜了一个DO的优惠码(coupon),这个优惠码显示可以省10美元,但是需要注册一个新的账户,我尝试这个老账号里使用,发现没有填这个优惠码的地方,就通过Support页面的New Ticket咨询如何使用?大概10分钟之类就收到回复,不过意思是很遗憾,老账号不能使用,只有新帐号可以使用,不过神奇的是在我的billing页面又显示我多了10美元(有邮件通知),所以这个优惠码还是生效了,估计是工作人员直接操作的,所以大家要是有优惠码的问题,不妨骚扰DO的工作人员。以下是我的support页面:

Digital Ocean Support

关于优惠码,可以通过goole "digitalocean coupon" 发掘,我上次就是google了一个"thechangelog10″, 不知道现在还能用不?另外微博上@devloperWorks同学爆料:DigitalOcean 继续给力!10美元免费送!最新优惠码:2014SSD 已亲测,可用。只对新用户注册有效,想买 VPS 的同学可以关注下:

digital ocean coupon

digital ocean优惠吗

关于DigitalOcean优惠码,稍微再补充一下:

1、DigitalOcean官网:https://www.digitalocean.com/

2、登录DigitalOcean后,点击添加信用卡。

3、然后在右下角输入免费赠送x美元的优惠码:例如2014SSD,稍等一会儿就可以直接返回到Billing中看到自己已获10美元了。

至于DNS,API之类的目前我还没有用到,这里就不介绍了。关于DigitalOcean的注册,今日到官方主页后,点击Sign Up后输入你的邮箱和密码即可,之后blabla的按照流程做即可,如果还不明白,可以看看下面这个"digitalocean注册及使用简单教程",这里就不详述了。

好久没有在这里扯淡了,今天晚上看到微博有感而发,从去年年初开始使用DigitalOcean,到目前为止DigitalOcean上超过100万个server在运行,深感口碑的力量之强大。最后再说明以下,这篇文章里嵌入了DigitalOcean的推介链接,这也是国外一种常用的商品推介模式,如果您通过这个链接注册DigitalOcean并成功消费10美元,这里将得到一点refer money, 也非常感谢您的支持。

最后关于DigitalOcean, 以下摘自36氪的一点介绍:

Digital Ocean 成立于 2012 年,是一家从 TechStars 孵化出来的云托管服务提供商。其特色服务是提供快速的固态硬盘服务器,宣称可在 55 秒钟搭建好一台云服务器。所有的服务器均拥有 1G 的网络接口,每月基础套餐为 1TB 流量,超出部分按每 GB2 美分计算。公司还提供了灵活的 API 供客户控制其私有虚拟服务器。控制面板也相当直观易用。目前在 Digital Ocean 上部署的服务器数量已达 34.6 万(注:现在以超过100万),公司目前每天新增的订户约为 500。

注:原创文章,转载请注明出处"我爱自然语言处理":www.52nlp.cn

本文链接地址:http://www.52nlp.cn/digitalocean使用小记

Web开发者必备:Web应用检查清单

本文由 伯乐在线 - 埃姆杰 翻译自 Ata Sasmaz。欢迎加入技术翻译小组。转载请参见文章末尾处的要求。

【伯乐在线导读】:想做一个高质量的Web应用,前前后后要做的事情非常多。国外开发者 Ata Sasmaz 为 Web 开发者制作分享了一份检查清单,包括应用开发、性能、安全、分析、可用性、可靠性、转换策略、竞争策略这些方面需要注意的事项。清单内容可能不全面,欢迎大家在评论中补充。

开发

  • 记录UI错误日志

JavaScript 允许捕获异常。这些异常需要通过Ajax请求提交到日志服务,否则很难截获Web环境中的错误。

  • 可交换的数据层

数据层可分离,也可以与另一个遵从规范的数据层互换。

  • 部署过程自动化

部署过程应自动化。生产环境所用的项目文件应由部署服务器生成,并在无人工干预的情况下自动完成。

  • 使用版本控制系统

版本控制系统保存代码更改的历史,防止现有代码的丢失。同时,它还有助于协同开发。GitHub是这项服务最流行的提供商。除此以外,还有BitBucket。微软也有提供了额外协作特性的Team Foundation

  • 代码审阅

人总会有写错代码的时候,而代码审阅系统能保证开发者的高质量产出。同时,该系统还能让不止一位开发者熟悉代码。在某段代码的作者不在的时候,其他开发者可以顺利地做出修改。GitHubTeam Foundation都提供了相应的代码审阅功能。

  • 权限与角色系统

每个应用都需要设计实现权限和角色系统。设立系统管理员,用户管理员等角色需要一个灵活的全局角色系统。

  • 记录所有未处理的错误

所有错误应当记录下来,并用于未来的全面检查。也就是所有错误都应当提交给全局错误记录机制。

  • 测试过程自动化

每次部署前,测试服务器应当运行所有测试。代码测试通过时部署应用,没能通过时报告给系统管理员。

  • 业务层可以在不同环境上使用

业务层中的代码必须通用。即使代码本身面向Web环境,它也应当能在不要求改变代码的情况下使用于桌面环境,服务器环境,移动设备环境的不同用户界面,不同数据层上。

  • 制定编码规范

一份规定明确的编码规范在未来项目开发的过程中起到重要作用。方法前需要写上注释吗?命名规范是什么?示例代码应放置何处?

  • 开发者机器配置的指导方案

开发时最耗时的问题是不同的开发者之间的开发环境不同。需要让人们知道的是,他们应当安装什么软件,使用的是什么版本,同时需要安装什么组件,以及怎样安装这些组件。

性能

  • 使用CDN

Content Delivery Networks(内容分发网络)通过离访客最近的服务器,为你的服务提供图片,JSCSS等静态文件来提高访问速度,同时削减了带宽的用量。CloudFlareCDN服务的绝佳示例。

  • 压缩所有的JSCSS文件

JSCSS文件应当使用YUI compressor这样的压缩器来减少文件体积,并且使用gzip传输。把JS代码的引用放到最后也是不错的做法。

  • 记录加载较慢的页面

Web应用程序应当响应迅速。分析页面加载的系统有责任识别加载较慢的页面。运行迅速的页面可能会遇到一些用户读取特定数据时加载时间过长的问题。

  • 非关键数据使用NoSQL存储

NoSQL数据库(文档型数据库)在接收数据和存储数据时的速度很快,并且可以大规模扩展。由于这类数据库不能确保关系的完整性,所以应当为关键数据使用关系型数据库。在诸如用户通知和聊天记录等场合,NoSQL可以节约成本,安全地使用。

  • 选择附近的数据中心

数据中心的位址应当靠近绝大多数用户。处在与用户同一个国家的数据中心对页面访问速度大有影响。有必要的情况下,还可以建立多个数据中心。

  • 允许数据多来源

存储数据的成倍增加,带来的是应用程序性能降低。程序架构应做好处理多来源的大规模数据的准备。

安全

  • 隔离数据库中的关键信息

数据库用户在访问关键信息时应受到限制,比如取得哪怕是已经Hash过了的密码和所有用户的Email地址等信息。应当使用存储过程和视图作验证,或者作自定义数据。

  • 防止远程执行代码

应用程序包含了对安全性较差代码的依赖时,会使攻击者在远程执行相应的攻击代码。

  • 防止洪水攻击和垃圾邮件攻击

认证用户发起的洪水攻击和垃圾邮件攻击都是可能的。要注意随时跟踪他们最后发起的不明操作,避免制造大量请求。

  • 对密码散列处理时使用唯一salt

所有密码都应当使用salt值散列处理,并且每个用户的salt值都是唯一的。人们容易在不同的服务上使用相同的密码,应用程序有责任保护用户的密码。

  • 全局的跨站脚本攻击(XSS)保护

XSS攻击的全称是Cross Site Scripting跨站脚本攻击,是让用户执行远程恶意脚本的Web漏洞。

  • 防止SQL注入漏洞

SQL注入是常见的漏洞。攻击者通过构造字符串,可以执行有害的SQL命令。使用ORM是一种防范的好方法。

  • 防止跨站请求伪造(CSRF

Cross-Site Request Forgery跨站请求伪造是一种常见的Web漏洞,攻击者在他们的网站上放置一个iframe框架,该框架从程序中请求页面,而用户并不处于应用程序中。GET请求不应该修改数据,这是硬性要求,防止从应用程序域名之外发出POST请求,同时,也可以保护程序不受攻击。相比之下,更好的做法则是在每个表单里提供接收请求后验证的token

  • 修改关键信息之前验证密码

即使用户信息在电脑上有所记录,甚至用户几分钟前成功登录了系统,在访问或者修改如密码,Email或者数据备份等关键信息时总是需要验证密码。

  • HTTP的严格安全传输

如果用HTTPS传输数据,就应该只使用HTTPS传输。否则中间人很可能有作为HTTPSHTTP传输的转换者,让用户使用HTTP发出请求以分析数据。

  • 在所有应用中使用HTTPS

HTTPS是世界范围的加密标准,在第一次连接握手之后没有额外的开销。所有的页面和资源都应当使用HTTPS传输。使用HTTPS的时候,推荐的信息来源也要是HTTPS。否则浏览器就会以安全原因不予显示。

  • 验证会话的浏览器和位置信息

会话和Cookies都可以被劫持。浏览器报头信息和用户最后的IP地址的位置信息都可以和原来的用户会话对比。一个积极防范的办法是将会话与用户IP绑定,但是可能会在动态地址和移动设备的情况下造成问题。

分析

  • 尽可能保留数据

每项数据、每条请求、每个事件都应当记录在大数据的存储中。这些数据将来会很有用处,数据挖掘技术将会呈现出有用的分析报告。

  • 观察用户意向

对于未来计划而言,找出用户使用应用程序与否背后的原因十分重要。

  • 允许用户灵活获取分析报告

现如今数据分析非常关键。分析报告揭示了未来业务的走向何方。优秀的应用程序不仅能便利用户,而且能让用户按需生成报表。

可靠性

  • 分发请求并做到100%上线率

应用服务器直接接受连接,不如在内部搭建一个分发请求的反向代理服务器。这样在有部分服务器当机的情况下也能由仍然运转的服务器提供服务。

  • 自动备份数据

数据应当至少每天备份,而更多的备份任务应当取决于特定存储和应用服务器,必要时还需要做好数据中心的灾备方案。

  • 100% 覆盖业务层和数据层的测试

测试应当覆盖业务层和数据层的所有代码。搅乱用户数据,计算出错误的结果,提供错误数据,以及存储发生错误将会造成用户流失和金钱损失。

  • 检测服务器在线时长

目前有许多检测服务器在线时长的第三方服务。他们同时也提供按指定时间间隔,检查服务器状态的定制服务。

可用性

  • 减少页面刷新

Ajax技术相比,刷新页面更慢,同时也在页面跳转时使用户流失。单页应用(类似Gmail)用户体验良好,同时也更难开发,更容易出bug。资源(人力)足够,则可以选择开发单页应用,否则更应该采用Ajax技术。

  • 隐藏生产环境中的详细错误信息

详细的错误提示页面输出了与错误有关的任何信息,是每位开发者都需要的。生产环境中的应用程序仍然能够记录这些信息日志,那么就有必要隐藏这些信息。

  • 简化用户界面

学习使用程序”的时代已经过去。在用户熟悉之前,程序要足够简单。在用户熟悉之后,高级操作就会显现出来。复杂的界面会使用户望而却步。

  • 全局搜索系统

使用搜索的倾向已在近年来逐渐上升。GoogleFacebookTwitter都有搜索功能。所有的软件巨头都会提供能对搜索结果筛选的全局搜索系统。要让用户们在你的应用上也能有一致的功能。

  • 发生状况时引导用户

发生错误或者输入密码之后,需要向用户指明他们的来向和去向,请记住这一点。

  • 移动端优先的UI

UI设计的通常做法是首先考虑桌面端,然后适配移动端设备。这种做法在适配时开销巨大。UI应当首先考虑移动设备,再适配桌面端。

  • 全局反馈系统

开发者和测试者不能预测问题的状况时有发生。最好的解决办法就是每个页面上都设置能让用户访问到的反馈机制。

  • 一致的UI行为

用户有可能使用着WindowsMacLinux、移动设备或者某个不知名的设备。而在这些环境中,UI的行为必须一致。实现这一点的方法就是遵循标准,并且不使用不标准的组件。同时,使用Bootstrap或者Foundation这样的框架也有帮助。

  • 使用友好的URL

虽然Web应用并不是针对有组织的访客(来自搜索引擎),人们在Email或者IM中分享地址的时候总是想要了解到点击以后出现的内容。人们通常对此解释较少,所以分享的时候URL本身至少能提供相关的信息。

转化策略

  • 邀请码系统

邀请注册是获得新用户最古老也是最有效的转化策略。成功的邀请系统不仅奖励邀请人,被邀请人也会受益。

  • 支持系统

用户总会有问题,而每个应用都需要支持系统。缺少支持系统会让用户望而却步。这里是一些外部方案:ZenDeskDeskFreshdeskZoho Support……

  • 消息通知和定时发送Email

让用户回头使用软件很重要。用户常常不记得软件,遗忘了便不再回来。定时发送带有消息通知的Email能留住用户。不要忘了保留这类选项的开关,不然那将会成为垃圾邮件。

  • 总做得更好

不论拥有多少用户,哪怕1个,甚至成千上万,总是要做得更好。这么做将会掩盖每个软件都会有的瑕疵。

  • 整合社交+激励

访客,哪怕是付费用户,都很难有机会在社交网络上分享你的应用。应该为此设立相应的激励机制。这要求使用FacebookTwitter等社交网络API散播相关信息。

  • 邮件列表

让用户保持更新十分重要。用户使用软件时,他们会很高兴地得知你会为此做出支持,并做到更好。创建邮件列表,让用户知道每月的改进是负责任的态度。

  • 了解潜在的客户

不要指望用户自然而来,你得为之奋斗。虽然有很多优质的广告方案,更好的做法是在互联网上花少量钱甚至免费提供相应的价值,然后将其引导到相应的产品上来。

  • 不要让用户流走

知道用户离开的原因十分重要。好的系统会在用户离开的时候发出一封邮件,提供优惠折扣,并且征求反馈。

竞争策略

  • 研究用户产品需求

软件产品的需求从来就不是凭空产生的。需求分析让开发者与产品经理有据可依。尝试着通过分析用户最常使用的部分来理解客户的真实需求。

  • 了解竞争对手

没有产品是生来完美的。一家公司开发,其他公司改进;最初的那一家因而得到进步。这是每个行业都会有的开发流程。每项产品都会有其竞争对手。