最近做数据中心应用运维的工作比较多,接触到了puppet这个工具。看了下官方文档,了解了基本语法,原理。直观的感觉puppet是一个使用起来比较简单的配置管理工具,跨平台方面做的也挺好的,还支持osx,比起chef来,概念要少一些。 PPT如下:
Introduction to Nagios
最近接了张从Nagios移植到PagerDuty的卡,活都让同事干了,自己就利用这个时间,看了看文档,基本理解了Nagios的监控的原理以及配置的方法,总结成PPT,在组内做了分享,如下。
Compressing and Uncompressing Files Under Linux
针对Linux下常用的压缩和解压的命令,做了一次分享,tar这个命令很强大,但是命令组合比较难记,总结了下规律,按照ppt中的方式应该会很容易记忆。
Learning Shell: Navigation File Content
Linux系统中浏览文件的命令很多,比如less
,more
, head
,tail
, cat
等,其中less
命令最为丰富,对于二进制文件和压缩文件,也有对应的命令去浏览。我整理了下,在组内做了一次分享,如下为主要内容。
less
这个命令可以查看一个文件的内容,和编辑器的打开要读取整个文件的方式不一样,less
只读取部分,因此,它占用的内存较少。如果是在产品环境下追踪问题,需要打开很大的文档,用这个命令要好过编辑器。
移动
- Ctrl + F(orward)/U(p)/B(ackward)/D(own) 或者 space 滚动
- j/k 向上或者向下移动一行
- g/G/q 跳到文件头/尾部, 退出浏览
Search
- ? 反向搜索
- / 正向搜索
- n/N 跳到下一处/前一处匹配行
- &pattern 只显示匹配 pattern 的行
有用的命令
- :v 使用缺省的编辑器进入编辑模式,可以通过
EDITOR
环境变量修改 - :F 类似
tail -f
的效果,等待文件即时的输出,但是tail命令是不能搜索的 - ma 标记,使用a跳到标记处,``跳到上次浏览位置
- ! 执行shell命令
- :s file 将管道中的内容保存在file中
- :h 显示所有快捷方式及命令
浏览多个文件
- less file1 file2 file3
- :n 查看下一个文件
- :p 查看前一个文件
- :e 打开一个文件
cat
查看文件内容,每次输出全部内容。tac
命令和cat
命令作用相反。
常用参数
- -T 显示文件中的tab
- -n 显示文件的行数
- -b 显示行数,不包括空行
重定向
- 清空文件:
cat /dev/null > empty_the_file.txt
- 合并文件:
cat -n file1 file2 > file3
- 重定向:
cat ~/.ssh/id_rsa.pub | ssh root@remote “cat >> ~/.ssh/authorized_keys”
head/tail
取文件前/尾部 10(n)行内容,用法简单直接。 - head -n 10 file - tail -f -n 10 file - tail -n 10 - tail -r file(reversely)
strings
浏览二进制文件,strings
命令可以抽取二进制文件中所有的字符串,在二进制文件没有提供很有效的信息的清空下,可以用这个命令获取到更多的信息,用法很简单。
- strings filename
Z
命令
z系列命令特指z开头的一系列命令,包括:
- zcat
- zless/zmore
- zgrep
- zdiff(zcmp)
这些命令可以看做是变异版的cat/less等,其针对的对象是压缩文件,如tar.gz
结尾的文件,在不解压的情况下,浏览/查找其内容,对比文件内容等。需要注意的是,这些命令只能操作单个文件压缩后的文件,如果是整个目录那就达不到效果了。
对于 bz2 结尾的压缩文件,也有对应的命令群,bz*
,以此类推。
本次session的ppt:
Learning Scala: Function
函数在Scala中是一等公民,这意味着你可以在任何时候定义函数,而且它不需要依附于类,在Class/Object中定义的函数叫做方法。
语法
函数由函数名称,参数以及函数体组成,未声明函数返回类型的,默认返回Unit。
1 2 3 4 5 6 7 8 9 10 11 |
|
对于递归函数,必须指定返回类型,否则编译无法通过。
默认参数和带名参数
可以给定函数的参数一个默认的值,调用函数时可以不用传入该参数。
1 2 3 4 5 |
|
不过,如果函数有多个参数并且默认参数是第一个,只传入一个参数时,编译无法通过,应该是没有特别指明,直接被当成了第一个参数。解决的办法是通过带名参数。
1 2 3 4 5 |
|
由此我们可以看出,带名参数不需要和参数列表的顺序相同。
call by name / call by value
Scala中有两种参数替换模型,call by name
和call by value
,直译就是传名或者传值。对于下面的函数
1
|
|
如果是传值的方式,那么 f(2, 2 * 2) 首先会被转换为f(2, 4),也就是说在函数体中未调用之前就已经计算好了。如果是传名的方式,那么2 * 2始终不会被计算,除非该参数被调用。Scala中支持两种传参方式,上面的例子中实际上是call by name
。call by value
是用下面的方式声明函数。
1 2 |
|
只要传入于参数一致的签名的函数即可。
变长参数
和其他编程语言一样,Scala也可以接受变长参数。函数会将变长参数转换参数序列。
1 2 3 4 5 6 7 8 9 |
|
但是直接传入Seq会出错……,因为类型不匹配。
1 2 3 4 5 6 7 8 9 |
|
所以还是需要转换称参数序列。
1 2 |
|
匿名函数
举个简单的栗子好了。
1 2 |
|
过程
过程是返回Unit的函数,利用的是函数的副作用。从语法上来说,和函数的区别就在于它没有等号。
1
|
|
当然也可以加上等号,显示的申明返回类型为Unit。
1
|
|
Learning Scala: Control Structure
任何语言的控制结构应当都是相似的,语言处理现实世界的问题,理应和现实世界对应。Scala的控制结构以及关键字与Java没什么不同,有区别的地方在于Scala中表达式可以有返回值,比如条件表达式。
条件表达式(if/else)
Scala中典型的条件表达式如下:
1 2 3 4 5 6 7 8 9 |
|
需要注意的有如下几点: 1. Scala中,表达式不需要分号表示结束; 2. Scala中没有?:三元表达式; 3. 条件表达式都有返回值; 4. 返回值的超类是Any,if语句没有输出值时,返回值为Unit; 5. 表达式过长或者,可以将其放在大括号中,如下:
1 2 3 4 |
|
循环(for/while)
Scala中的for/while循环和Java中没什么太大区别,但是Scala中没有类似Java中for(initialize; condition; update variable)的结构。
for循环的例子:
1 2 3 4 5 |
|
变量<-表达式 这样的语法被称作生成器, 变量i/c为集合元素类型,循环用其依次获得集合中的元素,并处理。
while的例子:
1 2 3 4 5 6 |
|
Scala中没有break或者continue关键字,如果要中途退出循环,需要自己设置Boolean型变量或者使用Breaks对象的break方法。
for推导
for推导是包含卫语句(guard clause)的for表达式,比如:
1
|
|
如果i 等于 j,表达式不会打印结果。
模式匹配
个人认为Scala最好用的特性之一,等理解透彻了专门写一篇,下面只是个简单的例子,可以认为是可以用来匹配类对象的switch。
1 2 3 4 5 6 |
|
Allow CORS Under Apache
处于安全的考虑,不允许Javascript跨站调用其他网站的服务。对于开放的API服务来说,允许跨站调用又是必须的。为了“解除”这个限制,需要在服务返回的header中添加Access-Control-Allow-Origin
字段。
在Apache的配置中,<Directory>
, <Location>
, <Files>
,<VirtualHost>
或者.htaccess
任意一个section下添加如下内容:
1
|
|
意为该服务允许接受任何跨站请求。当然你可以限制具体的请求网站,如:
1
|
|
要设置允许多个请求源, 可以很没节操的,写上很多遍Header set Access-Control-Allow-Origin "www.xxx.com"
, 或者
1 2 3 4 |
|
除了限制请求源,还可以限制http(s)请求的方法,添加“Access-Control-Allow-Methods”的白名单。
1
|
|
References
Add Swap Space to Solve 'Can Not Allocate Memory' Issue
这几天要把一个新的api服务扔到docker container里面,可能是因为把api和postgre数据库放在了一个container里面,出现了内存不足的情况。
1 2 3 4 5 6 |
|
首先尝试了增加虚拟机内存的方法,在Vagrantfile中修改了分配给virtualbox的内存:
1 2 3 4 5 |
|
错误依旧存在,于是尝试增加swap memory的空间:
1 2 3 4 |
|
然后问题就解决了……, 更合理的方式应该是把数据库和应用放在两个不同的container里面。
Delete Old VMs From Vagrant
想升级Vagrant配置文件中的Ubuntu,但是不想改变box的名字,因此需要删除旧的box,以及VM。
1 2 3 4 5 |
|
从Vagrant中删除box
1 2 3 4 5 6 7 |
|
从VirtualBox中删除虚拟机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Nicely done!
Learning Scala: Some Basics
简单介绍Scala一些基本的概念,主要参考书籍为高宇翔翻译的《快学Scala》第一章。
声明变量:val和var的区别
val
是Scala中用来申明常量(常量变量)的关键字,对应的 var
是用来申明变量的关键字。当我们知道这个概念的时候,对它们区别应该就比较清晰了。Scala中的常量字面量必须是全大写字母。有例为证:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 |
|
Scala会根据初始化的值,自动推断出常量/变量的类型,这个叫做“类型推断”,能想到的类似的概念是Ruby的duck typing,不过Scala是静态语言,并且类型安全(TypeSafe)。 当然你也可以显式的指明变量的类型,用过pascal的同学应该很熟悉这种方式:
1 2 3 4 |
|
Scala支持同时为多个变量赋同一个值,或者像Ruby一样并行赋值,只不过语法略有不同,:
1 2 3 4 5 6 7 8 9 10 |
|
并行赋值的例子,实际上是模式匹配:
1 2 3 |
|
对比下Ruby的代码:
1 2 3 4 5 6 |
|
常用类型
和Java一样,Scala有7种基本的数值类型(Byte, Char, Short, Double, Int, Long, Boolean),不同之处在于它们不是基本类型(Primary Type),全部都是Class。
1 2 3 4 5 6 7 8 |
|
Scala对这些数值类型做了扩展,功能远比Java的对应类型强大,比如在处理String对象的时候,Scala可以将String对象隐式转换成StringOps对象,使用一些高级的方法:
1 2 |
|
Scala中用方法进行类型转换,而不是和Java一样去强制类型转换。
1 2 3 4 |
|
算术符和操作符重载
就结果和使用来说,Scala中的算术符(+-*/%&|^>><<)和Java/c/c++/ruby没什么区别,不过Scala的算术/操作符本质上是方法,刚开始觉得奇怪,后来想想这样做可以保证一致性,也很不错:
1 2 3 4 5 |
|
Scala也没有提供++或者–操作符,+=和-=是等价的代替方式。为什么没有呢?书中给出的理由是实现这个特性不值得……不能理解,是觉得会像c++或者Java一样带来副作用么?
1 2 3 4 5 6 7 |
|
在Scala中,操作符重载功能没有实现,给出的理由比较牵强,不明白为什么那么想。
定义和使用方法
Scala中用def
关键字定义方法,可以显示的制定输入参数以及返回的类型。
1 2 3 4 5 |
|
调用方法
1 2 |
|
定义和使用类
1 2 3 4 5 6 |
|
类和伴生类必须同时定义,所以,可以进入paste
模式,将代码拷贝到Scala的解释器中。
1 2 3 4 5 6 7 8 |
|
能想到的(其实是读过的……)基础就是这些了,下一章介绍控制结构好了。