7

In the traditional monolithic software architecture, software development, testing, and operation and maintenance are all based on a single process.

When split into microservices, a single application can be split into multiple microservices, such as user systems, which can be split into multiple microservice modules such as basic information management, credit management, order management, user information management, and contract management .

At this time, if each module is packaged, released, run, developed, tested, and operated separately, the workload of testing and operation and maintenance will be greatly increased.

In this process, if there is a lack of capabilities such as automated testing, automated integration/deployment, and automated operation and maintenance, the impact will be

  1. Increased software delivery cycles
  2. In the case of multi-environment deployment, problems caused by differences in each environment.
  3. Manual operation and maintenance is easy to bring some irreproducible effects to the environment, and once an operation and maintenance error occurs, it is difficult to recover immediately, resulting in a long troubleshooting time. And higher requirements for the ability of operation and maintenance personnel

All of these issues lead to longer software delivery times, increased risk, and increased operational and maintenance costs. Therefore, we need an automated deployment system to build a CICD model.

image-20211204145303729

How ordinary Jar packages work

  1. Use maven package
  2. nohup java -jar ${APP_NAME} > goods-service.log 2>&1 &
  • nohup purpose: run commands without hanging up
  • & uses, runs in the background
  • 2>&1: In bash:

    • 0 represents STDIN_FILENO standard input (usually the keyboard),
    • 1 stands for STDOUT_FILENO standard output (usually the display screen, to be precise the user terminal console),
    • 2 and three represent STDERR_FILENO (standard error (error message output).

    2>&1 is used to redirect standard error 2 to standard output 1. The & in front of 1 here is to make bash interpret 1 as standard output instead of file 1. As for the last &, it makes bash execute in the background.

  • > Generate the content directly to the specified file

Build a Nexus private server environment

Nexus is a powerful Maven repository manager that greatly simplifies the maintenance of local internal repositories and access to external repositories. Nexus is an "out of the box" system that does not require a database, it uses a file system plus Lucene to organize data.

Maven private server environment needs to use sonatype nexus , let's make a detailed analysis from installation and configuration below

Deployment server: 192.168.8.138

Download and install

  1. Visit: https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.37.0-01-unix.tar.gz address to download Sonatype Nexus.
  2. Unzip to /data/program directory
[root@localhost program]# tar -zxvf nexus-3.37.0-01-unix.tar.gz 
  1. ${NEXUS_HOME}\bin to the 061e1349603178 directory and execute the following command to start Nexus
./nexus start 

Install Maven

  1. Download Maven: https://dlcdn.apache.org/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz
  2. Configure Maven and JDK environment variables.
export JAVA_HOME=/data/program/jdk1.8.0_241
export MAVEN_HOME=/data/program/apache-maven-3.8.4
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  1. ${NEXUS_HOME}\bin to the 061e134960325f directory and execute the following command to start Nexus

    Start with ./nexus start, start in the background, and you can access it after successful startup

    Start with ./nexus run, the foreground starts, the log is displayed, and it can be accessed after startup

./nexus start 
When starting, there will be the following prompt. This is to suggest that we use a non- root account to access.
WARNING: ************************************************************
WARNING: Detected execution as "root" user.  This is NOT recommended!
WARNING: ************************************************************
  1. Visit: http://localhost:8081 Visit Nexus Repository

If you want to configure the JVM parameter that the nexus application starts locally, you can nexus.vmoptions

If you want to change the port number of , you can use nexus-default.properties

log in to the console

  1. The default login account is admin , and the password will prompt you to be in: /data/program/sonatype-work/nexus3/admin.password file.

  1. The content is as follows, just copy the content and log in.
090849ac-cea7-4353-b2c8-59b2bceadb50

Nexus Console Instructions

Entering the Browse menu of the Nexus console, you can see four warehouse types:

1) maven-central: maven central library, pulls jar https://repo1.maven.org/maven2/

2) maven-releases: private library release jar

3) maven-snapshots: private library snapshot (debug version) jar

4) maven-public: Warehouse grouping, combining the above three warehouses to provide services to the outside world, and using them in the local maven basic configuration settings.xml.

image-20211205153818994

The default warehouse types of Nexus are as follows: (The above name can be chosen arbitrarily, the key is what warehouse type it corresponds to)

1) group (warehouse group type): also called group warehouse, which is used to facilitate the warehouse set by developers themselves;

2) hosted (host type): the release warehouse of the internal project (internal developers, the warehouse released and stored);

3) proxy (proxy type): Find the warehouse of data from the remote central warehouse (you can click the Configuration page of the corresponding warehouse to sign the value of the Remote Storage Location property, that is, the path of the remote warehouse being proxied);

4) virtual (virtual type): virtual warehouse (this is basically not used, focus on the use of the above three warehouses);

Nuget is a package manager for Microsoft's .NET development platform, similar to Maven.

Directory Description

nexus-3.34.0-01 directory
  1. bin contains nexus startup scripts and related configurations
  2. Configuration files such as jetty, karaf, etc.
  3. jre jre environment
  4. lib java rack package library
  5. public About the resources required for the nexus application to run locally
  6. system applies all plugins and components
  7. LICENSE.txt and NOTICE.txt Copyright Notice and Legal Details
sonatype-work\nexus3 directory
  1. blobs/ The default path for creating blobs, of course, it can also be re-specified
  2. cache/ Information about currently cached karaf packages
  3. db/ OrientDB database data, the database used to store nexus metadata
  4. elasticsearch/ The currently configured Elasticsearch state
  5. etc/ is presumably related to runtime configuration state and customizations about the repository
  6. health-check/ Look at the directory, the storage directory of the related reports of health check.
  7. keystores/ auto-generated ID primary key about the repository
  8. log/ The log files generated by the running instance, as well as the compressed package of the log files, seem to be generated every day, you can delete the old log files regularly
  9. tmp/ directory for storing temporary files

Nexus is set as a system service

Follow the steps below

  1. Modify ${NEXUS_HOME}\bin\nexus and add the following configuration
INSTALL4J_JAVA_HOME_OVERRIDE=/data/program/jdk1.8.0_241
  1. set soft link
[root@localhost bin]# ln -s /data/program/nexus-3.37.0-01/bin/nexus /etc/init.d/nexus
  1. Configure system services through chkconfig
cd /etc/init.d
sudo chkconfig --add nexus #添加nexus服务
sudo chkconfig --levels 345 nexus on #设置开启自启动
  1. Start and stop services

    sudo service nexus start #Start the service
    service nexus status #View service status

Setting up the Gitea environment

Reference document: https://docs.gitea.io/zh-cn/install-from-binary/
  1. Install git environment: yum -y install git .
  2. Download the installation package in linux to the /data/program/gitea directory through the following command.
wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64
  1. Execute the chmod +x gitea command and grant execute permission
  2. Execute the following command to run gitea
./gitea web
Install as a system service (important)
  1. Create a Git user
sudo useradd \
   --system \
   --shell /bin/bash \
   --comment 'Git Version Control' \
   --create-home \
   --home /home/git \
   git
  1. Download binaries
wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64
  1. According to the official recommendation of gitea, configure the installation directory of gitea as follows

    • Move the downloaded file to the /usr/local/bin directory

      sudo mv /data/program/gitea /usr/local/bin
    • Make the binary executable:

      chmod +x /usr/local/bin/gitea
    • Follow the commands below to create the necessary directories and set permissions

      sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
      sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
      sudo chown git: /var/lib/gitea/{data,indexers,custom,public,log}
      sudo chmod 750 /var/lib/gitea/{data,indexers,log}
      sudo mkdir /etc/gitea
      sudo chown root:git /etc/gitea
      sudo chmod 770 /etc/gitea
    • Configure system services according to the Systemd Unit file officially provided by Gitea.

      sudo wget https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/systemd/gitea.service -P /etc/systemd/system/
      Note that gitea.service cannot be downloaded through wget and needs to be copied on github
    • After completing the above process, enable automatic startup with the following command

      systemctl enable gitea
      systemctl start gitea
  2. After the installation is started, visit: http://192.168.8.136:3000 to configure the database related properties.

Build the Jenkins environment

Jenkins is an open source continuous integration tool written in JAVA, running in a servlet container, supporting software configuration management (SCM) tools, and can execute projects based on APACHE ANT and APACHE MAVEN, as well as arbitrary Shell scripts and Windows batch commands

Jenkins provides automatic build and deployment functions. The specific installation methods are as follows:

wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum upgrade
yum install epel-release java-11-openjdk-devel
yum install jenkins
systemctl daemon-reload
Start or stop jenkins by following command
systemctl start jenkins
systemctl stop jenkins
Visit: http://192.168.8.136:8080 visit jenkins

Follow the steps prompted by the console step by step.

image-20211206175235556

Note: Jenkins installation uses the JENKINS user by default, so if you use root privileges, you need to modify the account
[root@localhost bin]# vim /etc/sysconfig/jenkins

JENKINS_USER="root"

Project renovation

Project configuration local private server

  1. Modify the setting.xml file and add the mirror configuration

    <mirrors>
        <mirror>
            <id>nexus</id>
            <mirrorOf>maven-public</mirrorOf>
            <url>http://192.168.8.136:8081/repository/maven-public/</url>
        </mirror>
    </mirrors>
    Mirror is equivalent to an interceptor, which intercepts maven's related requests to the remote repository, and uses the mirror to obtain the jar package.
  1. Add the following configuration to the project, that is, specify the release repository of the jar package of different release versions of snapshots and releases

    <distributionManagement>
        <snapshotRepository>
            <id>snapshots</id>
            <name>Nexus Snapshot Repository</name>
            <url>http://192.168.8.136:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
        <repository>
            <id>releases</id>
            <name>Nexus Release Repository</name>
            <url>http://192.168.8.136:8081/repository/huhy-nexus/</url>
        </repository>
    </distributionManagement>

Modify the settings.xml file of the publisher

The purpose of modifying the settings.xml file of the publishing server is that when the Jenkins server performs continuous integration, it needs to download the dependent jar package through maven, and this download needs to be obtained from our local private server.

<mirrors>
    <mirror>
        <id>nexus</id>
        <mirrorOf>maven-public</mirrorOf>
        <url>http://192.168.8.136:8081/repository/maven-public/</url>
    </mirror>
</mirrors>
<profiles>
     <profile>
      <id>nexusRep</id>
      <repositories>
        <repository>
          <id>nexus</id>
          <url>http://192.168.8.136:8181/repository/maven-public/</url>
          <layout>default</layout>
          <releases>
              <enabled>true</enabled>
              <updatePolicy>always</updatePolicy>
          </releases>
        </repository>
      </repositories>
      <pluginRepositories>  
        <pluginRepository>  
          <!--插件地址--> 
            <id>nexus</id>  
            <url>http://192.168.8.136:8181/repository/maven-public/</url>  
            <snapshots>     
              <enabled>true</enabled>    
            </snapshots>    
            <releases>      
                <enabled>true</enabled>    
            </releases> 
        </pluginRepository>
       </pluginRepositories>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexusRep</activeProfile>
  </activeProfiles>

Configure automatic integration and publishing

Configure Jenkins environment variables

Go to the following page, the configuration marked in red.

image-20211206195831934

Configure the Maven environment and specify the Maven directory installed on the publishing server.

image-20211206200050850

Install the Jenkins plugin

  • Gitea, integrate Gitea, after installation, add Gitea Server information in Jenkins global configuration.

    image-20211206202555784

  • Git Parameter , configure Git publish properties
  • Publish Over SSH, execute the script on the remote machine, this step needs to configure the remote machine capable of ssh
  • Maven Integration, which supports the integration of Maven projects

Configure publish target server information

We treat the following two servers as web nodes

  1. 192.168.8.134
  2. 192.168.8.135

In the global configuration of Jenkins, configure the information of these two servers for subsequent remote transmission of jar packages. Among them, Remote Directory the working directory of the target server, and the jar package will be remotely transferred to this directory

image-20211206203254587

Add project release mechanism

The task of creating a Maven project.

image-20211206204153959

Configure the source code source, here use the source code address of the project in Gitea, and configure the login account password information.

image-20211206204554726

Configure the execution command of Maven, among which root POM , if it is in a multi-module project, you need to specify the pom.xml of the module to be built currently.

image-20211206205541294

Adding the execution logic after the successful build is to publish the jar package to the remote target server, and then execute the relevant shell script to start the service

image-20211206231510128

Write a release script

Write a shell script, and execute the following script when the jar package is sent to the target server.

  1. Do historical jar backup and cleanup
  2. Execute shell script to start service
#! bin/sh -e
export JAVA_HOME=/data/program/jdk1.8.0_241
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=${PATH}:$JAVA_HOME/bin
source /etc/profile 

# define property
JAR_PATH='/app/service/goods-service'
TEMP_PATH='/app/service/temp'
BACKUP_PATH='/app/service/backup'
JAR_NAME=goods-service.jar
FILE_NAME=goods-service

# stop target service
cd ${JAR_PATH}
sh run-goods-service.sh stop
sleep 2
rm -rf $FILE_NAME.log

# backup old jar
BACKUP_DATE=$(date +%Y%m%d_%H%M)

if [ ! -d $JAR_PATH/backup/$FILE_NAME ];then
    mkdir -p $JAR_PATH/backup/$FILE_NAME
fi

cd ${JAR_PATH}
pwd
if [ -f $JAR_NAME ];then
   mv -f ./$JAR_NAME ./backup/$FILE_NAME/$JAR_NAME$BACKUP_DATE
   sleep 1
fi

# start jar
BUILD_ID=dontKillMe
cd ${TEMP_PATH}
mv -f $JAR_NAME  $JAR_PATH
cd ${JAR_PATH}
sh run-goods-service.sh restart

# clear old backup
cd ${JAR_PATH}/backup/$FILE_NAME
ls -lt|awk 'NR>5{print $NF}' |xargs rm -rf

ps -ef|grep java
echo "=============deploy success========"

Write the run script run-goods-service.sh

# 表示当前脚本采用/bin路径的bash程序来解释执行
#!/bin/bash

# 执行的jar包
APP_NAME=goods-service.jar

usage() {
  echo "执行操作命令 [start|stop|restart|status]"
  exit 1
}

if_exist() {
  pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
  if [ -z "${pid}" ]; then
    return 1
  else
    return 0
  fi
}

start() {
  if_exist
  if [ $? -eq 0 ]; then
    echo "${APP_NAME} already running . pid=${pid}"
  else
    nohup java -jar ${APP_NAME} > goods-service.log 2>&1 &
    npid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
    echo "start ${APP_NAME} success, pid=${npid}"
  fi
}

stop() {
  if_exist
  if [ $? -eq 0 ]; then
    kill -9 $pid
    echo "stop $pid success".
  else
    echo "${APP_NAME} is not running"
  fi
}

status() {
  if_exist
  if [ $? -eq 0 ]; then
    echo "${APP_NAME} is running. pid is ${pid}"
  else
    echo "${APP_NAME} is not running "
  fi
}

restart() {
  stop
  sleep 5
  start
}

case "$1" in
   "start")
      start
       ;;
    "stop")
      stop
       ;;
    "status")
      status
       ;;
    "restart")
      restart
       ;;
    *)
    usage
     ;;
esac

Dynamic build after configuration code is submitted

If we want the code to be submitted and merged into a branch, it will be automatically built and released, how can we do it?

Install the Webhook plugin

  1. Generic Webhook Trigger plugin in Jenkins. After the installation is successful, an option shown below will be added to the build configuration page.

    image-20211207000120205

  2. Configure Generiac Webhook Trigger and add a token for verification.

    image-20211207000421036

    Pay attention to this address: http://JENKINS_URL/generic-webhook-trigger/invoke , you need to configure this as a trigger call in the webhook.

gitea add webhook hook

  1. In gitea's project, find the web hook and add the web hook. Select gitea .

    image-20211207000530187

  2. add webhook

    image-20211207000722202

Validate auto-triggered behavior

  1. Modify any code of the gpmall-pc project and submit it to gitea.
  2. Looking at Jenkin's project build directory, an automatic build task will be added, as shown in the following figure.

    image-20211207000953071

  3. And in gitea's webhook, you can see the latest push records

    image-20211207001046181

Source address

The source code used in the article demo: https://github.com/2227324689/spring-cloud-netflix-example.git

Copyright notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated. Reprint please indicate from Mic takes you to learn architecture!
If this article is helpful to you, please help to follow and like, your persistence is the driving force for my continuous creation. Welcome to follow the WeChat public account of the same name to get more technical dry goods!

跟着Mic学架构
810 声望1.1k 粉丝

《Spring Cloud Alibaba 微服务原理与实战》、《Java并发编程深度理解及实战》作者。 咕泡教育联合创始人,12年开发架构经验,对分布式微服务、高并发领域有非常丰富的实战经验。