现状

现在的开发模式基本是微服务开发模式,一个服务依靠N个其它服务,一个前端依靠N个后端,假如本地要debug的话,将会是一件十分头疼的事,常见的debug模式有以下几种:

1. 叫相关开发人员将服务运转起来,然后连接调试
2. 自己将一切代码clone下来,自己在本地运转相关服务

如同也没什么问题,也能够调试,但是坏处也很明显

先说计划1的坏处

  1. 假如开发某天请假了,你没调试环境了,你还能调试吗?
  2. 假如开发又加了新功用,由于功用是个半成品,不安稳,导致你依靠的接口访问不了,你还能调试吗?

计划2的坏处

  1. 这个要求一切开发要熟悉整个技能栈的环境创立、编译构建相关的常识,比方:前端用的是 vue ,后端开发要装置 nodejs ,要懂一些 npm,vue 啥的,后端用的是 go,前端要装置 go ,要懂 go 的依靠装置,go 编译啥的
  2. 由于有多个服务,服务间假如用了相同端口,就会有端口抵触,改了端口后,相关依靠的服务都要修正,这就要求相关开发要对整个架构、服务依靠十分了解,不然必定十分折腾

上述计划都只是用一些本钱比较大的方式供给了一个不太安稳的开发环境

几个工具

docker

要保证开发环境的安稳,就需要一个不可变的基础设施,说到不可变基础设施,必定就要说一下docker了,docker镜像解决了PaaS标准化的问题,将PaaS变成了一个不可变基础设施,这样不管咱们在什么操作系统上,创立出来的实例都能够运转起来,装备一样的情况下,供给的服务也是一样的,但docker只保证单实例的一致性,咱们的服务有N多个,如何将它们建立关联关系并运转起来呢

docker-compose

docker-compose 能够声明一组服务,指定发动镜像、发动指令、暴露服务端口,能够很好的解决服务编排的问题

咱们用以下这种服务架构为例子,为每个使用创立一个开发环境

如何快速创建一个稳定的开发环境

docker 镜像来解决服务运转环境问题,每个项目有一个Dockerfilebuild-dev-image.sh文件,用build-dev-image.sh来构建当时分支下的代码,并pushdocker registry,依靠项目只需要引证相关版别的镜像就好了

如何快速创建一个稳定的开发环境

docker-compose来解决服务依靠问题,每个项目都要有一个docker-compose.yml文件,声明依靠服务的镜像版别,服务的端口

如何快速创建一个稳定的开发环境

构建开发环境 docker 镜像


前端

如何快速创建一个稳定的开发环境

Dockerfile 如下:

FROM nginx:1.19.2-alpine
COPY ./dist /usr/share/nginx/html

build-dev-image.sh 如下:

#!/bin/bash
pwdStr=`pwd`
dirName=${pwdStr##*/}
buildTime=`date '+%Y%m%d%H%M'`
harborHost="docker registry domain"
latestTag=$harborHost/dev/${dirName}:latest
buildTimeTag=$harborHost/dev/${dirName}:${buildTime}
harborUser="dev"
harborPasswd="xxxx"
npm run build
docker build -t $latestTag -t $buildTimeTag .
docker login $harborHost -u"$harborUser" -p"$harborPasswd"
docker push $latestTag
docker push $buildTimeTag
echo "docker镜像称号: $latestTag"
echo "docker镜像称号: $buildTimeTag"

build-dev-image.sh 主要做了:

  1. 构建 docker 镜像
  2. pushdocker registry

功用开发完了,要联调了,履行一下build-dev-image.sh,镜像就构建好了,并 push 到镜像库房了,需要的项目按需取

这儿输出了两个tag,一个是latest,一个是用年月日的,具体用哪个,看变更频频度,假如很频频就用年月日的,不然就用latest的,这样就不必老是修正docker-compose.yml

如何快速创建一个稳定的开发环境

后端

如何快速创建一个稳定的开发环境

Dockerfile

FROM alpine:3.11.6
COPY main /app/
EXPOSE 8000
WORKDIR /app
CMD ["/app/main"]

build-dev-image.sh

#!/bin/bash
pwdStr=$(pwd)
dirName=${pwdStr##*/}
buildTime=$(date '+%Y%m%d%H%M')
harborHost="docker registry domain"
latestTag=$harborHost/dev/${dirName}:latest
buildTimeTag=$harborHost/dev/${dirName}:${buildTime}
harborUser="dev"
harborPasswd="xxxx"
GOOS=linux CGO_ENABLED=0 go build -o main main.go
docker build -t $latestTag -t $buildTimeTag .
docker login $harborHost -u"$harborUser" -p"$harborPasswd"
docker push $latestTag
docker push $buildTimeTag
echo "docker镜像称号: $latestTag"
echo "docker镜像称号: $buildTimeTag"
rm -f main

如何快速创建一个稳定的开发环境

服务信息

先看下项目信息

graph TD
example-front --> examplea --> exampleb

exampleb

只是简单的输出一个字符串

package main
import (
 "log"
 "net/http"
)
func main() {
 http.HandleFunc("/b/api", func(writer http.ResponseWriter, request *http.Request) {
  log.Println(request.URL.Path)
  writer.Write([]byte("project b"))
 })
 http.ListenAndServe(":8000", nil)
}

examplea

调用examplab,并输出一个字符串

const (
 // 从装备服务中取
 PROJECT_B_DOMAIN = "http://exampleb:8000"
)
func main() {
 http.HandleFunc("/a/api", func(writer http.ResponseWriter, request *http.Request) {
  log.Println(request.URL.Path)
  resp, _ := http.Get(PROJECT_B_DOMAIN + "/b/api")
  defer resp.Body.Close()
  result, _ := io.ReadAll(resp.Body)
  writer.Header().Set("Access-Control-Allow-Origin", "*")
  writer.Write([]byte("project a<br/>"))
  writer.Write(result)
 })
 http.ListenAndServe(":8000", nil)
}

example-front

调用examplea

<template>
  <div id="app">
    <h1>
      Server Response: <br /><span v-html="resp"></span>
    </h1>
  </div>
</template>
<script>
import axios from "axios";
export default {
  name: "App",
  data() {
    return {
      resp: "",
    };
  },
  mounted() {
    axios.get("http://localhost:8000/a/api").then((resp) => {
      this.resp = resp.data;
    });
  },
};
</script>

创立开发环境

example-front

example-front依靠exampleaexamplea又依靠exampleb,所以咱们需要两个服务,并暴露examplea的端口到宿主机上,供前端调用

docker-compose.yml 如下:

version: '3'
services:
  examplea:
    image: {{docker registry domain}}/dev/examplea:latest
    ports:
      - 8000:8000
  exampleb:
    image: {{docker registry domain}}/dev/exampleb:latest

然后运转docker-compose up,再履行npm run serve,然后翻开浏览器就能够看到

如何快速创建一个稳定的开发环境

为了便利一些,咱们能够直接修正 package.jsonscripts,将docker-compose up -d加到serve上,这样咱们直接npm run serve 也能够有一个开发环境

"scripts": {
    "serve": "docker-compose up -d && vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }

examplea

docker-compose.yml 如下:

version: '3'
services:
  exampleb:
    image: {{docker registry domain}}/dev/exampleb:latest
  example-front:
    image: {{docker registry domain}}/dev/example-front:latest
    ports:
      - "8080:80"
  examplea:
    image: golang:1.19.5
    working_dir: "/go/src/examplea"
    # 调试模式,请制造一个包括go和delve的镜像
#    command: [ "dlv", "debug", "--headless", "--listen=:2345", "--api-version=2", "--accept-multiclient", "main.go" ]
    command: [ "go","run","main.go" ]
    volumes:
      - .:/go/src/examplea
    depends_on:
      - exampleb
      - example-front
    ports:
      - "8000:8000"
      - "2345:2345"

这儿为了有点差异,输出改成了debug project a<br/>

如何快速创建一个稳定的开发环境
直接 docker-compose upexample-front80映射成8080了,翻开浏览器输入http://localhost:8080

如何快速创建一个稳定的开发环境

exampleb

docker-compose.yml如下:

version: '3'
services:
  examplea:
    image: {{docker registry domain}}/dev/examplea:latest
    ports:
      - "8000:8000"
  example-front:
    image: {{docker registry domain}}/dev/example-front:latest
    ports:
      - "8080:80"
  exampleb:
    image: golang:1.19.5
    working_dir: "/go/src/exampleb"
    # 调试模式,请制造一个包括go和delve的镜像
#    command: [ "dlv", "debug", "--headless", "--listen=:2345", "--api-version=2", "--accept-multiclient", "main.go" ]
    command: [ "go","run","main.go" ]
    volumes:
      - .:/go/src/exampleb
    depends_on:
      - examplea
      - example-front
    ports:
      - "2345:2345"

这儿为了有点差异,输出改成了debug project b<br/>

如何快速创建一个稳定的开发环境

如何快速创建一个稳定的开发环境

总结

现在各项目只需要履行一下docker-compose up或许npm run serve就能够有一个安稳的开发环境了,再也不必由于环境的问题,折腾大半天,成果还不一定能折腾出来


go 项目也是能够启用 debug 模式,只需要找一个或许自己制造一下包括godelve的镜像,然后把command改成[ "dlv", "debug", "--headless", "--listen=:2345", "--api-version=2", "--accept-multiclient", "main.go" ],并将端口用ports映射一下就好了

golandGo Remote

如何快速创建一个稳定的开发环境

看到 API server listening at: [::]:2345,点击dubug就OK了

如何快速创建一个稳定的开发环境

如何快速创建一个稳定的开发环境

事例代码

examplea

exampleb

example-front

clone记得替换docker-compose.yml{{docker registry}},修正build-dev-image.sh中的registry信息