成就梦想

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  21 随笔 :: 22 文章 :: 6 评论 :: 0 Trackbacks

2017年3月1日 #



1,nagios install 参考官方 

https://assets.nagios.com/downloads/nagioscore/docs/Installing_Nagios_Core_From_Source.pdf#_ga=1.136427443.2075387674.1488266439

上面只是参考,请自行安装最新版本的nagios,并自行忽略掉Apache的配置,我们来配置nginx支持nagios。

2,理解什么是cgi。fastcgi。写的非常棒。要多棒有多棒。

参考文章:http://www.cnblogs.com/skynet/p/4173450.html





3,上文理解了,就好办了。我们的目的就是让nginx支持执行我们nagios下的cgi。nginx基于安全性等考虑不让直接执行cgi,但支持fastcgi,所以我们要用到一个fastcig的warp来封装cgi

github上开源的项目 fcgiwarp https://github.com/gnosek/fcgiwrap


git clone https://github.com/gnosek/fcgiwrap.git

autoreconf -i
./configure
make
make instal
ps:
如果aotoreconf执行不了,请自行安装autoreconf。


然后就是怎么使用fcgiwarp ,作者提到了2种使用方法(针对这2种方法在nginx配置稍微不同):

usage

Most probably you will want fcgiwrap be launched by www-servers/spawn-fcgi. Or you could use the author's Perl launcher - see the homepage for that.



第1种是作者自己写的perl 的启动器:作者说在他的主页呢。。。。copy一下放在下面
#!/usr/bin/perl

use strict;
use warnings FATAL => qw( all );

use IO::Socket::UNIX;

my $bin_path = '/usr/local/bin/fcgiwrap';
my $socket_path = $ARGV[0] || '/tmp/cgi.sock';
my $num_children = $ARGV[1] || 1;

close STDIN;

unlink $socket_path;
my $socket = IO::Socket::UNIX->new(
    Local => $socket_path,
    Listen => 100,
);

die "Cannot create socket at $socket_path: $!\n" unless $socket;

for (1 .. $num_children) {
    my $pid = fork;
    die "Cannot fork: $!" unless defined $pid;
    next if $pid;

    exec $bin_path;
    die "Failed to exec $bin_path: $!\n";
}

我们把这个文件保存成 /etc/init.d/fcgiwrap 做成服务执行即可。


第二种方法是用fastcgi的进程管理器来启动。

还是GitHub上开源的牛逼项目
spawn-fcgi   https://github.com/lighttpd/spawn-fcgi

我们写一个启动脚本 

 

spawn-fcgi -f /usr/local/sbin/fcgiwrap -p 9009                       这个端口自己根据机器的端口使用情况自己来写



最后贴一个nginx简单的配置。

vim /etc/nginx/conf.d/nagios.conf  #根据自己的nginx启动位置自行调整


server {
        server_name nagios.tony.com;  #自己的域名
        access_log /var/log/nginx/nagios-access.log;
        error_log /var/log/nginx/nagios-error.log; #日志位置,发现nagios不能在浏览器展示,请看日志,看日志,

#       auth_basic "Private";
#
       auth_basic_user_file /etc/nagios/htpasswd.users;   #把认证先去掉。跑起来在说在。 要把 /usr/local/nagios/etc/cgi.cfg  中的use_ssl_authentication=0


        root /usr/local/nagios/share; #/usr/local/nagios   nagios安装目录
        index index.php index.html;

    #php 的配置,请自行去解决。
         location ~ \.php$ {  
            include /etc/nginx/fastcgi_params;
            fastcgi_pass  127.0.0.1:9000; #php-fpm 
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
                                    }
        location /nagios {
             alias /usr/local/nagios/share;
                                }

         location ~ \.cgi$ {
                root /usr/local/nagios/sbin;
                rewrite ^/nagios/cgi-bin/(.*)\.cgi /$1.cgi break;
                include /etc/nginx/fastcgi_params;

                fastcgi_param AUTH_USER $remote_user;
                fastcgi_param REMOTE_USER $remote_user;
                fastcgi_param SCRIPT_FILENAME /usr/local/nagios/sbin/$fastcgi_script_name;
                fastcgi_pass  unix:/tmp/cgi.sock; #这是上面第一种方式的配置。
                #fastcgi_pass  127.0.0.1:9009; #这是上面第二种方式的配置。
                                }
}
posted @ 2017-03-01 11:35 iamct 阅读(224) | 评论 (0)编辑 收藏

2012年6月14日 #

     摘要:   阅读全文
posted @ 2012-06-14 17:20 iamct 阅读(257) | 评论 (0)编辑 收藏

     摘要: DMA(Direct Memory Access,直接内存存取) 在实现DMA传输时,是由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题。即DMA传输前,CPU要把总线控制权交给DMA控制器,而在结束DMA传输后,DMA控制器应立即把总线控制权再交回给CPU。一个完整的DMA传输过程必须经过下面的4个步骤:1,DMA请求2,DMA响应3,DMA传输4,DMA结束DMA与cpu 使用内...  阅读全文
posted @ 2012-06-14 11:49 iamct 阅读(333) | 评论 (0)编辑 收藏

2012年5月26日 #

转自:http://article.yeeyan.org/view/58906/257928

许多人用shell脚本完成一些简单任务,而且变成了他们生命的一部分。不幸的是,shell脚本在运行异常时会受到非常大的影响。在写脚本时将这类问题最小化是十分必要的。本文中我将介绍一些让bash脚本变得健壮的技术。

使用set -u

你因为没有对变量初始化而使脚本崩溃过多少次?对于我来说,很多次。

chroot=$1 ... rm -rf $chroot/usr/share/doc
如果上面的代码你没有给参数就运行,你不会仅仅删除掉chroot中的文档,而是将系统的所有文档都删除。那你应该做些什么呢?好在bash提供了set -u,当你使用未初始化的变量时,让bash自动退出。你也可以使用可读性更强一点的set -o nounset

david% bash /tmp/shrink-chroot.sh

$chroot=

david% bash -u /tmp/shrink-chroot.sh

/tmp/shrink-chroot.sh: line 3: $1: unbound variable

david%

使用set -e

你写的每一个脚本的开始都应该包含set -e。这告诉bash一但有任何一个语句返回非真的值,则退出bash。使用-e的好处是避免错误滚雪球般的变成严重错误,能尽早的捕获错误。更加可读的版本:set -o errexit

使用-e把你从检查错误中解放出来。如果你忘记了检查,bash会替你做这件事。不过你也没有办法使用$?来获取命令执行状态了,因为bash无法获得任何非0的返回值。你可以使用另一种结构:

command

if [ "$?"-ne 0]; then echo "command failed"; exit 1; fi

可以替换成:

command || { echo "command failed"; exit 1; }

或者使用:

if ! command; then echo "command failed"; exit 1; fi

如果你必须使用返回非0值的命令,或者你对返回值并不感兴趣呢?你可以使用 command || true ,或者你有一段很长的代码,你可以暂时关闭错误检查功能,不过我建议你谨慎使用。

set +e

command1

command2

set -e

相关文档指出,bash默认返回管道中最后一个命令的值,也许是你不想要的那个。比如执行 false | true 将会被认为命令成功执行。如果你想让这样的命令被认为是执行失败,可以使用 set -o pipefail

程序防御 - 考虑意料之外的事

你的脚本也许会被放到“意外”的账户下运行,像缺少文件或者目录没有被创建等情况。你可以做一些预防这些错误事情。比如,当你创建一个目录后,如果父目录不存在,mkdir 命令会返回一个错误。如果你创建目录时给mkdir命令加上-p选项,它会在创建需要的目录前,把需要的父目录创建出来。另一个例子是 rm 命令。如果你要删除一个不存在的文件,它会“吐槽”并且你的脚本会停止工作。(因为你使用了-e选项,对吧?)你可以使用-f选项来解决这个问题,在文件不存在的时候让脚本继续工作。

准备好处理文件名中的空格

有些人从在文件名或者命令行参数中使用空格,你需要在编写脚本时时刻记得这件事。你需要时刻记得用引号包围变量。

if [ $filename = "foo" ];

$filename变量包含空格时就会挂掉。可以这样解决:

if [ "$filename" = "foo" ];

使用$@变量时,你也需要使用引号,因为空格隔开的两个参数会被解释成两个独立的部分。

david% foo() { for i in $@; do echo $i; done }; foo bar "baz quux"

bar

baz

quux

david% foo() { for i in "$@"; do echo $i; done }; foo bar "baz quux"

bar

baz quux

我没有想到任何不能使用"$@"的时候,所以当你有疑问的时候,使用引号就没有错误。

如果你同时使用find和xargs,你应该使用 -print0 来让字符分割文件名,而不是换行符分割。

david% touch "foo bar"

david% find | xargs ls

ls: ./foo: No such file or directory

ls: bar: No such file or directory

david% find -print0 | xargs -0 ls

./foo bar

设置的陷阱

当你编写的脚本挂掉后,文件系统处于未知状态。比如锁文件状态、临时文件状态或者更新了一个文件后在更新下一个文件前挂掉。如果你能解决这些问题,无论是 删除锁文件,又或者在脚本遇到问题时回滚到已知状态,你都是非常棒的。幸运的是,bash提供了一种方法,当bash接收到一个UNIX信号时,运行一个 命令或者一个函数。可以使用trap命令。

trap command signal [signal ...]

你可以链接多个信号(列表可以使用kill -l获得),但是为了清理残局,我们只使用其中的三个:INTTERMEXIT。你可以使用-as来让traps恢复到初始状态。

信号描述

INT

Interrupt - 当有人使用Ctrl-C终止脚本时被触发

TERM

Terminate - 当有人使用kill杀死脚本进程时被触发

EXIT

Exit - 这是一个伪信号,当脚本正常退出或者set -e后因为出错而退出时被触发





当你使用锁文件时,可以这样写:

if [ ! -e $lockfile ]; then

touch $lockfile

critical-section

rm $lockfile

else

echo "critical-section is already running"

fi

当最重要的部分(critical-section)正在运行时,如果杀死了脚本进程,会发生什么呢?锁文件会被扔在那,而且你的脚本在它被删除以前再也不会运行了。解决方法:

if [ ! -e $lockfile ]; then

trap " rm -f $lockfile; exit" INT TERM EXIT

touch $lockfile

critical-section

rm $lockfile

trap - INT TERM EXIT

else

echo "critical-section is already running"

fi

现在当你杀死进程时,锁文件一同被删除。注意在trap命令中明确地退出了脚本,否则脚本会继续执行trap后面的命令。

竟态条件 (wikipedia)

在上面锁文件的例子中,有一个竟态条件是不得不指出的,它存在于判断锁文件和创建锁文件之间。一个可行的解决方法是使用IO重定向和bash的noclobber(wikipedia)模式,重定向到不存在的文件。我们可以这么做:

if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null;

then

trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT

critical-section

rm -f "$lockfile"

trap - INT TERM EXIT

else

echo "Failed to acquire lockfile: $lockfile"

echo "held by $(cat $lockfile)"

fi

更复杂一点儿的问题是你要更新一大堆文件,当它们更新过程中出现问题时,你是否能让脚本挂得更加优雅一些。你想确认那些正确更新了,哪些根本没有变化。比如你需要一个添加用户的脚本。

add_to_passwd $user

cp -a /etc/skel /home/$user

chown $user /home/$user -R

当磁盘空间不足或者进程中途被杀死,这个脚本就会出现问题。在这种情况下,你也许希望用户账户不存在,而且他的文件也应该被删除。

rollback() {

del_from_passwd $user

if [ -e /home/$user ]; then

rm -rf /home/$user

fi

exit

}


trap rollback INT TERM EXIT

add_to_passwd $user


cp -a /etc/skel /home/$user

chown $user /home/$user -R

trap - INT TERM EXIT

在脚本最后需要使用trap关闭rollback调用,否则当脚本正常退出的时候rollback将会被调用,那么脚本等于什么都没做。

保持原子化

又是你需要一次更新目录中的一大堆文件,比如你需要将URL重写到另一个网站的域名。你也许会写:

for file in $(find /var/www -type f -name "*.html"); do

perl -pi -e 's/www.example.net/www.example.com/' $file

done

如果修改到一半是脚本出现问题,一部分使用www.example.com,而另一部分使用www.example.net。你可以使用备份和trap解决,但在升级过程中你的网站URL是不一致的。

解决方法是将这个改变做成一个原子操作。先对数据做一个副本,在副本中更新URL,再用副本替换掉现在工作的版本。你需要确认副本和工作版本目录在同一个磁盘分区上,这样你就可以利用Linux系统的优势,它移动目录仅仅是更新目录指向的inode节点。

cp -a /var/www /var/www-tmp

for file in $(find /var/www-tmp -type -f -name "*.html"); do

perl -pi -e 's/www.example.net/www.example.com/' $file

done

mv /var/www /var/www-old

mv /var/www-tmp /var/www

这意味着如果更新过程出问题,线上系统不会受影响。线上系统受影响的时间降低为两次mv操作的时间,这个时间非常短,因为文件系统仅更新inode而不用真正的复制所有的数据。

这种技术的缺点是你需要两倍的磁盘空间,而且那些长时间打开文件的进程需要比较长的时间才能升级到新文件版本,建议更新完成后重新启动这些进程。对于 apache服务器来说这不是问题,因为它每次都重新打开文件。你可以使用lsof命令查看当前正打开的文件。优势是你有了一个先前的备份,当你需要还原 时,它就派上用场了。

posted @ 2012-05-26 09:37 iamct 阅读(322) | 评论 (0)编辑 收藏

2012年4月26日 #

时间久了,会忘记命令。工具,备忘用。
将一个jar包安装成maven的pom样式,使用。

mvn install:install-file -DgroupId=com.bea.xml -DartifactId=jsr173-ri -Dversion=1.0 -Dpackaging=jar -Dfile=[path to file]
posted @ 2012-04-26 17:16 iamct 阅读(2118) | 评论 (0)编辑 收藏

2012年4月25日 #

Windows下调用程序

Process proc =Runtime.getRuntime().exec("exefile");

Linux下调用程序就要改成下面的格式

Process proc =Runtime.getRuntime().exec("./exefile");

Windows下调用系统命令

String [] cmd={"cmd","/C","dir"};
Process proc =Runtime.getRuntime().exec(cmd);

Linux下调用系统命令就要改成下面的格式

String [] cmd={"/bin/sh","-c","ln -s exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);

Windows下调用系统命令并弹出命令行窗口

String [] cmd={"cmd","/C","start copy exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);

Linux下调用系统命令并弹出终端窗口就要改成下面的格式

String [] cmd={"/bin/sh","-c","xterm -e ln -s exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);

还有要设置调用程序的工作目录就要

Process proc =Runtime.getRuntime().exec("exeflie",null, new File("workpath"))ProcessBuilder ;


同理:
ProcessBuilder也可以这么使用管道 ,使用 |
    ProcessBuilder builder = new ProcessBuilder("/bin/sh","-c","ps aux |grep java");

posted @ 2012-04-25 13:40 iamct 阅读(3669) | 评论 (0)编辑 收藏

2012年4月17日 #

 

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为"字节"。

再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去。他们看到这样是好的,于是它们就这机器称为"计算机"。



开始计算机只在美国用。八位的字节一共可以组合出256(2的8次方)种不同的状态。

他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作。遇上 00x10, 终端就换行,遇上0x07, 终端就向人们嘟嘟叫,例好遇上0x1b, 打印机就打印反白的字,或者终端就用彩色显示字母。他们看到这样很好,于是就把这些0x20以下的字节状态称为"控制码"。 

他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127号,这样计算机就可以用不同字节来存储英语的文字 了。大家看到这样,都感觉很好,于是大家都把这个方案叫做 ANSI 的"Ascii"编码(American Standard Code for Information Interchange,美国信息互换标准代码)。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。

后来,就像建造巴比伦塔一样,世界各地的都开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算 机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到 了最后一个状态255。从128到255这一页的字符集被称"扩展字符集"。从此之后,贪婪的人类再没有新的状态可以用了,美帝国主义可能没有想到还有第 三世界国家的人们也希望可以用到计算机吧! 

等中国人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存呢。但是这难不倒智慧的中国人民,我们不客 气地把那些127号之后的奇异符号们直接取消掉, 规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的 字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。 

中国人民看到这样很不错,于是就把这种汉字方案叫做 "GB2312"。GB2312 是对 ASCII 的中文扩展。

但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,特别是某些很会麻烦别人的国家领导人。于是我们不得不继续把 GB2312 没有用到的码位找出来老实不客气地用上。

后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不 是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。 

后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK 扩成了 GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了。

中国的程序员们看到这一系列汉字编码的标准是好的,于是通称他们叫做 "DBCS"(Double Byte Charecter Set 双字节字符集)。在DBCS系列标准里,最大的特点是两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里,因此他们写的程序为了支持中文处 理,必须要注意字串里的每一个字节的值,如果这个值是大于127的,那么就认为一个双字节字符集里的字符出现了。那时候凡是受过加持,会编程的计算机僧侣 们都要每天念下面这个咒语数百遍: 

"一个汉字算两个英文字符!一个汉字算两个英文字符......"



因为当时各个国家都像中国这样搞出一套自己的编码标准,结果互相之间谁也不懂谁的编码,谁也不支持别人的编码,连大陆和台湾这样只相隔了150海 里,使用着同一种语言的兄弟地区,也分别采用了不同的 DBCS 编码方案。当时的中国人想让电脑显示汉字,就必须装上一个"汉字系统",专门用来处理汉字的显示、输入的问题,但是那个台湾的愚昧封建人士写的算命程序就 必须加装另一套支持 BIG5 编码的什么"倚天汉字系统"才可以用,装错了字符系统,显示就会乱了套!这怎么办?而且世界民族之林中还有那些一时用不上电脑的穷苦人民,他们的文字又怎 么办?

真是计算机的巴比伦塔命题啊!

正在这时,大天使加百列及时出现了:一个叫 ISO (国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、所有字母和符号 的编码!他们打算叫它"Universal Multiple-Octet Coded Character Set",简称 UCS, 俗称 "UNICODE"。


转自 http://www.iteye.com/topic/351135


posted @ 2012-04-17 20:58 iamct 阅读(1044) | 评论 (3)编辑 收藏

2012年1月4日 #

项目中对于web项目 经常需要经 一些resource下的文件,打包时,移动到WEB-INF下。


<plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-war-plugin</artifactId>

                <configuration>

                    <webResources>

                        <resource>

                            <targetPath>WEB-INF</targetPath>

                            <directory>src/main/resources-${package.target}</directory>

                            <includes>

                                <include>

                                    log4j.properties

                                </include>

                            </includes>

                        </resource>

                    </webResources>

                </configuration>

            </plugin>
posted @ 2012-01-04 10:57 iamct 阅读(2922) | 评论 (0)编辑 收藏

2011年12月22日 #

redis 官方提供的 conf
https://raw.github.com/antirez/redis/2.2/redis.conf
中6中过期策略的具体方式。
redis 中的默认的过期策略是volatile-lru 。设置方式   
config set maxmemory-policy volatile-lru


maxmemory-policy 六种方式
  1. volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
  2. allkeys-lru : 删除lru算法的key   
  3. volatile-random:随机删除即将过期key   
  4. allkeys-random:随机删除   
  5. volatile-ttl : 删除即将过期的   
  6. noeviction : 永不过期,返回错误  
posted @ 2011-12-22 14:50 iamct 阅读(9592) | 评论 (0)编辑 收藏

2011年12月14日 #

因英语水平有限,一定有翻译不当的情况。请大家指正。不要包容。非常感谢。
原文链接:http://zookeeper.apache.org/

阿帕奇zookeeper的目的是开发和维护一个开源的,高可用的分布式协调的服务。

什么是zookeeper?


zookeeper 是一个集中式的服务用来维护配置信息,统一命名,提供分布式的同步和提供集群管理。

所有的这些种类的服务被用在一些或其他形式的分布式应用中。每次这些服务的实现都伴随着不可避免的修复bug,解决竞争条件等大量的工作。
因为这些服务实现的难,应用程序最初通常吝啬对他们,这导致了他们在变化面前非常脆弱和难于管理。即使实现正确了,当应用部署的时候,这些服务不同的实现导致了管理的复杂性。
更好的了解学习zookeeper ZooKeeper Wiki. (翻译的链接)

入门指南

Start by installing ZooKeeper on a single machine or a very small cluster.

从单机安装zookeeper或者安装一个zookeeper的集群开始 

   1.读这个文档学习了解zookeeper

   2.下载zookeeper


  1. Learn about ZooKeeper by reading the documentation.
  2. Download ZooKeeper from the release page.

进阶


zookeeper是一个在apache软件基金会下的一个开源项目。我们鼓励你尝试了解项目并贡献你的专业知识。下面是一些链接

  1. See our How to Contribute to ZooKeeper page.
  2. Give us feedback: What can we do better?
  3. Join the mailing list: Meet the community.



原文

Welcome to Apache ZooKeeper™

Apache ZooKeeper is an effort to develop and maintain an open-source server which enables highly reliable distributed coordination.

What is ZooKeeper?

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications. Each time they are implemented there is a lot of work that goes into fixing the bugs and race conditions that are inevitable. Because of the difficulty of implementing these kinds of services, applications initially usually skimp on them ,which make them brittle in the presence of change and difficult to manage. Even when done correctly, different implementations of these services lead to management complexity when the applications are deployed.

Learn more about ZooKeeper on the ZooKeeper Wiki.

Getting Started

Start by installing ZooKeeper on a single machine or a very small cluster.

  1. Learn about ZooKeeper by reading the documentation.
  2. Download ZooKeeper from the release page.

Getting Involved

Apache ZooKeeper is an open source volunteer project under the Apache Software Foundation. We encourage you to learn about the project and contribute your expertise. Here are some starter links:

  1. See our How to Contribute to ZooKeeper page.
  2. Give us feedback: What can we do better?
  3. Join the mailing list: Meet the community.

 


posted @ 2011-12-14 00:26 iamct 阅读(648) | 评论 (0)编辑 收藏

仅列出标题  下一页