本地多服务调试:开十个窗口?不如看看我怎么操作!

很多人搞开发的程序员都有着一颗创业心,但手里只有锤子和钉子(技术),对于做什么都没有什么想法(产品),个人觉得主要是因为程序员技术至上的思维,沉迷钻研技术,忽略了工作生活中的需求。正所谓需求来源于生活,so,如何通过技术实现需求,是每个程序员都需要思考的问题。作为一名程序员,你是否有过这样的感觉你觉得自己技术很牛,但你不知道该如何应用到实际工作中,你觉得自己技术不过关,但你又不知道如何突破瓶颈。今天分享一个我日常工作中提效的一个方法,并将整个版本的迭代过程分享给大家,希望能给你一些启发。 项目源码:github.com/Benny66/dev...

背景

我接手了一个项目,这个项目被拆分成多个不同的微服务,也有着不同的客户端(PC端、移动端),每一个服务都是一个独立的项目仓库,以下是该项目微服务架构缩略图:

在日常的开发过程中,经常需要启动、切换多个不同的服务来进行本地调试,比如启动一个后端服务,启动一个前端服务,启动一个数据计算服务等等。每次启动服务都需要打开一个新的命令行窗口,输入命令,等待服务启动完成,然后才能进行下一步操作。这样的工作效率非常低下,特别是当你需要启动的服务很多的时候,效率就更低了。

为了提高效率,我们可以把多个服务启动命令整合到一起,然后通过一个脚本来启动所有服务。这样只需要打开一个命令行窗口,输入脚本命令,就可以启动所有服务,而且可以同时启动多个服务,大大提高了工作效率。

技术选型

因为本地使用mac环境开发,所以选用shell脚本来实现。

第一版本

分析了平时工作中启动服务的流程,发现每次启动服务都需要打开一个新的命令行窗口,输入命令(yarn dev 或者 php bin/swoft http:start),等待服务启动完成,然后打开另一个服务,重复上面的操作。 所以,我们可以把启动命令整合到一起,然后通过一个脚本来启动所有服务。

这个版本包括了启动脚本和关闭脚本,启动脚本会启动所有服务,关闭脚本会杀死所有服务的进程。

  • 启动脚本原理就是遍历所有服务的绝对目录,然后启动服务的命令,并将输出写入日志文件。
  • 启动命令:./start.sh
  • 关闭脚本通过pgrep遍历进程列表,然后kill掉所有进程。
  • 关闭命令:./kill.sh

启动脚本

bash 复制代码
#!/bin/bash

# 执行本脚本需添加脚本权限
# chmod +x start.sh

# 定义日志文件路径
LOG_DIR=/Users/shahao/Project/tencent/script


# 定义函数,启动指定目录下的命令,并将输出写入日志文件
function start_command {
    local dir=$1
    local command=$2
    local log_file=$3
    echo "Starting $command in $dir ..."
    cd "$dir" || { echo "Failed to change directory to $dir."; exit 1; }
    # 本地还有其他前端项目,这个项目需要切换node版本为16
    if [ "$command" == "yarn dev" ]; then
        source ~/.nvm/nvm.sh
        nvm use 16
    fi
    nohup $command 2>&1 | tee "$log_file" &
    echo "Started $command."
}

# 启动 tpp_flow_srv,自行替换路径、脚本启动目录、日志存储名称
# start_command "/absolute_path" "your_cmd" "$LOG_DIR/your_log_filename.txt"
start_command "/Users/shahao/Project/tencent/elf" "air" "$LOG_DIR/tpp_flow_srv_log.txt"

# 启动 tpp_flow_web
start_command "/Users/shahao/Project/tencent/tpp_flow_web" "pnpm dev" "$LOG_DIR/tpp_flow_web_log.txt"

# 启动 dev_frame_service
start_command "/Users/shahao/Project/tencent/dev_frame_service" "php bin/swoft http:start" "$LOG_DIR/dev_frame_service_log.txt"

# 启动 dev_platform_web
start_command "/Users/shahao/Project/tencent/dev_platform_web" "yarn dev" "$LOG_DIR/dev_platform_web_log.txt"

关闭脚本

bash 复制代码
#!/bin/bash


# 定义需要杀死的进程列表
processes=(
    "php bin/swoft http:start"
    "air"
    "node /Users/shahao/.yarn/bin/yarn.js dev"
    "node /usr/local/bin/pnpm dev"
)

# 定义函数,杀死指定进程名的进程
function kill_process {
    local process_name=$1
    local pid=$(pgrep -f "$process_name")
    if [[ -n $pid ]]; then
        kill $pid
        echo "已杀死进程 $process_name $pid"
    else
        echo "未找到进程 $process_name"
    fi
}

# 遍历进程列表,执行杀死进程的操作
for process in "${processes[@]}"; do
    kill_process "$process"
done

第二版本

第一个版本将启动的命令写死在脚本中,这样每次启动都需要修改脚本,不利于后期维护。

第二个版本迭代

1、支持参数化启动,通过参数指定要启动的服务,这样可以灵活地启动不同的服务。

2、修复一下关闭脚本的bug。通过pid关闭进程但实际上会服务端口一直在占用,所以kill掉进程失败后,通过端口查询进程是否存在,如果存在,则kill掉进程。

3、新增查看权限项目服务状态参数,可以查看各个服务的运行状态。

4、shell脚本优化,使用函数封装逻辑,提高可读性。

  • 定义参数base为基础服务底座,user为用户端服务,rights为业务端服务,admin为超管端服务。

  • 启动脚本:./start.sh -r rights

bash 复制代码
# 初始化数组

params=()  # 使用数组来存储权限值

# 检查参数数量
if [[ $# -eq 0 ]]; then
    echo "错误:没有提供参数。"
    exit 1
fi

# 遍历所有传入的参数
while [[ $# -gt 0 ]]; do
    case "$1" in
        -r | run | -k | kill | status)
            if [[ -n "$2" ]]; then
                process_option "$1" "$2" params
                # 根据选项设置 action 变量
                case "$1" in
                    -r) action='run' ;;
                    -k) action='kill' ;;
                    status) action='status' ;;
                esac
                shift 2  # 移过选项和它的参数
            else
                echo "错误:$1 选项需要一个参数。"
                exit 1
            fi
            ;;
        -h | --help)
            help_info
            exit 0
            ;;
        *)
            echo "未知的选项 $1"
            exit 1
            ;;
    esac
done
# .. 省略其他代码
# 启动命令
function run {
    isRunBaseProject=false
    # 遍历数组
    for param in "${params[@]}"; do
        echo "StartProcessing: $param"
        if [[ "$param" == "rights" ]]; then
            if [[ "$isRunBaseProject" == false ]]; then
                start_command "$BASE_PROJECT_DIR/dev_frame_service" "php bin/swoft http:start" "$LOG_DIR/dev_frame_service_log.log"
                start_command "$BASE_PROJECT_DIR/dev_platform_web" "yarn dev" "$LOG_DIR/dev_platform_web_log.log"
                isRunBaseProject=true
            fi
            # 当 right 为 rights 时,执行 start_command
            start_command "$RIGHTS_PROJECT_DIR/rights_web" "yarn dev" "$LOG_DIR/right_rights_web_log.log"
            start_command "$RIGHTS_PROJECT_DIR/rights_service" "./shell/watch.sh" "$LOG_DIR/right_rights_service_log.log"
        fi
        # ...可添加其他的服务启动逻辑
    done
}

help_info() {
    echo "错误:没有提供参数。"
    echo "-r 选项:启动权限项目服务,参数为权限值,如 -r base,user,rights,admin 启动全部权限项目服务。"
    echo "如:./rights.sh -r base,user,rights,admin"
    echo "-k 选项:杀死权限项目服务,参数为权限值,如 -k base,user,rights,admin 杀死全部权限项目服务。"
    echo "如:./rights.sh -k base,user,rights,admin"
    echo "status 选项:查看权限项目服务状态。"
    echo "如:./rights.sh status"
    echo "-h 选项:显示帮助信息。"
}

第三版本

第二个版本在启动服务虽然可以灵活地启动不同的服务,但还是存在一些问题:项目的目录,启动命令都写死在脚本中,新增服务需要修改脚本,不利于后期维护。

第三个版本迭代

1、支持配置文件启动,通过配置文件指定要启动的服务,这样可以灵活地配置启动参数。

2、支持自定义启动服务参数,通过参数指定要启动的服务,这样可以灵活地启动不同的服务。

3、优化脚本参数,使用函数封装逻辑,提高可读性。

.env 文件位于脚本同一目录下,它包含了运行脚本所需的配置信息。以下是 .env 文件的配置项示例:

ini 复制代码
# .env 文件
# .env 文件
LOG_DIR="/Users/shahao/Project/tencent/script"  # 日志文件存放目录

PROJECT_NAMES="BASE,RIGHTS"
BASE_PROJECT_DIR="/Users/shahao/Project/tencent"  # 基础项目目录
BASE_PROJECT_NAMES="TPP"                          # 项目为TPP
BASE_TPP_FRONTEND_PROJECT_NAME="dev_platform_web"   # TPP项目的前端服务
BASE_TPP_FRONTEND_RUN_CMD="yarn dev"                # TPP项目的前端服务启动命令
BASE_TPP_BACKEND_PROJECT_NAME="dev_frame_service"   # TPP项目的后端服务
BASE_TPP_BACKEND_RUN_CMD="./shell/watch.sh"         # TPP项目的后端服务启动命令

#...其他忽略的配置项

请确保在运行脚本前,您的 .env 文件已经正确配置了上述路径。

示例

  • 启动所有权限项目服务:
bash 复制代码
./rights.sh -r rights user
  • 杀死所有权限项目服务:
bash 复制代码
./rights.sh -k base tpp
  • 查看服务状态:
bash 复制代码
./rights.sh status rights user

自定义启动服务

自定义启动服务,需要在启动命令后面加上-c选项,如:

bash 复制代码
# 自定义项目配置
CUSTOM_PROJECT="BASE,RIGHTS"        # 自定义项目名称
CUSTOM_BASE_SERVER="TPP"            # 自定义项目的服务名称
CUSTOM_RIGHTS_SERVER="USER,RIGHTS"  # 自定义项目的服务名称

# 启动服务
./rights.sh -c

总结

通过脚本来启动服务,可以大大提高工作效率,提高工作质量。通过配置文件来配置启动参数,可以灵活地启动不同的服务,提高工作效率。通过自定义启动服务参数,可以灵活地启动不同的服务,提高工作效率。 希望通过这篇文章,能给你一些启发,提高工作效率,提高工作质量。如果有什么建议,欢迎留言。

相关推荐
轩情吖15 分钟前
一文速通stack和queue的理解与使用
开发语言·c++·后端·deque·优先级队列·stack和queue
ByteBlossom66637 分钟前
JavaScript语言的正则表达式
开发语言·后端·golang
Pandaconda43 分钟前
【新人系列】Python 入门(二十八):常用标准库 - 上
开发语言·经验分享·笔记·后端·python·面试·标准库
Wanna7151 小时前
后端开发基础——JavaWeb(Servlet)
java·后端·servlet·tomcat
生产队队长1 小时前
项目练习:若依后台管理系统-后端服务开发步骤(springboot单节点版本)
java·spring boot·后端
m0_748236831 小时前
【wiki知识库】08.添加用户登录功能--后端SpringBoot部分
java·spring boot·后端
Wanna7151 小时前
后端开发基础——JavaWeb(根基,了解原理)浓缩
java·后端·servlet·tomcat
轩辕烨瑾1 小时前
Bash语言的安全开发
开发语言·后端·golang
C++小厨神1 小时前
MATLAB语言的文件操作
开发语言·后端·golang
Linux520小飞鱼2 小时前
PHP语言的软件工程
开发语言·后端·golang