修改默認鏡像源
vim /var/lib/jenkins/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?> <sites> <site> <id>default</id> <url>https://jenkins-zh.gitee.io/update-center-mirror/tsinghua/update-center.json</url> </site> </sites>
或者:
jenkins ==>系統管理 ==> 插件管理 ==> 高級 ==> 升級站點
-------------------------------------------------------------------------------------------------------------
想要“不自動構建下級項目”,需要在下級項目中配置
Build whenever a SNAPSHOT dependency is built 把這個選項取消掉就可以了
--------------------------------------------------------------------------------------------------------------
更改Jenkins啟動的用戶時的步驟:
1、# vim /etc/sysconfig/jenkins
JENKINS_USER="wjoyxt"
2、# chown -R wjoyxt.wjoyxt /var/log/jenkins /var/lib/jenkins /var/cache/jenkins 這三個目錄
--------------------------------------------------------------------------------------------------------------
忘記密碼時的處理辦法:
打開忘記密碼的用戶文件夾,默認 /var/lib/jenkins/users ,里面就一個文件config.xml。打開config.xml,找到<passwordHash>項,
把其中的hash值先改成 "#jbcrypt:$2a$10$DdaWzN64JgUtLdvxWIflcuQu2fgrrMSAMabF5TSrGK5nXitqK9ZMS"
保存並重啟jenkins,此時被修改用戶的密碼變為 "111111",進入jenkins后再通過用戶管理重新設置自己的密碼即可。
另:Jenkins中復制job的方法:復制/var/lib/jenkins/jobs中的項目目錄,並改成要新建的項目名稱即可。
--------------------------------------------------------------------------------------------------------------
一、Jenkins介紹以及安裝
什么是持續集成?
隨着軟件開發復雜度的不斷提高,團隊開發成員間如何更好地協同工作以確保軟件開發的質量已經慢慢成為開發過程中不可回避的問題。尤其是近些年來,敏捷(Agile) 在軟件工程領域越來越紅火,如何能再不斷變化的需求中快速適應和保證軟件的質量也顯得尤其的重要。
持續集成正是針對這一類問題的一種軟件開發實踐,對於提高軟件開發效率並保障軟件開發質量提供了理論基礎。它倡導團隊開發成員必須經常集成他們的工作,甚至每天都可能發生多次集成。而每次的集成都是通過自動化的構建來驗證,包括自動編譯、發布和測試,從而盡快地發現集成錯誤,讓團隊能夠更快的開發內聚的軟件。
持續集成最早由Martin Fowler 於10年前已經提出,希望通過持續集成能夠實現以下過程:
任何人在任何地點,任何時間可以構建整個項目。
在持續集成構建過程中,每一個單元測試都必須被執行。
在持續集成構建過程中,每一個單元測試都必須通過。
持續集成構建的結果是可以發布的軟件包。
當以上任何一點不能滿足時,整個團隊的主要任務就是去解決這個問題
持續集成的核心價值
持續集成中的任何一個環節都是自動完成的,無需太多的人工干預,有利於減少重復過程以節省時間、費用和工作量;
持續集成保障了每個時間點上團隊成員提交的代碼是能成功集成的。換言之,任何時間點都能第一時間發現軟件的集成問題,使任意時間發布可部署的軟件成為了可能;
持續集成還能利於軟件本身的發展趨勢,這點在需求不明確或是頻繁性變更的情景中尤其重要,持續集成的質量能幫助團隊進行有效決策,同時建立團隊對開發產品的信心。
本文此處采用yum安裝方式
除了直接java -jar jenkins.war方式,還可以用yum安裝,這種方式下提供了更多的可配置選項,更適合生產環境控制jenkins的行為。
1
2
3
|
sudo
wget -O
/etc/yum
.repos.d
/jenkins
.repo http:
//pkg
.jenkins-ci.org
/redhat/jenkins
.repo
sudo
rpm --
import
http:
//pkg
.jenkins-ci.org
/redhat/jenkins-ci
.org.key
sudo
yum
install
jenkins
|
安裝完成后,可用
1
|
sudo
service jenkins start
/stop/restart
|
不過,我在centos 7環境上測試下來,/etc/rc.d/init.d/jenkins這個腳本寫得有點小問題,如果java不在默認目錄下,會導致啟動失敗
1
|
sudo
vim
/etc/rc
.d
/init
.d
/jenkins +67
|
定位到67行,會發現該腳本會從以下位置找java可執行文件
1
2
3
4
5
6
7
8
9
10
|
candidates="
/etc/alternatives/java
/usr/lib/jvm/java-1
.6.0
/bin/java
/usr/lib/jvm/jre-1
.6.0
/bin/java
/usr/lib/jvm/java-1
.7.0
/bin/java
/usr/lib/jvm/jre-1
.7.0
/bin/java
/usr/lib/jvm/java-1
.8.0
/bin/java
/usr/lib/jvm/jre-1
.8.0
/bin/java
/usr/bin/java
"
|
如果java沒安裝在這些目錄下,啟動就會失敗,解決辦法:把java所在的正確位置加入其中即可,比如:
1
2
3
|
candidates="
/usr/local/java/jdk-1.8.51/bin/java
"
|
注:這樣處理后,還要執行一下sudo systemctl daemon-reload,然后就可以service jenkins start了,如果還出錯,嘗試 cd /etc/rc.d/init.d,然后sudo ./jenkins start 進一步排查。建議同學們把這個啟動腳本仔細閱讀一下,可以發現很多有用的信息,比如:
1
2
3
4
5
|
JENKINS_WAR=
"/usr/lib/jenkins/jenkins.war"
JENKINS_CONFIG=
/etc/sysconfig/jenkins
JENKINS_PID_FILE=
"/var/run/jenkins.pid"
PARAMS=
"--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon"
--simpleAccessLogger.
file
=
/var/log/jenkins/access_log
|
上面這些參數定義了配置文件、war包、pid文件、日志的位置,出問題時,我們可以直接到這些位置去查看詳情。
比如:端口8080被占用了,需要更改啟動端口,直接查看/etc/sysconfig/jenkins這個文件,找到
1
|
JENKINS_PORT=
"8080"
|
修改一下即可。
/etc/sysconfig/jenkins這個文件為jenkins的參數配置文件,比如:
JENKINS_USER=
"jenkins"
JENKINS_HOME=
"/var/lib/jenkins"
JENKINS_AJP_PORT=
"8009"
JENKINS_DEBUG_LEVEL=
"5"
JENKINS_ENABLE_ACCESS_LOG=
"no"
構建的狀態:下圖中分級符號概述了一個Job新近一次構建會產生的四種可能的狀態:
Successful:完成構建,且被認為是穩定的。
Unstable:完成構建,但被認為不穩定。
Failed:構建失敗。
Disabled:構建已禁用。

sonar.jdbc.username=sonar sonar.jdbc.password=sonar sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance
3、mysql數據庫配置
根據官網提供的文檔,http://docs.sonarqube.org/display/SONAR/Requirements 可以得到該版本所需求的基礎環境(JDK和數據庫版本等),所以這里先創建好所需的mysql數據庫
mysql> CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> CREATE USER 'sonar' IDENTIFIED BY 'sonar';
mysql> GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
mysql> GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
mysql> FLUSH PRIVILEGES;
4、啟動Sonar服務,默認9000端口
目錄切換至sonar的<install_directory>/bin/linux-x86-64/目錄,啟動服務
#./sonar.sh start 啟動服務
#./sonar.sh stop 停止服務
#./sonar.sh restart 重啟服務
- 安裝中文補丁包可以通過訪問http:\\localhost:9000,用戶名和密碼都是admin。打開sonar后,進入更新中心Available安裝 "Chines Pack"
- 或者從下載地址:https://github.com/SonarQubeCommunity/sonar-l10n-zh下載對應版本的中文補丁包后,放到SONARQUBE_HOME/extensions/plugins目錄,然后重啟SonarQube服務
各版本相對應的語言包:https://github.com/SonarQubeCommunity/sonar-l10n-zh/releases
6、安裝需要進行代碼分析的Java、PHP語言分析插件, "配置--系統--更新中心"
sonar.host.url=http://10.0.30.180:9000 sonar.sourceEncoding=UTF-8
3、配置環境變量/etc/profile,此處一並加上SONARQUBE_HOME的變量
export SONARQUBE_HOME=/usr/local/sonarqube
export SONAR_RUNNER_HOME=/usr/local/sonar-scanner/
sonar.projectKey=prepare-agent sonar.projectName=prepare-agent sonar.projectVersion=1.0 sonar.sources=. sonar.language=java sonar.sourceEncoding=UTF-8
工程的key和name維護成一樣即可
sonar.projectKey=weike_open
sonar.projectName=weike_open
#當前工程的版本
sonar.projectVersion=1.7.1.0
#進行掃描分析的代碼頂級目錄
sonar.sources=src
# 分析的語言
sonar.language=java
# 源碼編碼格式
sonar.sourceEncoding=UTF-8
Sonar官方已經提供了非常全的代碼樣例便於新手入門用。
下載地址:https://github.com/SonarSource/sonar-examples/archive/master.zip
下載后使用unzip解壓。進入執行sonar-scanner命令即可。執行完成后查看SonarQube的Web界面,正常的話應該就可以看到分析的結果啦。






Build whenever a SNAPSHOT dependency is built:當此項目所依賴的項目在jenkins中被構建時觸發開始進行構建
Build after other projects are built:在某個項目被構建后,構建此項目
Build periodically:按照指定的時間間隔進行自動構建,不管代碼有沒有變更。
Poll SCM:按照指定的時間間隔對SCM進行檢測,如果代碼庫有更新則拉取后進行構建。



workspace=/data/workspace/online-ucenter-front
appname=resin 此處的appname代表的是tomcat或resin的文件夾名稱,例如:dubbo resin tomcat-web tomcat-manager tomcat-zhibo
env=online-ucenter-front(生產環境) 或 prepare-ucenter-fromt(預發布環境)
#!/bin/bash #添加環境相關變量 source /home/sunyl/jenkins/openrc #以時間命名目錄名稱 time=`date +"%Y%m%d-%H%M%S"` #使用的hosts文件 hosts=`echo $env|awk -F '-' '{print $1}'` #目標應用啟動路徑 if [[ "$appname" =~ "dubbo" ]]; then work_dir=/data/ifengsite/java/dubbo/$appname package=$workspace/target/dubbo.zip else work_dir=/data/ifengsite/java/$appname/webapps package=$workspace/target/ROOT.war fi #目標應用保留目錄 releases_dir=/data/ifengsite/releases/$appname #建立軟連接源目錄 work2_dir=$releases_dir/$time ansible -i /home/sunyl/jenkins/$hosts $env -m copy -a "src=/home/sunyl/jenkins/openrc dest=/home/www/openrc" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "mkdir -p $work2_dir" -u www if [[ "$appname" =~ "dubbo" ]]; then cd $workspace/target/ rm -rf dubbo.zip zip -r dubbo.zip *.jar lib resources ansible -i /home/sunyl/jenkins/$hosts $env -m copy -a "src=/home/sunyl/jenkins/startup.sh dest=$work2_dir" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m copy -a "src=$package dest=$work2_dir" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "cd $work2_dir && unzip dubbo.zip && rm -rf dubbo.zip" -u www #ansible -i /home/sunyl/jenkins/$hosts $env -m unarchive -a "src=$package dest=$work2_dir " -u www else ansible -i /home/sunyl/jenkins/$hosts $env -m copy -a "src=$package dest=$work2_dir" -u www fi ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "ln -sfn $work2_dir $work_dir" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m script -a "/home/sunyl/jenkins/restart_app.sh" -u www
# cat /home/sunyl/jenkins/restart_app.sh
#!/bin/sh source /home/www/openrc #kill tomcat pid if [[ "$appname" =~ "dubbo" ]]; then appname=`ls /data/ifengsite/java/dubbo/$appname|grep jar` fi pidlist=`ps -ef|grep $appname|grep -v "grep"|grep -v $0|awk '{print $2}'` if [ "$pidlist" = "" ] then echo "no $appname pid alive!" else echo "$appname Id list :$pidlist" kill -9 $pidlist echo "KILL $pidlist:" echo "service stop success" fi source /home/www/openrc echo "start $appname" if [[ "$appname" =~ "dubbo" ]]; then cd /data/ifengsite/java/dubbo/$appname/ sh startup.sh else cd /data/ifengsite/java/$appname/bin sh startup.sh fi

#!/bin/bash # # Usage: start.sh [debug] # cd `dirname $0` BIN_DIR=`pwd` #cd .. DEPLOY_DIR=`pwd` APPNAME=`ls $DEPLOY_DIR | grep jar` LOGS_DIR=log STDOUT_FILE='log/console.log' if test -n "${JAVA_HOME}"; then if test -z "${JAVA_EXE}"; then JAVA_EXE=$JAVA_HOME/bin/java fi fi if test -z "${JAVA_EXE}"; then JAVA_EXE=java fi ${JAVA_EXE} -version >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "ERROR: Not Found java installed!" exit 1 fi if [ -z "$LOGS_DIR" ]; then LOGS_DIR=$DEPLOY_DIR/log fi if [ ! -d $LOGS_DIR ]; then mkdir $LOGS_DIR fi if [ ! -d $LOGS_DIR ]; then echo "ERROR: Please check LOGS_DIR=$LOGS_DIR is ok?" exit 1 fi STDOUT_FILE=$LOGS_DIR/console.log echo "Logs_dir: ${STDOUT_FILE}" JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true " JAVA_DEBUG_OPTS="" if [ "$1" = "debug" ]; then JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n " fi JAVA_JMX_OPTS="" if [ "$1" = "jmx" ]; then JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false " fi JAVA_MEM_OPTS="" BITS=`${JAVA_EXE} -version 2>&1 | grep -i 64-bit` if [ -n "$BITS" ]; then JAVA_MEM_OPTS=" -server -Xmx2048m -Xms2048m -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 " else JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:SurvivorRatio=2 -XX:+UseParallelGC " fi echo "Starting the $SERVER_NAME ..." nohup ${JAVA_EXE} $JAVA_SPRING_OPTS $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS -jar $APPNAME > $STDOUT_FILE 2>&1 & echo "OK!"



#!/bin/bash #添加環境相關變量 source /home/sunyl/jenkins/openrc #使用的hosts文件 hosts=`echo $env|awk -F '-' '{print $1}'` #以時間命名目錄名稱 time=`date +"%Y%m%d-%H%M%S"` #目標應用啟動路徑 work_dir=/data/ifengsite/htdocs/$appname package=$workspace/../$appname.tar #目標應用保留目錄 releases_dir=/data/ifengsite/releases/$appname #建立軟連接源目錄 work2_dir=$releases_dir/$time ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "mkdir -p $work2_dir" -u www cd $workspace/../ && rm -rf $appname.tar cd $workspace && tar cf $package * ansible -i /home/sunyl/jenkins/$hosts $env -m copy -a "src=$package dest=$work2_dir" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "cd $work2_dir && tar xf $appname.tar && rm -rf $appname.tar" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "ln -sfn $work2_dir $work_dir" -u www ansible -i /home/sunyl/jenkins/$hosts $env -m shell -a "/etc/init.d/php-fpm restart" -u www