Jenkins持续集成

一、前言
1、传统网站部署流程
传统运维网站部署主要靠手动部署,手工部署的网站流程大致分为 需求分析>原型设计>开发代码>提交测试>内网部署>确认上线>备份数据>外网更新>发布完毕>网站测试,如果发现外网部署的代码有异常,需要及时回滚。
2、目前主流网站部署流程
基于主流的Hudson/Jenkins 工具平台实现全自动网站部署、网站测试、网站回滚会大大减少网站部署的成本,Jenkins 的前身为Hudson,Hudson 为商业版,Jenkins 为开源免费版。
Jenkins 是一个可扩展的持续集成引擎,是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。而且Jenkins平台的安装和配置非常容易,使用也非常简单。构建Jenkins 平台可以解放人员的双手,具体内容如下:
• • 开发人员:对于开发人员来说,只需负责网站代码的编写,不需要手动再对源码进行编译、打包、单元测试等工作,开发人员直接将写好的代码分支存放在SVN、GIT仓库即可。
• • 运维人员:对于运维人员来说,使用Jenkins自动部署,可以减轻人工干预的错误率,同时解放运维人员繁杂的上传代码、手动备份、手动更新。
• • 测试人员:对于测试人员来说,可以通过Jenkins进行代码测试、网站功能或者性能测试。
基于Jenkins自动部署网站的流程大致分为 需求分析>原型设计>开发代码>提交测试>Jenkins 内网部署>确认上线>Jenkins备份数据>Jenkins 外网部署>发布完毕>Jenkins 网站测试等,如果发现外网部署的代码有异常,可以通过Jenkins 及时回滚。
 
二、简介
持续集成(continuous integration,CI)是一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础,持续集成的意义如下:
• • 持续集成中的任何一个环节都是自动完成的,无须太多的人工干预,有利于减少重复过程以节省时间、费用和工作量;
• • 持续集成保障了每个时间点上团队成员提交的代码是能成功集成的,换言之,任何时间点都能第一时间发现软件的集成问题,使任意时间发布可部署的软件成为可能;
• • 持续集成还能利于软件本身的发展趋势,在需求不明确或者频繁变更的情景中尤其重要,持续集成的质量能帮助团队进行有效决策,同时建立团队对开发产品的信心。
• • • • • •持续集成最佳实践
• 维护一个单一的代码库             【不要使用多个代码库,避免每个组使用单独得git/svn,减轻权限管理】
• 使构建自动化
• 执行测试是构建的一部分         【构建一个项目得时候,测试就包含在里面了,可以及时得发现问题】
• 集成日志及历史记录
• 使用统一的依赖包管理库                【很容易出错,所以要统一得管理】
• 每天至少集成一次                    【持续集成得时候,是最容易发现问题得时候】
 
三、Jenkins 持续集成组件
要掌握Jenkins技能,需要了解Jenkins持续集成平台依赖的组件,例如JOB工程、SVN仓库源、Jenkins 服务器,详解如下:
• • 自动构建过程JOB,JOB功能主要是获取SVN/GIT源码、自动编译、自动打包、部署分发和自动测试等。
• • 源代码存储库,开发编写代码需上传至SVN、GIT代码库中,供Jenkins来获取。
• • Jenkins 持续集成服务器,用于部署Jenkins UI、存放JOB工程、各种插件、编译打包的数据等。
 
四、Jenkins 相关概念
常见代码相关概念包括make、ant、maven、Eclipse、Jenkins等:
1、make 编译工具
make 编译工具是Linux和windows最原始的编译工具,在Linux下编译程序常用make,Windows下对应的工具为nmake。读取本地makefile文件,该文件永定了源文件之间的依赖关系,make负责makefile 文件去组织构建软件,负责指挥编译器如何编译,连接器如何连接,以及最后生成可用二进制的代码。
2、ant 编译工具
make 工具在编译比较复杂的工程中时使用起来不方便,语法很难理解,因此延伸出ant工具。ant工具属于Apache基金会软件成员之一,是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发。
ant构建文件是XML文件。每个构建文件定义一个唯一的项目(project元素)。每个项目下可以定义很多目标不元素,这些目标之间可以有依赖关系。
构建一个新项目时,应该编写ant构建文件。因为构建文件定义了构建过程,并为团队开发中每个人所使用。
ant 构建文件默认名为build.xml,也可以修改为其他的名称。只不过在运行的时候需把这个命名当作参数传给ant。构建文件可以放在任何的位置,一般做法是放在项目顶层目录也即根目录,这样可以保持项目的简洁和清晰。
3、maven 编译工具
maven 工具是对ant 工具的进一步改进,在make 工具中,如果需要编译某些源文件,首先要安装编译器等工具。有时候需要不同版本的编译器,例如Java编译器在编译文件时需要各种依赖包的支持,如果把每个包都下载下来,在makefile中进行配置制定,当需要的包非常多时,难以管理。
maven 与ant 类似,也是构建(buile)工具,它是如何调用各种不同的编译器连接器呢?使用maven plugin(maven 插件),maven 项目对象模型POM(project object model),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。maven除了以程序构建能力为特色之外,还提供高级项目管理工具。
POM是maven项目中的文件,使用XML表示 ,名称为pom.xml。在maven中,当构建project 的时候,不仅仅是一堆包含代码的文件,还包含pom.xml配置文件,该文件包括project 与开发者有关的、缺陷跟踪系统、组织与许可、项目的URL、项目依赖以及其他配置。
基于maven构建编译时,project 可以什么都没有,甚至没有代码,但是必须包含pom.xml 文件。由于maven 的默认构建规则有较高的可重用性,所以常常用两三行maven构建脚本就可以构建简单的项目。
由于maven的面向项目的方法,许多Apache Jakarta 项目发文时使用maven,而且公司项目采用maven 的比例持续增长。
4、Jenkins 框架工具
maven 可以实现对软件代码进行编译、打包、测试,功能已经很强大了,那还需要Jenkins做什么呢?maven 可以控制编译,控制连接,可以生成各种报告,可以进行代码测试,但是默认不能控制完整的流程。没有顺序定义,那是先编译还是先连接,先进行代码测试还是先生成报告?因此需要使用脚本来对maven进行控制,实现这些流程的控制。
5、Eclipse 工具
Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。Eclipse附带了一个标准的插件集,包括Java开发工具(Java development kit,JDK),主要用于开发者开发网站代码。
 
五、Jenkins 平台安装部署
Jenkins 官网免费获取Jenkins软件,官网地址 http://mirrors.jenkins-ci.org/下载稳定的Jenkins 版本。Jenkins 是基于Java开发的一种持续集成工具,所以Jenkins服务器需安装Java JDK 开发软件。
1、安装(rpm包)
• • 服务器环境:
# cat /etc/redhat-release
CentOS release 6.10 (Final)
• • 安装依赖包
# yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel
• • 安装jenkins
# rpm -ivh  jenkins-2.138.3-1.1.noarch.rpm        
• • 查看服务状态
# service jenkins status
jenkins 已停
• • 启动jenkins
# service jenkins start
Starting Jenkins          
• • 查看端口8080是否已启动
# netstat -lunpt
2、安装(yum方式)
• • 下载镜像源
# wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo
# rpm --import http://pkg.jenkins.io/redhat/jenkins.io.key
or
# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
• • yum安装jenkins
# yum –y install jenkins java-1.8.0-openjdk java-1.8.0-openjdk-devel
# service jenkins start
# ckconfig Jenkins on
3、Jenkins 初始化
第一步:
• • 访问Jenkins输入admin默认密码
http://192.168.28.135:8080
• • 查找admin默认密码,输入密码,点击继续
# cat /var/lib/jenkins/secrets/initialAdminPassword
c30fcd47412c421fb0788c430ce9f767
• • 注意:卡启动问题【采用离线模式】
Jenkins在第一次安装启动时会向官网回传信息
如果网络离线可以正常安装。
当网络在线,但是https://jenkins-ci.io 无法打开时,卡住。
解决:
如果出现卡启动,把网络关掉即可。
以后再出现问题,都是jenkins服务器内存不够了。
 
六、Jenkins 插件
1. 默认插件:
安装过程选Install suggested plugins.
插件用途:
Pipeline 工作流用到
Git plugin 拉代码会用到
SSH Slaves plugin 做集群
2、locale 插件
系统管理=>插件管理=>安装 locale插件
系统管理=>系统配置=> locale 设置zn_CN 设置中文
3、手动批量更新插件
• • 下载插件包解压到插件目录中
# mv plugins.tar.gz /var/lib/jenkins/
# cd /var/lib/jenkins; tar zxf plugins.tar.gz
• • 添加jenkins权限
# chown -R jenkins.jenkins plugins
• • 重启下jenkins服务
# /etc/init.d/jenkins restart
Shutting down Jenkins                                  [确定]
Starting Jenkins                                                   [确定]
4、手动安装插件
• • 手动安装ssh插件,下载到桌面:
执行过程:设置--管理插件--高级--上传
下载地址:http://updates.jenkins-ci.org/2.138/latest/ssh.hpi
 
七、Jenkins 配置
1、镜像管理:
• Jenkins所有镜像地址:
http://mirrors.jenkins-ci.org/status.html
• 官方镜像地址:https://updates.jenkins.io/update-center.json
• 更换镜像:【目前镜像还是推荐使用官网,比较好用些】
http://updates.jenkins-ci.org/update-center.json
https://mirrors.tuna.tsinghua.edu.cn/
http://mirror.esuni.jp/jenkins/updates/update-center.json
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
2、站点升级设置
系统管理=>插件管理=>高级=>升级站点:https://updates.jenkins.io/update-center.json
3、Jenkins 目录
# rpm -ql jenkins
/etc/init.d/jenkins                【启动文件】
/etc/logrotate.d/jenkins
/etc/sysconfig/jenkins                【配置文件】
/usr/lib/jenkins
/usr/lib/jenkins/jenkins.war
/usr/sbin/rcjenkins
/var/cache/jenkins                【程序文件,备份就需要备份该目录下war目录】
/var/lib/jenkins                        【主目录,升级得话直接把war包放到该目录,升级完成后jenkins会把war自动解压到/var/cache/Jenkins目录】
/var/log/jenkins                        【日志文件】
4、Jenkins 配置文件参数:/etc/sysconfig/jenkins
JENKINS_HOME="/var/lib/jenkins"        #主目录
JENKINS_USER=“root”                #因为Jenkins需要调用系统命令,采用root用户会比较方便,生产环境建议采用jenkins用户,多一步授权过程。
JENKINS_JAVA_OPTIONS=“-Djava.awt.headless=true”        #jenkins是依赖jvm启动得,如果内存不够用了,需要指定堆,就需要在这里做。
5、系统设置几个注意事项:
执行者数量   【不建议超过10个,太多得话,服务器可能会坑不住,一般5个就可以了。】
用法       【如果是从级得话一定要选择只允许运行绑定到这台机器的Job,不然会随机分别,可能会分配到别的机器跑任务,如果主得话就无所谓了。】
生成前等待时间 【建议改成10秒,可以有个反悔得余地。】
SCM签出重试次数   【建议改成不重试0,也可以设置为1。】
Jenkins Location:Jenkin URL 【设置域名地址】
Subversion:Subversion Workspace Version    【改成相对比较近点得版本】
6、Jenkins备份与恢复
• • • • • • 备份:【如果体积比较大,不建议采用全量备份,可以使用rsync来进行增量备份】
# tar zcvf jenknis.tar.gz /var/lib/jenkins/                每天定时备份的脚本,保留15天的备份
• • 对/var/lib/jenkins 进行备份
# mkdir -p /data/backup/jenkins
• • 拷贝时保留之前得目录和文件属性
# rsync -raz --delete --progress /var/lib/jenkins/ /data/backup/jenkins/
• • 不建议使用scp,采用rsync进行增量备份:
# scp -r /var/lib/jenkins/ /data/backup/jenkins/,scp是支持断点续传得。
• • 删除/var/lib/jenkins
# rm -rf /var/lib/jenkins/
• • 重启jenkin,还是能启动,启动之后,jenkins会生成默认得目录和配置文件,进入到初始化界面。
# /etc/init.d/jenkins restart
• • • • • • 恢复
# /etc/init.d/jenkins stop
Shutting down Jenkins                                      [确定]
# rm -rf /var/lib/jenkins/*
# rsync -arz --delete --progress /data/backup/jenkins/ /var/lib/jenkins/
# /etc/init.d/jenkins start
Starting Jenkins                                           [确定]
 
八、WEB界面配置
1、密码破解
cd /var/lib/jenkins/users/admin #此为admin用户的目录,也可以对应自己创建的用户
vim config.xml //定位到<passwordHash>那一行
删除改行,改为
<passwordHash>#jbcrypt:$2a$10$pDQks0ytOkCfmpdgpLygrOC3uY7i/XnZHBKRQDhrBPwKoN2f5Kz8C</passwordHash>
重启一下jenkins
新密码为admin
2、maven配置
针对之前手动安装的maven需要在web界面配置进行结合。
系统管理—全局工具配置(Maven Configuration)配置:
Default settings provider > Settings file in filesystem     File path > /usr/local/maven/conf/settings.xml
Default global settings provider > Global settings file on filesystem    File path > /usr/local/maven/conf/settings.xml
此处为手动安装的maven,需要取消自动安装maven,name可以自定义,MAVEN_HOME指定下载安装的maven具体文件目录
Maven 安装          name > maven                        MAVEN_HOME  >  /usr/local/maven
3、GIT配置
手动安装的git,web界面只需添加具体可执行路径即可
Git installations          Name >  git                        Path to Git executable  >  /usr/bin/git
4、jdk配置
对应手动安装的jdk,需要web配置java_home路径
JDK 安装             别名 >  jdk1.8                             JAVA_HOME  >  /usr/local/jdk1.8
5、邮件配置
jenkins有内置的邮件功能但由于其对于成功的发布不会发送邮件可定制化程度低,在此直接配置插件邮件(Editable Email Notification),2.32以上版本的jenkins,常用的插件都已经在最初部署的时候安装了(如果你当初选择的是suggest的plugins)。
可以使用qq邮件服务器或163等其他邮件服务器,在此配置使用163邮箱,首先需要开启163邮箱的smtp服务。
在jenkins 系统管理—系统设置—Extended E-mail Notification :163邮箱为例
SMTP server  >  smtp.163.com
Default user E-mail suffix  >  @163.com
SMTP port  >  465
在默认的触发器 Default Triggers 标签下,可以勾选邮件通知触发的情况,如任何情况下均需要选择always,也可以在仅失败情况下发送,也可以对应的邮件接受人不通,进行邮件分类。
至此全局插件邮件已经配置完毕,需要在具体的项目中使用此邮件进行发送通知。
 
九、实战php程序自动发布
1、插件安装
系统管理—管理插件—已安装
检查是否有“Git plugin”和“Publish Over SSH”两个插件,如果没有,则需点击“可选插件”,找到它并安装
安装好两个插件后,点击“系统管理”– “系统设置”
2、SSH配置
系统管理—系统设置—Publish over SSH
在key内填写jenkins服务器的私钥,如果没有需要先在jenkins服务器生成私钥与公钥。ssh-keygen -t rsa回车后会在登录用户的家目录下生成一个.ssh 的目录,此目录下存在id_rsa私钥与id_rsa.pub公钥。且讲公钥发布至代码发布的目标服务器上ssh-copy-id -i /root/.ssh/id_rsa.pub root@IP。
• • SSH Server配置
name:需要将php程序发布到目标服务器的名称,可自定义
Hostname:填写目录服务器的IP地址
Username:使用那个用户进行发布,此处为进行密钥互信的用户
Remote Directory:此出为发布到目标服务器的相对根路径,建议填写/,防止后续填写路径异常。
3、构建项目
新建Item—填入项目名称—选择构建一个自由风格的软件项目—确定
源码管理选择git
Repository URL 填写具体git上的仓库url,如果为私有,需要继续添加Credentials,如果为公有直接填写url即可,Credentials为none,
• • 构建后操作
选择(Send files or execute commands over SSH)
SSH Server选择目标服务器如:php-server
Source files:/ #将git拉去下来的原始文件
Remote directory:/var/www/html #发布到目标服务器的制定目录
Exec command:chown apache:apache -R /var/www/html/* #制定后续的操作
此时可以选择Editable Email Notification来构建邮件通知。
在此处,之前的邮件主题,内容均可以自定义,在高级里面,选择邮件接受人。
点击保存,并立即构建,可以点击console output查看日志
此时打开php程序发现程序文件已经成功发布到目标服务器上
此时可以查看邮件也已经发送成功。
4、查看Jenkins构建实时日志
控制台日志打印Finished: SUCCESS,则表示 Jenkins 持续集成构建完成,会在Jenkins  服务器目录工程名下生成网站可用的war文件,将该war包部署至其他服务器即可,war路径为/root/.jenkins/workspace/工程名/target/库名.war。
至此,Jenkins 持续集成平台自动构建软件完成,该步骤只是生成了war包,并没有实现自动将该war包部署至其他服务器,如果要自动部署需要基于Jenkins 插件或者shell、Python 等自动化部署脚本。
 
十、Jenkins 自动化部署
通过手动构建Jenkins JOB工程、自动编译、打包生成war包,并不能实现自动部署,要实现自动部署可以使用自动部署插件或者shell脚本、Python 脚本等。
Jenkins 自动部署完整操作步骤:
1、单击工程名(例如:www.tang.com),选择“配置>构建后操作>Add post-build step > Archive the artifacts > 用于存档的文件”,输入入**/target/*.war,该选择主要用于Jenkins 编译后会将war包存档一份到target目录,该文件可以通过Jenkins HTTP端口访问。
2、Jenkins 构建完毕,访问Jenkins war 存档的文件,URL 地址如下:
http://x.x.x.x:8080/job/工程名/lastSuccessfulBuild/artifact/target/库名.war
3、依次Add post-build step > Execute shell > Command,输入如下代码,实现Jenkins *.war包自动部署
cp /root/.jenkins/workspace/工程名/target/库名.war /root/.jenkins/jobs/工程名/builds/lastSuccessfulBuild/archive/target/
ssh root@x.x.x.x 'bash -x -s' </data/sh/suto_deploy.sh
# for I in `cat ip.txt`;do ssh root@${I} 'bash -x -s'</data/sh/auto_deploy.sh;done
4、Jenkins 将库名.war自动部署至x.x.x.x服务器Tomcat发布目录,需提前配置登录远程客户端免秘钥,免秘钥配置首先在Jenkins服务器执行ssh-keygen命令,然后按Enter键生成公钥和私钥,再将公钥id_rsa.pub复制到客户端/root/.ssh/目录,并重命名为authorized_keys,操作命令如下:
# ssh-keygen -t rsa -P ' ' -f /root/.ssh/id_rsa
# ssh-copy-id -i /root/.ssh/id_rsa.pub x.x.x.x
5、shell 脚本需放在Jenkins服务器/data/sh/,无须放在客户端,shell脚本内容如下:
#!/bin/bash
#Auto deploy Tomcat for jenkins
export JAVA_HOME=/usr/java/jdk.1.6.0_25
TOMCAT_PID=`/usr/sbin/lsof -n -P -t -i :xxxx`
TOMCAT_DIR="/usr/local/tomcat"
FILES="库名.war"
DES_DIR="/usr/local/tomcat/webapps/ROOT/"
DES_URL="http://x.x.x.x:xx/job/工程名/lastSuccessfulBuild/artifact/target/"
BAK_DIR="/export/backup/`date +%Y%m%d-%H%M`"
[ -n "$TOMCAT_PID" ]&&kill -9 $TOMCAT_PID
cd $DES_DIR
rm -rf $FILES
mkdir -p $BAK_BIR;\cp -a $DES_DIR/*  $BAK_DIR/
rm -rf $DES_URL/$FILES
/usr/java/jdk1.6.0_25/bin/jar -xvf $FILES
########################################
cd $TOMCAT_DIR;rm -rf work
/bin/sh $TOMCAT_DIR/bin/start.sh
sleep 10
tail -n 50 $TOMCAT_DIR/logs/catalina.out
如上通过shell+for 循环可以实现网站简单部署。
 
十一、Jenkins 多实例配置
基于Jenkins 分布式,即多slave方式可以缓解Jenkins 服务器的压力。
Jenkins 多 slave 原理是将原本在Jenkins master 端的构建项目分配任务时,Jenkins master端通过SSH远程slave,在slave端启动slave.jar程序,通过slave.jar实现对网站工程的构建编译以及自动部署。所以在slave 端服务器必须安装Jave JDK 环境来执行master端分配的构建任务。
配置多slave服务器方法和步骤如下:
1、在slave 服务器创建远程执行Jenkins 任务的用户,名称为jenkins,Jenkins 工作目录/home/Jenkins,Jenkins master 免秘钥登录 slave 服务器或者通过用户名和密码登录slave。
2、slave 服务器安装Java JDK版本,并将其软件路径加入系统环境变量。
3、Jenkins master 端平台添加管理节点,依次选择“系统管理>管理节点>新建节点>输入节点名称”。
4、配置www_slave 节点,指定其Jenkins编译工作目录,设置IP地址,在Add Credentials 界面中添加登录slave 用户名和密码。
5、Jenkins slave 配置完毕,查看slave 状态。
6、单击www_slave节点,然后选择Launch slave agent,单击测试slave agent是否正常工作。
7、如上配置完毕,Jenkins master 通过SSH 方式来启动slave的slave.jar脚本,基于Java命令启动slave.jar包,命令为java-jar slave.jar,slave 等待master 端的任务分配,单击 工程名 ,然后选择立即构建。
8、Jenkins slave 配置完毕后。如果同时运行多个任务,会发现只会运行一个任务,另外的任务在等待,此时需要配置JOB工程,选中“在必要的时候并发构建”即可。
 
十二、Jenkins + Ansible 高并发构建
Jenkins 自动部署基于shell+for 循环方式部署10台以下的Java服务器,效率是可以接受的,但是如果大规模服务器需要部署或者更新网站,通过for循环串行执行效率会大打折扣,所以需要考虑到并行机制。
1、Jenkins 服务器安装 Ansible 软件
rpm -Uvh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install epel-release -y
yum install ansible -y
2、添加客户端服务器,在/etc/ansible/hosts 中添加需要部署的客户端IP列表
[www_tang]
192.168.10.10
192.168.10.11
192.168.10.12
192.168.10.13
3、在Jenkins 平台首页中单击所建工程项目,选择"配置>Post Steps > Execute shell > Command",输入如下代码
cp /root/.jenkins/workspace/工程名/target/库名.war /root/.jenkins/jobs/工程名/builds/lastSuccessfulBuild/archive/target/
ansible www_tang -m copy -a "src=/data/sh/auto_deploy.sh dest=/tmp/"
ansible www_tang -m shell -a "cd /tmp/;/bin/bash auto_deploy.sh"
4、Jenkins 服务器端/data/sh/auto_deploy.sh shell 脚本内容:
#!/bin/bash
#Auto deploy Tomcat for jenkins
export JAVA_HOME=/usr/java/jdk.1.6.0_25
TOMCAT_PID=`/usr/sbin/lsof -n -P -t -i :xxxx`
TOMCAT_DIR="/usr/local/tomcat"
FILES="库名.war"
DES_DIR="/usr/local/tomcat/webapps/ROOT/"
DES_URL="http://x.x.x.x:xx/job/工程名/lastSuccessfulBuild/artifact/target/"
BAK_DIR="/export/backup/`date +%Y%m%d-%H%M`"
[ -n "$TOMCAT_PID" ]&&kill -9 $TOMCAT_PID
cd $DES_DIR
rm -rf $FILES
mkdir -p $BAK_BIR;\cp -a $DES_DIR/*  $BAK_DIR/
rm -rf $DES_URL/$FILES
/usr/java/jdk1.6.0_25/bin/jar -xvf $FILES
########################################
cd $TOMCAT_DIR;rm -rf work
/bin/sh $TOMCAT_DIR/bin/start.sh
sleep 10
tail -n 50 $TOMCAT_DIR/logs/catalina.out
5、单击工程名构建任务,查看控制台信息。
 
  一、Nginx 介绍
1、简介
Nginx具有高度并发(特别是静态资源)、占用系统资源少等特性,且功能丰富。
Nginx 不但是一个优秀的Web服务软件,还具有反向代理负载均衡功能和缓存服务功能。它类似于大名鼎鼎的LVS负载均衡及Haproxy等专业代理软件,但是Nginx部署起来更为简单、方便;在缓存服务功能方面,它又类似于Squid等专业的缓存服务软件。
 
2、Nginx 重要特性
 • 静态资源高速高并发访问及缓存
 • 反向代理加速,数据缓存
 • 简单负载均衡,节点健康检查容错功能
 • FastCGI服务的缓存加速
 • 支持FastCGI,Uwsgi,SCGI,Memcached Servers的加速和缓存
 • 支持SSL,TLS,SNI
 •具有模块化结构:过滤器包括gzip压缩,ranges支持,chunked响应,XSLT,SSL及图像缩放等功能。在SSI过滤器中,一个包含多个SSI的页面,如果经由FastCGI或反向代理处理,可被并行处理。
 
3、WWW 服务特性
 • 支持基于名字,端口及ip的多虚拟主机站点
 • 支持keep-alive 和 pipelined 连接
 • 可进行简单,方便,灵活的配置和管理
 • 支持修改nginx配置时平滑重启,不影响线上业务
 • 可自定义访问日志格式,临时缓冲写日志操作,快速日志轮询及通过rsyslog处理日志
 • 可利用信号控制nginx进程
 • 支持3xx-5xx HTTP状态码重定向
 • 支持rewrite模块,支持URI重写及正则表达式匹配
 • 基于客户端ip地址和HTTP基本认证的访问控制
 • 支持PUT,DELETE,MKCOL,COPY,MOVE等特殊的HTTP请求方法
 • 支持FLV流和MP4流产品应用
 • 支持HTTP响应速率限制
 • 支持同一IP地址并发连接或请求数限制
 • 支持邮件代理服务
 
4、Nginx 重点
 • 支持高并发:能支持几万并发连接(特别是静态小文件业务环境)
 • 资源消耗少:在3万并发连接下,开启10个nginx线程消耗的内存不到200MB
 •可以做HTTP反向代理及加速缓存,即负载均衡功能,内置对RS节点服务器健康检查功能,这相当于专业的Haproxy软件或LVS的功能
 • 具备Squid等专业缓存软件等的缓存功能
 • 支持异步网络I/O时间模型epoll
 
5、Nginx 企业中应用
 • WEB服务软件
·运行HTML、JS、CSS、小图片等静态数据
·结合FastCGI运行PHP 等动态程序(例如使用fastcgi_pass方式)
·结合Tomcat/Resin等支持Java 动态程序(常用proxy_pass方式)
 • 反向代理负载均衡(upstream)
 • 前端数据缓存 (proxy-cache模块)
 
6、Nginx 与其他 Web软件产品对比
 • apache软件的特点:
·Apache2.2版本非常稳定强大,性能好。
·prefork模式取消了进程开销
·处理动态业务数据时,因关联到后端的引擎和数据库,瓶颈不在Apache上
·高并发时消耗资源相对多一些
·基于传统的select模型,高并发能力有限
·支持扩展库,可以通过DSO、apxs方法编译安装额外的插件功能,不需要重新编译Apache
·功能多,更稳定,更安全,插件也多
·市场份额逐渐递减
 •处理静态小文件(小于1Mb),nginx比Apache和Lighttpd更有优势,处理动态文件时Apache更有优势,但是差距不大。这是因为处理动态数据的能力取决于PHP(java)和后端数据库的服务能力,也就是说瓶颈不在web服务器上,一般情况下普通的PHP引擎支持的并发连接参考值为300~1000,java引擎和数据库的并发连接参考值为300~1500。
 •nginx使用最新的epoll和kqueue(freebsb)异步网络I/O模型,而Apache使用的是传统的select模型,异步的安全性、稳定性没有同步高,中间容易被人窃取,用户收不到数据
 • select和epoll的释义:
·select:
性能:随着连接数的增加而急剧下降。处理成千上万的并发连接数时,性能很差。
连接数:连接数有限制,处理最大连接数不超过1024.如果超过1024那么就要修改FD_SETSIZE宏,并重新编译。
内在处理机制:性能轮询
开发复杂性:低
·epoll
性能:随着连接数的增加,性能基本没有下降,处理成千上万的并发连接数时,性能好
连接数:连接数无限制
内在处理机制:回调callback
开发复杂性:中
 
7、选用web
 • 静态业务:若是高并发场景,尽量采用nginx或Lighttpd,首选nginx
 •动态业务:理论上采用nginx和Apache均可,为了避免相同业务服务软件多样化,增加维护成本
 • 既有动态又有静态:选用nginx
 
二、Nginx 安装
1、安装nginx有3种方法:
 • rpm –ivh ngin*.rpm(有依赖问题)
 • yum(自动解决rpm的安装依赖问题,安装简单化,缺点:不能定制)
 • make编译安装(./configure(配置),make(编译),makeinstall(安装),缺点:复杂,效率低)
 
2、YUM安装:
2.1、更换国内的yum源
 • CentOS 5
#wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo
 • CentOS 6
#wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
 • CentOS 7
#wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
2.2、安装阿里云的epol源
 • 备份epel.repo源
# mv/etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
# mv/etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup
 • epel(RHEL 7)
#wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
 • epel(RHEL 6)
#wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
 • epel(RHEL 5)
#wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-5.rep
2.3、配置安装nginx的yum源
# cd /etc/yum.repos.d/
# vimnginx.repo,填写如下内容:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
 
3、编译安装步骤
3.1、安装nginx需要的pcre库
# yum install pcrepcre-devel -y
安装pcre库是为了是nginx支持具备URI重写功能的rewrite模块,不安装那就无法使用rewrite模块的功能。基本上rewrite功能是企业必须的。
3.2、安装openssl-devel
# yum -y installopenssl openssl-devel
3.3、开始安装nginx
# mkdir /application
# wget http://nginx.org/download/nginx-1.12.2.tar.gz
# tar xfnginx-1.12.2.tar.gz
# useradd www -M -s/sbin/nologin
# cd nginx-1.12.2
# ./configure --help
# ./configure--prefix=/application/nginx-1.12.2 --user=www --group=www--with-http_ssl_module --with-http_stub_status_module
# make
# make install
# ls/application/nginx-1.12.2/
auto  CHANGES CHANGES.ru  conf  configure contrib  html  LICENSE Makefile  man  objs README  src
# ln -s/application/nginx-1.12.2/ /application/nginx
# mkdir logs
#/application/nginx/sbin/nginx
3.4、验证安装结果
 • 检查语法
#/application/nginx/sbin/nginx -t
/application/nginx/sbin/nginx-V        #显示编译参数
/application/nginx/sbin/nginx-h        #man帮助
 • 启动nginx服务
#/application/nginx/sbin/nginx
 • 查看服务对应的端口是否成功开启
# netstat -tunlp|grep80
tcp        0     0 0.0.0.0:80                 0.0.0.0:*                   LISTEN      12742/nginx     
#  ps -ef|grep nginx
root     12742    1  0 12:55 ?        00:00:00 nginx: master process/application/nginx/sbin/nginx
www      12743 12742  0 12:55 ?        00:00:00 nginx: worker process       
root     12749 2485  0 12:58 pts/0    00:00:00 grep nginx
# lsof -i:80
COMMAND   PID USER  FD   TYPE DEVICE SIZE/OFF NODENAME
nginx   12742 root   6u  IPv4  24891     0t0  TCP *:http (LISTEN)
nginx   12743 www    6u  IPv4 24891      0t0  TCP *:http (LISTEN)
 • 结果:用浏览器输入192.168.10.3 看到 Welcome to nginx!就是成功了。
 
4、安装目录信息
# tree/application/nginx-1.12.2/
/application/nginx-1.12.2/
├── client_body_temp
├── conf                                  #Nginx所有配置文件的目录
│   ├── fastcgi.conf                      # fastcgi相关参数的配置文件
│   ├── fastcgi.conf.default                # fastcgi.conf的原始备份文件
│   ├── fastcgi_params                     # fastcgi的参数文件
│   ├── fastcgi_params.default              # 所有结尾为default的文件都是备份文件
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types                        # 媒体类型
│   ├── mime.types.default
│   ├── nginx.conf                        # Nginx主配置文件
│   ├── nginx.conf.default
│   ├── scgi_params                        # scgi相关参数文件
│   ├── scgi_params.default
│   ├── uwsgi_params                     # uwsgi相关参数文件
│   ├── uwsgi_params.default
│   └── win-utf
├── fastcgi_temp                         # fastcgi临时数据目录
├── html                                    # Nginx默认站点目录
│   ├── 50x.html              #错误页面优雅替代显示文件,例如当出现502错误时会调用此页面
│   └── index.html                           # 默认的首页文件
├── logs                                      # Nginx日志目录
│   ├── access.log                          # 访问日志文件
│   ├── error.log                          # 错误日志文件
│   └── nginx.pid               #pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件
├── proxy_temp                            # 临时目录
├── sbin                                    # Nginx命令目录
│   └── nginx                               # Nginx的启动命令
├── scgi_temp                             # 临时目录
└── uwsgi_temp                          # 临时目录
 
5、编译安装nginx参数详解
编译安装nginx软件时。可以使用./configure--help查看相关参数帮助。
--prefix                                        #设置安装路径
--user=USER                              #进程用户权限
--group=GROUP                         #进程用户组权限
--with-http_stub_status_module      #激活状态信息
--with-http_ssl_module                    #激活ssl功能
 
6、Nginx http 功能模块
Nginx http 功能模块                #模块说明
ngx_http_core_module             #包括一些核心的http参数配置对应的配置为http区块部分
ngx_http_access_module                 #访问控制模块,用来控制网站用户对Nginx的访问
ngx_http_gzip_module                #压缩模块,对Nginx返回的数据压缩,属于性能优化模块
ngx_http_fastcgi_module            #FastCGI模块,和动态应用相关的模块,例如PHP
ngx_http_proxy_moduleproxy     #代理模块
ngx_http_upstream_module             #负载均衡模块,实现网站的负载均衡功能及节点的健康检查
ngx_http_rewrite_module                 #URL地址重写模块
ngx_http_limit_conn_module      #限制用户并发连接数及请求数模块
ngx_http_limit_req_module         #根据定义的key限制Nginx请求过程的速率
ngx_http_log_module                  #访问日志模块,指定的格式记录Nginx客户访问日志等信息
ngx_http_auth_basic_moduleweb   #认证模块,设置web用户通过账号、密码访问Nginx
ngx_http_ssl_module                   #ssl模块,用于加密的http连接,如https
ngx_http_stub_status_module     #记录Nginx基本访问状态信息等的模块
 
7、nginx.conf 配置信息详解
# egrep -v '#|^$'nginx.conf
worker_processes  1;                               #work进程的数量
events {                                            #事件区块开始
    worker_connections  1024;                          #每个worker进程支持的最大连接数
}                                                    #事件区块结束
http {                                             #http区块开始
    include       mime.types;                   #nginx支持的媒体类型库文件
    default_type  application/octet-stream;     #默认的媒体类型
    sendfile        on;                            #开启高效的传输模式
    keepalive_timeout  65;                      #连接超时
 include  path/*.conf;                          #如果server标签过多可以摘出去,到任何路径下
    server {                                #第一个server区块开始,表示一个独立的虚拟主机站点
        listen       80;                           #提供服务的端口,默认是80
        server_name  localhost;                     #提供服务的域名主机名
        location / {                                #第一个location区块开始
            root   html;                         #站点的根目录,相当于nginx安装目录
            index  index.html index.htm;      #默认的首页文件,如果没有首页文件报403,报403的除了添加首页文件的另一个解决方法,在这放置autoindex on
        }                                        #第一个location区块结束
        error_page   500 502 503 504  /50x.html;  #出现对应的http状态码时,使用50x.html回应客户
        location = /50x.html {                   #location区块开始,访问50x.html
            root   html;                           #指定站点目录html
        }
    }
}                                                #http区块结束
 
三、nginx虚拟主机配置
1、虚拟主机
  所谓的虚拟主机,在web访问里就是一个独立的网站站点,这个站点对应独立的域名(也可能是IP或端口),具有独立的程序和目资源录,可以独立的对外提供服务供用户访问。
  这个独立的站点在配置里由一定的格式的标签段标记的。在nginx软件里是使用一个server{}标签来标识一个虚拟主机,一个web服务里可以有多个虚拟主机,即可以支持多个虚拟主机站点。
 
2、虚拟主机类型
2.1、域名(应用层)
企业外网场景,通过不同的域名区分不同的虚拟主机,企业应用最广的类型
 • 配置基于域名的nginx.conf内容
# egrep -v '#|^$'nginx.conf.default >nginx.conf
# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  www.wuyutang.top;
        location / {
            root   html;            
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
 • 检查语法重新加载
#/application/nginx/sbin/nginx -t
#/application/nginx/sbin/nginx -s reload
2.2、端口(传输层)
公司后台,测试场景,内部服务。这类虚拟主机主要是针对企业内部网站,一些不希望直接对外提供用户访问的网站后台
# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  www.wuyutang.top;
        location / {
            root   html/www;
            index  index.html index.htm;
        }
   }
    server {
        listen       81;
        server_name  bbs.wuyutang.top;
        location / {
            root   html/bbs;
            index  index.html index.htm;
        }
   }
    server {
        listen       82;
        server_name  blog.wuyutang.top;
        location / {
            root   html/blog;
            index  index.html index.htm;
        }
   }
}
2.3、IP(网络层)
 • 网卡上增加IP
·法一:
# ip addr add10.0.0.3/24 dev eth0 label eth0:3
# ip addr add10.0.0.4/24 dev eth0 label eth0:4
·法二:
# ifconfig eth0:010.0.0.101/24 up
# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       10.0.0.8:80;
        server_name  www.wuyutang.top;
        location / {
            root   html/www;
            index  index.html index.htm;
        }
   }
    server {
        listen       10.0.0.3:81;
        server_name  bbs.wuyutang.top;
        location / {
            root   html/bbs;
            index  index.html index.htm;
        }
   }
    server {
        listen       10.0.0.4:82;
        server_name  blog.wuyutang.top;
        location / {
            root   html/blog;
            index  index.html index.htm;
        }
   }
}
 
3、nginx状态信息功能
也就是新添加一个server标签打开stub_statuson;,编译安装nginx的时候的参数--with-http_stub_status_module
server {
        listen       80;
        server_name  status.wuyutang.top;
        location / {
          stub_status on;
          access_log off;
        }
    }
浏览器访问 status.wuyutang.top 查看状态信息。
或者在server块下面加上如下配置:
location/nginx_status {
stub_status  on;
access_log    off;
#allow127.0.0.1;允许哪个ip可以访问
}
# nginx -s reload
在浏览器中输入"域名/nginx_status" 就会显示nginx上次启动以来工作状态的统计的结果。
 
4、nginx访问日志
4.1、日志配置
server {
        listen       80;
        server_name  blog.wuyutang.top;
        location / {
            root   html/blog;
            index  index.html index.htm;
        }
        access_log  logs/access.log  [format buffer=size [flush=time]]  main;
   }
 • 注意
       1.这行配置中的main是http标签中配置的log_format后面的main对应的格式,可以多个格式,方便使用.
       2. 配置行的[]括号内的选项是可选的,配置缓存,防止高并发的大量IO
       3. format gzip[=level]
 • 错误日志级别
default:error_log     logs/error.log      level;
         关键配置    日志文件            错误日志级别[debug|info|warn|error|alert|notice|crit|emerg]
生产场景一般用warn|error|crit三个级别
 • 标签端的配置
  main,http,server,location
4.2、nginx日志变量说明
 • 日志格式
http {
    log_format main  '$remote_addr - $remote_user[$time_local] "$request" '
                                 '$status$body_bytes_sent "$http_referer" '
                               '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log logs/access.log main;
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    include extra/*.conf;
}
 • 日志变量参数详解:
nginx日志变量                        说明
$remote_addr                记录访问网站客户端地址
$remote_user                远程客户端用户名称
$time_local                访问时间和时区
$request                用户的http请求的起始行信息
$status                        http状态码,记录请求返回的状态
$body_bytes_sent        服务器发送给客户端的响应body字节数
$http_referer                此链接是从哪个连接访问过来的
$http_user_agent        记录客户端的访问信息
$http_x_forwarded_for        当前有代理服务器时,设置了web节点机理客户端地址的配置
4.3、nginx 访问日志切割
# mv access.log $(date+%F -d "-1day")_access.log
#/application/nginx/sbin/nginx -sreload                        #重新启动就会重新生成access.log文件,然后写定时任务。
 • 使用定时任务加脚本的形式:
# crontab -l
  ################ timesync
  */5 * * * */usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1
  ################ catnginx access.log
  00 00 * * * /bin/sh/server/scripts/cut_log.sh >/dev/null 2>&1
# vim cut_log.sh
#!/bin/bash
cd/application/nginx/logs &&\
mvaccess.log $(date +%F -d "-1day")_access.log
/application/nginx/sbin/nginx-s reload
Nginx常用日志收集及分析工具有rsyslog、awstats、flume、ELK(Elasticsearchlogstash Kibana)、storm等。
 
5、nginx location
 • 作用:是根据用户请求的URI来执行不同的应用
 • 语法:location { = | ~ | ~* | ^~ } uri {
  …
  }
 • 注意:   = 精确匹配,~区分大小写,~*不区分大小写,!匹配取反,^~在常规字符串检查之后,不做正则表达式的检查
    URI是关键部分,可以是普通字符串地址路径,或者是正则表达式
 • location示例:
server {
        listen       80;
        server_name  blog.wuyutang.top;
        location / {
           return 401;
        }
        location = / {
            return 402;
        }
        location /documents/ {
            return 403;
        }
        location ^~ /images/ {
            return 404;
        }
        location ~* \.(gif|jpg|jpeg)$ {
            return 500;
        }
   }
检查语法,重启生效。
实验返回状态码:
  # curl -s -o/dev/null -I -w "%{http_code}\n" http://blog.wuyutang.top/
  # curl -s -o/dev/null -I -w "%{http_code}\n" http://www.wuyutang.top/images/
参数解释:-s静默,-o不输出,-I请求头,-w"%{http_code}\n"状态码
“location = / {”                                精确匹配
“location ^~ /images/ {”                匹配常规字符串,不做正则匹配检查
“location ~*\.(gif/jpg/jpeg)$ { ”        正则匹配
“location /documents/ {”                路径匹配
“location / {”                                所有location都不能匹配后的默认匹配
 
6、nginx rewrite
 • rewrite用法
  和Apache等的web服务软件一样,nginxrewrite的主要功能也是实现URL地址重写,nginx的rewrite规则需要PCRE软件的支持,通过Perl兼容正则表达式语法进行规则匹配。
 • rewrite指令语法:
  rewrite regexreplacement [flag]
默认值:none    应用位置:server、location、if
例子:rewrite ^/(.*) http://www.wuyutang.top/$1 permanent;
server标签下:
  直接rewrite ^/(.*) http://www.wuyutang.top/$1permanent;
 • 正则表达式
字符                描述
\        将后面的字符标记为一个特殊字符或一个后项引用,例:\\和\n匹配换行符
^        匹配输入字符串的起始位置
$        匹配输入字符串的结束位置
*        匹配前面字符0次或多次,例:ol*匹配“o”或者“olllll”
+        匹配前面字符1次或多次,例:ol*匹配“ol”或者“olllll”
?        匹配前面字符0次或1次
.        匹配除‘\n’之外的任何单个字符
(pattern)        匹配括号内得pattern,并且在后面获取对应的匹配,会后项通过$1~n引用
 • flag标记的说明
flag标记符号                说明
last                本条规则匹配完成后,继续向下匹配新的locationURI规则
break                本条规则匹配完成即终止,不再匹配后面的任何规则
redirect        返回302临时重定向,浏览器地址栏会显示跳转后的URL地址
permanent        返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
##rewrite ^(.*)/bbs/ h有关rewrite特殊flag标记last与break的说明:
在根location中或者server标签中编写rewrite规则,建议使用last标记,而在普通的location或if{}中编写rewrite规则,则建议使用break标记。
注意:
last和break用来URL重写,浏览器的URL地址不变,
redirect和permanent用来实现URL跳转,浏览器的URL地址显示跳转后的地址
 
7、nginx 访问认证
示例:
  location / {
   auth_basic           "accessauthentication";             #这是个提示
   auth_basic_user_file/application/nginx/conf/htpasswd;  #认证读取的文件
  }
创建账号密码:此账号就是登陆时需要的
# htpasswd -cb/application/nginx/conf/htpasswd tang 123456
  Adding password foruser tang
# chmod 400/application/nginx/conf/htpasswd
# chown www/application/nginx/conf/htpasswd
检查语法,重启生效。