乐正

Actions speak louder than words.

成都金夫人从零部署记录

成都金夫人香港服务器需要部署网站,记录整个服务器搭建的全部流程,涉及安全、用户、 系统等综合性管理。

Task List

  • 添加部署用户
  • 禁止root用户登录
  • 网站部署
  • 防火墙
  • FTP功能

用户管理

建立deployment用户组,负责项目部署;并且在sudoers文件中添加组deployment为管 理员组。

1
2
3
4
5
useradd deployment

# In /etc/sudoers
# Allows people in group deployment to run all commands
%deployment ALL=(ALL) ALL

禁用root用户远程登录系统

1
2
# In /etc/ssh/sshd_config
PermitRootLogin no

服务器环境搭建

  • 安装lnmp(Linux + Nginx + Mysql + PHP)

    参考 LNMP, PHP升级

  • 安装git

1
yum install git
  • 配置PHP
1
2
3
4
5
# php.ini 添加或者修改配置
max_post_size = 300M
file_upload_size = 300M
extension = fileinfo.so
disable_functions =
  • 源码迁移与数据库迁移
1
2
3
4
5
6
# 源码迁移
zip -r project /path/to/project
unzip /path/to/source -d /path/to/destination

# 数据库迁移
mysqldump -u username -p db_name > db_name.sql
  • 配置Nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# default.conf
server {
  listen 80 default;
  server_name _;
  set $root_path '/bjdata/bj/golden_ladies/public';
  root $root_path;
  index index.php index.html index.htm;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

# Removes trailing slashes
  if (!-d $request_filename) {
    rewrite ^/(.+)/$ /$1 permanent;
  }

# Rewrite to index.php unless the request is for an existing file
  (image, js,
# css, etc.)
    if (!-e $request_filename) {
      rewrite ^/(.*)$ /index.php?/$1 last;
      break;
    }

  error_page 404  /404.html;
  location = /404.html {
    root /bjdata/error_pages/;
  }

  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /bjdata/error_pages/;
  }

  location ~ \.php$ {
    try_files $uri /index.php =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
# fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_pass unix:/tmp/php-cgi.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
  }

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
  location ~ /\.ht {
    deny all;
  }

  access_log /var/log/nginx/www.cdjfr.com.log;
  error_log  /var/log/nginx/www.cdjfr.com.error.log;
}

The Meta Programming in Ruby

The machine could be used to create new programming that it could then execute. And that would be meta programming –writing code that writes code.

Base

The basement of meta programming.

Objects and Classes

In reality, however, Ruby has just a single underline class and object structure.

A Ruby object has three components: a set of flags, some instance variables, and an associated class.

self and Method calling

self has two significant roles in running Ruby program.

  • self control how Ruby finds instance variables.
  • self plays a vital role in method calling. If there is no explicit reciever, Ruby uses self as default reciever.

Inside a class definition, self is set to the class object of the class being defined.

Singletons

Ruby lets you define methods that are specific to a particular object. These are called singleton methods.

1
2
3
4
5
6
animal = 'cat'
def animal.speak
  puts "The #{ self } says miaow."
end

animal.speak # => "The animal says miaow."

When we defined singleton method for the animal object, Ruby create a new anonymous class and defined the speak.

Singletons and Classes

Newcomers to Ruby commonly make the mistake of setting instance variables inline in the class definition and then attempting to access these variables from instance methods.

Instance variables defined in the class body are associated with the class object, not the instance of the class.

Another way to access the singleton class

You can do the same thing Ruby’s Class << an_object notation.

You can’t create a new instance of a singleton class.

To make attr_accessor work with class level instance variables, you must have to invoke attr_accessor in singleton class.

Inheritance and Visibility

Within a class definition, you can change the visibility of a method in an ancestor class.

If a subclass changes the visibility of a method in a parent, Ruby effectively inserts a hidden proxy method in the subclass that invoke the original method using super.

The call of super can access the parent’s methods regardless of its visibility.

Modules and Mixins

The module that you include is effectively added as a superclass of the class being defined.

When you include a module in class Example, Ruby Constructs a new class object, makes it the superclass of Example, and then set the superclass of the new class to be the original superclass of Example.

Ruby will include a module only once in a inheritance chain.

prepend

New feature in 2.0

If a method inside a prepended module has the same name as one in the original class, it will be invoked instead of the original. The prepended module can then call the original using super.

extend

Add the instance methods to a particular object.If you use it in a class definition, the module’s methods become class methods.

Refinements

New feature in 2.0

A refinement is a way of packaging a set of changes to one or more classes. These refinements are defined within a module.

Meta programming Class-Level Macros

Because of the way they expand into something bigger, folks sometimes call these kinds of methods macros.

A class method is defined in the class object’s singleton class. That means we can call it later in the class definition without an explicit receiver.

Use define_method to define a log method on the fly.

1
2
3
4
5
6
7
8
9
10
11
12
class Logger
  def self.add_logging(id_string)
    define_method(:log) do |msg|
      now = Time.now.strftime("%H:%M:%S")
      STDERR.puts "#{ now }-#{ id_string }: #{ self } #{ msg }"
    end
  end
end

class Song < Logger
  add_logging('Tune')
end

As well as passing parameters from the class method into the body of the method being defined, we can also use the parameter to determine the name of the method or methods to create.

1
2
3
4
5
6
7
8
9
10
class AttrLogger
  def self.attr_logger(name)
    attr_reader name

    define_method("@#{ name }=") do |val|
      puts "Assigning #{ val.inspect } to #{ name }"
      instance_variable_set("@#{ name }", val)
    end
  end
end

We use instance_variable_set to set the value of an instance variable. There’s a corresponding _get method that fetches the value of a named instance variable.

Class Methods And Modules

You can use module to hold your meta programming implementation. In this case, using extend inside a class definition will add the methods in a module as class methods to the class being defined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module AttrLogger
  def attr_logger(name)
    attr_reader name

    define_method "@#{ name }" do |val|
      puts "Assigning #{ val.inspect }" to #{ name }
      instance_variable_set "@#{ name }", val
    end
  end
end

class Example
  extend AttrLogger

  attr_logger :value
end

Here’s one technique, make us to add both class methods and instance methods into the class being defined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module GeneralLogger
  module ClassMethods
    def attr_logger(name)
      attr_reader name

      define_method "#{ name }=" do |val|
        puts "Assigning #{ val.inspect } to #{ name }"
        instance_variable_set "@#{ name }", val
      end
    end
  end

  module InstanceMethods
    def log(msg)
      puts Time.now.strftime("%Y-%m-%d %H:%M:%S " + msg)
    end
  end

  def self.included(receiver)
    receiver.extend         ClassMethods
    receiver.send :include, InstanceMethods
  end
end

class Example
  include GeneralLogger

  attr_logger :name
end

ex = Example.new
ex.log "A new Example created."
# => 2014-10-31 08:56:56 A new Example created.

ex.name = "Yuez"
# => Assigning "Yuez" to name

ex.name = "Lucky"
# => Assigning "Lucky" to name

Creating Singleton Class

Use Class#new directly to create a singleton class. By default this class will be direct decendent of Object. You can give them a different parent by passing the parent’s class as a parameter.

instance_eval and class_eval

  • Object#instance_eval
  • Module#class_eval
  • Module#module_eval

instance_eval and class_eval both set self for the duration of the block. However, they differ in the way they set up the environment for method definition. class_eval sets things up as if you were in the body of a class definition.

In contrast, calling instance_eval on a class acts as if you were working inside the singleton class of self

Ruby has variants of these methods.

  • Object#instance_exec
  • Module#class_exec
  • Module#module_exec

behave identically to there _eval counterparts but take only a block(they do not take a string).

Hook Methods

included is an example of a hood method (sometime called a callback). A hook method is a method that you write but that Ruby calls from within the interpreter when some particular events occurs.

The interpreter looks for these methods by name–if you define a method in the right context with an appropriate name, Ruby will call it when the corresponding event happens.

The methods that can be invoked from within the interpreter are:

  • Method related hooks.

    method_added, method_missing, method_removed, method_undefined, singleton_method_added, singleton_method_removed, singleton_method_undefined

  • Class and module related hooks.

    append_features, const_missing, extend_object, extended, included, inherited, initialize_clone, initialize_coty, initialize_dup

  • Object marshaling hooks.

    marshal_dump, marshal_load

  • Coercion hooks.

    coerce, included_from, to_xxx

君子固有穷乎?

匪兕匪虎 率彼旷野

“那人在外面不就成了野人吗?”耳边是江河文青特有的幽默,让我想起先贤孔子的感慨:“吾等既非野牛,也非猛虎,何以不得不彷徨原野?”

孔子,子路,颜回,子贡师徒一行,坐道陈都三载。不料吴楚二国,以陈地为战场,一决雌雄。虽非所愿,可是陈都必然将无逃避之途,是故,孔子一行即日离开陈都,前往楚地。

孰料,一行人于野地宿营时,遭吴残兵败部所袭,夺取马车及车上所载粮食。此番逃离陈都之行,已有无法描述的险阻艰辛。如此饿着肚腹,蹒跚前进。路途间或分得一些陈兵粮食,然而也是所得有限,一经平分,根本无济于事。到了不知第八天还是第九天,不折不扣成为了游魂的一行人,挣扎到了某个村落,再也动弹不得。

此时,子路突然趟步走到夫子跟前,掷出一句:

“君子亦有穷乎?”

看似子路真的生气了,如若就此饿死,那么过往所做何为?

“君子亦有穷乎?”子路复问一句。

夫子转向子路,言道:“君子固穷,小人穷斯滥矣。”声音强而有力。

君子固穷 小人穷斯滥矣

小人一旦陷入窘境,就会动摇心智,无法约束自己。君子却是再如何窘迫,也不至于动摇心智。

这一番经历与马浩汉、江河、胡说一行人的平凡之路,再相似不过了。

马浩汉振兴东极村旅游业失败之后,为送江河到西极某地执教,一行三人,收拾行囊,驱车离开家乡。三人决定,先是看望青梅竹马的周沫,继而寻找与马浩汉书信互往十多年的笔友刘莺莺,最后再前往西极。第一个令我心有感触之地,便是周沫送别马浩汉一幕。

周沫是一名替身演员,遵着“小城市的人都是凭借着关系,大城市里或多或少更公平一些”的信念,在演员一行中摸爬滚打。见到周沫,几番寒暄,终是送别之际来临。如若没有记错的话,应是长桥送别。道别之后,周沫行到片场,这次她饰演的是被日本兵枪决的知情少女,“轰”得一声枪响,这是对马浩汉行程至此的终结,也是对接下来行程艰难的伏笔。而这意味深藏的一幕——因为送别之后,他们将面临的是——

波涛汹涌,充满荒谬与悖论的成人世界。

——却被故意设定为马浩汉以为听到的枪声是车胎破裂,从而下车没头没脑检查,随即演员中一片笑声。这一定又是文青式的幽默——刻意设计笑点,将哲理隐藏在幽默中——或许是为了避免“太矫情”。文绉绉的台词不如藏起来好了。

于此之后,直到阿吕登场,剧情有些起色。而在周沫后、阿吕前,所经历两件事,一是“真老师嫖娼不成反被追,假妓女斗智斗勇为讹钱。”,二是马浩汉初见刘莺莺,俱是故事平常,人物平庸,刘莺莺一句心灵鸡汤:“喜欢就会放肆,爱就是克制”,更是将我雷到不行。所幸,阿吕是一位性格丰满的骗子。

马浩汉和江河是在迷路后偶遇阿吕的。你问胡说?胡说在开场五分钟后便已宣告该角色杀青。阿吕原本在一座小镇上经营一家摩托车修理店,为了不被昔日同窗小觑,也为了吸引女神注意,他做出小镇上从来没有过的壮举——摩托车骑行中国。他成功了,虽然没能得到同窗的尊重,却是赢得了女神的爱情,正如阿吕自己所说:“有时,你想证明给一万个人看,最终只得到了一个人的关注,这就够了。”好景不长,不去经年,便在一场雨夜骑行中,与妻子阴阳两隔。此后每年,阿吕都会重走与妻子的路,以此祭奠。碰到马浩汉两人时,已是第六个年头。

至此,故事与孔子一行的经历更相似了。

阿吕随即与二人同行。

一路之上,阿吕时而追忆陈年往事,时而豪迈放声歌唱;在谈及妻子时是那么真诚,在宿营地,激励二人真是鼓舞人心。然而,孰真孰假?阿吕就是村上春树笔下的成人世界吧,充满荒谬与悖论的成人世界。

我并不怕被欺骗,我怕的是我刚刚信任一个人,就被欺骗。

诚如马浩汉所言,辅一得到信任,阿吕便拉勾收网,将这一份情谊以车价贱卖。或许,本就没有什么情谊,或许,阿吕便是孔子口中的小人,或许,不是在这种环境下他们真的能拥有情谊。

狗的寿命只有十四年,但是比情谊长。

所幸,马浩汉二人并没有到山穷水尽的地步,阿吕在开走车时,尚且将他们的行李留下,还有那条代表情谊的阿拉斯加犬。这时的二人,应是到了比绝境也好不了多少的地步。令人起敬的是,马浩汉口中仍是念念不忘事业,江河更是从始至终都没有过动摇。正如他们二人的名字,浩汉江河,奔流到海不复回。二人收拾行李,复又上路,这次他们用步行走完这最后的平凡之路。最终,二人在西极之地的山坡前分别。

故事就此结束,无论如何,我认为故事就此结束。

三分未满

洋洋洒洒许多字,看的人头晕脑胀,还是直接给一个评分吧,清晰明了。

若以十分满计,至西极前我给四分,结尾给一分,平均一下,二点五分,我姑 且算是韩寒半个读者,再加零点五分,最后我给出的得分是三分。缘何会如此 之低?

一段并不精彩的故事,一位并不高明的讲故事人,中间穿杂着一些并不符合人 物身份的心灵鸡汤, 配上突兀生硬的结局,三分可能已经很多了。

不想写了,先到这里吧。