From 92d8c65aa0d03ad7af41a856789ff0e896533a92 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw-openim)" <3293172751nss@gmail.com> Date: Tue, 15 Aug 2023 15:35:57 +0800 Subject: [PATCH] feat: save all file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --- deployments/templates/init/README.md | 141 ++++++++++++++++++ deployments/templates/init/openim-api.service | 14 ++ .../templates/init/openim-crontask.service | 15 ++ deployments/templates/openim-crontask.yaml | 1 + scripts/install/environment.sh | 21 ++- scripts/install/openim-crontask | 106 ++++++------- scripts/lib/golang.sh | 2 +- scripts/lib/logging.sh | 6 +- scripts/lib/util.sh | 101 +++++++++++-- scripts/make-rules/golang.mk | 11 +- 10 files changed, 328 insertions(+), 90 deletions(-) create mode 100644 deployments/templates/init/README.md create mode 100644 deployments/templates/init/openim-api.service create mode 100644 deployments/templates/init/openim-crontask.service create mode 100644 deployments/templates/openim-crontask.yaml diff --git a/deployments/templates/init/README.md b/deployments/templates/init/README.md new file mode 100644 index 000000000..0210a8b87 --- /dev/null +++ b/deployments/templates/init/README.md @@ -0,0 +1,141 @@ +# Systemd 配置、安装和启动 + +- [Systemd 配置、安装和启动](#systemd-配置安装和启动) + - [0. 介绍](#0-介绍) + - [1. 前置操作(需要 root 权限)](#1-前置操作需要-root-权限) + - [2. 创建 openim-api systemd unit 模板文件](#2-创建-openim-api-systemd-unit-模板文件) + - [3. 创建 openim-crontask systemd unit 模板文件](#3-创建-openim-crontask-systemd-unit-模板文件) + - [6. 复制 systemd unit 模板文件到 sysmted 配置目录(需要有root权限)](#6-复制-systemd-unit-模板文件到-sysmted-配置目录需要有root权限) + - [7. 启动 systemd 服务](#7-启动-systemd-服务) + +## 0. 介绍 + +systemd是最新linux发行版管理后台的服务的默认形式,用以取代原有的init。 + +格式介绍: + +```bash +[Unit] :服务单元 + +Description:对该服务进行简单的描述 + +[Service]:服务运行时行为配置 + +ExecStart:程序的完整路径 + +Restart:重启配置,no、always、on-success、on-failure、on-abnormal、on-abort、on-watchdog + +[Install]:安装配置 + +WantedBy:多用户等 +``` + +更多介绍阅读:https://www.freedesktop.org/software/systemd/man/systemd.service.html + +启动命令: + +```bash +systemctl daemon-reload && systemctl enable openim-api && systemctl restart openim-api +``` + +服务状态: + +```bash +systemctl status openim-api +``` + +停止命令: + +```bash +systemctl stop openim-api +``` + +**为什么选择 systemd?** + +**高级需求:** + ++ 方便分析问题的服务运行日志记录 + ++ 服务管理的日志 + ++ 异常退出时可以根据需要重新启动 + +daemon不能实现上面的高级需求。 + +nohup 只能记录服务运行时的输出和出错日志。 + +只有systemd能够实现上述所有需求。 + +> 默认的日志中增加了时间、用户名、服务名称、PID等,非常人性化。还能看到服务运行异常退出的日志。还能通过/lib/systemd/system/下的配置文件定制各种需求。 + +总而言之,systemd是目前linux管理后台服务的主流方式,所以我新版本的 bash 抛弃 nohup,改用 systemd 来管理服务。 + + + +## 1. 前置操作(需要 root 权限) + +1. 根据注释配置 `environment.sh` + +2. 创建 data 目录 + +``` +mkdir -p ${OPENIM_DATA_DIR}/{openim-api,openim-crontask} +``` + +3. 创建 bin 目录,并将 `openim-api` 和 `openim-crontask` 可执行文件复制过去 + +```bash +source ./environment.sh +mkdir -p ${OPENIM_INSTALL_DIR}/bin +cp openim-api openim-crontask ${OPENIM_INSTALL_DIR}/bin +``` + +4. 将 `openim-api` 和 `openim-crontask` 配置文件拷贝到 `${OPENIM_CONFIG_DIR}` 目录下 + +```bash +mkdir -p ${OPENIM_CONFIG_DIR} +cp openim-api.yaml openim-crontask.yaml ${OPENIM_CONFIG_DIR} +``` + +## 2. 创建 openim-api systemd unit 模板文件 + +执行如下 shell 脚本生成 `openim-api.service.template` + +```bash +source ./environment.sh +cat > openim-api.service.template <>${LOG_FILE} 2>&1 & +# openim::util::check_process_names ${SERVER_NAME} -nohup ${SERVER_PATH} >>${log_file} 2>&1 & +# # Print the necessary information after installation +# function openim::crontask::info() { +# cat << EOF +# openim-crontask listen on: ${OPENIM_CRONTASK_HOST} +# EOF +# } -# Check launched service process -check=`ps | grep -w ./${cron_task_name} | grep -v grep| wc -l` -if [ $check -ge 1 ] -then -newPid=`ps | grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'` -allPorts="" - echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${cron_task_name}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} -else - echo -e ${BACKGROUND_GREEN}${cron_task_name}${COLOR_SUFFIX}${RED_PREFIX}"\n SERVICE START ERROR, PLEASE CHECK openIM.log"${COLOR_SUFFIX} -fi - - -# Print the necessary information after installation -function iam::pump::info() { -cat << EOF -iam-pumpn listen on: ${IAM_PUMP_HOST} -EOF -} - -# 安装 -function iam::pump::install() +# install openim-crontask +function openim::crontask::install() { - pushd ${IAM_ROOT} + pushd ${OPENIM_ROOT} - # 1. 构建 iam-pump - make build BINS=iam-pump - iam::common::sudo "cp ${LOCAL_OUTPUT_ROOT}/platforms/linux/amd64/iam-pump ${IAM_INSTALL_DIR}/bin" + # 1. Build openim-crontask + make build BINS=${SERVER_NAME} + openim::common::sudo "cp ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/bin" - # 2. 生成并安装 iam-pump 的配置文件(iam-pump.yaml) + # 2. Generate and install the openim-crontask configuration file (openim-crontask.yaml) echo ${LINUX_PASSWORD} | sudo -S bash -c \ - "./scripts/genconfig.sh ${ENV_FILE} configs/iam-pump.yaml > ${IAM_CONFIG_DIR}/iam-pump.yaml" + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/openim-crontask.yaml > ${OPENIM_CONFIG_DIR}/openim-crontask.yaml" - # 3. 创建并安装 iam-pump systemd unit 文件 + # 3. Create and install the openim-crontask systemd unit file echo ${LINUX_PASSWORD} | sudo -S bash -c \ - "./scripts/genconfig.sh ${ENV_FILE} init/iam-pump.service > /etc/systemd/system/iam-pump.service" + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/init/openim-crontask.service > /etc/systemd/system/openim-crontask.service" - # 4. 启动 iam-pump 服务 - iam::common::sudo "systemctl daemon-reload" - iam::common::sudo "systemctl restart iam-pump" - iam::common::sudo "systemctl enable iam-pump" - iam::pump::status || return 1 - iam::pump::info + # 4. Start the openim-crontask service + openim::common::sudo "systemctl daemon-reload" + openim::common::sudo "systemctl restart openim-crontask" + openim::common::sudo "systemctl enable openim-crontask" + openim::crontask::status || return 1 + openim::crontask::info - iam::log::info "install iam-pump successfully" + openim::log::info "install openim-crontask successfully" popd } -# 卸载 -function iam::pump::uninstall() +# Unload +function openim::crontask::uninstall() { set +o errexit - iam::common::sudo "systemctl stop iam-pump" - iam::common::sudo "systemctl disable iam-pump" - iam::common::sudo "rm -f ${IAM_INSTALL_DIR}/bin/iam-pump" - iam::common::sudo "rm -f ${IAM_CONFIG_DIR}/iam-pump.yaml" - iam::common::sudo "rm -f /etc/systemd/system/iam-pump.service" + openim::common::sudo "systemctl stop openim-crontask" + openim::common::sudo "systemctl disable openim-crontask" + openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/bin/openim-crontask" + openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/openim-crontask.yaml" + openim::common::sudo "rm -f /etc/systemd/system/openim-crontask.service" set -o errexit - iam::log::info "uninstall iam-pump successfully" + openim::log::info "uninstall openim-crontask successfully" } -# 状态检查 -function iam::pump::status() +# Status Check +function openim::crontask::status() { - # 查看 iam-pump 运行状态,如果输出中包含 active (running) 字样说明 iam-pump 成功启动。 - systemctl status iam-pump|grep -q 'active' || { - iam::log::error "iam-pump failed to start, maybe not installed properly" + # 查看 openim-crontask 运行状态,如果输出中包含 active (running) 字样说明 openim-crontask 成功启动。 + systemctl status openim-crontask|grep -q 'active' || { + openim::log::error "openim-crontask failed to start, maybe not installed properly" return 1 } # 监听端口在配置文件中是 hardcode if echo | telnet 127.0.0.1 7070 2>&1|grep refused &>/dev/null;then - iam::log::error "cannot access health check port, iam-pump maybe not startup" + openim::log::error "cannot access health check port, openim-crontask maybe not startup" return 1 fi } -if [[ "$*" =~ iam::pump:: ]];then +if [[ "$*" =~ openim::crontask:: ]];then eval $* fi diff --git a/scripts/lib/golang.sh b/scripts/lib/golang.sh index ba9f51a1c..05c926f39 100755 --- a/scripts/lib/golang.sh +++ b/scripts/lib/golang.sh @@ -94,7 +94,7 @@ readonly OPENIM_SERVER_BINARIES=("${OPENIM_SERVER_TARGETS[@]##*/}") START_SCRIPTS_PATH="${OPENIM_ROOT}/scripts/install/" openim::golang::start_script_list() { local targets=( - start_rpc_service.sh + start-rpc_service.sh push_start.sh msg_transfer_start.sh msg_gateway_start.sh diff --git a/scripts/lib/logging.sh b/scripts/lib/logging.sh index 5b9f8dbdc..502323706 100755 --- a/scripts/lib/logging.sh +++ b/scripts/lib/logging.sh @@ -25,17 +25,17 @@ if [[ ! -v OPENIM_OUTPUT ]]; then fi # Set the log file path -log_file="${OPENIM_OUTPUT}/logs/openim_$(date '+%Y%m%d').log" +LOG_FILE="${OPENIM_OUTPUT}/logs/openim_$(date '+%Y%m%d').log" if [[ ! -d "${OPENIM_OUTPUT}/logs" ]]; then mkdir -p "${OPENIM_OUTPUT}/logs" - touch "$log_file" + touch "$LOG_FILE" fi # Define the logging function function echo_log() { if $ENABLE_LOGGING; then - echo -e "$@" | tee -a "${log_file}" + echo -e "$@" | tee -a "${LOG_FILE}" else echo -e "$@" fi diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh index 690c8d043..6a6fb34dc 100755 --- a/scripts/lib/util.sh +++ b/scripts/lib/util.sh @@ -255,15 +255,15 @@ openim::util::host_arch() { # The function returns a status of 1 if any of the processes is not running. openim::util::check_ports() { # An array to collect ports of processes that are not running. - not_started=() + local not_started=() # An array to collect information about processes that are running. - started=() + local started=() # Iterate over each given port. for port in "$@"; do # Use the `lsof` command to find process information related to the given port. - info=$(lsof -i :$port -n -P | grep LISTEN || true) + local info=$(lsof -i :$port -n -P | grep LISTEN || true) # If there's no process information, it means the process associated with the port is not running. if [[ -z $info ]]; then @@ -271,9 +271,9 @@ openim::util::check_ports() { else # If there's process information, extract relevant details: # Process ID, Command Name, and Start Time. - pid=$(echo $info | awk '{print $2}') - command=$(echo $info | awk '{print $1}') - start_time=$(ps -o lstart= -p $pid) + local pid=$(echo $info | awk '{print $2}') + local command=$(echo $info | awk '{print $1}') + local start_time=$(ps -o lstart= -p $pid) started+=("Port $port - Command: $command, PID: $pid, Start time: $start_time") fi done @@ -304,6 +304,66 @@ openim::util::check_ports() { fi } +# The `openim::util::check_process_names` function analyzes the state of processes based on given names. +# It accepts multiple process names as arguments and prints: +# 1. The state of the process (whether it's running or not). +# 2. The start time of the process if it's running. +# User: +# openim::util::check_process_names nginx mysql redis +# The function returns a status of 1 if any of the processes is not running. +openim::util::check_process_names() { + # An array to collect names of processes that are not running. + local not_started=() + + # An array to collect information about processes that are running. + local started=() + + # Iterate over each given process name. + for process_name in "$@"; do + # Use the `pgrep` command to find process information related to the given process name. + local pid=$(pgrep -f $process_name) + # If there's no process information, it means the process with the given name is not running. + if [[ -z $pid ]]; then + not_started+=($process_name) + else + # If there's process information, extract relevant details: + # Command Name, and Start Time. + # local pid=$(echo $info | awk '{print $2}') + local command=$(ps -p $pid -o cmd=) + local start_time=$(ps -p $pid -o lstart=) + started+=("Process $process_name - Command: $command, PID: $pid, Start time: $start_time") + echo "---------------command=$command" + echo "---------------pid=$pid" + echo "---------------start_time=$start_time" + fi + done + + # Print information about processes which are not running. + if [[ ${#not_started[@]} -ne 0 ]]; then + openim::log::info "Not started processes:" + for process_name in "${not_started[@]}"; do + openim::log::error "Process $process_name is not started." + done + fi + + # Print information about processes which are running. + if [[ ${#started[@]} -ne 0 ]]; then + echo + openim::log::info "Started processes:" + for info in "${started[@]}"; do + openim::log::info "$info" + done + fi + + # If any of the processes is not running, return a status of 1. + if [[ ${#not_started[@]} -ne 0 ]]; then + return 1 + else + openim::log::success "All processes are running." + return 0 + fi +} + # The `openim::util::stop_services_on_ports` function stops services running on specified ports. # It accepts multiple ports as arguments and performs the following: # 1. Attempts to stop any services running on the specified ports. @@ -313,10 +373,10 @@ openim::util::check_ports() { # The function returns a status of 1 if any service couldn't be stopped. openim::util::stop_services_on_ports() { # An array to collect ports of processes that couldn't be stopped. - not_stopped=() + local not_stopped=() # An array to collect information about processes that were stopped. - stopped=() + local stopped=() # Iterate over each given port. for port in "$@"; do @@ -326,7 +386,7 @@ openim::util::stop_services_on_ports() { # If there's process information, it means the process associated with the port is running. if [[ -n $info ]]; then # Extract the Process ID. - pid=$(echo $info | awk '{print $2}') + local pid=$(echo $info | awk '{print $2}') # Try to stop the service by killing its process. if kill -TERM $pid; then @@ -363,6 +423,7 @@ openim::util::stop_services_on_ports() { fi } + # The `openim::util::stop_services_with_name` function stops services with specified names. # It accepts multiple service names as arguments and performs the following: # 1. Attempts to stop any services with the specified names. @@ -372,15 +433,15 @@ openim::util::stop_services_on_ports() { # The function returns a status of 1 if any service couldn't be stopped. openim::util::stop_services_with_name() { # An array to collect names of processes that couldn't be stopped. - not_stopped=() + local not_stopped=() # An array to collect information about processes that were stopped. - stopped=() + local stopped=() # Iterate over each given service name. for server_name in "$@"; do # Use the `pgrep` command to find process IDs related to the given service name. - pids=$(ps aux | awk -v pattern="$server_name" '$0 ~ pattern {print $2}') + local pids=$(ps aux | awk -v pattern="$server_name" '$0 ~ pattern {print $2}') for pid in $pids; do # If there's a Process ID, it means the service with the name is running. @@ -1117,8 +1178,20 @@ function openim::util::remove_space() { } function openim::util::gencpu() { - cpu=$(lscpu | grep -e '^CPU(s):' | awk '{print $2}') - echo $cpu + # Check the system type + system_type=$(uname) + + if [[ "$system_type" == "Darwin" ]]; then + # macOS (using sysctl) + cpu_count=$(sysctl -n hw.ncpu) + elif [[ "$system_type" == "Linux" ]]; then + # Linux (using lscpu) + cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l) + else + echo "Unsupported operating system: $system_type" + exit 1 + fi + echo $cpu_count } function openim::util::gen_os_arch() { diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 36f9a74bc..697eb565d 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -45,7 +45,7 @@ ifeq ($(origin GOBIN), undefined) endif # COMMANDS is Specify all files under ${ROOT_DIR}/cmd/ and ${ROOT_DIR}/tools/ except those ending in.md -COMMANDS ?= $(filter-out %.md, $(wildcard ${ROOT_DIR}/cmd/* ${ROOT_DIR}/tools/*)) +COMMANDS ?= $(filter-out %.md, $(wildcard ${ROOT_DIR}/cmd/* ${ROOT_DIR}/tools/* ${ROOT_DIR}/cmd/openim-rpc/*)) ifeq (${COMMANDS},) $(error Could not determine COMMANDS, set ROOT_DIR or run in source dir) endif @@ -134,16 +134,13 @@ go.build.%: $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) @echo "=====> COMMAND=$(COMMAND)" @echo "=====> PLATFORM=$(PLATFORM)" - @echo "=====> BIN_DIR=$(BIN_DIR)" @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS)_$(ARCH)" @mkdir -p $(BIN_DIR)/platforms/$(OS)/$(ARCH) @if [ "$(COMMAND)" == "openim-sdk-core" ]; then \ echo "===========> DEBUG: OpenIM-SDK-Core It is no longer supported for openim-server $(COMMAND)"; \ - elif [ "$(COMMAND)" == "openim-rpc" ]; then \ - for d in $(wildcard $(ROOT_DIR)/cmd/openim-rpc/*); do \ - cd $${d} && CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \ - $(BIN_DIR)/platforms/$(OS)/$(ARCH)/$$(basename $${d})$(GO_OUT_EXT) $${d}/main.go; \ - done; \ + elif [ -d $(ROOT_DIR)/cmd/openim-rpc/$(COMMAND) ]; then \ + CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \ + $(BIN_DIR)/platforms/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_DIR)/cmd/openim-rpc/$(COMMAND)/main.go; \ else \ if [ -f $(ROOT_DIR)/cmd/$(COMMAND)/main.go ]; then \ CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \