March 25th, 2012 | Categories: 技术笔记 | Tags:

什么是RubyGems/RubyOPT?什么情况要设置RUBYOPT?

关于标准库,第三方库

编程语言的标准库,是该种语言的每种实现中都按例提供的库,大多数语言的标准库包含以下组件,以实现一些基本功能:

  1. 算法
  2. 数据结构
  3. 与操作系统交互

ruby标准库可以在源码的lib目录中找到。可以看的ruby标准库包含从文件操作到网络库,从多语言支持到测试工具,从多线程到日期处理等,基本能满足简单使用的需要。

除了标准库的功能,应用开发者希望共享一些代码,这些代码在特定场合经常使用,却没有或不适合加入标准库中,于是就产生约定了格式和使用方式的第三方库,方便管理,分享和搜索。

你可以下载第三方代码,在自己的程序中通过完整的路径来引用相关功能。但是便捷性太差,一个包管理的框架成为必需品。rubygem在这种情况下出现。

怎么确定是否使用rubygems或其它第三方库提供的软件包呢?Ruby中的一个环境变量起到了这个作用,这就是RUBYOPT变量。使用RUBYOPT变量的效果与在ruby命令行中增加参数是相同的。

March 15th, 2012 | Categories: Uncategorized | Tags:

人人网系统运维部招聘系统工程师,欢迎有志之士加入。

如果你有一技之长,对网站运维有深刻理解,或者有牛B的想法想要付诸实践,请发简历到lantao.liu[at]renren-inc.com。

我们的日常工作包括两个方向:
1  系统运维:CDN、存储、LVS集群的运维管理,保障服务稳定;管理系统维护与监控方案实施。
2  技术支持:负责人人公司旗下人人网的系统运维技术支持。为业务开发部门、产品及运营部门提供网络与系统技术支持及运营数据支持,改善支持效率。

除日常工作外,可以对网站优化的各个方向进行研究(性能、流程、用户体验等),制定并推动实施优化方案。

另外需要有经验的c/c++开发工程师做基础软件开发,以及内核优化方面的专家。如果你想换个工作环境,可加qq:103074在线交流。

======================

人人网
系统工程师

工作地点: 北京 工作类别: 技术类

工作描述:

1、CDN全局流量调度系统,监控、管理系统的开发与运维;
2、响应用户/业务团队的技术支持需求,推动技术产品方案的优化与实施;
3、服务器监控系统开发与配置,及时响应业务线监控需求;
4、分布式存储系统的管理、优化及管理工具开发;
5、实施系统/网络参数优化,改进系统效率。

岗位要求:

1、具备Linux操作系统管理经验,了解Nginx/Squid等常用软件的管理与优化;
2、熟悉负载均衡技术原理,了解分布式系统的设计与实现;
3、网络基础扎实,熟悉TCP/IP协议的原理及应用;
4、Php/Python/Perl/C/Ruby等语言,能使用其中一种在Linux下熟练开发;
5、有强烈的服务意识,能够7*24响应处理紧急事件;
6、有大型互联网公司运维/开发经验者优先;
7、有数据分析/数据挖掘相关经验者优先。

 

 

February 25th, 2012 | Categories: 技术笔记 | Tags: ,

在一个程序里使用多种语言进行开发,出发点有若干种:

  • 为了性能,嵌入低级语言的代码进行优化
  • 为了开发效率,嵌入高级语言减少代码行数
  • 重用一些成熟的工具和库文件
  • DSL简化配置,降低维护成本

最近因为要重用一段C++代码,遇到了原来代码逻辑比较复杂的问题。新项目是一段测试程序,首选是一种解释语言。想在脚本中重用这些功能,完全重写的代价比较高,需要花费精力理清原来程序的逻辑。好在输入和输出的内容都很简单,而Ruby提供了可以方便利用的接口,写一个功能扩展来调用旧的C++代码似乎是一个说得过去的选择。

C++的接口为:
std::string PrivateUtil::getInfo(std::string);

首先创建一个文件private_util.cc,包含头文件ruby.h
#include
#include

然后声明所有要实现的功能,与ruby脚本通讯:
VALUE getInfo(VALUE input_str);

下一步,开始进入模块功能注册,也是这个文件的核心。定义一个Ruby的Module,名字为PrivateUtil;另外定义一个getInfo的方法,并且用刚才声明的getInfo与之对应。
extern “C” void Init_foo()
{
VALUE private_util = rb_define_module(“PrivateUtil”);
rb_define_module_function(private_util, “getInfo”, RUBY_METHOD_FUNC(getInfo), 2);
}

现在可以去实现getInfo的具体逻辑了。getInfo的实现也很简单,调用了旧代码的接口,返回一个ruby_str即可。这个返回值需要是ruby的数据类型,以便在脚本中直接使用。
VALUE getInfo(VALUE input_str)
{
return ruby_str_new2(PrivateUtil::getInfo(input_str));
}

到此步骤,c++文件基本完成。

下面开始,建立extconf.rb
require ‘mkmf’
$libs = ‘-lstdc++’
create_makefile ‘private_util’

执行ruby extconf.rb && make,自动生成一个Makefile文件。make后生成了可供ruby脚本调用的so文件。private_util.so。

直接在ruby中调用private_util:
irb > require ‘private_util’
true
irb > PrivateUtils::getInfo(“abc”)
“abc”

如果想在系统全局使用,可以执行make install,这样就能在其它脚本里方面调用。

欢迎交流使用心得。http://www.liulantao.com/

December 28th, 2011 | Categories: 技术笔记 | Tags: , ,

taobao技术团队最近把Tengine开放出来了。

Tengine基于目前很流行的Nginx,在Nginx基础上整合了一些第三方模块,并加入taobao团队研发的一些模块。由于Nginx有设计精美的模块机制,使得整合与模块开发非常方便,在此之前taobao团队开放的另一个项目openresty就是在Nginx基础上完成的。

最新版本的tengine基于nginx-1.0.10稳定版(最新的nginx稳定版是1.0.11)。我在试用时加入了人人网系统运维团队开发的ngx_http_accounting_modulehttp_upstream_consistent_hash_module,并按照部署需求进行了RPM包的制作,这个流程与Nginx官方版本一致性很高,几乎不用做修改就能整合到现在的工作流。

可以看出为适应大规模运维的需求,tengine对nginx做了一些修改:

  • access_log/error_log支持file/pipe/syslog
  • worker_processes和worker_cpu_affinity自动设置
  • expires_by_types
  • stub_status增加了响应时间
  • sysguard
  • limit_req和forbid_action

 

我们关注一下log部分的变化。

tengine对log部分做了较大改变,在原有的文件作为输出目标基础上,增加了syslog和pipe功能。syslog作为日志输出,在nginx-0.6.35时就有过一个patch,但是由于种种原因被拒绝加入官方代码(这可能也是taobao撇开nginx.org另立山头的原因之一)。

syslog的配置语法为:

access_log  syslog:user::debug  main;

access_log  syslog:user::192.168.10.10:514  main;

配置之后需要对syslogd的配置文件做一些修改。虽然部署很方便,但是syslog的方案比较鸡肋,因为现在已经有比较多的更“现代”的方法来进行分布式数据的收集,比如scribe。

使用pipe方式则可以方便地与scribe等系统进行整合。

测试中我使用了更简单的一个方案:通过netcat将管道中的日志发送到远程日志收集端。

配置文件是这样的:

# 将日志实时发送到远程主机192.168.10.10的8000端口,使用TCP协议

access_log “pipe:/usr/bin/nc  192.168.10.10  8000″ main;

在此我选用了便于脚本化且功能强大的netcat。你也可以把其它工具来进行整合,比如与gzip组合使用,进行压缩以降低传输的流量。

pipe方式的日志方式,使得无数想法成为可能,大大提高了运维的灵活性。

 

关于提到的其它特性更详细的使用说明,可以参考Tengine官方网站的文档。

欢迎留言交流。@我#renren.com @我#weibo.com

Comments Off
December 22nd, 2011 | Categories: 技术笔记 | Tags: , , , ,

最近两天我维护的一组缓存服务器遇到一些情况。在处理过程中对集群的调度算法进行了一些思考。欢迎各位看官拍砖。

 

先说一下背景。

这个缓存集群有30多台缓存节点,缓存目标是大小为2-5k的图片文件。

最早的部署方案是将这些缓存节点分成六组(G1-G6),每组4-6个节点。根据文件名特征,将每个文件对应到六组之一;而在组内则采取轮询的方式选择节点进行访问,比较随机。
访问文件在选择的节点中MISS时,选择的缓存节点会从源站或同组内其它节点读取文件,放入自己的缓存,并返回给查询方。
当节点访问出错时(如DOWN机,断网等),文件访问的发起方被轮询算法调度到同组的另外一个节点。
这种方案会造成同组内保存了同一文件的多个副本,这既是好事有事坏事:好的方面是能解决单个缓存节点失效的问题;不好的方面是重复文件使集群的空间利用率不高,对源站造成一定的压力。

 

之后开始实施了一种改进方案,在负载均衡器中使用一致性哈希算法进行调度。一致性哈希的简单原理为:
1、所有缓存节点通过一种哈希算法计算,根据哈希值被分布到一个虚拟的环上,每个缓存节点对应环中的一个节点(改进的算法中会生成多个节点,以提高随机性);
2、将查询的文件名使用相同的哈希算法计算,得到索引值;
3、使用索引值在环上查找。如果索引值正好是一个节点的值,则直接选择对应的缓存节点;否则从索引值所在位置顺着环的方向寻找下一个缓存节点。
4、根据上一步选择的结果,对相应缓存节点进行文件存取操作。

 

根据实际部署需求我们在一个开源的负载均衡模块进行开发。由于缓存节点的能力基本均等,我们通过多组测试选择了更好的哈希算法来提高均衡性,防止个别节点过热;为了处理节点失效的情形,我们开发了响应的调度功能,当某个缓存节点失效时,环上相邻缓存节点会被选择。

至此,这种方案的雏形就完成了。既能解决有效利用容量的需求,又能处理节点失效。由于使用一致性哈希后不在需要进行分组管理,这种方案也带来运维成本的降低。

 

(未完)
>>多个负载均衡器的情况下,缓存失效时的调度算法

Comments Off
November 23rd, 2011 | Categories: 技术笔记 | Tags: ,

pypy是一个高效的python解释器。由于采用了JIT编译器,它的速度快于传统的解释器。

据称这次发布的PyPy 1.7的整体性能性能比1.6提升30%。

用python重新了JSON编码器。新的编码器性能二倍于CPython中C扩展,比1.6版本性能提升高达20倍!

还有一些其它改变,如numpypy。有些特性列入了1.8版本的计划中,包括PowerPC和ARM处理器的JIT汇编器后端。

PyPy 1.7 released [LWN.net].

Comments Off
October 19th, 2011 | Categories: 技术笔记 | Tags: ,

nginx作为反向代理服务器时,打开access_log可以用来查找后端的问题。

默认的nginx.conf有一个log_format配置。这个配置对于普通的静态服务器有些帮助,但是作为代理,还需要做一些定制。

log_format  main  ‘$host $remote_addr – $remote_user [$time_local] $request ‘
‘”$status” $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

我们使用nginx作为反向代理,代理后端部署的实际服务地址可能不止一个(一般情况下是这样)。我们要了解后端服务器的响应情况,就需要在log_format中增加几个变量。

下面列出几个重要的变量:

$status  $upstream_status :  响应的状态码(响应正常还是出错了?)复习一下HTTP CODE

$request_time  $upstream_response_time :  关注性能必备!看看前天传输文件的时间,以及后台处理的时间。前者对了解网络状态有益,后者对了解服务性能有益。

$remote_addr  $upstream_addr :  用户的IP地址,后端服务的IP地址

$bytes_sent $body_bytes_sent  :  发送给用户端的数据量(包含HTTP头和不包含HTTP头)

$host $request :  最重要的,搞定具体域名具体URL,不抓瞎。

根据实际情况,把以上的变量组合放进log_format中。

Comments Off
September 28th, 2011 | Categories: 技术笔记 | Tags: , , , , ,

heroku

heroku是目前最方便使用的PaaS系统,是大部分开发者部署ruby服务的首选,基于git的部署工具带给它比google appengine更好的便捷性。

在heroku创建一个rails程序是非常简单的,基本步骤(只是基本步骤,具体命令需要查rails和git的使用说明):
1、rails create myapp
2、heroku create
3、cd myapp && git init .
4、git commit && git push

搞出这样的开发流程,是造福广大程序员的伟大事业。

 

Why Rack + DataMapper on heroku

Rails + ActiveRecord可以算作一种标配,引领了Ruby开发的潮流。这次尝试Ruby off Rails,选用了Rack + DataMapper的组合。

大部分ruby web框架都支持rack规范,如主流的rails、sinatra、merb。rack定义了一系列规范,类似java的servlet。遵循规范的结果,使得大量rack容器被开发出来。heroku目前默认的容器是thin。

从heroku的文档中看出,heroku使用了postgresql数据库。对于大部分ruby程序而言,使用mysql或pgsql或sqlite都不会影响部署——因为引入数据库抽象层已成惯例,比如ActiveRecord、DataMapper和Sequeel等。

 

First thing first: 部署一个简单的Rack程序

在heroku上部署基于Rack的程序,也是非常简单的。

最简单的config.ru内容如下

map “/”

do    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, StringIO.new("sysadmin 0.1")] }

end

本地直接用rackup即可执行。

如果在heroku上部署,需要额外的Gemfile文件来指明服务器端需要的rubygem。最简单的Gemfile内容为:

gem ‘rack’

将这两个文件git push到heroku上去,可以通过myapp.heroku.com看到页面显示”sysadmin 0.1″。到此最简单的部署完成。

 

Setup DataMapper

require ‘data_mapper’

DataMapper.setup(:default, ENV['DATABASE_URL'] || ‘sqlite::memory:’)

class Tweet

include DataMapper::Resource

property :id,   Serial

property :name, String

property :value, Text

property :created_at, DateTime

end
DataMapper.finalize
DataMapper.auto_upgrade!

经过这一操作,我们就有了一个class:Tweet,并且在数据库中有相应的表生成。一个基于DataMapper进行数据操作的应用就此诞生。

Comments Off
September 28th, 2011 | Categories: 技术笔记 | Tags: , , , , ,

Java and Play! on Heroku

Java and Play! on Heroku

At Heroku, we believe you should be able to choose the best programming language for your application. That’s why we are transforming Heroku into a ploygot platform. We are excited to announce that Java is now available on Heroku as our fourth official language! We also want to introduce Play!, a Java based web framework that is as easy and elegant as Rails for Ruby.

以上为heroku官方的通知,在Ruby,Python,PHP,Node.js,Closure之后,heroku终于支持了Java语言。相信这一次升级会吸引更多的开发者使用heroku平台。

heroku所带来的便捷部署方式,提升开发者效率,改善上线速度,提高程序员生产率和生活质量,一度受到广泛好评。近半年heroku升级速度加快,从单一的ruby平台过渡到多语言平台,一举进入主流的云服务行列。

同时看到一个消息,facebook内置为开放平台用户在heroku上创建应用的功能,独立应用平台与内容平台将各施展所长。

Comments Off
September 27th, 2011 | Categories: 技术笔记 | Tags: , , , , ,

 

一个偶然的机会,看到田春正在翻译Practical Common Lisp——前一天刚看到这本书,还苦苦找了它的中译版而未得。

说说Common Lisp(常被简称CL)。CL是lisp的一种实现,代码和数据都是数学符号的模样——采用polish notation。

如加法表达式:

(+ 2 2)

再如定义一个函数:

(defun square (x) (* x x))

作为一种符号语言,它有坚固的理论基础。CL强大的表达能力和灵活的语言特性,成为被很多技术牛人吹捧的原因。最著名的推广者是Paul Graham——《黑客与画家》等书的作者。

CL的另一个强大之处在于eval,这个功能将一段数据变成可执行的操作,实现了数据与函数的统一。eval对程序开发带来深远影响,之后一些其它语言也有了相似的功能实现,比如Ruby中的实现

a = 1
eval('a + 1') #  (evaluates to 2)

# evaluating within a context
def get_binding(a)
  binding
end
eval('a+1',get_binding(3)) # (evaluates to 4, because 'a' in the context of get_binding is 3)
class Test; end
Test.class_eval("def hello; return 'hello';end") # add a method 'hello' to this class
Test.new.hello                    # evaluates to "hello"

太灵活了,有木有?!

作为程序员的一门最佳练级语言,CL值得一看。

 

Comments Off
September 13th, 2011 | Categories: 技术笔记 | Tags: , , ,

tac – concatenate and print files in reverse

cat是一个查看文件内容的工具,能够将文件内容发送到标准输出。有时候为了按行反序查看一个文件的内容,可以试试tac

 

Comments Off
September 11th, 2011 | Categories: 技术笔记 | Tags: , , , ,

算来使用Linux作为桌面系统,连续下来已经达到5年,如果算上第一次下载刻盘并安装红帽,已经超过8年了。
这些时间中,一半是在Fedora系统上,几个月时间在用Freebsd、debian,以及短暂的使用ubuntu等。有一年时间在使用Gentoo,也是目前觉得最稳定的发行版。

使用Gentoo,虽然每次emerge安装软件都需要进行编译,但是这些都与其它现代发行版的包管理工具没有使用难度方面的差异。

但是使用Gentoo作为桌面的第一个壁垒是内核编译。没有声音,图形不正常等现象,问题的核心大都在内核选项配置。虽然Gentoo.org的文档水平一流,但是选择正确的内核编译选项仍然需要提前做很多功课。

第一门功课是了解硬件型号。
你可以找回电脑的配置单,可以从其它正常工作的系统里查一下。当然一般情况下只需要记下主要硬件的品牌即可。需要关注的硬件列表包含:CPU,网卡、显卡,声卡,键盘鼠标,摄像头及其它外设。

第二门功课是了解内核配置方法。
emerge sys-kernel/gentoo-sources之后,在/usr/src/linux目录下执行make menuconfig命令。
在Device Drivers中选择你的硬件对应的驱动,如果不清楚型号可以把同品牌的驱动都选上。
一些配置的默认值与电脑的实际情况不同,需要修改。如CPU的个数,就需要按照实际情况修改。这点要小心,我前几天就遇到个问题,最后才发现是CPU个数少配置了2个。

第三门功课是学习make.conf中USE的配置方法。
在/usr/portage/profiles/use.desc中有所有USE标签的介绍。系统范围的USE标签在make.conf文件中配置,对单个软件有效的USE标签在/etc/portage/package.use中。

了解这些之后,可以安装软件啦。桌面建议安装gnome-light。

Comments Off