小心 linode 的流量

Posted by wxianfeng Wed, 09 Mar 2011 00:07:00 GMT

linode 真是让人火大,没有任何通知的情况下,扣除了我信用卡 40 usd ,但是事出有因

因为我超过每个月200G流量了,前几天一直收到 linode 的报警邮件,说我的 VPS 流量比较大 超过了了 平均 5M/s, 但是没有提示超流量的后果. 看看我的 blog 能正常访问 ,也就没管它,后来被扣了 40 美元,真让人火大,FUCK LINODE!,越来越讨厌linode了,随便举几个例子:

1,时常会停电
2,ip偶尔被和谐
3,后台 经常session error 和 硬盘使用量 始终显示100%


4,,价格 偏贵
5,超流量 扣费非常严重
6,….

为什么流量这么大,这个可能是大家关心的

我用iftop实时监控流量,发现 下行流量最高达到 20M/s 确实吓人,下图:

linode 后台也可以看出:

由于个人运维经验有限,没发现什么,只发现了 连到我 80 端口nginx 上的ip数很多,下图:

我把nginx 重启了 ,重启后 还是很多 ,流量依然很大,后来我没办法就 关机了 ,隔了一天后 重启了 机器 ,系统正常了 。。。目前还是不知道 解决办法!

最后看下我这两天被扣的钱,你就知道 超过流量 有多么 惨了

让全球人 都来 fuck linode吧!摸下面网址:

fucklinode!!!


Heroku Permission denied (publickey)

Posted by wxianfeng Mon, 07 Mar 2011 18:57:00 GMT

今天 push project 到 heroku ,可是怎么都出现下面这个错误:

Permission denied (publickey).
fatal: The remote end hung up unexpectedly

不解,push 到github 就没有问题, 网上搜了下 说是 publickey 问题 , 可是看了 heroku 上 和本地的 就是一样的 。。

wxianfeng@ubuntu:/usr/local/system/projects/git/fucklinode$ heroku keys
=== 1 key for wang.fl1429@gmail.com
ssh-dss AAAAB3NzaC...ZALatGdA== wang.fl1429@gmail.com

本地的

~/.ssh/id_rsa.pub 也是这个key

如果发现不一样的 可以 添加一个新的 key

>heroku keys:add  ~/.ssh/id_rsa.pub

更多关于keys的命令可以

>heroku help

继续研究,后来发现 heroku 找的 不是 id_rsa.pub ,而是 id_dsa.pub ,通过 ssh -v git@heroku.com 查出

>ssh -v git@heroku.com 
...
debug1: Trying private key: /home/wxianfeng/.ssh/id_dsa
...

好 , 那我就给你生成 dsa 加密的

>cd ~/.ssh
>rm -rf  *
>ssh-keygen -C "wang.fl1429@gmail.com" -t dsa   # rsa 加密的 -t rsa 即可

上传 key

>heroku keys:add ~/.ssh/id_dsa.pub

>git push heroku master 

就ok了

按照官方的教程 就应该是 id_rsa.pub , 之前也一直好好的,可是 今天 找的怎么是 id_dsa.pub 呢 , 如果你同样遇到这个问题,看看是不是 也是这里的问题 ….

SEE:
http://stackoverflow.com/questions/3481973/heroku-error-permission-denied-public-key
http://devcenter.heroku.com/articles/quickstart
http://help.github.com/troubleshooting-ssh/


Linux 服务器流量监控iftop

Posted by wxianfeng Thu, 03 Mar 2011 02:37:00 GMT

环境:centos5.5 + ubuntu 10.10

最近我的VPS的流量超级大,平均达到了 5m/s , 不知道怎么回事 ,怎么流量这么大 ,最后找到了一个不错的工具 iftop 监控流量

和 top 命令相似,很实用,很方便

1,安装

ubuntu:

>sudo  apt-get install iftop

centos:

yum install flex byacc  libpcap ncurses ncurses-devel
wget ftp://fr2.rpmfind.net/linux/dag/redhat/el5/en/i386/dag/RPMS/iftop-0.17-1.el5.rf.i386.rpm
rpm -ivh iftop-0.17-1.el5.rf.i386.rpm

2,使用

>iftop

3,查看帮助

iftop 后 ? 查看

4,截图

更详细的摸下面网址:
http://www.vpser.net/manage/iftop.html


rails3.1 新特性

Posted by wxianfeng Wed, 02 Mar 2011 02:59:00 GMT

目前 rails的稳定版本是 rails3.0.5,但是rails3.1的新特性已经出来了 , 来看看 。。。

1,Scopes

rails 3.0 我们使用scope,常这样使用:

class Product < ActiveRecord::Base
  scope :nokia, lambda {
    where(:name => 'Nokia')
  }
  scope :category, lambda { |value|
    where(:category => value)
  }
  scope :combined, lambda { |value|
    nokia.category(value)
  }
end
$ @nokia = Product.nokia.all # to get all the products with name Nokia
$ Product.category("Mobile").all # to get all the products with category Mobile
$ Product.nokia.category("Mobile").all #Combined : to get all the products with name = Nokia and category = Mobile

发现scope 只能使用在一个Class中,那么有多个Class 怎么办,rails 3.1 你可以创建一个类 作为 通用的 filter

class Filter < Struct.new(:klass)
  def call(*args); end
end

module NameFilter
  def call(*args)
    klass.where(:name => args.shift)
    super(*args)
  end
end

module CategoryFilter
  def call(category, *args)
    klass.where(:category => args.shift)
    super(*args)
  end
end

class Product < ActiveRecord::Base
  scope :combined, Filter.new(self).extend(CategoryFilter).extend(NameFilter)
end

class User < ActiveRecord::Base
  scope :combined, Filter.new(self).extend(CategoryFilter).extend(NameFilter)
end

Product.combined('Nokia','Mobile').all
User.combined('John','Manager').all

2,Automatic Flushing

Automatic Flushing 是改善性能的一项技术,例如 之前rails渲染页面的机理是这样的,第一步 rails 生成 静态页面 ,例如css,图片,js文件 ,页面html ,然后在一个一个的下载

添加了 Automatic Flushing 这个技术后 ,将会 大大提高性能 , 服务器端一边 生成静态文件 ,浏览器一边就下载了 ,改善了用户体验 和性能

3,css sprites(图片拼合)

rails 3.1 默认支持 icons sprite , 多个icon放在一张图片上 ,显示icon通过css来控制,这样有利于减少http请求数

4,js,css文件可以放到views 下面

#Preprocess:
app/views/js/item.js.erb
app/views/css/style.css.erb
#This code will be compiled to the files like this:
#Compiles:
public/application.js
public/style.css

5,一些旧的用法将不被支持,例如 :conditions

旧的写法:

class User
  scope :name, :conditions => { :name => 'David' }
  scope :age, lambda {|age| {:conditions => ["age > ?", age] }}
end

新的写法:

class User
  scope :name, where(:name => 'David')
  scope :age, lambda {|age| where("age > ?", age) }
end

SEE:

http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/


Rails console 测试路由

Posted by wxianfeng Tue, 01 Mar 2011 17:00:00 GMT

环境:ruby 1.9.2 + rails 3.0.3

rails console 用起来还是很爽的,路由也可以在console下使用 , 甚至可以 get , post , 下面介绍惯用手法:

1,rake 查看routes

>rake routes

2,console 下查看 routes

Rails.application.routes.routes # rails 2.x 使用 ActionController::Routing::Routes.routes 

3, 查看 root(routes)

ruby-1.9.2-p0 > app.root_path
 => "/" 
ruby-1.9.2-p0 > app.root_url
 => "http://www.example.com/" 
ruby-1.9.2-p0 > app.host = "www.wxianfeng.com"
 => "www.wxianfeng.com" 
ruby-1.9.2-p0 > app.root_url
 => "http://www.wxianfeng.com/" 

4,查看资源 路由

ruby-1.9.2-p0 >   user = User.first
  User Load (0.3ms)  SELECT `users`.* FROM `users` LIMIT 1
 => #<User id: 1, login: "entos", name: "", email: "entos@entos.com", crypted_password: "3dea29b4e40bc9a70bb63678678c5ff37fe49753", salt: "2ec7e5db7f3ce5de61f1add8275b674dbd2770dc", remember_token: nil, remember_token_expires_at: nil, activation_code: nil, activated_at: nil, status: 2, suspend_at: nil, avatar_id: nil, orgunit_id: nil, mobile_phone: nil, last_login_at: nil, language: nil, options: nil, created_at: "2011-03-01 07:42:37", updated_at: "2011-03-01 07:42:37"> 
ruby-1.9.2-p0 > app.user_path(user)
 => "/users/1" 
ruby-1.9.2-p0 > app.users_path
 => "/users" 
ruby-1.9.2-p0 > app.new_user_path
 => "/users/new" 
ruby-1.9.2-p0 > app.edit_user_path(:id=>user.id)
 => "/users/1/edit" 
ruby-1.9.2-p0 > app.users_url
 => "http://www.wxianfeng.com/users" 

5,不使用app调用

ruby-1.9.2-p0 > include ActionController::UrlWriter
 => Object 
ruby-1.9.2-p0 > default_url_options[:host] = "wxianfeng.com"
 => "wxianfeng.com" 
ruby-1.9.2-p0 > users_url
 => "http://wxianfeng.com/users"

6,path 和 route Hash 互转

ruby-1.9.2-p0 > r = Rails.application.routes
ruby-1.9.2-p0 > r.generate :controller => "users" , :action=>"new"
 => "/signup" 
ruby-1.9.2-p0 > r.generate :controller => "users" , :action=>"edit" , :id=>1
 => "/users/1/edit" 
ruby-1.9.2-p0 > r.recognize_path "/users/index"
 => {:action=>"show", :controller=>"users", :id=>"index"} 
ruby-1.9.2-p0 > r.recognize_path "/users",:method=>"post"
 => {:action=>"create", :controller=>"users"} 

7,get ,post

模拟get访问首页,没登录 然后跳转到了/login , 然后 post 提交登录 成功

ruby-1.9.2-p0 > app.class
 => ActionDispatch::Integration::Session 
ruby-1.9.2-p0 > app.get "/"
 => 302 
ruby-1.9.2-p0 > app.controller.params
 => {"controller"=>"welcome", "action"=>"index"} 
ruby-1.9.2-p0 > app.response.redirect_url
 => "http://www.example.com/login" 
ruby-1.9.2-p0 > app.post "/session" , {:login=>"entos",:password=>"netposa"}
  SQL (0.3ms)  SHOW TABLES
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE (status = 2) AND (`users`.`login` = 'entos') LIMIT 1
  SQL (0.1ms)  BEGIN
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE (`users`.`id` = 1) LIMIT 1
  SQL (0.0ms)  COMMIT
 => 302 
ruby-1.9.2-p0 > app.controller.params
 => {"login"=>"entos", "password"=>"netposa", "action"=>"create", "controller"=>"sessions"} 
ruby-1.9.2-p0 > app.session[:user_id]
 => 1 
ruby-1.9.2-p0 > app.cookies
 => #<Rack::Test::CookieJar:0xb010120 @default_host="www.example.com", @cookies=[#<Rack::Test::Cookie:0x9b726f0 @default_host="www.example.com", @name_value_raw="_ent_os_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRiIlMzM4ZTdhYzU4OTY3NDhmMmZmMGFhNDkyYTExZWVmOThJIgx1c2VyX2lkBjsARmkGSSIKZmxhc2gGOwBGSUM6JUFjdGlvbkRpc3BhdGNoOjpGbGFzaDo6Rmxhc2hIYXNoewY6C25vdGljZUkiG0xvZ2dlZCBpbiBzdWNjZXNzZnVsbHkGOwBUBjoKQHVzZWRvOghTZXQGOgpAaGFzaHsA--d8652cbfebcae436e64a824d7ac2f64a81aa6619", @name="_ent_os_session", @value="BAh7CEkiD3Nlc3Npb25faWQGOgZFRiIlMzM4ZTdhYzU4OTY3NDhmMmZmMGFhNDkyYTExZWVmOThJIgx1c2VyX2lkBjsARmkGSSIKZmxhc2gGOwBGSUM6JUFjdGlvbkRpc3BhdGNoOjpGbGFzaDo6Rmxhc2hIYXNoewY6C25vdGljZUkiG0xvZ2dlZCBpbiBzdWNjZXNzZnVsbHkGOwBUBjoKQHVzZWRvOghTZXQGOgpAaGFzaHsA--d8652cbfebcae436e64a824d7ac2f64a81aa6619", @options={"path"=>"/", "HttpOnly"=>nil, "domain"=>"www.example.com"}>, #<Rack::Test::Cookie:0x9b826f4 @default_host="www.example.com", @name_value_raw="auth_token=", @name="auth_token", @value="", @options={"path"=>"/", "domain"=>"www.example.com"}>]> 
ruby-1.9.2-p0 > app.response.redirect_url
 => "http://www.example.com/" 
ruby-1.9.2-p0 > app.flash
 => {:notice=>"Logged in successfully"} 
ruby-1.9.2-p0 >

甚至 你还可以 ajax 异步提交

>> app.xml_http_request "/store/add_to_cart", :id => 1
=> 200

8,分配一个 实例变量

>>app.assigns[:foo] = “bar”

SEE

http://clarkware.com/blog/2006/04/04/running-your-rails-app-headless
http://blog.zobie.com/2008/11/testing-routes-in-rails/
http://railstech.com/2010/06/routes-testing-in-rails/
http://stuartsierra.com/2008/01/08/testing-named-routes-in-the-rails-console


ruby yaml 表示数组

Posted by wxianfeng Tue, 01 Mar 2011 00:24:00 GMT

yaml 的语法真是变态 , 表示个数组这么麻烦, 更复杂的数据结构 那不是更麻烦 !!!

yaml 文件:

# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

one:
  name: MyString
  orgunit_id: 1
  inheritable: false
 # codes 是yaml数组表示方法
 # 缩进只能是两个空格为一级,不能是其他字符
  codes: 
    - 1
    - a
    - 2
    - b
    - 3
    - c

ruby 解析yaml:

ruby-1.9.2-p0 >   file =  "#{Rails.root}/test/fixtures/enumerations.yml"
 => "/usr/local/system/projects/entos/ent_os/test/fixtures/enumerations.yml" 
ruby-1.9.2-p0 > YAML.load File.read(file) 
 => {"one"=>{"name"=>"MyString", "orgunit_id"=>1, "inheritable"=>false, "codes"=>[1, "a", 2, "b", 3, "c"]}} 

不知道怎么写的可以 使用 to_yaml 方法 看一下:

irb(main):001:0> 
=> {"one"=>{"name"=>"MyString", "inheritable"=>false, "orgunit_id"=>1, "codes"=>[1, "a", 2, "b", 3, "c"]}}
irb(main):002:0> require "yaml"
=> true
irb(main):003:0> hsh.to_yaml
=> "--- \none: \n  name: MyString\n  inheritable: false\n  orgunit_id: 1\n  codes: \n  - 1\n  - a\n  - 2\n  - b\n  - 3\n  - c\n"

可读性 更好的 使用 y 方法

ruby-1.9.2-p0 > y hsh
--- 
one: 
  name: MyString
  orgunit_id: 1
  inheritable: false
  codes: 
  - 1
  - a
  - 2
  - b
  - 3
  - c
 => nil