Spring Cloud(15): 마이크로서비스 자동 배포 DevOps CI/CD, Maven 패키징, ELK 로그 수집

  • 데브옵스 CI/CD
    • Gitlab(무료 버전 및 유료 버전)
    • 젠킨스
    • GitLab+Jenkins 기반 CI\CD의 신속한 구현
  • 백엔드 프로젝트 패키징 및 배포 방법
    1. 스프링 부트 메이븐 플러그인
    2. 메이븐 의존성 플러그인
    3. 메이븐 공식 홈페이지 플러그인
    4. maven-jar-플러그인
    5. maven 개인 서버에 jar 패키지 업로드
  • ELK 로그 수집
    • FileBeat+Logstash+ES를 사용하여 분산 로그 수집 실현
    • maven(logstash-logback-encoder) + Logstash +ES를 사용하여 분산 로그 수집 실현

데브옵스 CI/CD

데브옵스:

  • 즉, 개발(development)과 운영(operations and maintenance)의 합성어로 응용 프로그램이나 소프트웨어 엔지니어링 개발 사이의 커뮤니케이션, 협업 및 협력을 촉진하기 위해 사용되는 프로세스, 방법 및 시스템 그룹을 총칭하는 용어입니다. 기술 운영 및 품질 보증 QA 부서 통합

CI/CD:

  • CI는 개발자를 위한 자동화된 프로세스인 지속적인 통합을 의미합니다. 성공적인 CI는
    새로운 코드 변경이 정기적으로 빌드, 테스트 및 공유 저장소(예: Git 또는 SVN)로 병합됨을 의미합니다.
  • CD는 지속적인 제공 및 지속적인 배포를 나타냅니다. 성공적인 CD는 운영자가
    공유 저장소에서 최신 제품 사본을 지속적으로 얻을 수 있고 최신 제품 사본을 서버에 올바르게 업데이트할 수 있음을 의미합니다.

Gitlab(무료 버전 및 유료 버전)

  • GitLab은 기업에서 가장 일반적으로 사용되는 프라이빗 코드 웨어하우스 솔루션입니다.
  • GitLab은 무료 CE 커뮤니티 에디션과 유료 EE 엔터프라이즈 에디션으로 구분되는 오픈 소스 프로젝트입니다.
  • GitLab은 많은 백그라운드 서비스를 배포해야 하며 일반적으로 단일 시스템의 메모리가 4G보다 낮지 않아야 하는 것이 좋습니다. 구성이 너무 낮으면 이상한 문제가 많이 발생합니다.
  • Linux 서버에는 여러 서비스가 미리 설치되어 있어야 합니다 yum install -y curl policycoreutils-python openssh-server. 이미 설치되어 있는 경우 이 단계를 생략할 수 있습니다.
  • GitLab 설치 패키지를 가져옵니다. GitLab 커뮤니티 버전 다운로드 주소 https://packages.gitlab.com/gitlab/gitlab-ce. 전자 상거래 프로젝트에 사용되는 Linux 서버를 다운로드하도록 선택할 수 있습니다.gitlab-ce-15.1.0-ce.0.el7.x86_64.rpm
  • GitLab Execute를 설치하여 설치 rpm -Uvh gitlab-ce-15.1.0-ce.0.el7.x86_64.rpm시작
  • 설치가 완료된 후 GitLab을 처음 실행하기 전에 구성 초기화 작업을 수행해야 합니다. gitlab-ctl reconfig이 과정은 오랜 시간이 걸립니다
  • gitlab-ctl 명령을 사용하여 gitlab 서비스를 작동
    gitlab-ctl reconfigure하고 gitlab을 재구성합니다.
    gitlab-ctl start gitlab 시작 gitlab
    gitlab-ctl stop중지 gitlab
    gitlab-ctl restart 다시 시작
    gitlab-ctl statusgitlab 서비스 상태 보기
    gitlab-ctl tail gitlab 서비스 로그 보기
  • 서비스가 시작되면 gitlab 서비스에 접근할 수 있습니다. 기본 서비스 포트는 포트 80입니다. 기본 사용자 이름과 비밀번호는
    root/123456입니다(일반적으로 로그인 후 기본 비밀번호를 즉시 변경하는 것이 좋습니다).
  • 액세스 주소 및 포트(기본적으로만 액세스 가능)를 수정하고 /etc/gitlab/gitlab.rb 구성 파일을 수정하고 그 안에 있는 external_url 속성을 수정할 수 있습니다.

젠킨스

Jenkins는 기업에서 가장 일반적으로 사용되는 자동 배포 소프트웨어입니다. 다운로드 주소는 https://www.jenkins.io/download/입니다.
LTS(장기 지원) 버전의 war 패키지 배포를 다운로드하는 것이 좋습니다.jenkins.war

  • JDK 설치 필요 - Jenkins를 실행하려면 JDK 환경 지원이 필요합니다. 현재 Jenkins는 JDK11 버전 사용을 권장합니다.
  • Jenkins 시작 - 시작 명령 nohup java -jar jenkins.war --httpPort=8080 &포트는 기본적으로 포트 8080입니다.
  • 첫 번째 시작 프로세스 중에 Jenkins는 로그 파일에 기본 관리자 암호를 인쇄합니다.xxxxxxxxxxxxxxxxxxxxxxx
  • 시작이 완료되면 Jenkins의 프런트 엔드 관리 페이지를 방문할 수 있으며 http://x.x.x.x:8080/처음 방문하는 경우 프런트 엔드 페이지에서 일부 초기화 작업을 안내합니다. 예를 들어 시작 로그에 있는 admin 사용자의 기본 암호를 입력해야 합니다.
  • 일부 플러그인 설치 안내 및 나중에 플러그인을 설치할 수도 있습니다.
  • 플러그인 관리 페이지에는 Git, Git 클라이언트, NodeJS 플러그인, Maven 통합 플러그인, 현지화: 중국어(간체) 중국어 플러그인이 Manage Jenkins-> Manage Plugins포함됩니다
  • 다운로드가 완료된 후 일부 플러그인을 적용하려면 다시 시작해야 합니다. Jenkins를 다시 시작하는 방법은 브라우저에서 다시 시작 인터페이스에 직접 액세스하는 것입니다.
  • 여러 기본 구성 요소를 구성하려면
    • Mange Jenkins->Global ToolConfiguration 페이지에 들어가 Maven, Git 및 NodeJS 구성 요소를 구성해야 합니다.
    • yum -install git을 사용하여 git 클라이언트를 설치합니다.
    • Maven 및 NodeJS 플러그인, 공식 웹 사이트로 이동하여 해당 압축 패키지를 다운로드하고 압축을 푼 후 bin 하위 디렉토리를 환경 변수로 구성할 수 있습니다.

GitLab+Jenkins 기반 CI\CD의 신속한 구현

  1. 메이븐 프로젝트 만들기
  2. 프로젝트 빌드 및 배포 프로세스 구성
  3. 소스코드 관리 부분은 해당 git 웨어하우스 주소, git 사용자명과 비밀번호, git branch를 설정한다.
  4. 빌드 트리거 - 선택적으로 Poll SCM 옵션을 구성합니다. 이 옵션은 Git 코드 웨어하우스를 정기적으로 스캔할 수 있습니다.
  5. 빌드 환경 섹션에서 JDK 버전을 선택하는 것이 좋습니다.
  6. 빌드 섹션에서 실행해야 하는 컴파일 스크립트를 선택할 수 있습니다.
    • 루트 폼pom.xml
    • pacakge -Dmaven.test.skip=true비슷한 mvn package -Dmaven.test.skip=true
    • 프론트엔드 프로젝트라면 Nodejs npm run build명령어 로 빌드해야 합니다.
  7. 빌드가 완료되면 백엔드 프로젝트의 각 모듈의 대상 디렉토리에 실행 가능한 패키지가 생성됩니다. 이때
    Jenkins를 사용하여 이러한 Jar 패키지를 원격 서버에 배포하고 직접 실행할 수 있습니다.
    • SSH 서버 대상 서버
    • 전송 세트 소스 파일은 Jar 주소를 실행합니다. 대상 루트 경로에서 검색 시작xx/tarter/xx-exec.jar
    • 접두사 제거 접두사를 사용하지 마십시오. 해당 jar 패키지만 전달됨을 나타냅니다.xx/tarter
    • 디렉토리 제거 원격 서버의 대상 주소/xxx
    • exec 명령 원격 서버에서 실행되는 시작 스크립트
      • 후단
        ps -ef | grep *demo* | grep -v grep | awk '{print $2}' | xargs kill -9
        nohup java -jar ../../xx-exec.jar > /app/xxx/xxx.log 2 > &1 %
        
      • 프런트 엔드
        nginx -s reload
        
  8. 코드 품질 감지 Blue Ocean 플러그인
  9. 태스크 파이프라인
  10. MeterSphere는 자동화된 인터페이스 테스트를 완료합니다.
  11. 또는 SonarQube 서비스를 구축하고 jenkins를 통해 통합합니다. 이런 식으로 SonarQube 서비스를 코드 품질 검사에 사용할 수 있습니다.
  12. 가상화 배포를 위해 Docker 통합

백엔드 프로젝트 패키징 및 배포 방법

1. jar 패키지는 다음과 같이 spring-boot-maven-plugin에 의해 입력됩니다 所有的依赖都打在了一个包中, 包太大, 但是可以直接使用Java -jar指令执行. 이렇게 큰 Jar 패키지를 컴파일하는 것은 시간이 많이 걸리고 네트워크에서 전송하는 것이 매우 번거로울 것입니다.사실 대부분의 종속 패키지는 jdbc, mybatis 등을 변경하지 않습니다.

여기에 이미지 설명 삽입

<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<version>2.3.12.RELEASE</version>
	<executions>
	    <!-- 不排除repackage, 打包会多大一次 将原始Maven打包的jar重命名为XXX.jar.original作为原始文件 
	    包含:类文件和配置文件,还会包含应用所依赖的jar包以及Springboot启动相关类(loader等),以此来满足Springboot独立应用的特性 -->
		<execution>
			<goals>
				<goal>repackage</goal>
			</goals>
		</execution>
	</executions>
	<!-- 解决运行包不能被其他包依赖的问题 -->
	<configuration>
		<classifier>exec</classifier>
	</configuration>
</plugin>

2. maven-dependency-plugin은 모두 결합할 수 있으므로 依赖的jar包都放到export文件夹中파일 target目录下的jar包只包含当前项目的源码크기가 훨씬 작아집니다.

  • 현재 프로젝트의 소스 코드
    여기에 이미지 설명 삽입
  • 종속 jar 패키지
    여기에 이미지 설명 삽입
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
     <version>2.10</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <!-- 将依赖包放入export文件夹 -->
                <outputDirectory>export</outputDirectory>
                <excludeTransitive>false</excludeTransitive>
                <stripVersion>true</stripVersion>
            </configuration>
        </execution>
    </executions>
</plugin>
  • java -cp 指定Classpath 和 启动类도구를 통해 종속성을 배포 및 추가하는 방법rsync
#!/bin/sh

#执行jar包
RUN_LIBS=""

#依赖jar包 自行制定目录
SUPPORT_LIBS=""
RUN_LIB_PATH="/app/lib"
SUPPORT_LIB_PATH="/app/support"

#加载程序包
for i in ${RUN_LIB_PATH}/* ; do
  RUN_LIBS=${RUN_LIBS}:$i
done

#加载依赖包
for i in ${SUPPORT_LIB_PATH}/* ; do
  SUPPORT_LIBS=${SUPPORT_LIBS}:$i
done

#整合classpath
CLASSPATH=${RUN_LIBS}:${SUPPORT_LIBS}
export CLASSPATH

#调用java指令执行。-D输入参数 java中可以用 System.getProperties读取。同时指定执行入口类 SpringBootApplication 这是一个典型的Springboot的执行方式。
java -Xdebug -Xnoagent -Djava.compiler=NONE - Xrunjdwp:transport=dt_socket,server=y,address=27899,suspend=n -cp $CLASSPATH - Dspring.profiles.active=prod com.demo.DemoAdminApplication -D user.timezone=GMT+08 1>demo-admin.out 2>demo-admin.err & echo Start App Success!

3. 메이븐 공식 홈페이지 플러그인

https://maven.apache.org/plugins/index.html

  • Maven 리포지토리의 최신 커밋 레코드를 출력할 수 있는 changelog 플러그인
  • checkstyle 및 pmd 플러그인은 코드를 정적으로 확인할 수 있습니다.
  • javadoc 플러그인은 프로젝트 문서를 인쇄할 수 있으며 pdf 플러그인을 사용하여 프로젝트 문서의 pdf 버전을 인쇄할 수도 있습니다.
  • 일부 ant 스크립트를 실행하는 Antrun 플러그인(오래된 프로그래머는 ant에 익숙해야 함)
  • pmd 정적 코드 검사 도구 https://maven.apache.org/plugins/maven-pmd-plugin/

Pmd는 자체 규칙을 정의할 수 있습니다 https://maven.apache.org/plugins/maven-pmd-plugin/examples/multi-module-config.html

 <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-pmd-plugin</artifactId>
     <version>3.19</version>
     <executions>
         <execution>
             <phase>package</phase>
             <goals>
                 <goal>aggregate-pmd</goal>
             </goals>
         </execution>
     </executions>
 </plugin>

여기에 이미지 설명 삽입

여기에 이미지 설명 삽입

4. maven-jar-plugin 툴킷은 Jar 패키지에 포함되어 있습니다.<packaging>jar</packaging>

<modelVersion>4.0.0</modelVersion>
<artifactId>demo-common</artifactId>
<packaging>jar</packaging>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
        </plugin>
    </plugins>
</build>

5. maven-jar-plugin은 모든 코드를 하나의 jar 패키지로 출력하는 대신 다양한 모듈을 여러 개의 다른 jar 패키지로 출력합니다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.2.2</version>
    <configuration>
        <!-- manifest配置信息 主要是可以配置主执行类。有主执行类,可以用java -jar直接执行。没有的话就需要指定执行类 -->
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>support/</classpathPrefix>
                <mainClass>com.myapp.MyAppApplication</mainClass>
                <!-- 可以按上面的方式自己配置,也可以指定MF文件打包。 -->
                <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>myapp1-jar</id>
            <phase>package</phase>
            <goals>
                <goal>jar</goal>
            </goals>
            <configuration>
                <classifier>myapp</classifier>
                <includes>
                    <include>com/myapp/**</include>
                    <include>mybatis/**</include>
                    <include>templates/**</include>
                    <include>*.properties</include>
                    <include>dubbo.xml</include>
                </includes>
            </configuration>
        </execution>
        <execution>
            <id>myapp2-jar</id>
            <phase>package</phase>
            <goals>
                <goal>jar</goal>
            </goals>
            <configuration>
                <classifier>myapp2</classifier>
                <includes>
                    <include>com/myapp2/crawler/*</include>
                    <include>com/myapp2/crawler/*</include>
                    <include>com/myapp2/utils/**</include>
                    <include>log4j.properties</include>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

6. maven 사설 서버에 jar 패키지 업로드mvn deploy -P release

distributionManagement에서 스냅샷 스냅샷 라이브러리 및 릴리스 릴리스 라이브러리의 주소 구성

 <distributionManagement>
     <repository>
         <id>maven-public</id>
         <name>release</name>
         <url>http://x.x.x.x:8081/repository/maven-releases/</url>
     </repository>

     <snapshotRepository>
         <id>maven-public-snapshot</id>
         <name>snapshot</name>
         <url>http://x.x.x.x:8081/repository/maven-snapshots/</url>
     </snapshotRepository>
 </distributionManagement>

메이븐~/.m2/settings.xml

<server>  
  <id>nexus-releases</id>  
  <username>admin</username>  
  <password>admin123</password>  
</server>  
  
<server>  
  <id>nexus-snapshots</id>  
  <username>admin</username>  
  <password>admin123</password>  
</server>  

ELK 로그 수집

ELK 아키텍처: https://blog.csdn.net/menxu_work/article/details/126032167

Prometheus 및 Grafana 자동 모니터링: https://blog.csdn.net/menxu_work/article/details/125776376

FileBeat+Logstash+ES를 사용하여 분산 로그 수집 실현

maven(logstash-logback-encoder) + Logstash +ES를 사용하여 분산 로그 수집 실현

logstash 로그백 인코더

<!-- apm-toolkit-logback-1.x -->
<dependency>
	<groupId>org.apache.skywalking</groupId>
	<artifactId>apm-toolkit-logback-1.x</artifactId>
	<version>8.9.0</version>
</dependency>

<dependency>
	<groupId>net.logstash.logback</groupId>
	<artifactId>logstash-logback-encoder</artifactId>
	<version>6.3</version>
</dependency>

net.logstash.logback.appender.LogstashTcpSocketAppender<destination>logstash.localhost.com:5055</destination>

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!-- 控制台 Appender -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志的格式化 -->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern>
            </layout>
        </encoder>
    </appender>

    <!-- https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-logback-1.x/  -->
    <!-- 通过grpc上报日志到skywalking oap-->
    <appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n</Pattern>
            </layout>
        </encoder>
    </appender>

    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>1024</queueSize>
        <neverBlock>true</neverBlock>
        <appender-ref ref="console"/>
    </appender>

    <!-- add converter for %tid -->
    <conversionRule conversionWord="tid" converterClass="org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter"/>
    <!-- add converter for %sw_ctx -->
    <conversionRule conversionWord="sw_ctx" converterClass="org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackSkyWalkingContextPatternConverter"/>
    <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>logstash.localhost.com:5055</destination>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                       {
                        "level": "%level",
                        "tid": "%tid",
                        "skyWalkingContext": "%sw_ctx",
                        "thread": "%thread",
                        "class": "%logger{1.}:%L",
                        "message": "%message",
                        "stackTrace": "%exception{10}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <!-- 设置 Appender -->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="grpc-log"/>
        <appender-ref ref="async"/>
        <appender-ref ref="logstash" />
    </root>
</configuration>

Supongo que te gusta

Origin blog.csdn.net/menxu_work/article/details/128211795
Recomendado
Clasificación