开源项目微服务改造--微人事

本文详细介绍了如何对微人事系统进行前后端分离部署,包括使用SpringBoot和Vue的项目结构,以及通过Jenkins、Kubernetes和Docker进行持续集成和部署的过程。涉及到的中间件有MySQL、Redis和RabbitMQ,并提供了代码库改造、Dockerfile和Jenkinsfile的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前后端分离项目:微人事(SpringBoot+Vue)

源码GitHub:https://github.com/lenve/vhr
克隆Gitee:https://gitee.com/duolili/vhr

部署方式1:多个代码仓库

前后端分离部署,前端nginx,后端jar,均使用单独的代码库

准备

环境

jenkins 2.387.1
git 1.8.3.1
node 14.0.0(更高版本构建报错)
maven 3.9.1
k8s 1.26.0(containerd)
harbor 2.2.2

代码库

基于 https://gitee.com/duolili/vhr ,拆分成两个代码库,运行2个微服务:

中间件
名称IP:PORT用户名密码备注
MySQL(5.7.38)192.168.1.156:13306rootCloudEasy2020新建空库:vhr
Redis(6.7.2单机)192.168.1.156:16379123456
RabbitMQ(3.8.11)192.168.1.156:15672
192.168.1.156:5672
adminCloudEasy2020

k8s
[root@master ~]# kubectl create ns test
[root@master ~]# kubectl create secret -n test docker-registry myregistrykey --docker-server=192.168.1.23:80 --docker-username=admin --docker-password=Harbor12345

代码库改造–后端

将源代码库中的 vhr 目录分离出来,新代码库命名:vhr-service
image.png
新库删除 mailserver 目录(用于新员工邮件通知,暂不使用),修改 pom.xml 文件,注释 mailserver jar
image.png
新库目录结构如下

├── Dockerfile
├── master-k8s
│   ├── Jenkinsfile
│   └── k8s.yaml
├── pom.xml
├── vhr.iml
└── vhrserver
    ├── pom.xml
    ├── vhr-mapper
    │   ├── pom.xml
    │   ├── src
    │   │   └── ...
    │   └── vhr-mapper.iml
    ├── vhr-model
    │   ├── pom.xml
    │   ├── src
    │   │   └── ...
    │   └── vhr-model.iml
    ├── vhrserver.iml
    ├── vhr-service
    │   ├── pom.xml
    │   ├── src
    │   │   └── ...
    │   └── vhr-service.iml
    └── vhr-web
        ├── pom.xml
        ├── src
        │   ├── main
        │   │   ├── java
        │   │   │   └──...
        │   │   └── resources
        │   │       ├── application.yml
        │   │       ├──...
        │   └── test
        │       └── ...
        └── vhr-web.iml

修改文件

修改中间件连接信息 vhrserver/vhr-web/src/main/resources/application.yml
image.png

新增文件
  • Dockerfile
#FROM java:openjdk-8
FROM 192.168.1.23:80/test/java:openjdk-8
ENV TZ=Asia/Shanghai
VOLUME /tmp
EXPOSE 8081
ENV JAVA_OPTS=$JAVA_OPTS
WORKDIR /home/apps/
ADD vhrserver/vhr-web/target/vhr-web-0.0.1-SNAPSHOT.jar .
ENTRYPOINT ["sh","-c","java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom,-Djava.awt.headless=true,-agentlib:jdwp=transport=dt_socket,address=0:8000,server=y,suspend=n -jar /home/apps/vhr-web-0.0.1-SNAPSHOT.jar"]

image.png

  • master-k8s/Jenkinsfile
pipeline {
    agent any
    parameters {
        string(name: "branch", defaultValue: "master", description: "code branch")
        choice(name: 'module',choices: ['vhrservice'], description: 'module_name')
    }
    stages{
        stage('setting env') {
            agent any
            options {
                skipDefaultCheckout(true)
            }
            steps {
                script {
                    env.NAMESPACE = "test"
                    env.PROJECT = "test"
                    env.IMAGE_NAME = "192.168.1.23:80/$PROJECT/$module:build-$BUILD_NUMBER"
                }
            }
        }	
        stage('get code'){
            steps{
                git branch: '${branch}', credentialsId: '209653a1-f5b9-4214-bac8-a927c8b36060', url: 'https://gitee.com/duolili/vhr-service.git'
            }
        }
        stage('vhrservice jar build'){
            when {
                environment name: 'module', value: 'vhrservice'            
            }
            steps {                
                sh "mvn clean install"
                //sh "mvn deploy -Dmaven.test.skip=true -U -e -X -B"    	
            }
        }                     


        stage('vhrservice image build'){
            when {
                environment name: 'module', value: 'vhrservice' 
            }
            steps{              
                script {		
                    def imageName = docker.build("$IMAGE_NAME")
                    docker.withRegistry('http://192.168.1.23:80/','5ed303ec-6229-488d-aa73-847e1bb8ee6c'){
                        imageName.push()
                    }
                    sh "/bin/docker rmi ${IMAGE_NAME}"                      
                }               
            }
        }

        stage('vhrservice deploy k8s'){
            when {
                environment name: 'module', value: 'vhrservice'
            }
            steps{

                script {
                    sh "sed -i 's/<BUILD_TAG>/${BUILD_NUMBER}/g' master-k8s/k8s.yaml"
                    sh "/home/jenkins/bin/kubectl apply -f master-k8s/k8s.yaml -n ${NAMESPACE} --kubeconfig /home/jenkins/.kube/config --record"
                }

            }
        }     	            	  		   

    }       

}

image.png

  • master-k8s/k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vhrservice
  labels:
    k8s-app: vhrservice
spec:
  replicas: 1
  revisionHistoryLimit: 3
  #滚动升级时70s后认为该pod就绪
  minReadySeconds: 70
  strategy:
    rollingUpdate:
      #滚动升级时会先启动1个pod    
      maxSurge: 1 
      #滚动升级时允许的最大Unavailable的pod个数      
      maxUnavailable: 1   
  selector:
    matchLabels:
      k8s-app: vhrservice
  template:
    metadata:
      labels:
        k8s-app: vhrservice
    spec:
      containers:
      - name: vhrservice
        image: 192.168.1.23:80/test/vhrservice:build-<BUILD_TAG>
        #resources:
          # need more cpu upon initialization, therefore burstable class
          #limits:
          #  memory: 4096Mi
          #  cpu:  2000m
          #requests:
          #  cpu: 1000m
          # memory:  2048Mi
        ports:
        #容器的端口
        - containerPort: 8081
          name: vhrservice
          protocol: TCP        
        readinessProbe:
          tcpSocket:
            port: 8081
          initialDelaySeconds: 120
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 8081
          initialDelaySeconds: 360
          periodSeconds: 20   
      imagePullSecrets:
      - name: myregistrykey    
---
apiVersion: v1
kind: Service
metadata:
  name: vhrservice
  labels:
    k8s-app: vhrservice
spec:
  ports:
  #集群IP的端口
  - port: 8081
    name: vhrservice
    protocol: TCP
    #容器的端口
    targetPort: 8081
  selector:
    k8s-app: vhrservice

jenkins流水线–后端

image.png
image.png
效果展示
image.png

代码库改造–前端

将源代码库中的 vuehr 目录分离出来,新代码库命名:vhr-ui
image.png
新库目录结构如下

├── babel.config.js
├── build.sh
├── default.conf
├── dev-k8s
│   ├── Jenkinsfile
│   └── k8s.yaml
├── Dockerfile
├── package.json
├── package-lock.json
├── public
│   ├── ...
├── README.md
├── ...
└── vue.config.js

新增文件
  • default.conf
gzip on;  #开启gzip
gzip_min_length 1k;  #低于1kb的资源不压缩
gzip_comp_level 5; #压缩级别【1-9】,越大压缩率越高,同时消耗cpu资源也越多,建议设置在4左右。
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;  #需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片,下面会讲为什么。
gzip_disable "MSIE [1-6]\.";  #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_vary on;  #是否添加“Vary: Accept-Encoding”响应头


upstream javaboy.org {
    server vhrservice:8081;
}

server {
        listen 80;
        server_name  127.0.0.1;

        location / {
            proxy_pass http://javaboy.org;
            proxy_redirect default;
        }
        location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff|html) {
            # 所有静态文件直接读取硬盘
            root /usr/share/nginx/html/;
            expires 30d; #缓存30天
        }


        ssl_protocols TLSv1.2;

        error_page 405 =200 http://$host$request_uri;

        

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}
  • Dockerfile
#设置基础镜像
FROM nginx

#WORKDIR /home/apps/

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone
	
#将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
COPY dist/  /usr/share/nginx/html/

#ADD ca/ /etc/nginx/ca/

#删除nginx 默认配置
RUN rm /etc/nginx/conf.d/default.conf
#添加自己的配置 default.conf 在下面
ADD default.conf /etc/nginx/conf.d/
#使用自定义nginx.conf配置端口和监听
#COPY nginx.conf /etc/nginx/nginx.conf

RUN ln -sf /dev/stdout /var/log/nginx/broker.access.log \
	&& ln -sf /dev/stderr /var/log/nginx/broker.error.log
  
#EXPOSE 8088

CMD ["nginx","-g","daemon off;"]
  • dev-k8s/Jenkinsfile
pipeline {
    agent any
    parameters {
	    string(name: "branch", defaultValue: "master", description: "code branch")
        choice(name: 'module',choices: ['vhrui'], description: 'module_name')
    }
    stages{
		stage('setting env') {
		  agent any
		  options {
			skipDefaultCheckout(true)
		  }
		  steps {
			script {
			  env.NAMESPACE = "test"
              env.PROJECT = "test"
              env.IMAGE_NAME = "192.168.1.23:80/$PROJECT/$module:build-$BUILD_NUMBER"
			}
		  }
		}	
        stage('get code'){
            steps{
			          git branch: '${branch}', credentialsId: '209653a1-f5b9-4214-bac8-a927c8b36060', url: 'https://gitee.com/duolili/vhr-ui.git'
            }
        }
        stage('vhrui npm build'){
             when {
                environment name: 'module', value: 'vhrui'            
            }
            steps {                
                sh "/usr/local/node14/bin/npm install"
                sh "/usr/local/node14/bin/npm run build"       	
              }
          }                     


        stage('vhrui image build'){
            when {
                environment name: 'module', value: 'vhrui' 
            }
           steps{              
                  script {		
						        def imageName = docker.build("$IMAGE_NAME")
                                docker.withRegistry('http://192.168.1.23:80/','5ed303ec-6229-488d-aa73-847e1bb8ee6c'){
						          	imageName.push()
						        }
						          sh "/bin/docker rmi ${IMAGE_NAME}"                      
				    }               
		    }
        }

        stage('adminui deploy k8s'){
           when {
               environment name: 'module', value: 'vhrui'
           }
           steps{
             
                    script {
                    sh "sed -i 's/<BUILD_TAG>/${BUILD_NUMBER}/g' dev-k8s/k8s.yaml"
                    sh "/home/jenkins/bin/kubectl apply -f dev-k8s/k8s.yaml -n ${NAMESPACE} --kubeconfig /home/jenkins/.kube/config --record"
                  }
                   
            }
        }     	            	  		   

    }       

}
  • dev-k8s/k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vhrui
  labels:
    k8s-app: vhrui
spec:
  replicas: 1
  revisionHistoryLimit: 3
  #滚动升级时70s后认为该pod就绪
  minReadySeconds: 70
  strategy:
    rollingUpdate:
      #滚动升级时会先启动1个pod    
      maxSurge: 1 
      #滚动升级时允许的最大Unavailable的pod个数      
      maxUnavailable: 1   
  selector:
    matchLabels:
      k8s-app: vhrui
  template:
    metadata:
      labels:
        k8s-app: vhrui
    spec:
      containers:
      - name: vhrui
        image: 192.168.1.23:80/test/vhrui:build-<BUILD_TAG>
        #resources:
          # need more cpu upon initialization, therefore burstable class
          #limits:
          #  memory: 4096Mi
          #  cpu:  2000m
          #requests:
          #  cpu: 1000m
          # memory:  2048Mi
        ports:
        #容器的端口
        - containerPort: 80
          name: vhrui
          protocol: TCP        
        readinessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 120
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 360
          periodSeconds: 20   
      imagePullSecrets:
      - name: myregistrykey    
---
apiVersion: v1
kind: Service
metadata:
  name: vhrui
  labels:
    k8s-app: vhrui
spec:
  ports:
  #集群IP的端口
  - port: 80
    name: vhrui
    protocol: TCP
    #容器的端口
    targetPort: 80
  selector:
    k8s-app: vhrui
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: vhrui-http
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`vhrui.test.com`) && PathPrefix(`/`)
    kind: Rule
    services:
    - name: vhrui
      port: 80

jenkins流水线–前端

image.png
image.png
效果展示
image.png

web访问

http://vhrui.test.com/index.html

image.png
image.png
image.png

部署方式2:一个代码库

使用同一个代码库,分别部署前后端项目
代码库
https://gitee.com/duolili/vhr.git – dev分支

流水线–后端
image.png
image.png
流水线–前端
image.png
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值