13
Aug 13

国内各种云服务器比较

云服务器在我看来主要分为两类,一类是VPS,另外一类就是专门提供某种特定服务的云,比如七牛的静态文件存储。

VPS类:

  • 阿里云:一般提到阿里云,大家都会和亚马逊云联系在一起,因为他们的有很多相像之处,同是电商巨头,自然会给大家更多的安全感。在阿里云我们有非常长时间的使用,总结下来有这么几点,价格在各家云主机中是最高的,但是服务未必是最很好,例行升级经常会出问题,严重的会直接导致服务器宕机。反正这一年多来没有少受阿里云的折磨。当然,阿里云的故障响应速度还是很快的,出问题一般都能很快解决。

  • UCloud:作为非常有技术背景的创业公司,服务和体验做得都很不错,BGP机房线路,速度没话说。防火墙配置比阿里云来得简单直接,不用太懂Linux都能完成配置,十分方便。同时UCloud云主机可选高性能磁盘,对随机文件读写要求高的业务非常有用,UCloud的高性能磁盘是用SSD做加速的,所以价格也相当实惠。

  • 腾讯云:腾讯云在内测阶段我们就已经拿到内测权限,也是国内最早尝试腾讯云的公司之一,因为目前仍然处在内测阶段,功能相对来说不算特别完善,但是作为国内巨头之一的腾讯,我们还是有理由期待的,现在还不是正式上线的产品,所以就不多做评论。

云数据库:(云数据库可以看做云主机的附属产品,极大方便没有数据库经验的团队。)

  • 阿里云RDS:阿里云的云数据库支持Mysql和sqlServer。价格是同类产品最贵的,不支持主从,灵活性很差,谁用谁后悔,除非业务对数据库依赖不大。

  • UCloud的UDB:只支持Mysql。配置比较灵活,可以按照需求改数据库的配置文件参数,支持主从,唯一美中不足的是相同配置,和腾讯云数据横线对比,速度要慢上许多。也许是内测阶段的腾讯云的资源隔离有问题。

  • 腾讯云CDB:只支持Mysql。配置没有UCloud灵活,不能做主从,速度快,价格不便宜。内测阶段,不评论。

文档云:

  • 又拍云存储:图片云存储起家,速度不错。图片处理和防盗链这块做得不错,图片支持自定义缩略图,水印。同时支持普通文件存储。问题也不少,比如覆盖文件不会自动更新到不同节点,需要手动刷新= =!,后台可以根据链接刷新= =!!!。图片缩略图配置有上限,而且创建后不能删除。

  • 七牛云存储:后起之秀,团队技术能力强,没有又拍更新文件的Bug。缩略图可以直接设置尺寸,不需要先到后台配置,这点很方便。图片处理上有很有趣的小功能。不得不提的是:除了图片处理之外,七牛还支持音频,视频服务器端转码,处理Markdown,还能支持自定义的管道命令,拓展性很强。但是,防盗链这块七牛做得不如又拍,后台暂时无法直接配置。

其他云服务:

  • SendCloud:邮件发送服务,收费合理,送达率很高。

  • 百度云推送:据@zerob13说这个团队很靠谱,目前还是免费(api完善度还不高,开发者还需要多留心,毕竟刚开始,很多东西都做的不是特别完善)。当然百度还有一整套云服务解决方案,没用过,不了解。

PS:盛大云已死,新浪SAE我没有使用经验,所以这里不多阐述。


15
Mar 13

RSS凋零——主动获取信息到推送时代

看到一个消息,Google Reader将在公元2013年7月1日将要下架。有点伤心,也有些感慨。其实从我08年开始用到现在也只有5年时间,没想到RSS这么快已经是这个时代接近尾声。作为一个有十多年编程经验的老网民,深感互联网变化之快,互联网才刚刚开始,新的一波移动互联网正赶在浪潮之巅。

今天一个同事说了一句Google Reader,RSS是主动获取知识,现在已经是信息推送的时代了。仔细一想,的确,移动互联网已经无孔不入,闲暇时间被微博、微信占据,至于Google Reader,我也是抽时间集中阅读。所以,RSS这种获取信息的方式被抛弃是迟早的事情。这不是谁取代了谁,这是人们思维方式的变革,是一次革命,这个不是两头藏羚羊谁比谁强壮的事情,当遇到了狮子,只有咔嚓一口。而我们这些老网虫应该主动拥抱变化。

这时候一定有人问了,RSS都快不行了,你还写什么博客?这个问题太好了,这个年代,博客早已经被主流的微博所替代,很少人还会在博客上写一点博文,在企鹅的空间上发一篇日志,人人上我就不说了。快餐化娱乐化的信息已经占据了我们的视野。虽然我写东西不指望能有多少干货,作为理科生,也总是被各种文科记者“耻笑”词穷,但是我希望我更有价值的信息会出现在这里,微博,娱乐娱乐罢了,我说的太多观点观点别太当真。(ps:有好多朋友的博客都停止更新了,虽然不惊讶,也难免觉得可惜。)

现在,说道微信,微博,又会有一个新的名词出现:“自媒体”。可以想象,互联网是由千万个自由的节点组成的,每个节点不仅仅可能获取互联网上的信息,也可以从中分享。微博就是这个时代的产物,有了这个平台,节点和节点之间就可以相互的获取和分享信息。这好比摆地摊的形式,大家各取所需、同时贡献自己的所长,每个个体相对独立。慢慢的就会有部分人联合在一起,开一个小店,这就是我说的“自媒体”,这是零散的摆地摊形式的一种进化。但是和农贸市场,百货商店比起来这个足够小,自成一派。也足够的灵活,比起传统媒体庞然大物来说要轻快很多。这样的体型正好能够适应现在互联网日新月异的变化,置于将来会不会出现非常大型的媒体,我现在也也不知道,也不想知道。只是现在自媒体才刚刚开始,这个机会窗口正在打开,如果错过了,就要等待下一个窗口。当然,我不保证窗口里面一定有宝藏。

从RSS的凋零扯到信息推送时代的来临,移动互联网正变得越来越有趣。


23
Feb 13

科班出身

看到知乎上有个问题:「你所学的专业对你思维上最大的影响是什么?」 大家的回答基本上都是所学专业给大家的带来了些什么好的影响,对现在的思考问题上带来哪些好处云云。但是我回答的是另外一面,知乎上我简单说明了我所学的专业给我的思维上带来的负面影响,这里我想更加详细的阐述我的观点。

正式开始我的话题之前,我还是想先声明,我并不否定所学专业给我的积极影响,只是现在不在讨论范围以内。

我是计算机专业的,说到计算机或者是程序员,大家脑子里一定会突然浮现这样的一个形象:屌丝、呆板、高度近视、和吸血鬼,僵尸一样,喜欢夜间出没,并且曾经都有一个健康的身体。

我在这里当然不是要告诉大家计算机专业让我变成如上所述。而是正如上面描述一样,我们会陷入一种思维定式当中。其实我身边很多优秀的程序员完全不是上述那样。

举个栗子,计算机专业除了给我们带来了计算机的知识以外,也使我们形成了一种自然不自然的容易只从技术角度出发看问题的毛病。我也曾经遇到这样的问题。比如,有个交互逻辑复杂,为了能让用户有更好的体验,我们会想各种算法实现这个复杂逻辑,其实只要一句文案就解决了;再比如,一个好的idea还没有获得市场的验证,我们就拿名片识别作为例子。我们应该怎样快速开发一套可以投入市场的应用并快速验证市场?我们可能会想寻找一套开源的库,或者找一个懂算法的人一起才能最快的开发。其实根本就没有这么复杂,既然是验证市场,最快的方法就是人工识别,抛开那些看似很酷技术,只要有人在后台盯着用户扫描的名片,人工识别并返回结果,这样开发周期是不是很短?

最近看罗振宇老师的《罗辑思维》,也特别有感触,太多我们习以为常的正确观点其实是经不起推敲的,在这里我推荐给大家都去看看。所以,科班出身有其优势,扎实的功底,同时也要克服这种只从专业角度思考问题的所带来的局限性。


01
Jan 13

2012年个人总结

2012年算不上特别精彩和跌宕起伏,但一定是我这20多年来目标最明确的一年,创业项目小恩爱在2012开始有一些起色,这一年里,我每天都在思考,如果才能让更多人用上小恩爱,如果才能让小恩爱体验更好。

公司方面:

2012年,小恩爱的几个里程碑:

  1. 小恩爱进入移动互联网,推出了iOS和Android版本
  2. iOS刚刚上线,点燃了国内私密社交的热潮
  3. 小恩爱几个月内用户总数突破100w
  4. 小恩爱2.0初步成型

2013年,需要继续改进的:

  1. 加大对Android的投入,重点优化Android用户体验
  2. 尝试给用户提供更好的服务,开始尝试盈利模式
  3. 加强运营和渠道推广

我在2013年的目标:

学习优化团队的组织和沟通。重点是改进开发和沟通方式,琢磨出一套适合自己团队的敏捷开发模式。

有限度的参加几次技术型的会议,加强对外的团队交流。

加强数据分析工作,用数据说话,大胆尝试,没有数据的情况下不妄下结论。

个人方面需要加强锻炼,下半年开始健身房锻炼计划,身体是革命的本钱。

有关博客,每个月至少出1~2篇文章,不仅仅局限于技术和创业。

致谢

感谢所有小恩爱用户的支持和团队的不懈努力,感谢朋友们在创业路上给我们帮助和鼓励。

最后祝愿每一位朋友在新的一年里能有更好的发展。家庭幸福和睦。


06
Dec 12

解决最近GFW升级导致VPN失效问题

最近,公司的VPN总是掉线,后来才看到,方校长的研究文章。「网络流量分类研究进展与展望 」。通过机器学习的方法封锁翻墙了。SSH隧道、IPSEC隧道、SSL, 以及P2P均被破解。无论如何换端口或者ip,只要流量稍大一点,就立刻掉线。

研究了几天后,终于找到对策:VPN通过SSH隧道映射穿越GFW。该方法可以绕过企业级的防火墙,同样,绕过GFW似乎也非常好使。下面简单说说配置的过程。

基本原理: 客户端 –> 本地映射端口 <-- SSH隧道 --> 远程VPN服务器

前期准备

1、可以翻墙的SSH账户(最好和VPN在一台主机上)

2、可以翻墙的VPN账户(openVPN、pptp 等)

配置方法

1、本地设置端口转发的脚本并运行

#! /usr/bin/env python
#coding=utf-8

import pexpect
import re
local_port = "本地转发端口"   #pptp默认是1723 openVPN默认是1194
username = "ssh用户名"     
password = "ssh密码"              
ssh_host = "ssh的地址"
vpn_host = "vpn的地址"     #如果ssh和vpn是一台机子,这里可以是127.0.0.1
vpn_port = "vpn端口"
cmd = "ssh  -C -f -N -g -o CompressionLevel=9 -o Cipher=none "
cmd += username + "@" + ssh_host + " -L "
cmd += local_port +":"+ vpn_host + ":" + vpn_port
pattern = re.compile("^.*assword:\s*")
child = pexpect.spawn(cmd)
child.expect(pattern)
child.sendline(password)
child.expect(pexpect.EOF)

2、设置VPN的地址和端口到本地映射地址

按照上面脚本,如果是openVPN,那么连接的地址应该是127.0.0.1:1194。

3、特别注意

由于SSH端口转发不支持UDP,所以openVPN要把连接方式改成TCP的才能顺利连接。
上面是简单的介绍,如果还有疑问可以在微博私信我。


06
Nov 12

出道一年总结

好久没有写博客了,一来这段时间很忙,二来我真的不知道写什么好。作为技术型的博客,我本应该分享一些我实践是感悟和体会,但是出道1年来,我对创业又有了新的理解。以至于我不好意思在博客上炫耀我浅薄的技术,也不敢晒我仅仅创业一年多来的肤浅的理解。但是博客终究不能这样就不了了知了,眼看快要4个月没有出文章了,这已经让我忍无可忍。

技术方面:

  1. 不要重复制造“烂”轮子

    不要重复制造轮子这个道理在会看我的博客的人中应该是耳熟能详(如果这个都不知道,那自觉去Google补习)。不过我这里说的是另外一个道理,我相信,大多数创业公司在初期都会经历产品的快速迭代和大面积的修改,每次都会改动很大一部分代码,相信一段时间以后这些代码已经千疮百孔,惨不忍睹。如果你很幸运,在经历某一个版本的迭代以后,你会惊奇的发现,你能把握用户的口味了,同时,你也会知道这个产品如果才能更受用户欢迎。不知不觉中,用户会在短时间内突飞猛涨。这时候是时候需要学着开始稍稍放慢脚步了,不能一味的追求快速开发和迭代,因为在时间的压力下,代码质量会急剧的下降,同时之前的很多欠考虑的设计会凸显出来。比如服务器无法承受高峰期的流量,数据库结构不合理,某个版本无法向下兼容等等。如果很多模块在不停的重写->更新->重写…这样必然造成时间浪费,也许,放慢10%的速度,这些问题就会迎刃而解。

  2. 发现问题越早解决越好

    我不是神人,也无法夜观天象。每次虽然尽量考虑周全但是也一定会有疏漏。100个用户个100万的用户差别还是很大的,在用户高速增长的过程总会时不时的暴露出各种问题,当你遇到这些问题的时候一定要提前解决,不然小问题堆积在一起,最终会无从下手,特别是服务器底层的数据库问题,如果某个数据库设计不合理,千万及时想办法解决,不然将来你有得苦吃的。

  3. 最简单的一点

    顺手删除没用的代码,不要让冗余的代码一直存在于生产环境。这个很简单,也很容易被忽视,顺手删除没用代码(SVN有备份,所以不用担心),不然你会在某天发现,你的项目中几十万行代码,不知道那些有用,那些没用。只要在开发过程中顺手解决,将来会减少很多头疼问题。

有关创业

  1. 不停的否定自己

    也许你在某个方面非常出色,也许你也有你独到的观点。但这都没关系,更多的时候需要接纳别人的想法(不一定要吸收),或者别人不同的见解。我发现人都有个习惯,当别人的想法和自己的思维产生冲突的时候,总是很难接受,或者说,非常排斥。我觉得社会和环境在一直变化,如果一成不变一定是没用希望的,时时刻刻提醒自己,需要变化,需要总结,有时候更需要否定自己。这样才能有所突破。

  2. 没用经历过的想法都是错的

    我们总是能从之前的经验中总结出一些道理,我们也习惯用经验去判断一个事情。但是,我想非常郑重的提出来,没用亲身经历的很多东西都是错的,单纯凭经验判断都是不准确的。有时候我宁可笨一点,宁可多尝试,不要被所谓的经验所束缚。


20
Apr 12

创业公司需要怎样的技术

从开始到现在也已经过去大半个年头了,在这过程中有许多体会,正好最近也在思考团队建设问题,这里就顺便谈谈我的一些理解和体会。

既然是创业团队,想必初始团队成员不会很多,但基本上至少会有1~2个人负责技术。我相信选择创业的每一个起初都是满怀希望,胸有大志的。但是,一个月后呢?这里我首先想所的就是团队的执行力,作为创业团队都知道这比什么都重要。“设计师已经迭代了3个版本了,结果第一个版本都还没上线”,这种事情在创业团队似乎很常见,如果你做了3个月连一个Demo都没上线,你还如何创业?

天下武功为快不破,创业者需要具备的基本技能之一就是快,快速迭代,快速成长。这里想到白鸦的逛guang.com,4天就上线了,虽然只有4张静态页面,但至少表达出了自己的产品。不知道是不是受苹果的影响,很多创业者非得做的把产品做到非常完美才愿意上线,我就经常听到某些团队工作一年多了,产品还未上线,以至于我们以为他们早就洗手不干了。所以,我这里说的快指的不仅仅是没日没夜的工作,也要讲究一些方法,要有取舍,要丢得起面子,大不了第二个版本再完善。

从技术角的选择来看,尽量选择开源且有良好社区支持的技术,这样万一在使用过程中出现问题也可以快速找到解决方案,就如现在Unix/Linux占领服务器大半市场,必尤其合理性。微软的产品虽然刚开始的时候入门门槛低,但是它其实并不简单,如果真的碰上什么问题,这个风险和成本很难控制,如果你不小心已经上了微软的贼船,是否破釜沉舟掉头就另当别论了。但初创团队,在决定自己技术之前,我觉得你可以大胆的使用开源技术。但这时候问题又来了,开源技术就像大海一样广阔,人人都可以从中分享和获取资源。很多人在大海中拼命的探索最新最酷的技术,我也是一枚Coder,我很能理解作为程序员的这种满足感,但是这是在创业,做公司,不是一个释放自己满足感的地方,很新很酷技术可以研究,以备将来之用,但不要用在自己的产品上,这样会浪费本多不必要的时间,就如当初在决定小恩爱xiaoenai.com的技术时,Ruby on Rails 也是我能接受的最大尺度。Go、NodeJS、Opa什么的了解了解就可以了。

在研发的过程中,也会遇到这样的问题,我们希望把代码写得尽量简洁,美观。有时候我们会为了把一个50行的代码优化成30行清晰、具有维护性的代码花去半天甚至一天时间,这样的错误我相信所有阅读这篇文章的Coder们都犯过。在产品还没有稳定前,不要急于重构代码。这点不细说,大家应该都明白。但换个角度估计会有很多人想不明白,在产品研发初期,我们是否需要在效率问题上话太多时间?有些人一开始就用100w用户的标准做一个网站我觉得是不适合的,在我看来在初期只要考虑能承受上线后3个月内用户增长规模的标准就可以了,甚至第一版、第二版压根不儿用考虑什么效率问题,肯定跑不死。

有了这些技术和素质,作为创业公司在技术应该80%以上可以站稳了,剩下的就是活动你的双手,用代码构建产品的灵魂。


06
Mar 12

从Github被Hack谈Rails安全隐患

小恩爱在第二版开始采用rails框架进行开发,在体验极度便捷的同时,我们也得时刻提防便利同时带来的安全隐患。
昨天得知Github被Hack,让我再次提高了警惕。下面让我们看看Rails是如何带来的安全隐患。

Github发生了什么

Github上Rails的master被hacker插入了一个commit,Github终于被入侵了。这事情在国外的开发圈闹得沸沸扬扬,这几天在微博上我也看到相关的消息。

Github是如何被Hack,Rails出现了什么问题

Rails拥有极大的便利我们使用的ActiveRecord,当我们需要插入一条数据库时,特别是提交10多项表单的时候喜欢使用下面这样的语句,这就是我们熟悉的massive assignement 特性

model = Model.create(params[:post])
model.save

举个简单的例子说明这个问题

假设我们有一个users表,我们有如下字段:

id  username    password    nickname    motto    point    created_at   updated_at   

其中,point表示积分

我们有一个用户注册的单项

<%= form_for @post do |f| %>
<%= f.text_field :username %>
<%= f.text_field :passowrd %>
<%= f.text_field :nickname %>
<%= f.text_field :motto %>
<%= f.sumbit "Submit" %>
<% end %>

后台提交代码如下

class UserController < ApplicationController
    def create
        @user = User.create(params[:post])
        if @user.save
            # do something
        else
            # do another thing
        end
    end
end

用起来的确非常简单,如此多的表单只要一句话就搞定了,但是真是这一句话,稍不留神就带来了安全隐患。

剖析Rails安全隐患

正常情况下,这段代码可能很顺利的运行,但是如果Hacker在post多加一个字段会如何?但我们在post里面增加一项point,把value设置成99999,我们会惊奇的发现,该新注册用户瞬间就拥有了99999个积分。举一个例子。拿这个漏洞还可以盗用别人的名义发信息,添加任何人为好友等等

Rails的漏洞?如何解决?

很多人在微博上惊呼,Rails出现重大bug,其实不然,真正的原因在于开发者自己,Rails早就为我们做好的这方面的考虑,Rails为Model提供了attr_accessibleattr_protected,这个属性的作用是保护字段,受保护字段只能通过@post.point = 10这种方式赋值,这样就解决了上述情况带来的风险。

class User < ActiveRecord::Base
    attr_accessible :username, :nickname, :motto
    #或者
    #attr_protected :id, :point, :password, :created_at, :updated_at
    #
    # !! 个人认为,从防御式编程的角度讲, attr_accessible 更安全 
end

04
Mar 12

Windows 8 终将是个过渡系统

前几天微软放出Windows 8 消费者预览版。顿时间,微博上充满了各种有关Win8的讨论。虽然我一直都用Mac,但是我还是不能免俗的加入了Win8的试用阵营。现在网上讨论Win8的文章多了去了,不过大多都是从用户体验方面下手。我接下从另外一个角度谈,我认为 Win8 将是一个过度系统。

  1. 硬件需求过高
    如果要真正的体验Metro的操作性,显然还得有一个触摸(这个重担只能落在Win8平板上面了),否则win8和Win7几乎无异,唯一的区别就是硬件要求更高,速度变慢而已。看如今平板是ipad天下,Android奋力追赶依旧被远远甩在后头,Android在手机横行的时候却无法占领平板市场,而wp7还没热,win8平板短时间也难成气候。

  2. 操作革新,老用户很难适应
    Metro界面的引进的确让我们觉得Win8用户体验比以之前任何版本好上很多,但是在中国就不得不考虑庞大的小白用户群体,太多人觉得的Win7都不能适应,而且近30% IE6用户中我们不难得出,至少还有1/3的用户依然跑着10年前的Windows XP。而如今Metro界面和传统界面交错的Win8难道能让小白们买单(这里我说的买单指得是硬件升级,因为国内几乎没有人买正版。)?我看未必。

  3. 兼容性
    微软虽然尽最大努力确保Win8能尽可能的向下兼容,但是重目前的情况看来结果并不乐观,加上很多企业依然跑着N久前开发的系统以及昂贵的升级费用,企业用户升级更是难上加难。此外Desktop应用不能兼容Metro UI,这样势必带来开发成本,可以断言,很长一段时间里面,Metro仅仅是一个摆设。

总结:与其说Windows 8是革命性产品不如说其是过度产品,Desktop 和 Metro、传统计算机和平板的分水岭,从目前4.5亿Win7的销售量来说,Win8要想超过Win7几乎是不可能,但是否会像vista那样悲剧,这还得市场说了算。

附: Windows 8 预览版下载地址: 点击下载


02
Mar 12

Android摘记——在Java中设置width和height

Android 开发的确是个令人头疼的东西,代码不统一,API几乎几天一个变化,今天我就遇到一个问题,在Java代码中修改空间的widthheight
众所周知,在resource的xml中我们通常这样写:

<relativelayout android:layout_width="wrap_content"  
    android:layout_height="wrap_content" >
</relativelayout>

而在Java中的代码应该是这样:

public class Demo extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.demo); 
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( 
            ViewGroup.LayoutParams.FILL_PARENT, // 对应 xml中的 fill_content,数字则代表实际高度
            ViewGroup.LayoutParams.WRAP_CONTENT // 对应 xml中的 wrap_content
        ); 
        layout.setLayoutParams(params);
    RelativeLayout layout = ((RelativeLayout) findViewById(R.id.relativelayout));
    } 
} 
返回顶部 ^