• Docker 和一个正常的虚拟机有何区别?

    问:

    我多次重读 Docker.io 文档,希望搞明白 Docker.io 和一个完全的虚拟机的区别。Docker 是如何做到提供一个完整的文件系统,独立的网络环境等等这些功能,同时还没有如此庞大?

    为什么部署软件在一个 docker 镜像(image)比部署在一致的生产环境上要容易?

    答:

    当前,Docker 内部使用的是 Linux 容器技术(LXC),这是运行在与它的宿主机器同样的操作系统上。这准许它可以和宿主机器共享许多系统资源。它也会使用 AuFS 作为文件系统,也为你管理网络。

    AuFS 是一个层状的文件系统,因此你可以有一个只读部分和一个只写部分,然后将二者组合起来。你可以使系统的共同的部分用作只读,那块是被所有容器共享,并且给每个容器自己的可写区域

    好吧,让我们假设你有一个容器镜像(image)容量是 1GB,如果你想用一个完整的虚拟机来装载,你得需要容量的大小是 1GB 乘上你需要虚拟机的数量。但使用 Linux 容器虚拟化技术(LXC)和 AuFS,你可以共享 1GB 容量,如果你需要 1000 个容器,假设他们都运行在同样的系统影像上,你仍然可以用稍微比 1GB 多一点的空间来给容器系统,

    一个完整的虚拟化系统得到了分给它的自有全部资源,只有最小的共享。你获得了更多的隔离,但是这是很庞大的(需要更多的资源)

    使用 Linux 容器虚拟化技术(LXC),隔离性方面有所缺失,但是他们更加轻量,而且需要更少资源。所以你可以轻松运行 1000 个容器在一个宿主机器上,甚至眼都不眨。试着用 Xen 来实现那个,我想除非你有一个超级强大的主机,不然我看是不可能的了

    一个完整的虚拟系统通常得用几分钟去启动,linux 容器虚拟技术(LXC)只要数秒,甚至有时时间更短。

    对于每种虚拟系统都有反对者和支持者。如果你希望一个完全隔离的和资源有保障的环境,那么完全的虚拟机是你的选择。如果你只希望进程之间相互隔离,并且希望大量运行他们在一个合理大小的宿主机器上。那么 linux 容器虚拟技术(LXC)是你的选择。

    更多有关信息,可以参考这些博客,这非常详细介绍了 LXC 的工作 http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part

    “为嘛在 docker 镜像上部署软件比在一致生产环境上容易?” 我觉得问这个问题是非常愚蠢的

    部署一个一致的生产环境说起来容易做起来难。即使你使用了 chef 和 puppet 之类的工具,像操作系统升级,还有一些其它的事情而造成的主机及环境之间的改变,往往是常有的事。

    docker 所做的事情就是赋予你一种能力,使你可以将 OS 快照存入一个通用的镜像,并使得在往其它的 docker 主机上部署时变得容易。对于本地,开发、质量管理、产品等等,都是用的同一个镜像。当然你也可以用其它的工具来做到这一点,但是可能没有这么容易或者这么快。

    这对于单元测试是非常棒的。让我们来看看你有 1000 个测试,而且都需要连接数据库。为了不破坏任何事情,你需要一个接着一个的运行,以便这些测试不会相互影响(每个测试都在事务中,然后回滚回去)。使用 Docker,那么你可以创建一个数据库的镜像(image),既然你知道这些测试会运行在相同的的数据库快照下,那么就可以并行地运行所有测试。既然这些测试都是并行运行在 linux 容器中,那么他们可以同时运行在同样的环境中。这样你的测试会完成的非常快。试着用完整的虚拟机来做这件事。

    编辑:来着评论…

    有趣!我觉得我仍然对于 “系统快照” 的概念有些模糊,如何没有使用这些系统 镜像(image)会怎么样啊?

    好的,试着看我能不能解释。你开始有个基础 镜像(image),然后进行改变数据,并且使用 docker 提交这些改变,这个会建立一个镜像(image),这个 镜像(image)只包含数据改变的部分。当你想运行你的这个 镜像(image)你仍然需要这基础 镜像(image),然后使用层式的文件系统,将你的映像置于基础映像之上,这个例子中用 AUFS,AUFS 将不同层融合起来,然后你就会得到你想要的,你只要简单运行就可以了。你可以增加许多的 镜像(image),这些 镜像(image)只会记录改变的地方。

    英文原文:How is Docker.io different from a normal virtual machine?

    1. SYSTEM

    $ uname –a => Display linux system information $ uname –r => Display kernel release information (refer uname command in detail) $ cat /etc/redhat_release => Show which version of redhat installed $ uptime => Show how long system running + load (learn uptime command) $ hostname => Show system host name $ hostname -i => Display the IP address of the host (all options hostname) $ last reboot => Show system reboot history (more examples last command) $ date => Show the current date and time (options of date command) $ cal => Show this month calendar (what more in cal) $ w => Display who is online (learn more about w command) $ whoami => Who you are logged in as (example + sreenshots) $ finger user => Display information about user (many options of finger command)

    1. HARDWARE

    $ dmesg => Detected hardware and boot messages (dmesg many more options) $ cat /proc/cpuinfo => CPU model $ cat /proc/meminfo => Hardware memory $ cat /proc/interrupts => Lists the number of interrupts per CPU per I/O device $ lshw => Displays information on hardware configuration of the system $ lsblk => Displays block device related information in Linux (sudo yum install util-linux-ng) $ free -m => Used and free memory (-m for MB) (free command in detail) $ lspci -tv => Show PCI devices (very useful to find vendor ids) $ lsusb -tv => Show USB devices (read more lsusb options) $ lshal => Show a list of all devices with their properties $ dmidecode => Show hardware info from the BIOS (vendor details) $ hdparm -i /dev/sda # Show info about disk sda $ hdparm -tT /dev/sda # Do a read speed test on disk sda $ badblocks -s /dev/sda # Test for unreadable blocks on disk sda

    1. STATISTICS

    $ top => Display and update the top cpu processes (30 example options) $ mpstat 1 => Display processors related statistics (learn mpstat command) $ vmstat 2 => Display virtual memory statistics (very useful performance tool) $ iostat 2 => Display I/O statistics (2sec Intervals) (more examples) $ tail -n 500 /var/log/messages => Last 10 kernel/syslog messages (everyday use tail options) $ tcpdump -i eth1 => Capture all packets flows on interface eth1 (useful to sort network issue) $ tcpdump -i eth0 'port 80' => Monitor all traffic on port 80 ( HTTP ) $ lsof => List all open files belonging to all active processes.(sysadmin favorite command) $ lsof -u testuser => List files opened by specific user $ free –m => Show amount of RAM (daily usage command) $ watch df –h => Watch changeable data continuously(interesting linux command)

    1. USERS

    $ id => Show the active user id with login and group(with screenshot) $ last => Show last logins on the system (few more examples) $ who => Show who is logged on the system(real user who logged in) $ groupadd admin => Add group "admin" (force add existing group) $ useradd -c "Sam Tomshi" -g admin -m sam => Create user "sam" and add to group "admin"(here read all parameter) $ userdel sam => Delete user sam (force,file removal) $ adduser sam => Add user "sam" $ usermod => Modify user information(mostly useful for linux system admins)

    1. FILE COMMANDS

    $ ls –al => Display all information about files/ directories(20 examples) $ pwd => Show current directory path(simple but need every day) $ mkdir directory-name => Create a directory(create mutiple directory) $ rm file-name => Delete file(be careful of using rm command) $ rm -r directory-name => Delete directory recursively $ rm -f file-name => Forcefully remove file $ rm -rf directory-name => Forcefully remove directory recursively $ cp file1 file2 => Copy file1 to file2 (15 cd command examples) $ cp -r dir1 dir2 => Copy dir1 to dir2, create dir2 if it doesn’t exist $ mv file1 file2 => Move files from one place to another(with 10 examples) $ ln –s /path/to/file-name link-name => Create symbolic link to file-name (examples) $ touch file => Create or update file (timestamp change) $ cat > file => Place standard input into file (15 cat command examples) $ more file => Output the contents of file (help display long tail files) $ head file => Output the first 10 lines of file (with different parameters) $ tail file => Output the last 10 lines of file (detailed article with tail options) $ tail -f file => Output the contents of file as it grows starting with the last 10 lines $ gpg -c file => Encrypt file (how to use gpg) $ gpg file.gpg => Decrypt file

    1. PROCESS RELATED

    $ ps # Display your currently active processes (many parameters to learn) $ ps aux | grep 'telnet' # Find all process id related to telnet process $ pmap # Memory map of process (kernel,user memory etc) $ top # Display all running processes (30 examples) $ kill pid # Kill process with mentioned pid id (types of signals) $ killall proc # Kill all processes named proc $ pkill processname # Send signal to a process with its name $ bg # Resumes suspended jobs without bringing them to foreground (bg and fg command) $ fg # Brings the most recent job to foreground $ fg n # Brings job n to the foreground

    1. FILE PERMISSION RELATED

    $ chmod octal file-name # Change the permissions of file to octal , which can be found separately for user, group and world octal value (more examples) 4 - read 2 – write 1 – execute Example $ chmod 777 /data/test.c # Set rwx permission for owner , rwx permission for group, rwx permission for world $ chmod 755 /data/test.c # Set rwx permission for owner,rx for group and world $ chown owner-user file # Change owner of the file (chown more examples) $ chown owner-user:owner-group file-name # Change owner and group owner of the file $ chown owner-user:owner-group directory # Change owner and group owner of the directory Example $ chown bobbin:linoxide test.txt $ ls -l test.txt -rw-r--r-- 1 bobbin linoxide 0 Mar 04 08:56 test.txt

    1. NETWORK

    $ ifconfig –a # Display all network ports and ip address (set mtu and other all options) $ ifconfig eth0 # Display specific ethernet port ip address and details $ ip addr show # Display all network interfaces and ip address(available in iproute2 package,powerful than ifconfig) $ ip address add 192.168.0.1 dev eth0 # Set ip address $ ethtool eth0 # Linux tool to show ethernet status (set full duplex , pause parameter) $ mii-tool eth0 # Linux tool to show ethernet status (more or like ethtool) $ ping host # Send echo request to test connection (learn sing enhanced ping tool) $ whois domain # Get who is information for domain $ dig domain # Get DNS information for domain (screenshots with other available parameters) $ dig -x host # Reverse lookup host $ host google.com # Lookup DNS ip address for the name (8 examples of host command) $ hostname –i # Lookup local ip address (set hostname too) $ wget file # Download file (very useful other option) $ netstat -tupl # Listing all active listening ports(tcp,udp,pid) (13 examples)

    1. COMPRESSION / ARCHIVES

    $ tar cf home.tar home # Create tar named home.tar containing home/ (11 tar examples) $ tar xf file.tar # Extract the files from file.tar $ tar czf file.tar.gz files # Create a tar with gzip compression $ gzip file # Compress file and renames it to file.gz (untar gzip file)

    1. INSTALL PACKAGE

    $ rpm -i pkgname.rpm # Install rpm based package (Installing, Uninstalling, Updating, Querying ,Verifying) $ rpm -e pkgname # Remove package Install from source ./configure make make install (what it is)

    1. SEARCH

    $ grep pattern files # Search for pattern in files (you will this command often) $ grep -r pattern dir # Search recursively for pattern in dir $ locate file # Find all instances of file $ find /home/tom -name 'index*' # Find files names that start with "index"(10 find examples) $ find /home -size +10000k # Find files larger than 10000k in /home

    1. LOGIN (SSH AND TELNET)

    $ ssh user@host # Connect to host as user (secure data communication command) $ ssh -p port user@host # Connect to host using specific port $ telnet host # Connect to the system using telnet port

    1. FILE TRANSFER

    scp $ scp file.txt server2:/tmp # Secure copy file.txt to remote host /tmp folder $ scp nixsavy@server2:/www/*.html /www/tmp # Copy *.html files from remote host to current system /www/tmp folder $ scp -r nixsavy@server2:/www /www/tmp # Copy all files and folders recursively from remote server to the current system /www/tmp folder rsync $ rsync -a /home/apps /backup/ # Synchronize source to destination $ rsync -avz /home/apps [email] linoxide@192.168.10.1[/email]:/backup # Synchronize files/directories between the local and remote system with compression enabled

    1. DISK USAGE

    $ df –h # Show free space on mounted filesystems(commonly used command) $ df -i # Show free inodes on mounted filesystems $ fdisk -l # Show disks partitions sizes and types(fdisk command output) $ du -ah # Display disk usage in human readable form (command variations) $ du -sh # Display total disk usage on the current directory $ findmnt # Displays target mount point for all filesystem (refer type,list,evaluate output) $ mount device-path mount-point # Mount a device

    1. DIRECTORY TRAVERSE

    $ cd .. # To go up one level of the directory tree(simple & most needed) $ cd # Go to $HOME directory $ cd /test # Change to /test directory

    pdf 版本下载。可以打印出来慢慢看。 http://linoxide.com/doc/linux_command_shelf_pdf_ver1_1.pdf

  • 目前还不成熟,今年 4.1 号左右,会发布一个稳定版本

  • @ 光风 ake: 这个功能我们一直也没好办法,现在一种方式是通过日期时间去寻找 commitid 然后回退,repo forall 和 git log --until --pretty=format 再加 git reset 组合, 就是按日期来的不够精确。另外帖子里说的报错应该在.repo/manifest 里面提交一把就可以了~ 抛砖引玉,请各位指点~

  • What is a bare git repository? at 2014年03月19日

    一 个 bare repo 与普通 repo 的区别是没有项目文件的 working copy,即 repo 根目录下只有专用目录,而没有任何其他代码文件和文件夹;这是为了响应作为 codebase 应当遵循的 “Only store, never update from revisions(只存储版本,不更新到实际代码文件)” 原则。

    hg 管理的 repo 天生就能做 codebase 使用,无论是否是 bare 的,这点是由其分布式版本控制系统的本质决定的,它可以随时把当前的 repo 通过自带的 http server 发布代码,特别适合分布式开源项目的代码分享。

    git 也是分布式代码版本管理工具,不过它对作为 codebase 的 repo 做了严格的 bare 要求。可以看到的是许多人在初学 git 时不了解这一点,抱怨自己做 spike 时不知如何提交代码到在本机上的 codebase。这里顺手写下两个 tips:

    • 初始建立一个 bare repo

    $ git init --bare

    • 如果已有一个 repo 了,使用下面的方法将其转化为 bare 的

    之后可删除除了 repo 根目录.git 文件夹之外的所有文件,即只保留专用目录

  • What is a bare git repository? at 2014年03月19日

    [i=s] 本帖最后由 scmroad 于 2014-3-19 17:45 编辑

    [color=Green][b] A "normal" repository is a directory containing the actual repository, and a working copy. The actual repository is located in a hidden subdirectory with the name .git. The working copy are those files and directories you work with.

    A "bare" repository is just the contents of the .git directory, without a working copy.[/b]

    You can not work on a bare repository. You first have to clone the bare repository to a normal repository, then work on the clone.

    In your first attempt you created a "normal" repository. Then you cloned that. Then you tried to push back to the normal repository. Then you got a warning. You should not push to a normal repository. Git warns you when you try to do that. You should only push to a bare repository.

    In your second attempt you created a "bare" repository. Then you created a "normal" repository. Then you pushed from the normal to the bare repository. That is (one of) the expected workflow(s). That is why you got no errors or warnings.

    When you want to work on your project from the windows machine and from the ubuntu machine then you have two options:

    Create a bare repository (doesn't matter where). Then clone from that repository, one on the windows machine and one on the ubuntu machine. Now push from the clones to the bare repository, and pull from the bare repository to the clones. Do not push to the normal repositories.

    Create two normal repositories, one on the windows machine and one on the ubuntu machine. Now, when working on ubuntu, you can pull from the windows machine and vice versa. Do not push to each other.

    Bottom line: only ever push to bare repositories. In all other cases, when you think you want to push from A to B, instead, go to B then pull from A.

    It seems that you are very new to git. Please read one or both of the following very fine books: Git Book, Pro Git.

  • What is a bare git repository? at 2014年03月19日

    GIT 初始化--bare 参数:git init & git init --bare 在使用 Git 初始化版本库的时候,使用"git init"命令和使用"git init --bare"命令有什么区别呢? 用"git init"初始化的版本库(暂且称之为 working repository)将会生成 2 类文件:“.git“版本库目录 (记录版本历史) 和实际项目文件的拷贝。你可以把这类版本库叫做 “工作目录”。工作目录是一个包含有版本历史目录 “.git"和源文件的目录。你可以在工作目录修改你的源文件并使用"git add"和"git commit"命令进行版本管理。 用 “git init --bare"初始化的版本库(暂且称之为 bare repository)仅包含".git"目录(记录版本历史),不含项目源文件拷贝。如果你进入版本目录,你会发现仅有".git"目录,没有其他文件。版本库仅包含记录着版本历史的文件。 什么情况下使用 “git init"和"git init --bare"呢? working repository 适合于实际编辑生产过程中,在工作目录下,你将会进行实际的编码、文件管理操作和保存项目在本地工作。如果你开始创建一个项目将包含有源代码和和版本跟踪记录的时候你可以使用"git init".或者,如果你克隆"git clone"一个已经存在的版本库的时候,你也可以得到一个 working repository,它也将包含".git"目录和源文件的拷贝。 bare repository 主要是用作分享版本库。开发者使用 bare repository 可以向其他人分享存储在本地的版本库,以便于实时分享代码更新和团队协作 。通过使用"git push"命令,你可以将你的本地更新提交至 “中心版本库”(其他开发者可访问的中心库)。其他开发者可以使用 “git pull"命令者接受你提交的版本更新。如果你正在一个多人协作的项目团队或者同一个项目需要在不同电脑上面完成的时候,bare repository 可以满足你的分布式开发需求。 总结:“工作目录” 是通过使用 “git init“或 “git clone” 创建的本地项目拷贝。我们可以在工作目录下面修改和测试代码。通过测试后我们可以使用 “git add“和” git commit“命令本地提交修改,然后使用 “git push” 命令向远程 bare repository 库提交更新,通常 bare repository 指定其他服务器,其他开发者将可以及时看到你的更新。当我们想去更新本地工作目录的时候,我们可以使用 “git pull” 命令去接受其他开发者提交的更新。

    译 By: 直来直往 http://hi.baidu.com/aboutstudy/blog/item/8cec7226e3c101098a82a1c6.html

  • 502 一般都是服务器配置问题

  • SVN 负载均衡方案 at 2014年03月17日

    你说的的确不错。原作者其实只是想做到读写分离,减轻单节点 svn server 的负载。这点原作者的方案达到了。 原作者采用方案的优势: 1)架构简单,清晰 2)功能容易实现。 Nginx 做前端代理 + 后端 svnsync

    而且实现方法、nginx 的配置都列出来了,这是难能可贵之处。 针对你的方案,能否详细说说实现?

  • 说具体问题。

    顺便谢谢主的保佑

  • 在这一点上,svn 的确需要改善。

    要么就不允许此类文件的提交,既然允许提交就能正常工作。

  • 多谢参与

  • @Huang冰兵:使用 putty 连接并设置编码为 utf8 应该就 ok 了。ubuntu 默认是使用 utf8 的编码,而 win 不是。

  • @ 峰 XFeng: 前端再加一台 Nginx,把请求转发到 master 和多个 slave, slave 的权重设高一点,用户无论提交还是检出代码都可以通过同一个域名,但是没有出现过 slave 总是落后 master 一个版本的情况, 既然每次提交都会触发同步,那肯定会把所有版本都同步了,如果最新版有问题同步不过来,下次提交也应该还是卡在那个版本

  • 触发条件是 commit,只有 master 上有 commit,才向 slave 同步一次。

    虽然同步失败了,它也不会再重新自动同步一次,还是要等有新 commit 的时候再同步。

  • 要不你试试 svnadmin obliterate ? 或者 svnadmin dump ,svndumpfilter (excluding the bad path) 和 svnadmin load ?

    How do I completely remove a file from the repository's history?

    There are special cases where you might want to destroy all evidence of a file or commit. (Perhaps somebody accidentally committed a confidential document.) This isn't so easy, because Subversion is deliberately designed to never lose information. Revisions are immutable trees which build upon one another. Removing a revision from history would cause a domino effect, creating chaos in all subsequent revisions and possibly invalidating all working copies.

    The project has plans, however, to someday implement an svnadmin obliterate command which would accomplish the task of permanently deleting information. (See issue 516.)

    In the meantime, your only recourse is to svnadmin dump your repository, then pipe the dumpfile through svndumpfilter (excluding the bad path) into an svnadmin load command. See chapter 5 of the Subversion book for details about this.

    An alternative approach is to replicate the repository with svnsync after configuring path-based authorization rules that deny read access to any paths that need to be filtered from history. Unlike svndumpfilter, svnsync will automatically translate copy operations with an unreadable source path into normal additions, which is useful if history involving copy operations needs to be filtered.

    http://subversion.apache.org/faq.html#removal

  • "单个文件超过 1G 的文件" 有必要放 svn 里么?

  • 支持多库 svnsync 的小工具 at 2014年03月03日

    最喜欢这种动手的态度了。支持一个。

  • 貌似还是在那里。 当时他们给多少?

    地址:北京市海淀区中关村东路 8 号东升大厦 B 座 7 层 706

  • 好的。能把卡拔下来么?

  • 锋利的 blade 到底锋利在哪里

    刀是什么样的刀? 诸位看到标题,千万不要以为我是模仿《锋利的 JQuery》,或者什么书籍,而是因为,介绍 Blade 的文章,标题不得不这样。 Blade 由腾讯台风云计算平台出品,大约在 2012 年下半年开源,它是一把专用于构建软件的宝刀。Blade 的字面意义应该是"刀锋",意思是使用该软件构建软件更加强大,更加便捷。该系列宝刀,最早应该是由 Google 这位顶级刀匠打造而成,当年事迹见诸互联网记载: http://google-engtools.blogspot.hk/2011/08/build-in-cloud-how-build-system-works.html http://mike-bland.com/2012/10/01/tools.html#tools-blaze-forge-srcfs-objfs

    听说 Google 内部打磨的宝刀,其名为"火焰刀",英文名为"Blaze",一样是锋芒毕露,炙热灼物,其面世后,以其熊熊烈焰,统一了 google 内部的软件编译方式。腾讯出品的 blade, 英文写法,只有一字之差,不过"火焰""刀锋"各得风流,虽说取名有点像偶像致敬的意思,但是也是锋芒不让。

    提起 google 的宝刀,其实到 google 洗练过几年武学的 IT 牛人们,在远走他方后,也都各自打磨了一把。我的前东家,就成绩打磨过一把类似的宝剑,取名"Ymake",名字是虽然朴拙了一些,但是假如你见过他们亮出过宝刀,也会被其锋芒所吸引。在云壤的江湖朋友们,都称道其"活儿好"。

    就互联网上能搜索到的铸刀秘诀而言,我能搜索到的,应该是我的前任授业恩师放出去的,其实他应该还没有加入云壤。项目地址为: https://code.google.com/p/qa52/ 其 BUILD 语法,虽然还没有简洁到极致,但是功能上似乎看起来也已经有模有样。

    其示例的 BUILD 文件如下所示:

    假如你仔细瞅瞅,会发现语法已经基本接近 google 开放出来的 BUILD 文件示例。

    好吧,花了九牛二虎之力,追溯了 blade 的历史掌故,却还没点到题上。言归正传,blade 其实是一个多语言的构建工具,之所以使用"构建",而不是"编译"两字,实在是因为软件构建并不仅仅是软件编译,而非我喜欢故弄玄虚。Blade 除了编译软件以外,还奉上了很多其它的福利,比如集成了单元测试,性能测试等。这正如一把好刀,不仅应该能杀人,还且最好能力最短的时间内杀死对方,刀光一起,人已倒地,但是刀不流血,刀已回鞘。

    那么,Blade 藏身何处,不急,以下就是它的所在: https://code.google.com/p/typhoon-blade/ https://github.com/chen3feng/typhoon-blade

    目前该项目与陈峰维护,其微博名为"陈三丰",虽然我猜测可能是由于"陈峰"这个名字已经被他人抢先使用,继而只好采用拆字法,将"峰"一分为二,是为"三丰",不过从名字看,倒也和大侠张三丰很有渊源,就此而言,blade(刀锋) 由他维护倒是最妙不过了。

    刀锋的锋芒在哪里?

    既然号称刀锋,那么其锋芒何在?为什么有了 make 这把天下闻名的好刀,还要试试 blade 的锋芒?

    那么下面就在历数一下 blade 的不同凡响处。

    天下武功,唯快不破

    江湖上最知名的刀,无不以快而闻名,blade 的一个好处,也是其编译速度快,快得益于几个方面: 1,可以进行并行编译和并行测试, 2,使用了 ccache 等库,可以将编译中间结果进行缓存。 3,如果使用了 distcc 模式,则可以享有更多的用于编译的硬件资源。听说 google 内部的 blaze 有三个模式,一个是 Local,一个是 distcc,一个是 Forge,按理说,forge 模式由于运行在大规模的集群中,编译的速度应该最为快。 刀虽为刀,却不仅仅是刀

    在仙剑奇侠传四中,宝剑望舒,被男主角云天河各种虐待,从猎野猪、烤肉、劈柴到射箭、御剑,无所不用其极。而一把好刀,其功能自然不应该局限与杀人见血。 Blade 作为一个构建工具,其作用不仅仅是替代 make 和 makefile,且听我细细道来: 1,Blade 是软件工程的利器,有助于模块化,模块化的力度控制自如,对于提高系统的可维护性,复杂性的隔离,代码复用的最大化,都有很大的好处。 2,Blade 提供了单元测试的最佳使用方式。 假若单元测试和代码是分离的,编译代码和运行测试各自为政,那么往往测试只是测试,很难对开发有什么帮助,因为很多时候,虽然有测试代码,但是测试却很少被运行,或者时过境迁后,测试多有失效。大家假如编译过一些开源项目的话,可能就会有类似的经验,编译完静态库,拿到静态库文件就完了,很少有人去运行所有的单元测试,确保所有的测试都能运行通过。 有了 Blade,通过 cc_test 将 gtest_main.a 默认链接,使得单元测试的代码简化到极致。同时,主要运行 blade test target,就能在编译完目标程序后,运行(而且可并发运行)相应的单元测试,以随时跟进代码是否已经偏离了该有的轨道,开发是否早已脱缰狂奔。 只要发布部署时,使用上 Blade test target, 那么就可以保证,上线的模块,能够通过所有单元测试用例的验证把关。Blade 集成单元测试,提供 cc_test,看似功能简单,但是正是这个简单的功能,使得测试驱动开发,开发者测试等理念,能够在 google 全功能范围内得到认同并贯彻实现。 3,blade 实现了递归编译。 Blade build …即可对当前目录及其子目录下的所有编译对象进行编译。该功能虽然小,但是却很实用。在一个十几人的团队中,百万行级别的代码规模,只有递归编译功能,可以很方便地实现一个循环编译工具,当某个模块编译失败,或者某个单元测试失败后,自动发出邮件通知相关的开发人员,以保证频繁的开发提交代码成为开发。当然,相关的功能,可以通过类似 hudson 之类的软件完成。不过 blade 递归编译,对中小规模的代码而言,基本已经游刃有余。 4,blade 实现了依赖查询。 Blade query 可以查询依赖到某个模块的所有模块,这个对于代码重构而言,是个不错的功能。假如你在重构 code base,或者是修改接口,或者是 fix bug,或者是改进性能, 都可能使得使用到该库的相关模块,集体罢工,单元测试无法通过。这时候,假如使用上 blade query,你就可能编译相关模块,使得你提交的代码,不会给其它模块带来麻烦。 5,blade 绑定了静态代码审查功能。 对整个项目而言,严把质量关非常重要,因为一旦一些烂代码进去了,清扫牛粪的工作将会非常痛苦而且艰巨。这里的异己分子,可能包括 bug,风格差异迥异等。 Blade 会在进行编译之前,会所有被变更的编码,使用指定的静态代码审查功能进行代码审查。C++ 代码审查脚本,google cpplint 较为知名,地址为: http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py 当然,每个公司都可以定制其自己的检查脚本,以符合其自己的代码风格等。 Blade 绑定该功能,可以避免出现一些常见的 Bug,统一团队的代码风格,对公司工程文化的塑造有润物细无声之效。 6,blade 是编译的统一入口,并且是开放的 这点是最重要的,也是 blade 的锋芒所在。因为 Blade 是统一的编译如果,因此修改统一的编译选项,设置统一的编译警告级别,实现 cc_test 等全部成为可能。 只要愿意,你不仅可以在编译前实现代码审查,也可以在编译时设置不同的参数,选择指定的编译器,更可以在编译后,运行单元测试,统计单元测试覆盖率,当可以定制各种操作。 因为统一,所以要升级编译器,使用统一的警告级别等牵一发而动全身的动作成为可能。因为开发,实现 cc_test, cc_benchmark, proto_library, thrift_library 成为可能。

    好使的刀,方为好刀 假如刀虽然,但是太笨重,使用起来仿佛破解机关,这只有寂寞的高手才能使用了,普通人得知,如同废铁。因此,好使的刀,才是好刀。 Blade 之所以好使,在于其采用了足够简洁的语法,比如下面便是编译一个静态库 libencoding.a 的语法描述: cc_library( name = 'encoding', srcs = [ 'ascii.cpp', 'base64.cpp', 'hex.cpp', 'percent.cpp', 'shell.cpp', ], deps = [ '//toft/base/string:string', '//thirdparty/stringencoders:stringencoders' ] ) 你需要的只有三件事,要打造的刀叫什么刀,它需要使用什么特别的原料,它需要依赖哪些现成的原料。也就是 name, srcs,deps, 换言之,就是编译对象名,编译需要的源文件,需要依赖的其它静态库。你需要描述的有且仅有他们。怎么编译,编译选项,在哪里编译,中间产物是什么,中间产物放在哪里,你通通不需要关注。刀一出鞘,东西已在那,躺在了你希望它在的所在,热乎乎的,等你去品尝。

    这种简单到极致的语法,好处却有很多。比如: 1, 容易学习,容易记忆,你需要记忆的只有 name, srcs,deps 等掰着十指都能数的过来的关键字和规则,剩下的就是,告诉它用到哪些代码文件,用到了哪些外部的库。 相比 Makefile 繁琐的语法,BUILD 文件可谓清爽宜人。 2,简化到了极致的好处是,各种 cc_library 可以在力度中间轻松转换,因此使用了 BUILD 文件后,模块划分会更加合理,哪怕有一个文件,其它模块可能可以使用上,你也可以方便地将它打包到一个静态库中,这样其它地方只要依赖上这个 cc_library,就可以坐享其成。 我曾经见识过各种 thrift 文件,protobuf 文件散落在代码各个目录甚至分支中,如果使用上 thrift_library, proto_library,将 thrift 文件定义出细粒度的 library,则可以避免因 Makefile 中频繁描述 thrift/protobuf 源文件生成与编译的痛苦。 羞于告诉他人的是,我至今都对 Makefile 不太熟悉,不过所幸,Blade 已经开源,我从此不必也不像和 Makefile 再打交道,我也没有必要告诉别人说,我认识 Makefile 这个哥们。

    宝刀待屠龙 江湖中向来有"武林至尊,宝刀屠龙,号令天下,莫敢不从,倚天不出,谁与争锋."的说法,blade 既然是一把绝世好刀,在倚天剑面世之前,各位江湖好友,不妨试试其刀锋如何!

    转自:http://blog.sina.com.cn/s/blog_4af176450101bg69.html

  • 离下载成功又远了。。。。

  • repo init -u https://android.googlesource.com/a/platform/manifest

    目前为止,这是离成功最近的一次 [attach] 2265[/attach]

  • CODE 的起源 CODE 起源于豆瓣内部,豆瓣最开始使用的版本控制系统是 svn,当然也尝试过 mercurial,最终切换到了 git。

    CODE 本身并不是一个强设计的系统,从改 Trac 开始,一点一点成长到现在的样子。 现在他开源了,希望更多的人可以使用 CODE,希望更多的人可以一起开发 CODE。

    CODE 的用途 CODE 在豆瓣内部的主要用途:

    存储代码仓库。 代码审查,工程师日常的沟通。 与持续集成,上线系统的联动。

    https://github.com/douban/code

  • 哪家公司?可以私信我一下。