access.log为nginx的访问日志,默认路径在
/var/log/nginx/access.log
分析access.log的ip命令如下:
awk '{print $1}' access.log |sort|uniq -c|sort -n
-
命令里使用awk过滤出访问的ip
-
使用sort对ip排序
-
对排序后的ip进行统计,统计每一个ip访问数
-
最后使用sort 对访问数进行排序,排序为升序。
access.log为nginx的访问日志,默认路径在
/var/log/nginx/access.log
分析access.log的ip命令如下:
awk '{print $1}' access.log |sort|uniq -c|sort -n
命令里使用awk过滤出访问的ip
使用sort对ip排序
对排序后的ip进行统计,统计每一个ip访问数
最后使用sort 对访问数进行排序,排序为升序。
将文件夹中的两个目录分别赋值给两个变量
文件夹名:test_dev、test_release
#! /bin/bash
FOLDERS=$(ls | grep -v '.sh')
echo $FOLDERS
if [[ $FOLDERS =~ "dev" && $FOLDERS =~ "release" ]]; then
eval $(echo $FOLDERS | awk -F' ' '{printf("DEV_PATH=%s;RELEASE_PATH=%s",$1,$2);}')
fi
echo "DEV_PATH: " $DEV_PATH
echo "RELEASE_PATH: " $RELEASE_PATH
test_dev test_release
DEV_PATH: test_dev
RELEASE_PATH: test_release
使用HTTP2 首先必须部署SSL,走HTTPS协议 可参考NGINX服务器网站升级HTTPS
首先查看下nginx支持不支持http2,我是使用yum 安装的默认已经安装了模块,使用下面命令查看
nginx -V
查看下是否有下面的模块
--with-http_v2_module
修改虚拟主机配置
server {
# listen 80;
listen 443 ssl http2;
#....
}
重启服务器,restart 而不是reload
service nginx restart
第一种方法
在谷歌浏览器上打开你使用http2的站点,在浏览器地址栏输入chrome://net-internals/#http2,看下HTTP/2 sessions 里面有没有你的主机地址
第二种方法
在谷歌浏览器上打开你使用http2的站点,打开调试工具(F12),进入Network,刷新页面,然后在右键导航栏,勾选下’Protocol’,就可以看到在那一栏,显示h2
要让网站升级成HTTPS,首先要申请或者购买ssl证书.
证书可以自己在服务器生成,但是这种证书的兼容性以及安全性都会存在比较大的问题.我们可以从专门的证书机构获取比较好的证书,比如可以通过阿里云去申请证书,但是这种证书有要求限制,只能免费使用一年.
server {
listen 443;
server_name www.vstary.com
ssl on;
root html;
index index.html index.htm;
ssl_certificate /home/test/cert/test.pem;
ssl_certificate_key /home/test/cert/test.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
重启服务器.
测试下你的域名,https://www.vstary.com,是否可以访问.
在证书正确的情况下,如果无法访问,可以查看下防火墙是否开放了端口,ssl貌似只能监听443接口.
修改允许端口参考: https://www.vstary.com/article/198
修改服务器配置:
server {
listen 80;
server_name www.vstary.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
同时允许HTTP跟HTTPS协议访问
server {
listen 80
listen 443 ssl;
server_name www.vstary.com
ssl on;
root html;
index index.html index.htm;
ssl_certificate /home/test/cert/test.pem;
ssl_certificate_key /home/test/cert/test.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}

熟悉 MySQL 的人,都知道 InnoDB 存储引擎,如大家所知,Redo Log 是 innodb 的核心事务日志之一,innodb 写入 Redo Log 后就会提交事务,而非写入到 Datafile。之后 innodb 再异步地将新事务的数据异步地写入 Datafile,真正存储起来。
那么 innodb 引擎有了 redo log 和 buffer pool 以后,为什么能够在提升性能的同时,还能保证不丢数据呢? Buffer Pool, Redo Log 以及 Datafile 之间的具体关系是什么呢。
另外 Innodb 还有一大堆概念,Dirty Page, LRU, LSN,Checkpoint 等等,这些概念在 Innodb 里是什么运作的呢?
下面通过一张图来告诉大家
Buffer Pool, Redo Log 以及 Datafile 的关系

图 1 Innodb 的原理
大家可以把 innodb 的事务写入过程看成写作一篇文章的过程。Innodb 的写入过程其实和我们写作的过程是非常类似的。
试想,领导让我们写一篇文章,发表在论坛上。然后我们想到了一个绝佳的点子,并决定要放到文章里,可是手上还有其他事情,一时半会儿写不完,又担心过后忘了,领导还等着我们答复,此时我们会怎么做呢?我们一定会先大概构思个提纲,并把提纲和一些关键细节记录到本子上,作为草稿,然后立刻告诉领导自己要写什么东西,让其确认。最后等晚上有时间了,再根据草稿去斟词酌句,编写正稿。
在这个过程中,我们用到的几个关键的东西:
我们的大脑,用来临时暂时记住我们的点子
草稿,我们需要草稿来保证不会把点子和关键的细节给忘了
正稿,这是我们最终要输出的东西
有了这几个东西,我们不仅能确保我们不会错过一篇漂亮的文章,还能快速告诉领导自己一定可以搞定这件事情。
Innodb 实际上也用到了这几个关键的东西:
Buffer Pool:就是我们的大脑
事务日志:就是我们的草稿
Datafile:就是我们的正稿
只要按照之前写文章的过程,来进行整个事务的写入操作,不仅能保证不丢失数据,而且能够快速响应。
一次写入操作是一次事务,innodb 首先把事务数据写入到 Buffer Pool 和事务日志中,也就是在大脑中记忆下来,并写下草稿。然后就可以提交事务,响应客户端了。之后 innodb 在 “有时间的时候”,异步地把这次写入的数据从 Buffer Pool,或者事务日志中正式地写入到 Datafile 中,形成 “正稿”。
其中,innodb 为了保证事务日志这个 “草稿” 一定能无损地还原成正稿,还不能占用太多空间,事务日志需要有以下特点:
事务日志中一定保存了要写入的所有数据内容
事务日志只会把新事务追加在日志最后,而不会去修改之前的内容
一旦事务数据被写到 datafile,事务日志中的 “草稿” 就可以删除了
通过上面 3 个特点我们可以看出,在形成 “正稿” 之前,“草稿” 是不会被删除的;同时,“草稿” 的空间是可以被循环利用的;最后,只要 “草稿” 在,我们一定能写出 “正稿”。
这里还需要说明的,是 Recovery 流程。也就是如果在形成 “正稿” 前,数据库 Crash 了,我们需要重启整个进程,服务器,甚至只能把数据复制到另外一台服务器来进行恢复。这个时候,事务日志这个 “草稿” 就发挥了它最大的作用——数据恢复。这也和我们在工作生活中常出现的问题——把事情忘了——非常类似。
Buffer Pool 本质就是存储于内存中的一个数据结构,内存和人的大脑一样,是 “健忘” 的。数据库 Crash 时,Buffer Pool中的数据极大可能 “灰飞烟灭” 了。因此,事务日志就如我们贴心的 “记事本”,它把我们的记忆,保存为 “草稿”,当我们忘了的时候,就可以翻开,把记忆重新回想起来。

图 2 恢复的逻辑
LSN 和 Checkpoint
上面介绍了一次写入事务的情况,而数据库在使用过程中,事务都是连续不断,根据上面所述 innodb 逻辑,写 “草稿” 和写 “正稿” 速度和进度绝大部分情况下是不一样的。
再继续上面 “写作文章” 例子,如果我们的文章很长,一天写不完,而白天都有其他工作,我们只能记录草稿,只有晚上回去才能继续写正稿。那么我们就面临一个问题:我们昨天写到哪了。
最常见的办法就是,每天晚上去对照一下草稿的内容和正稿的内容,以此来判断写到哪了,但这比较花时间,因为正稿中可能包含了很多华丽的语句,我们需要思考一下才能对比上内容。
另外一个更简单的办法,就是每天晚上写完正稿后,我们在草稿上做个标记,标记下最后一条被写为正稿的内容,这样第二天晚上,我们就可以从这个标记的后面一条开始,继续写我们的正稿,而不需要去对比内容。
显然第二个方法效率更高,而且没有什么额外的风险。因此 innodb 就使用了这个办法。LSN 是草稿上每一条记录的编号,我们每天晚上标记下最后一条写到正稿的记录编号,这个标记的编号,就是 Checkpoint。Innodb 根据这个 checkpoint,就可以很快知道上次回放到哪里,同时也可以把这个编号之前的草稿,全部删掉了。
第一篇有点干货的文章,虽然没什么技术含量但还是写一篇方便有相同需求的人快速搭出一个环境吧。
基本的Jenkins Docker Git 和 Linux 知识。
一台运行了Docker的x86设备。
首先将[Dockerfile]和运行脚本下载下来,接着build镜像。镜像建好之后,从该镜像新建一个容器。如果你的 Jenkins 不是运行在 Docker 里的话。那么建议添加-p的端口映射指令,将22端口映射到主机的某个 Docker ,使 Jenkins 能够访问得到。
打开 Jenkins,登入。在主界面点击 Manage Jenkins -> Manage Nodes。

之后点击左边的 New Node -> 选择 Permanent Agent 输入完名称之后点击 OK。在接来下出现的设置对话框中,我们需要注意的有这么几个选项。
# of executors -> 这个决定了该节点能够同时运行的任务数量,如果你的编译脚本或者说编译任务没有对多线程CPU进行优化的话, 那么我建议设置成 CPU个数 * 核心数。
Remote root directory -> 这个决定了该节点的工作目录。可以配合Docker的挂载目录使用。
Usage -> 这个需要根据个人需求来做设置了。默认有两个选项一个是仅执行指定分配的任务,另外一个是尽可能的执行任务。我自己的设置是仅执行指定分配的任务,因为该节点是只用来编译测试x86环境的。所以只运行需要在x86环境上测试的任务。
Launch method -> 这个是选项Jenkins启动节点的方式,这里选择用SSH(需要安装SSH连接slave的插件)。Host是slave的ip(Jenkins和slave运行在同一个Docker,那么你需要查看一下运行slave容器的所分配到的IP)点击 Advanced 可以选择配置端口,添加好ssh的帐号密码 (默认密码查看slave的Dockerfile注释),以及根据个人的需求选择下放的 Host Key 验证方式。
设置完成之后就可以点击Save了。那么此时我们可以看到节点虽然添加成功了但是显示的是offline。不过如果一切正常的话,点击Launch agent就能够上线了。

我这里随便选择了一个git上的项目作为测试用。具体可以参考一下配图。需要注意的是我之前节点设置的是只执行分配到节点的任务。所以在设置job的时候,需要勾上 Restrict where this project can be run 然后输入node的名称。这样构建脚本的时候才能slave才能执行。


添加完成之后点击构建,一切顺利的话就能够正常编译了。

需要安装Git plugin和Publish Over SSH插件
系统管理–插件管理–可选插件里搜索安装,安装完后需要重启Jenkins。
可以在安装时勾选下面的安装完后自动重启Jenkins选项,会看到以下画面:

安装完成后自动刷新,需要重新登录
需要在插件管理里配置Publish Over SSH,并在管理主机上生成密钥对
首先,利用ssh-keygen工具来生成密钥对:ssh-keygen -t rsa
[root@elk-test1 .jenkins]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): #密钥存放位置,默认回车
Enter passphrase (empty for no passphrase): #密码,直接回车表示为空
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
20:05:8f:9f:f5:8e:53:36:d5:ae:3f:5c:b3:2c:f3:2d root@elk-test1
The key's randomart image is:
+--[ RSA 2048]----+
| ... |
| + . |
| o o . . . |
| o + . . . |
| o S = . |
| = . . ..|
| o . ....o|
| . +Eo.|
| =+.|
+-----------------+
其次,在系统管理–系统设置中,拉取到最下面位置填写以下信息:

我们在此直接将私钥的内容直接填写到key栏里。
高级选项中:
SSH Servers中:
指的是Jenkins需要发布包的远程机器,需要将公钥复制一份在远程机器上,以供Jenkins来连接它
在172.16.16.201的/root/.ssh/下创建文件:authorized_keys,将Jenkins上生成的id_rsa.pub的内容拷贝进去:
vim authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxA4lH50gkIRrr0kSf7qEXYbt/vPC83zdfaXb+qkWyZ4bUzpulp2
fCms70OL8BIKBXVcYxVjZVPnm0zINijX07ChjlAxL8yhVAUcUqoKTyy2mQIW5cm6mYzutmHBXNNHlFEzYeylKcE/L1
qHvrt2aBuP7D2LmdOU+dF4TdmRrUOoeuXbuz8xVSoT5qorQhhMSJbhAtm9UZK+sHXqW7Uf3+b5YxZkEh6Zpyd+MbzB
LILfw668CFwi1wYU4Fq7iR/Wycd/dIvYzGUrr+Fcisl8hHO5aKZXBFK5DsgvhQR8BqNmYsaHROzLLEOwU8kXvC2ZNq
SAtnAU9KA5edBX+bipnz root@elk-test1
在SSH Servers的高级选项卡里,需要填写连接用户的密码

然后点击”Test Cofiguration“,测试连接,会提示”Success” ,然后保存提交即可。
如果有多个主机,则继续添加。也可以 添加本机进去。

开始创建任务,输入任务名称,选择“构建一个自由风格的软件项目”

在源码管理栏目里,输入测试的(代码所在仓库,svn、git、gitlab均可)git项目地址:

以下留空,因为我们要发布的内容不需要解压编译安装等进一步的操作:

首先需要选择构建步骤,因为我们是通过插件Publish Over SSH来构建发布php,所以,此处选择Send files or execute commands over SSH。

填写构建信息:

在高级设置里的其他细节设置暂且忽略;在Add Transfer Set中可以添加更多的传输信息。
有多个远程主机需要发布,则Add Server更多主机信息。
填写完成后就可以“保存”。
选择刚刚添加的任务,点击“立即构建”开始构建

进入构建任务的输出控制台,查看构建进度:

在172.16.16.201远程发布的sever上查看项目是否发布过来,并且修改了属组
[root@test02 .ssh]# cd /tmp/jenkins_php/
[root@test02 jenkins_php]# ll
total 136
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D11Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D12Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D13Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D14Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D15Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D17Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D18Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D19Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D20Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D21Z
drwxr-xr-x 2 root root 4096 Jan 15 10:43 D22Z
-rw-r--r-- 1 root root 18044 Jan 15 10:43 LICENSE
-rw-r--r-- 1 root root 419 Jan 15 10:43 README.md
-rw-r--r-- 1 root root 66243 Jan 15 10:43 习题答案.txt
至此,简单的Jenkins发布php代码就实验完成了。
Jenkins默认提供了邮件配置的模块:系统管理–系统设置–邮件配置

按照如上图所示配置,填写对应的邮箱信息。
注意:发件者的邮箱必须与Jenkins中管理员邮箱的设置一样,否则在”Test configuration”时会报错!
Jenkins管理员邮箱设置位置:系统管理–系统设置–Jenkins Location

配置完成后点击”Test configuration“测试邮件发送状态

编辑之前的项目,添加构建后的操作配置:

填写信息,根据需要勾选

默认的邮件模块有一个缺点:只对构建失败的情况进行邮件报警处理。构建成功不会发送邮件。这不能完全满足我们的工作需求。
而在安装Jenkins时默认还会安装另外一个插件:E-mail Extension plugin,可以满足需求。
在系统管理–系统配置里,可以找到Extended E-mail Notification插件的配置界面.
先删除掉之前配置的默认邮件告警配置,修改 Extended E-mail Notification的具体信息:

选择默认的触发条件,这里我们选择Always,就是不管什么状态都发送邮件,完成后提交保存。


修改项目构建后的动作配置:
删除之前的配置,选择 Editable Email Notification

根据需要配置邮件的选项

配置完成后保存退出。
重新构建一次项目,查看是否能收到邮件

发现已经收到了构建成功的邮件。
以上对插件E-mail Extension plugin的设置仅仅为最简单最基础的连通实验,具体的邮件模板配置等,后续继续学习。
两种使用方式:
1、 直接使用$标志:如$BUILD_STATUS
2、 使用${}标志:如${BUILD_STATUS}

备注:
如果工作中遇到了什么问题,或者对软件测试感兴趣的小伙伴,可以加群680748947一起交流进步~
如果是使用批处理命令来使用环境变量,则是通过%%来标志,如% BUILD_STATUS %
环境变量列表:
BUILD_NUMBER,唯一标识一次build,例如23;
BUILD_ID,基本上等同于BUILD_NUMBER,但是是字符串,例如2011-11-15_16-06-21;
JOB_NAME, job的名字,例如JavaHelloWorld;
BUILD_TAG,作用同BUILD_ID,BUILD_NUMBER,用来全局地唯一标识一此build,例如jenkins-JavaHelloWorld-23;
EXECUTOR_NUMBER, 例如0;
NODE_NAME,slave的名字,例如MyServer01;
NODE_LABELS,slave的label,标识slave的用处,例如JavaHelloWorldMyServer01;
JAVA_HOME, java的home目录,例如C:Program Files (x86)Javajdk1.7.0_01;
WORKSPACE,job的当前工作目录,例如c:jenkinsworkspaceJavaHelloWorld;
HUDSON_URL = JENKINS_URL, jenkins的url,例如http://localhost:8000/;
BUILD_URL,build的url 例如http://localhost:8000/job/JavaHelloWorld/23/;
JOB_URL, job的url,例如http://localhost:8000/job/JavaHelloWorld/;
SVN_REVISION,svn 的revison, 例如4;
一、可用环境变量列表(以下来自google翻译):
BRANCH_NAME
对于多分支项目,这将被设置为正在构建的分支的名称,例如,如果您希望从而master不是从特征分支部署到生产。
CHANGE_ID
对于与某种更改请求相对应的多分支项目,这将被设置为更改ID,例如拉取请求号。
CHANGE_URL
对于与某种更改请求相对应的多分支项目,这将被设置为更改URL。
CHANGE_TITLE
对于对应于某种变更请求的多分支项目,这将被设置为更改的标题。
CHANGE_AUTHOR
对于对应于某种变更请求的多分支项目,这将被设置为拟议更改的作者的用户名。
CHANGE_AUTHOR_DISPLAY_NAME
对于对应于某种变更请求的多分支项目,这将被设置为作者的人名。
CHANGE_AUTHOR_EMAIL
对于对应于某种变更请求的多分支项目,这将被设置为作者的电子邮件地址。
CHANGE_TARGET
对于对应于某种变更请求的多分支项目,这将被设置为可以合并更改的目标或基本分支。
BUILD_NUMBER
目前的编号,如“153”
BUILD_ID
当前版本ID,与BUILD_NUMBER相同,用于在1.597+中创建的构建,但较旧版本的YYYY-MM-DD_hh-mm-ss时间戳记
BUILD_DISPLAY_NAME
当前版本的显示名称,默认为“#153”。
JOB_NAME
此构建项目的名称,如“foo”或“foo / bar”。
JOB_BASE_NAME
此建立项目的名称将剥离文件夹路径,例如“bar / foo”的“foo”。
BUILD_TAG
“jenkins- $ {JOB_NAME} – $ {BUILD_NUMBER} ”的字符串。JOB_NAME中的所有正斜杠(/)都会用破折号( – )替换。方便放入资源文件,jar文件等,以方便识别。
EXECUTOR_NUMBER
识别执行此构建的当前执行程序(在同一台计算机的执行程序中)的唯一编号。这是您在“构建执行者状态”中看到的数字,但数字从0开始,而不是1。
NODE_NAME
代理的名称,如果构建是代理,或者“主”,如果在主机上运行
NODE_LABELS
空格分隔的节点分配的标签列表。
WORKSPACE
分配给构建作为工作区的目录的绝对路径。
JENKINS_HOME
Jenkins主节点上分配的目录绝对路径存储数据。
JENKINS_URL
完整的Jenkins网址,例如http:// server:port / jenkins /(注意:只有在系统配置中设置了Jenkins URL)
BUILD_URL
此构建的完整URL,如http:// server:port / jenkins / job / foo / 15 /(Jenkins URL必须设置)
JOB_URL
此作业的完整URL,如http:// server:port / jenkins / job / foo /(必须设置Jenkins URL)
SVN_REVISION
Subversion版本号,当前已被检出到工作区,如“12345”
SVN_URL
当前已经检出到工作空间的Subversion URL。
Jenkins自动发送邮件配置:
1、打开”系统管理”——”系统设置”
2、在”Jenkins Location”设置系统管理员地址(重要:不能省略!)
3、在”邮件通知”部分配置发送邮件的用户名、密码(注意这里的密码使用的是163邮箱设置的”客户端授权码”,不是登陆密码)
4、勾选”通过发送测试邮件测试配置”,填入测试收件人,点击”Test Configuration”
5、到163邮箱里check新邮件
6、

7、
